Skip to content

Commit c19f87d

Browse files
clbondSethDavenport
authored andcommitted
Add seamless support for ImmutableJS structures in select() path (#160)
* Add seamless support for ImmutableJS structures in select() path * Do not depend upon immutablejs, only use it if the project uses it * Add comment to make clear the purpose of the try/catch * Add unit tests related to optional ImmutableJS support
1 parent 3816ca7 commit c19f87d

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"es6-shim": "^0.35.0",
5252
"expect": "^1.8.0",
5353
"mocha": "^2.4.5",
54+
"proxyquire": "^1.7.10",
5455
"redux": "^3.4.0",
5556
"reflect-metadata": "0.1.3",
5657
"rimraf": "^2.5.2",
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const proxyquire = require('proxyquire');
2+
3+
const { getIn: getInWithImmutable } = proxyquire('../../utils/get-in', {
4+
immutable: {
5+
Iterable: {
6+
isIterable: value => typeof value.getIn === 'function',
7+
},
8+
'@noCallThru': true,
9+
},
10+
});
11+
12+
const { getIn: getInWithNoImmutable } = require('../../utils/get-in');
13+
14+
import { expect } from 'chai';
15+
16+
describe('getIn', () => {
17+
it('should make use of immutable when available in host project', () => {
18+
const getIn =
19+
path => {
20+
expect(path.length).to.equal(1);
21+
expect(path[0]).to.equal('foo');
22+
return 't';
23+
};
24+
25+
const fakeImmutable = { getIn: getIn };
26+
27+
expect(getInWithImmutable(fakeImmutable, [ 'foo' ])).to.equal('t');
28+
});
29+
30+
it('should work on regular objects even when immutable is available', () => {
31+
const test = { foo: 1 };
32+
33+
expect(getInWithImmutable(test, [ 'foo' ])).to.equal(1);
34+
});
35+
36+
it('should run without immutable when immutable is not available', () => {
37+
const test = { foo: 1 };
38+
39+
expect(getInWithNoImmutable(test, [ 'foo' ])).to.equal(1);
40+
});
41+
});

src/utils/get-in.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1+
// This may look suspicious, but the point is to add ImmutableJS integration
2+
// only if the project itself already has a dependency on immutable. If not,
3+
// then this variable is left null and no integration is attempted.
4+
let immutable;
5+
try {
6+
immutable = require('immutable');
7+
} catch (e) {}
8+
19
/*
210
* Gets a deeply-nested property value from an object, given a 'path'
311
* of property names or array indices.
412
*/
513
export function getIn(
614
v: Object,
715
pathElems: (string | number)[]): any {
8-
const [ firstElem, ...restElems] = pathElems;
916
if (!v) {
1017
return v;
1118
}
1219

20+
if (immutable && immutable.Iterable.isIterable(v)) {
21+
return (<{getIn: (path: (string | number)[]) => any}>v).getIn(pathElems);
22+
}
23+
24+
const [ firstElem, ...restElems] = pathElems;
25+
1326
if (undefined === v[firstElem]) {
1427
return undefined;
1528
}
@@ -20,3 +33,4 @@ export function getIn(
2033

2134
return getIn(v[firstElem], restElems);
2235
}
36+

0 commit comments

Comments
 (0)