Add u.if
This commit is contained in:
parent
c5ab11e176
commit
750200df76
@ -1,6 +1,7 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
## [unreleased]
|
## [unreleased]
|
||||||
|
* Add `u.if` to conditionally update objects.
|
||||||
|
|
||||||
## [0.3.1]
|
## [0.3.1]
|
||||||
* Actually expose `u.in`.
|
* Actually expose `u.in`.
|
||||||
|
16
README.md
16
README.md
@ -128,6 +128,22 @@ u({
|
|||||||
// => { x: { a: { b: 3 } } };
|
// => { x: { a: { b: 3 } } };
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `u.if(predicate(, updates)(, object))`
|
||||||
|
|
||||||
|
Apply updates only if `predicate` is truthy or, if `predicate` is a function,
|
||||||
|
if it evaluates to truthy when called with `object`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
var obj = { a: 2 };
|
||||||
|
function isEven(x) { return x % 2 === 0; }
|
||||||
|
function inc(x) { return x + 1; }
|
||||||
|
|
||||||
|
u({
|
||||||
|
a: u.if(isEven, inc),
|
||||||
|
}, obj);
|
||||||
|
// => { a: 3 }
|
||||||
|
```
|
||||||
|
|
||||||
### `u.omit(predicate(, object))`
|
### `u.omit(predicate(, object))`
|
||||||
|
|
||||||
Remove properties. See [`_.omit`](https://lodash.com/docs#omit).
|
Remove properties. See [`_.omit`](https://lodash.com/docs#omit).
|
||||||
|
16
lib/if.js
Normal file
16
lib/if.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import curry from 'lodash/function/curry';
|
||||||
|
import update from './update';
|
||||||
|
|
||||||
|
function updateIf(predicate, updates, object) {
|
||||||
|
const test = typeof predicate === 'function' ?
|
||||||
|
predicate(object) :
|
||||||
|
predicate;
|
||||||
|
|
||||||
|
if (!test) {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
return update(updates, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default curry(updateIf);
|
@ -1,5 +1,6 @@
|
|||||||
import update from './update';
|
import update from './update';
|
||||||
import updateIn from './updateIn';
|
import _in from './in';
|
||||||
|
import _if from './if';
|
||||||
import omit from './omit';
|
import omit from './omit';
|
||||||
import reject from './reject';
|
import reject from './reject';
|
||||||
import withDefault from './withDefault';
|
import withDefault from './withDefault';
|
||||||
@ -12,7 +13,8 @@ function updateAndFreeze(updates, obj) {
|
|||||||
|
|
||||||
const updeep = curry(updateAndFreeze);
|
const updeep = curry(updateAndFreeze);
|
||||||
|
|
||||||
updeep.in = updateIn;
|
updeep.if = _if;
|
||||||
|
updeep.in = _in;
|
||||||
updeep.freeze = freeze;
|
updeep.freeze = freeze;
|
||||||
updeep.omit = omit;
|
updeep.omit = omit;
|
||||||
updeep.reject = reject;
|
updeep.reject = reject;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import freeze from '../lib/freeze';
|
import u from '../lib';
|
||||||
|
|
||||||
describe('u.freeze', () => {
|
describe('u.freeze', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -8,21 +8,21 @@ describe('u.freeze', () => {
|
|||||||
|
|
||||||
it('freezes objects', () => {
|
it('freezes objects', () => {
|
||||||
const obj = {};
|
const obj = {};
|
||||||
freeze(obj);
|
u.freeze(obj);
|
||||||
|
|
||||||
expect(Object.isFrozen(obj)).to.be.true;
|
expect(Object.isFrozen(obj)).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('freezes nested objects', () => {
|
it('freezes nested objects', () => {
|
||||||
const obj = { foo: { bar: 3 } };
|
const obj = { foo: { bar: 3 } };
|
||||||
freeze(obj);
|
u.freeze(obj);
|
||||||
|
|
||||||
expect(Object.isFrozen(obj.foo)).to.be.true;
|
expect(Object.isFrozen(obj.foo)).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('freezes nested arrays', () => {
|
it('freezes nested arrays', () => {
|
||||||
const obj = [[0]];
|
const obj = [[0]];
|
||||||
freeze(obj);
|
u.freeze(obj);
|
||||||
|
|
||||||
expect(Object.isFrozen(obj)).to.be.true;
|
expect(Object.isFrozen(obj)).to.be.true;
|
||||||
expect(Object.isFrozen(obj[0])).to.be.true;
|
expect(Object.isFrozen(obj[0])).to.be.true;
|
||||||
@ -30,7 +30,7 @@ describe('u.freeze', () => {
|
|||||||
|
|
||||||
it('ignores functions', () => {
|
it('ignores functions', () => {
|
||||||
const obj = { foo: () => 1 };
|
const obj = { foo: () => 1 };
|
||||||
freeze(obj);
|
u.freeze(obj);
|
||||||
|
|
||||||
expect(Object.isFrozen(obj.foo)).to.be.false;
|
expect(Object.isFrozen(obj.foo)).to.be.false;
|
||||||
});
|
});
|
||||||
@ -38,7 +38,7 @@ describe('u.freeze', () => {
|
|||||||
it('does not freeze children if the parent is already frozen', () => {
|
it('does not freeze children if the parent is already frozen', () => {
|
||||||
const obj = { foo: {} };
|
const obj = { foo: {} };
|
||||||
Object.freeze(obj);
|
Object.freeze(obj);
|
||||||
freeze(obj);
|
u.freeze(obj);
|
||||||
|
|
||||||
expect(Object.isFrozen(obj.foo)).to.be.false;
|
expect(Object.isFrozen(obj.foo)).to.be.false;
|
||||||
});
|
});
|
||||||
@ -46,20 +46,20 @@ describe('u.freeze', () => {
|
|||||||
it('does not freeze in production', () => {
|
it('does not freeze in production', () => {
|
||||||
process.env.NODE_ENV = 'production';
|
process.env.NODE_ENV = 'production';
|
||||||
const obj = {};
|
const obj = {};
|
||||||
freeze(obj);
|
u.freeze(obj);
|
||||||
|
|
||||||
expect(Object.isFrozen(obj)).to.be.false;
|
expect(Object.isFrozen(obj)).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles null objects', () => {
|
it('handles null objects', () => {
|
||||||
const obj = { foo: null };
|
const obj = { foo: null };
|
||||||
freeze(obj);
|
u.freeze(obj);
|
||||||
expect(Object.isFrozen(obj)).to.be.true;
|
expect(Object.isFrozen(obj)).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns the same object', () => {
|
it('returns the same object', () => {
|
||||||
const obj = {};
|
const obj = {};
|
||||||
const result = freeze(obj);
|
const result = u.freeze(obj);
|
||||||
expect(result).to.equal(obj);
|
expect(result).to.equal(obj);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
36
test/if-spec.js
Normal file
36
test/if-spec.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { expect } from 'chai';
|
||||||
|
import u from '../lib';
|
||||||
|
|
||||||
|
describe('u.if', () => {
|
||||||
|
it('does not update if the predicate is false', () => {
|
||||||
|
const obj = { a: 0 };
|
||||||
|
const result = u.if(false, { b: 1 }, obj);
|
||||||
|
expect(result).to.eql(obj);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does update if the predicate is true', () => {
|
||||||
|
const obj = { a: 0 };
|
||||||
|
const result = u.if(true, { b: 1 }, obj);
|
||||||
|
expect(result).to.eql({ a: 0, b: 1 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will use the result of a function passed as a predicate', () => {
|
||||||
|
const obj = { a: 0 };
|
||||||
|
const aIsThree = x => x.a === 3;
|
||||||
|
const result = u.if(aIsThree, { b: 1 }, obj);
|
||||||
|
|
||||||
|
expect(result).to.eql({ a: 0 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can be partially applied', () => {
|
||||||
|
const obj = { a: 2 };
|
||||||
|
const isEven = x => x % 2 === 0;
|
||||||
|
const inc = x => x + 1;
|
||||||
|
|
||||||
|
const result = u({
|
||||||
|
a: u.if(isEven, inc),
|
||||||
|
}, obj);
|
||||||
|
|
||||||
|
expect(result).to.eql({ a: 3 });
|
||||||
|
});
|
||||||
|
});
|
@ -1,35 +1,35 @@
|
|||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import updateIn from '../lib/updateIn';
|
import u from '../lib';
|
||||||
|
|
||||||
describe('u.in', () => {
|
describe('u.in', () => {
|
||||||
it('can update a single path described with a string', () => {
|
it('can update a single path described with a string', () => {
|
||||||
const obj = { a: { b: 0 } };
|
const obj = { a: { b: 0 } };
|
||||||
const result = updateIn('a.b', 3, obj);
|
const result = u.in('a.b', 3, obj);
|
||||||
expect(result).to.eql({ a: { b: 3 } });
|
expect(result).to.eql({ a: { b: 3 } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can update a single path described with a string with a function', () => {
|
it('can update a single path described with a string with a function', () => {
|
||||||
const inc = x => x + 1;
|
const inc = x => x + 1;
|
||||||
const obj = { a: { b: 0 } };
|
const obj = { a: { b: 0 } };
|
||||||
const result = updateIn('a.b', inc, obj);
|
const result = u.in('a.b', inc, obj);
|
||||||
expect(result).to.eql({ a: { b: 1 } });
|
expect(result).to.eql({ a: { b: 1 } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can update a single path described with an array', () => {
|
it('can update a single path described with an array', () => {
|
||||||
const obj = { a: { b: 0 } };
|
const obj = { a: { b: 0 } };
|
||||||
const result = updateIn(['a', 'b'], 3, obj);
|
const result = u.in(['a', 'b'], 3, obj);
|
||||||
expect(result).to.eql({ a: { b: 3 } });
|
expect(result).to.eql({ a: { b: 3 } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can update arrays', () => {
|
it('can update arrays', () => {
|
||||||
const obj = { a: [0, 0, 0] };
|
const obj = { a: [0, 0, 0] };
|
||||||
const result = updateIn('a.1', 3, obj);
|
const result = u.in('a.1', 3, obj);
|
||||||
expect(result).to.eql({ a: [0, 3, 0] });
|
expect(result).to.eql({ a: [0, 3, 0] });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be partially applied', () => {
|
it('can be partially applied', () => {
|
||||||
const obj = { a: { b: 0 } };
|
const obj = { a: { b: 0 } };
|
||||||
const result = updateIn('a.b')(3)(obj);
|
const result = u.in('a.b')(3)(obj);
|
||||||
expect(result).to.eql({ a: { b: 3 } });
|
expect(result).to.eql({ a: { b: 3 } });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -116,6 +116,7 @@ describe('updeep', () => {
|
|||||||
|
|
||||||
it('has additional functions', () => {
|
it('has additional functions', () => {
|
||||||
expect(u.freeze).to.be.a('function');
|
expect(u.freeze).to.be.a('function');
|
||||||
|
expect(u.if).to.be.a('function');
|
||||||
expect(u.in).to.be.a('function');
|
expect(u.in).to.be.a('function');
|
||||||
expect(u.omit).to.be.a('function');
|
expect(u.omit).to.be.a('function');
|
||||||
expect(u.withDefault).to.be.a('function');
|
expect(u.withDefault).to.be.a('function');
|
||||||
|
Loading…
Reference in New Issue
Block a user