UNPKG

validated-changeset

Version:
438 lines (363 loc) 11.2 kB
import setDeep from '../../src/utils/set-deep'; import Change from '../../src/-private/change'; describe('Unit | Utility | set deep', () => { it('it sets value', () => { const objA = { other: 'Ivan' }; const value = setDeep(objA, 'foo', 'bar'); expect(value).toEqual({ other: 'Ivan', foo: 'bar' }); }); it('it sets deeper', () => { const objA = { other: 'Ivan' }; const value = setDeep(objA, 'other.nick', 'bar'); expect(value).toEqual({ other: { nick: 'bar' } }); }); it('it overrides leaf key', () => { const objA = { name: { other: 'Ivan' } }; const value = setDeep(objA, 'name', 'foo'); expect(value).toEqual({ name: 'foo' }); }); it('handles null case', () => { const objA = { name: { other: 'Ivan', nick: null } }; const value = setDeep(objA, 'name.other', null); expect(value).toEqual({ name: { other: null, nick: null } }); }); it('handles booleans', () => { const objA = { name: [{ nick: false }] }; const value = setDeep(objA, 'name.0.nick', true); expect(value).toEqual({ name: [{ nick: true }] }); const value2 = setDeep(value, 'name.0.nick', false); expect(value2).toEqual({ name: [{ nick: false }] }); }); it('handles function case', () => { const objA = { name: { other: 'Ivan' } }; const anon = () => {}; const value = setDeep(objA, 'name.other', anon); expect(value).toEqual({ name: { other: anon } }); }); it('it handles nested key', () => { const objA = { name: { other: 'Ivan' } }; const value = setDeep(objA, 'name.other', 'foo'); expect(value).toEqual({ name: { other: 'foo' } }); }); it('handles existing arrays', () => { const objA = { entries: [{ prop: 'foo' }] }; const value = setDeep(objA, 'entries.0.prop', 'bar'); expect(value).toEqual({ entries: [{ prop: 'bar' }] }); }); it('inserts data into existing arrays', () => { const objA = { entries: [{ prop: 'foo' }] }; const value = setDeep(objA, 'entries.1.prop', 'bar'); expect(value).toEqual({ entries: [{ prop: 'foo' }, { prop: 'bar' }] }); }); it('inserts data into empty arrays', () => { const objA = { entries: [] }; const value = setDeep(objA, 'entries.0.prop', 'bar'); expect(value).toEqual({ entries: [{ prop: 'bar' }] }); }); it('does not allow inserting into arrays at negative values', () => { const objA = { entries: [] }; expect(() => { setDeep(objA, 'entries.-1.prop', 'bar'); }).toThrow( 'Negative indices are not allowed as arrays do not serialize values at negative indices' ); }); it('inserts primitive types into existing arrays', () => { const objA = { entries: ['foo'] }; const value = setDeep(objA, 'entries.1', 'bar'); expect(value).toEqual({ entries: ['foo', 'bar'] }); }); it('inserts primitive types into empty arrays', () => { const objA = { entries: [] }; const value = setDeep(objA, 'entries.0', 'bar'); expect(value).toEqual({ entries: ['bar'] }); }); it('it does not lose sibling keys', () => { const objA = { name: { other: 'Ivan', koala: 'bear', location: { state: 'MN', zip: '45554' } }, star: 'wars' }; let value = setDeep(objA, 'name.other', 'foo'); value = setDeep(objA, 'name.location.state', 'CO'); const expected = { name: { other: 'foo', koala: 'bear', location: { state: 'CO', zip: '45554' } }, star: 'wars' }; expect(value).toEqual(expected); }); it('it works with multiple values', () => { const objA = { name: { other: 'Ivan' }, foo: { other: 'bar' } }; const value = setDeep(objA, 'name', 'zoo'); expect(value).toEqual({ foo: { other: 'bar' }, name: 'zoo' }); }); it('it works with nested multiple values', () => { const objA = { top: { name: 'jimmy', foo: { other: 'bar' } } }; const value = setDeep(objA, 'top.name', 'zoo'); expect(value).toEqual({ top: { foo: { other: 'bar' }, name: 'zoo' } }); }); it('it works with nested multiple values with Changes', () => { const objA = { top: new Change({ name: 'jimmy', foo: { other: 'bar' } }) }; const value = setDeep(objA, 'top.name', 'zoo'); expect(value).toEqual({ top: new Change({ foo: { other: 'bar' }, name: 'zoo' }) }); }); it('it works with nested Changes', () => { const objA = { top: new Change({ name: 'jimmy', foo: { other: 'bar' } }) }; const value = setDeep(objA, 'top.name', new Change('zoo')); expect(value).toEqual({ top: new Change({ foo: { other: 'bar' }, name: 'zoo' // value is not a Change instance }) }); }); it('it works with nested Changes null', () => { const objA = { top: new Change({ name: 'jimmy', foo: { other: null } }) }; let value = setDeep(objA, 'top.name', new Change(null)); value = setDeep(objA, 'top.foo', new Change(null)); expect(value).toEqual({ top: new Change({ foo: null, name: null }) }); }); it('sets changes to undefined values', () => { const objA = { contacts: { 0: new Change({ emails: { primary: 'sanholo@email.com' } }), 1: { emails: { primary: 'fred@email.com' } } } }; let value = setDeep(objA, 'contacts.0', new Change(null)); expect(value).toEqual({ contacts: { 0: new Change(null), 1: { emails: { primary: 'fred@email.com' } } } }); }); it('it works with nested Changes with different order', () => { const objA = { top: new Change({ foo: { other: 'bar' }, name: 'jimmy' }) }; const value = setDeep(objA, 'top.name', new Change('zoo')); expect(value).toEqual({ top: new Change({ foo: { other: 'bar' }, name: 'zoo' // value is not a Change instance }) }); }); it('it works with nested Changes with different order', () => { const objA = { top: new Change({ foo: { other: 'bar' }, name: 'jimmy' }) }; const value = setDeep(objA, 'top.name', new Change('zoo')); expect(value).toEqual({ top: new Change({ foo: { other: 'bar' }, name: 'zoo' // value is not a Change instance }) }); }); it('set on nested Changes', () => { const objA = { top: new Change({ foo: { other: 'bar' }, name: 'jimmy' }) }; let value = setDeep(objA, 'top.name', new Change('zoo')); expect(value).toEqual({ top: new Change({ foo: { other: 'bar' }, name: 'zoo' // value is not a Change instance }) }); value = setDeep(value, 'top.foo.other', new Change('baz')); expect(value).toEqual({ top: new Change({ foo: { other: 'baz' }, name: 'zoo' }) }); }); it('set on nested properties within an empty object', () => { const objA = { top: {} }; let value = setDeep(objA, 'top.name', new Change('zoo')); expect(value).toEqual({ top: { name: new Change('zoo') } }); value = setDeep(value, 'top.foo.other', new Change('baz')); expect(value).toEqual({ top: { name: new Change('zoo'), foo: { other: new Change('baz') } } }); }); describe('arrays at various nestings within an object', () => { describe('array nested one level deep', () => { it('sets when teh array is initially empty', () => { const objA = { top: [] }; let value = setDeep(objA, 'top.0.name', new Change('zoo')); expect(value).toEqual({ top: [{ name: new Change('zoo') }] }); value = setDeep(value, 'top.0.foo.other', new Change('baz')); expect(value).toEqual({ top: [ { name: new Change('zoo'), foo: { other: new Change('baz') } } ] }); }); it('sets with existing changes', () => { const objA = { top: [new Change({ foo: { other: 'bar' }, name: 'jimmy' })] }; let value = setDeep(objA, 'top.0.name', new Change('zoo')); expect(value).toEqual({ top: [ new Change({ foo: { other: 'bar' }, name: 'zoo' // value is not a Change instance }) ] }); value = setDeep(value, 'top.0.foo.other', new Change('baz')); expect(value).toEqual({ top: [ new Change({ foo: { other: 'baz' }, name: 'zoo' }) ] }); }); }); }); describe('faux arrays at various nestings within an object', () => { describe('faux array deeply nested', () => { it('works with existing changes', () => { const objA = { contact: { emails: { 1: new Change({ funEmail: 'fun@email.com', primary: 'primary@email.com' }) } } }; let value = setDeep(objA, 'contact.emails.1.primary', new Change('primary2@email.com')); expect(value).toEqual({ contact: { emails: { 1: new Change({ funEmail: 'fun@email.com', primary: 'primary2@email.com' }) } } }); }); }); }); it('set with class instances', () => { class Person { name = 'baz'; } const objA = { top: new Change({ foo: { other: 'bar' }, name: 'jimmy' }) }; let value = setDeep(objA, 'top.name', new Change(new Person())); expect(value).toEqual({ top: new Change({ foo: { other: 'bar' }, name: new Person() }) }); class Foo { other = 'baz'; } value = setDeep(value, 'top.foo', new Change(new Foo())); expect(value).toEqual({ top: new Change({ foo: new Foo(), name: new Person() }) }); }); it('super deep set does not lose siblings', () => { const resource = { styles: { colors: { main: { sync: true, color: '#3D3D3D', contrastColor: '#FFFFFF', syncedColor: '#575757', syncedContrastColor: '#FFFFFF' }, accent: { sync: true, color: '#967E6E', contrastColor: '#ffffff', syncedColor: '#967E6E', syncedContrastColor: '#ffffff' }, ambient: { sync: true, color: '#FFFFFF', contrastColor: '#3D3D3D', syncedColor: '#FFFFFF', syncedContrastColor: '#575757' } } } }; setDeep(resource, 'styles.colors.main.sync', false); const value = resource.styles.colors.main; expect(value).toEqual({ sync: false, color: '#3D3D3D', contrastColor: '#FFFFFF', syncedColor: '#575757', syncedContrastColor: '#FFFFFF' }); }); });