Skip to content

Commit 9fa34af

Browse files
committedNov 26, 2018
Support symbol properties for reach(). Closes #267
1 parent ea1ee6a commit 9fa34af

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed
 

‎lib/index.js

+12-4
Original file line numberDiff line numberDiff line change
@@ -486,13 +486,21 @@ exports.reach = function (obj, chain, options) {
486486
options = { separator: options };
487487
}
488488

489-
const path = chain.split(options.separator || '.');
489+
const isChainArray = Array.isArray(chain);
490+
491+
exports.assert(!isChainArray || !options.separator, 'Separator option no valid for array-based chain');
492+
493+
const path = isChainArray ? chain : chain.split(options.separator || '.');
490494
let ref = obj;
491495
for (let i = 0; i < path.length; ++i) {
492496
let key = path[i];
493-
if (key[0] === '-' && Array.isArray(ref)) {
494-
key = key.slice(1, key.length);
495-
key = ref.length - key;
497+
498+
if (Array.isArray(ref)) {
499+
const number = Number(key);
500+
501+
if (Number.isInteger(number) && number < 0) {
502+
key = ref.length + number;
503+
}
496504
}
497505

498506
if (!ref ||

‎test/index.js

+27-2
Original file line numberDiff line numberDiff line change
@@ -1780,6 +1780,7 @@ describe('flatten()', () => {
17801780

17811781
describe('reach()', () => {
17821782

1783+
const sym = Symbol();
17831784
const obj = {
17841785
a: {
17851786
b: {
@@ -1792,7 +1793,10 @@ describe('reach()', () => {
17921793
g: {
17931794
h: 3
17941795
},
1795-
'-2': true
1796+
'-2': true,
1797+
[sym]: {
1798+
v: true
1799+
}
17961800
},
17971801
i: function () { },
17981802
j: null,
@@ -1806,15 +1810,18 @@ describe('reach()', () => {
18061810
expect(Hoek.reach(obj, null)).to.equal(obj);
18071811
expect(Hoek.reach(obj, false)).to.equal(obj);
18081812
expect(Hoek.reach(obj)).to.equal(obj);
1813+
expect(Hoek.reach(obj, [])).to.equal(obj);
18091814
});
18101815

1811-
it('returns first value of array', () => {
1816+
it('returns values of array', () => {
18121817

18131818
expect(Hoek.reach(obj, 'k.0')).to.equal(4);
1819+
expect(Hoek.reach(obj, 'k.1')).to.equal(8);
18141820
});
18151821

18161822
it('returns last value of array using negative index', () => {
18171823

1824+
expect(Hoek.reach(obj, 'k.-1')).to.equal(1);
18181825
expect(Hoek.reach(obj, 'k.-2')).to.equal(9);
18191826
});
18201827

@@ -1860,6 +1867,9 @@ describe('reach()', () => {
18601867
it('returns undefined on invalid member', () => {
18611868

18621869
expect(Hoek.reach(obj, 'a.b.c.d-.x')).to.equal(undefined);
1870+
expect(Hoek.reach(obj, 'k.x')).to.equal(undefined);
1871+
expect(Hoek.reach(obj, 'k.1000')).to.equal(undefined);
1872+
expect(Hoek.reach(obj, 'k/0.5', '/')).to.equal(undefined);
18631873
});
18641874

18651875
it('returns function member', () => {
@@ -1899,6 +1909,21 @@ describe('reach()', () => {
18991909

19001910
expect(Hoek.reach(obj, 'q', { default: '' })).to.equal('');
19011911
});
1912+
1913+
it('allows array-based lookup', () => {
1914+
1915+
expect(Hoek.reach(obj, ['a', 'b', 'c', 'd'])).to.equal(1);
1916+
expect(Hoek.reach(obj, ['k', '1'])).to.equal(8);
1917+
expect(Hoek.reach(obj, ['k', 1])).to.equal(8);
1918+
expect(Hoek.reach(obj, ['k', '-2'])).to.equal(9);
1919+
expect(Hoek.reach(obj, ['k', -2])).to.equal(9);
1920+
});
1921+
1922+
it('allows array-based lookup with symbols', () => {
1923+
1924+
expect(Hoek.reach(obj, ['a', sym, 'v'])).to.equal(true);
1925+
expect(Hoek.reach(obj, ['a', Symbol(), 'v'])).to.equal(undefined);
1926+
});
19021927
});
19031928

19041929
describe('reachTemplate()', () => {

0 commit comments

Comments
 (0)
Please sign in to comment.