Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/many-functions #45

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,17 @@ dotProp.set(obj, 'foo.$end', 'platin-unicorn')

```

### setMany

Set multiple nested values by passing a map of path: value

```javascript
// Setter
var obj = { foo: { bar: 'a' } };
// var obj2 = dotProp.set(dotProp.set(obj, 'foo.bar', 'b') , 'foo.baz', 'x');
var obj2 = dotProp.setMany(obj, { 'foo.bar': 'b', 'foo.baz': 'x' });
//obj2 => {foo: {bar: 'b', baz: 'x'}}
```

### delete

Expand Down
18 changes: 12 additions & 6 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
type Path = number | string | (string | number)[];

interface DotPropImmutable {
get<I, T = any>(source: I, path: number | string | (string | number)[], defaultValue?: any): T;
set<I, T = any>(source: I, path: number | string | (string | number)[], value: any): T;
delete<I, T = any>(source: I, path: number | string | (string | number)[]): Partial<T>;
toggle<I, T = any>(source: I, path: number | string | (string | number)[]): T;
merge<I, T = any>(source: I, path: number | string | (string | number)[], value: any): T;
get<I, T = any>(source: I, path: Path, defaultValue?: any): T;
set<I, T = any>(source: I, path: Path, value: any): T;
delete<I, T = any>(source: I, path: Path): Partial<T>;
toggle<I, T = any>(source: I, path: Path): T;
merge<I, T = any>(source: I, path: Path, value: any): T;
getMany<I, T = any>(): T;
setMany<I, T = any>(source, paths: Path[]): T;
deleteMany<I, T = any>(source: I, paths: Path[]): T;
toggleMany<I, T = any>(): T;
}

declare const dotPropImmutable: DotPropImmutable;

export = dotPropImmutable;
export = dotPropImmutable;
45 changes: 42 additions & 3 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,41 @@ function set(obj, prop, value) {
return setPropImmutableRec(obj, prop, value, 0);
}

/**
* Set many values defined in a map on the obj
* @param obj
* @param map
*/
function setMany(obj, map) {
return Object.keys(map).reduce((acc, path) => {
return set(acc, path, map[path]);
}, obj);
}

/**
*
*/
function getMany(obj, props) {
return props.map((prop) => get(obj, prop));
}

/**
*
*/
function deleteMany(obj, props) {
return props.reduce(_delete, obj);
}

function toggleMany(obj, props) {
return props.reduce((acc, current) => {
console.log('acc', acc);
console.log('current', current);

const toggled = toggle(acc, current);
console.log('toggled', toggled);
}, obj);
}

/**
* Get a value by a dot path.
* @param obj The object to evaluate.
Expand Down Expand Up @@ -59,8 +94,8 @@ function get(obj, prop, value) {
* If target container is an object, the property is deleted.
* If target container is an array, the index is deleted.
* If target container is undefined, nothing is deleted.
* @param obj The object to evaluate.
* @param prop The path to the property or index that should be deleted.
* @param {object} obj The object to evaluate.
* @param {string | number} prop The path to the property or index that should be deleted.
*/
function _delete(obj, prop) {
prop = typeof prop === 'number' ? propToArray(prop.toString()) : typeof prop === 'string' ? propToArray(prop) : prop;
Expand Down Expand Up @@ -169,5 +204,9 @@ module.exports = {
get,
delete: _delete,
toggle,
merge
merge,
setMany,
deleteMany,
getMany,
toggleMany
};
4 changes: 3 additions & 1 deletion test/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
"mocha": true
},
"globals": {
"expect": true
"expect": true,
"baseObj": true,
"baseArr": true
}
}
38 changes: 38 additions & 0 deletions test/dotPropImmutable/deleteMany.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const dotProp = require('../../lib');

describe('deleteMany.spec.js', () => {
describe('when provided one existent object key', () => {
it('should delete the object key', () => {
const actual = dotProp.deleteMany(baseObj, ['b']);

expect(actual).to.deep.equal({
a: 1,
c: [1, 2],
'b.x': 10
});
});
});
describe('when provided two existent object keys', () => {
it('should delete the object keys', () => {
const actual = dotProp.deleteMany(baseObj, ['a', 'b.x']);

expect(actual).to.deep.equal({
c: [1, 2],
b: { y: 2 },
'b.x': 10
});
});
});
describe('when provided two non-existent object keys', () => {
it('should delete the object keys', () => {
const actual = dotProp.deleteMany(baseObj, ['foo', 'bar']);

expect(actual).to.deep.equal({
a: 1,
c: [1, 2],
b: { x: 1, y: 2 },
'b.x': 10
});
});
});
});
59 changes: 59 additions & 0 deletions test/dotPropImmutable/getMany.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const dotProp = require('../../lib');

describe('getMany.spec.js', () => {
describe('when object', () => {
describe('when object keys exist', () => {
it('should return an an array of values', () => {
const actual = dotProp.getMany(baseObj, ['a', 'b']);

expect(actual).to.deep.equal([
1,
{
x: 1,
y: 2
}
]);
});
});
describe('when empty object', () => {
it('should return an array of undefined values', () => {
const actual = dotProp.getMany({}, ['a', 'b']);

expect(actual).to.deep.equal([
undefined,
undefined
]);
});
});
describe('when object key do not exist', () => {
it('should return an array of undefined value', () => {
const actual = dotProp.getMany(baseObj, ['foo']);

expect(actual).to.deep.equal([undefined]);
});
});
});
describe('when array', () => {
describe('when array[index] exist', () => {
it('should return expected', () => {
const actual = dotProp.getMany(baseArr, ['1.a']);

expect(actual).to.deep.equal([false]);
});
});
describe('when two array[index] exists', () => {
it('should return expected', () => {
const actual = dotProp.getMany(baseArr, ['1.a', '2.b']);

expect(actual).to.deep.equal([false, true]);
});
});
describe('when array index do not exist', () => {
it('should return expected', () => {
const actual = dotProp.getMany(baseArr, ['10']);

expect(actual).to.deep.equal([undefined]);
});
});
});
});
20 changes: 20 additions & 0 deletions test/dotPropImmutable/setMany.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const dotProp = require('../../lib');

describe('setMany.spec.js', () => {
describe('when an object', () => {

});
describe('when an array', () => {
it('Sets a map of elements', () => {
expect(dotProp.setMany({ foo: 0, bar: { baz: 1 } }, { foo: 2, 'bar.baz': 3 })).to.eql(
{ foo: 2, bar: { baz: 3 } }
);
});

it('Sets a map of elements un existent', () => {
expect(dotProp.setMany({}, { foo: 2, 'bar.baz': 3 })).to.eql(
{ foo: 2, bar: { baz: 3 } }
);
});
});
});
34 changes: 34 additions & 0 deletions test/dotPropImmutable/toggleMany.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const { toggleMany } = require('../../lib');

describe.only('toggleMany.spec.js', () => {
describe('when have an object', () => {
describe('when ', () => {

});
});
describe('when have an array', () => {
describe('when array indexes exist', () => {
it('should return expected', () => {
const actual = toggleMany(baseArr, ['1.a', '2.b']);

expect(actual).to.deep.equal([
1,
{ a: true },
{ b: false }
]);
});
});
// TODO bug here - adding unexpected empty values and "true" to result array
describe.skip('when array indexes dont exist', () => {
it('should return expected', () => {
const actual = toggleMany(baseArr, ['10']);

expect(actual).to.deep.equal([
1,
{ a: false },
{ b: true }
]);
});
});
});
});
15 changes: 15 additions & 0 deletions test/examples.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,21 @@ describe('examples.spec.js', () => {
});
});

describe('when setMany', function() {

it('Sets a map of elements', function() {
expect(dotProp.setMany({ foo: 0, bar: { baz: 1 } }, { foo: 2, 'bar.baz': 3 })).to.eql(
{ foo: 2, bar: { baz: 3 } }
);
});

it('Sets a map of elements un existent', function() {
expect(dotProp.setMany({}, { foo: 2, 'bar.baz': 3 })).to.eql(
{ foo: 2, bar: { baz: 3 } }
);
});
});

describe('when delete', () => {

it('Array element by index', () => {
Expand Down
13 changes: 13 additions & 0 deletions test/globals.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
const chai = require('chai');
global.expect = chai.expect;

global.baseObj = {
a: 1,
b: {
x: 1,
y: 2
},
c: [1, 2],
'b.x': 10
};
global.baseArr = [
1, { a: false }, { b: true }
];