-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat!(accessors): update get/set methods to allow for arrays to be tr…
…aversed (#45) BREAKING CHANGE: The get and set methods will new process numeric path accessors as array indicies. This is probably the expected behaviour but wasn't how it previously worked and is therefore a breaking change.
- Loading branch information
1 parent
5b305c7
commit 9207675
Showing
4 changed files
with
165 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,56 @@ | ||
import get from './get' | ||
|
||
describe('Recursive Set (set)', () => { | ||
const testObject = { foo: { bar: 'hello' } } | ||
const testObject = { | ||
value: 'layer 1', | ||
child: { | ||
value: 'layer 2', | ||
child: { | ||
value: 'layer 3', | ||
child: { | ||
value: 'layer 4', | ||
}, | ||
children: [{ value: 'layer 3 child 1' }, { value: 'layer 3 child 2' }], | ||
}, | ||
children: [{ value: 'layer 2 child 1' }, { value: 'layer 2 child 2' }], | ||
}, | ||
} | ||
|
||
test('Fetches nested keys', () => { | ||
expect(get(testObject, ['foo', 'bar'])).toBe('hello') | ||
}) | ||
describe('Nested accessor', () => { | ||
it('should retrieve nested values with a path array of any depth', () => { | ||
expect(get(testObject, ['value'])).toBe('layer 1') | ||
expect(get(testObject, ['child', 'value'])).toBe('layer 2') | ||
expect(get(testObject, ['child', 'child', 'value'])).toBe('layer 3') | ||
expect(get(testObject, ['child', 'child', 'child', 'value'])).toBe('layer 4') | ||
}) | ||
|
||
test('Accepts period delimited string for path', () => { | ||
expect(get(testObject, 'foo.bar')).toBe('hello') | ||
}) | ||
it('should retrieve nested values with a period delimited string of any depth', () => { | ||
expect(get(testObject, 'value')).toBe('layer 1') | ||
expect(get(testObject, 'child.value')).toBe('layer 2') | ||
expect(get(testObject, 'child.child.value')).toBe('layer 3') | ||
expect(get(testObject, 'child.child.child.value')).toBe('layer 4') | ||
}) | ||
|
||
test(`Returns undefined if the property doesn't exist`, () => { | ||
expect(get(testObject, ['bar', 'baz'])).toBeUndefined() | ||
it('should traverse both objects and arrays when using a string path', () => { | ||
expect(get(testObject, 'child.children[0].value')).toBe('layer 2 child 1') | ||
expect(get(testObject, 'child.child.children[1].value')).toBe('layer 3 child 2') | ||
}) | ||
}) | ||
|
||
test(`Returns a default value if one is provided and they key doesn't exist`, () => { | ||
expect(get(testObject, ['bar', 'baz'], 'world')).toBe('world') | ||
describe('Default value', () => { | ||
it(`should return undefined if the property doesn't exist and a default value is not provided`, () => { | ||
expect(get(testObject, 'child.baz')).toBeUndefined() | ||
expect(get(testObject, ['child', 'baz'])).toBeUndefined() | ||
}) | ||
|
||
it(`should return a default value if one is provided and a value isn't found`, () => { | ||
expect(get(testObject, 'child.baz', 'world')).toBe('world') | ||
expect(get(testObject, ['child', 'baz'], 'world')).toBe('world') | ||
}) | ||
|
||
it(`should ignore the default value if one is provided but a value is found`, () => { | ||
expect(get(testObject, 'child.value', 'world')).toBe('layer 2') | ||
expect(get(testObject, ['child', 'value'], 'world')).toBe('layer 2') | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,106 @@ | ||
import set from './set' | ||
|
||
describe('Recursive Set (set)', () => { | ||
test('Updates nested keys', () => { | ||
const testObject = { foo: { bar: 'hello' } } | ||
set(testObject, ['foo', 'bar'], 'world') | ||
describe('Nested accessor', () => { | ||
it('should update nested values with a path array of any depth', () => { | ||
const testObject = { | ||
value: 'layer 1', | ||
child: { | ||
value: 'layer 2', | ||
child: { | ||
value: 'layer 3', | ||
child: { | ||
value: 'layer 4', | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
expect(testObject).toEqual({ foo: { bar: 'world' } }) | ||
}) | ||
set(testObject, ['value'], 'updated layer 1') | ||
expect(testObject.value).toBe('updated layer 1') | ||
|
||
test('Accepts period delimited string for path', () => { | ||
const testObject = { foo: { bar: { baz: 'hello' } } } | ||
set(testObject, 'foo.bar.baz', 'world') | ||
set(testObject, ['child', 'value'], 'updated layer 2') | ||
expect(testObject.child.value).toBe('updated layer 2') | ||
|
||
expect(testObject).toEqual({ foo: { bar: { baz: 'world' } } }) | ||
}) | ||
set(testObject, ['child', 'child', 'value'], 'updated layer 3') | ||
expect(testObject.child.child.value).toBe('updated layer 3') | ||
|
||
test('Creates nested objects if they do not exist', () => { | ||
const testObject = { foo: { bar: 'hello' } } | ||
set(testObject, ['bar', 'baz'], 'world') | ||
set(testObject, ['child', 'child', 'child', 'value'], 'updated layer 4') | ||
expect(testObject.child.child.child.value).toBe('updated layer 4') | ||
|
||
expect(testObject).toEqual({ bar: { baz: 'world' }, foo: { bar: 'hello' } }) | ||
}) | ||
expect(testObject).toEqual({ | ||
value: 'updated layer 1', | ||
child: { | ||
value: 'updated layer 2', | ||
child: { | ||
value: 'updated layer 3', | ||
child: { | ||
value: 'updated layer 4', | ||
}, | ||
}, | ||
}, | ||
}) | ||
}) | ||
|
||
it('should update nested values with a period delimited string of any depth', () => { | ||
const testObject = { | ||
value: 'layer 1', | ||
child: { | ||
value: 'layer 2', | ||
child: { | ||
value: 'layer 3', | ||
child: { | ||
value: 'layer 4', | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
set(testObject, 'value', 'updated layer 1') | ||
expect(testObject.value).toBe('updated layer 1') | ||
|
||
set(testObject, 'child.value', 'updated layer 2') | ||
expect(testObject.child.value).toBe('updated layer 2') | ||
|
||
set(testObject, 'child.child.value', 'updated layer 3') | ||
expect(testObject.child.child.value).toBe('updated layer 3') | ||
|
||
set(testObject, 'child.child.child.value', 'updated layer 4') | ||
expect(testObject.child.child.child.value).toBe('updated layer 4') | ||
|
||
expect(testObject).toEqual({ | ||
value: 'updated layer 1', | ||
child: { | ||
value: 'updated layer 2', | ||
child: { | ||
value: 'updated layer 3', | ||
child: { | ||
value: 'updated layer 4', | ||
}, | ||
}, | ||
}, | ||
}) | ||
}) | ||
|
||
it('should create empty objects or arrays when descending the object if they do not exist', () => { | ||
const testObject = { foo: { bar: 'hello' } } | ||
set(testObject, 'bar.baz', 'world') | ||
expect(testObject).toEqual({ bar: { baz: 'world' }, foo: { bar: 'hello' } }) | ||
|
||
const testObjectEmpty = {} | ||
set(testObjectEmpty, 'foo[0].bar[0].baz', 'world') | ||
expect(testObjectEmpty).toEqual({ foo: [{ bar: [{ baz: 'world' }] }] }) | ||
}) | ||
|
||
test('Overrides keys in the path if they are not objects', () => { | ||
const testObject = { foo: { bar: 'hello' } } | ||
set(testObject, ['foo', 'bar', 'baz'], 'world') | ||
it('should convert values in the path to objects if they are not indexable', () => { | ||
const testObject = { foo: { bar: 'hello' } } | ||
set(testObject, 'foo.bar.baz', 'world') | ||
expect(testObject).toEqual({ foo: { bar: { baz: 'world' } } }) | ||
|
||
expect(testObject).toEqual({ foo: { bar: { baz: 'world' } } }) | ||
const testObjectArray = { foo: 'hello world' } | ||
set(testObjectArray, 'foo[0]', 'hola') | ||
set(testObjectArray, 'foo[1]', 'world') | ||
expect(testObjectArray).toEqual({ foo: ['hola', 'world'] }) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters