golden-path
Version:
621 lines (541 loc) • 32.4 kB
JavaScript
import { update, v } from '.';
describe('update', () => {
it('should update one level path when exist', () => {
const object = { islam: 1 };
const result = update('islam', 4, object);
expect(result).toEqual({ islam: 4 });
});
it('should return same reference once key updated with same value', () => {
const object = { islam: 1 };
const result = update('islam', 1, object);
// referential equality
expect(result).toBe(object);
});
it('should return same reference once key updated with same shallow equal value', () => {
const object = { islam: [1] };
const result = update('islam', [1], object);
// referential equality
expect(result).toBe(object);
});
it('should update one level path when exist when function is being passed', () => {
const object = { islam: 1 };
const result = update('islam', (x) => x + 1, object);
expect(result).toEqual({ islam: 2 });
});
it('should throw relevant error if thrown in the updater function', () => {
const object = { islam: 1 };
expect(() => {
update('islam.x', (x) => x.map(() => true), object);
}).toThrow(`Cannot read property 'map' of undefined`);
});
it('should create one level path when not exist', () => {
const object = { sabel: 2 };
const result = update('islam', 4, object);
expect(result).toEqual({ islam: 4, sabel: 2 });
});
it('should create one level path when not exist when function is being passed', () => {
const object = { sabel: 2 };
const result = update('islam', (x) => `islam_${x}`, object);
expect(result).toEqual({ islam: 'islam_undefined', sabel: 2 });
});
it('should override the whole object when path is empty', () => {
const object = { islam: 1 };
const result = update('', 4, object);
expect(result).toEqual(4);
});
it('should override the whole object when path is empty when function is being passed', () => {
const object = { islam: 1 };
const result = update(() => '', 4, object);
expect(result).toEqual(4);
});
it('should update array items when exist', () => {
const object = { friends: [2] };
const result = update('friends.0', 3, object);
expect(result).toEqual({ friends: [3] });
});
it('should push to array items when updating the array length', () => {
const object = { friends: [2] };
const result = update(`friends.${object.friends.length}`, 3, object);
expect(result).toEqual({ friends: [2, 3] });
});
it('should update array items when exist when function is being passed', () => {
const object = { friends: [2] };
const result = update('friends.0', (x) => x - 1, object);
expect(result).toEqual({ friends: [1] });
});
it('should update nested path in object when exist', () => {
const object = { islam: { is: { nested: false } } };
const result = update('islam.is.nested', true, object);
expect(result).toEqual({ islam: { is: { nested: true } } });
});
it('should update nested path in object when exist when function is being passed', () => {
const object = { islam: { is: { nested: false } } };
const result = update('islam.is.nested', (x) => !x, object);
expect(result).toEqual({ islam: { is: { nested: true } } });
});
it('should create nested path in object when not exist', () => {
const object = { sabel: 'wife' };
const result = update('islam.is.exist.now', true, object);
expect(result).toEqual({ sabel: 'wife', islam: { is: { exist: { now: true } } } });
});
it('should create nested path in object when not exist when function is being passed', () => {
const object = { sabel: 'wife' };
const result = update('islam.is.exist.now', (x) => `${x}`, object);
expect(result).toEqual({ sabel: 'wife', islam: { is: { exist: { now: 'undefined' } } } });
});
it('should update the property path in nested array of objects', () => {
const object = { peoples: [{ id: 1 } ] };
const result = update(`peoples.${0}.id`, 3, object);
expect(result).toEqual({ peoples: [{ id: 3 }] });
});
it('should curry the function when less params passed', () => {
const object = { peoples: [{ id: 1 } ] };
const result = update(`peoples.${0}.id`)(3)(object);
expect(result).toEqual({ peoples: [{ id: 3 }] });
const object2 = { peoples: [{ id: 1 } ] };
const result2 = update(`peoples.${0}.id`, 3)(object2);
expect(result2).toEqual({ peoples: [{ id: 3 }] });
});
it('should update the property path in nested array of objects when function in passed', () => {
const object = { peoples: [{ id: 1 } ] };
const result = update(`peoples.${0}.id`, (id) => id + 1, object);
expect(result).toEqual({ peoples: [{ id: 2 }] });
});
describe('Conditional Updates For Arrays', () => {
describe('Equals Symbol', () => {
it('should update array when conditions satisfied', () => {
const object = { peoples: [{ id: 1 }, { id: 5 } ] };
const result = update(`peoples[id=1]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 10, name: 'islam' }, { id: 5 }] });
});
it('should update array when conditions satisfied for undefined and null types', () => {
const object = { peoples: [{ id: undefined }, { id: 5 } ] };
const result = update(`peoples[id=undefined]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 10, name: 'islam' }, { id: 5 }] });
const object2 = { peoples: [{ id: null }, { id: 5 } ] };
const result2 = update(`peoples[id=null]`, { id: 10, name: 'islam' }, object2);
expect(result2).toEqual({ peoples: [{ id: 10, name: 'islam' }, { id: 5 }] });
});
it('should update array when conditions satisfied when value is hashed', () => {
const object = { peoples: [{ id: 1 }, { id: 5 } ] };
const result = update(`peoples[id=${v(1)}]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 10, name: 'islam' }, { id: 5 }] });
});
it('should update first existence when conditions satisfied for singular queries', () => {
const object = { peoples: [{ id: 1 }, { id: 1, other: true }] };
const result = update(`peoples[id=1]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 10, name: 'islam' }, { id: 1, other: true }] });
});
it('should update all existence when conditions satisfied for greedy queries', () => {
const object = { peoples: [{ id: 1 }, { id: 1, other: true }] };
const result = update(`peoples*[id=1]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 10, name: 'islam' }, { id: 10, name: 'islam' }] });
});
it('should update relevant existence when multiple conditions are used', () => {
const object = { peoples: [{ id: 1, other: false }, { id: 1, other: true }] };
const result = update(`peoples[id=1][other=true]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 1, other: false }, { id: 10, name: 'islam' }] });
});
it('should update relevant existence when multiple conditions are used with complex string value', () => {
const complexString = '[]&%.';
const object = { peoples: [{ id: 1, other: false }, { id: 1, other: complexString }] };
const result = update(`peoples[id=1][other="${v(complexString)}"]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 1, other: false }, { id: 10, name: 'islam' }] });
});
it('should update relevant existence when multiple conditions are used with complex string key', () => {
const complexString = '[]&%.';
const object = { peoples: [{ id: 1, other: false }, { id: 1, [complexString]: 1 }] };
const result = update(`peoples[id=1][${v(complexString)}=1]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 1, other: false }, { id: 10, name: 'islam' }] });
});
it('should update all array items being nested in object when conditions satisfied in greedy queries when being the only the query token', () => {
const array = { array: [{ id: 1, name: 'islam', visited: true }, { id: 1, name: 'sabel', visited: false }] };
const result = update(`array.*`, 1, array);
expect(result).toEqual({ array: [1, 1] });
});
it('should update all array items when conditions satisfied in greedy queries when being the only the query token', () => {
const array = [{ id: 1, name: 'islam', visited: true }, { id: 1, name: 'sabel', visited: false }];
const result = update(`*`, 2, array);
expect(result).toEqual([2, 2]);
});
it('should update pluck array items property when conditions satisfied in greedy queries', () => {
const array = [{ id: 1, name: 'islam', visited: true }, { id: 1, name: 'sabel', visited: false }];
const result = update(`*.name`, 'newName', array);
expect(result).toEqual([{ id: 1, name: 'newName', visited: true }, { id: 1, name: 'newName', visited: false }]);
});
it('should update all array names being nested in object when conditions satisfied in greedy queries when being the only the query token', () => {
const array = { array: [{ id: 1, name: 'islam', visited: true }, { id: 1, name: 'sabel', visited: false }] };
const result = update(`array.*.name`, 'newName', array);
expect(result).toEqual({ array: [{ id: 1, name: 'newName', visited: true }, { id: 1, name: 'newName', visited: false }] });
});
it('should update second item when first item type is not identical when conditions satisfied', () => {
const object = { peoples: [{ id: '1' }, { id: 1 }] };
const result = update(`peoples[id=1]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: '1' }, { id: 10, name: 'islam' }] });
});
it('should not update array when condition do not match', () => {
const object = { peoples: [{ id: 1 }, { id: 3 } ] };
const result = update(`peoples[id=2]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 1 }, { id: 3 } ] });
});
it('should update array deep property when conditions satisfied', () => {
const object = { peoples: [{ id: 1, name: 'islam' }, { id: 10, name: 'sabel' }] };
const result = update(`peoples[id=1].name`, 'sabel', object);
expect(result).toEqual({ peoples: [{ id: 1, name: 'sabel' }, { id: 10, name: 'sabel' }] });
});
it('should update array deep property when conditions satisfied in greedy queries', () => {
const object = { peoples: [{ id: 1, name: 'islam' }, { id: 1, name: 'sabel' }] };
const result = update(`peoples*[id=1].visited`, true, object);
expect(result).toEqual({ peoples: [{ id: 1, name: 'islam', visited: true }, { id: 1, name: 'sabel', visited: true }] });
});
it('should update array deep deep property when conditions satisfied', () => {
const object = { peoples: [{ name: 'islam', friends: [{ sex: 'male', name: 'max' }, { sex: 'male', name: 'Aseel' }, { sex: 'female', name: 'sabel' } ] } ] };
const result = update(`peoples[name='islam'].friends[sex='male'].name`, 'Sohaib', object);
expect(result).toEqual({ peoples: [{ name: 'islam', friends: [{ sex: 'male', name: 'Sohaib' }, { sex: 'male', name: 'Aseel' }, { sex: 'female', name: 'sabel' } ] } ] });
});
it('should update array deep deep property when conditions satisfied in multiple greedy queries', () => {
const object = {
peoples: [
{
name: 'Islam',
sex: 'male',
friends: [
{
sex: 'male',
name: 'max'
},
{
sex: 'male',
name: 'Aseel'
},
{
sex: 'female',
name: 'sabel'
}
]
},
{
name: 'Harel',
sex: 'male',
friends: [
{
sex: 'male',
name: 'Max'
},
{
sex: 'male',
name: 'Aseel'
},
{
sex: 'female',
name: 'sabel'
}
]
}
]
};
const result = update(`peoples*[sex='male'].friends*[sex='male'].name`, 'Sohaib', object);
expect(result).toEqual(
{
peoples: [
{
name: 'Islam',
sex: 'male',
friends: [
{
sex: 'male',
name: 'Sohaib'
},
{
sex: 'male',
name: 'Sohaib'
},
{
sex: 'female',
name: 'sabel'
}
]
},
{
name: 'Harel',
sex: 'male',
friends: [
{
sex: 'male',
name: 'Sohaib'
},
{
sex: 'male',
name: 'Sohaib'
},
{
sex: 'female',
name: 'sabel'
}
]
}
]
}
);
});
it('should update array deep deep property when conditions satisfied in single greedy queries', () => {
const object = {
peoples: [
{
name: 'Islam',
sex: 'male',
friends: [
{
sex: 'male',
name: 'max'
},
{
sex: 'male',
name: 'Aseel'
},
{
sex: 'female',
name: 'sabel'
}
]
},
{
name: 'Harel',
sex: 'male',
friends: [
{
sex: 'male',
name: 'Max'
},
{
sex: 'male',
name: 'Aseel'
},
{
sex: 'female',
name: 'sabel'
}
]
}
]
};
const result = update(`peoples*[sex='male'].friends[sex='male'].name`, 'Sohaib', object);
expect(result).toEqual(
{
peoples: [
{
name: 'Islam',
sex: 'male',
friends: [
{
sex: 'male',
name: 'Sohaib'
},
{
sex: 'male',
name: 'Aseel'
},
{
sex: 'female',
name: 'sabel'
}
]
},
{
name: 'Harel',
sex: 'male',
friends: [
{
sex: 'male',
name: 'Sohaib'
},
{
sex: 'male',
name: 'Aseel'
},
{
sex: 'female',
name: 'sabel'
}
]
}
]
}
);
});
});
describe('NotEquals Symbol', () => {
it('should update array when conditions satisfied', () => {
const object = { peoples: [{ id: 2 }, { id: 3 } ] };
const result = update(`peoples[id!=1]`, { id: 3, name: 'michael' }, object);
expect(result).toEqual({ peoples: [{ id: 3, name: 'michael' }, { id: 3 }] });
});
it('should update array when conditions satisfied when value is hashed', () => {
const object = { peoples: [{ id: 2 }, { id: 3 } ] };
const result = update(`peoples[id!=${v(1)}]`, { id: 3, name: 'michael' }, object);
expect(result).toEqual({ peoples: [{ id: 3, name: 'michael' }, { id: 3 }] });
});
it('should update first existence when conditions satisfied for singular queries', () => {
const object = { peoples: [{ id: 2 }, { id: 2, other: true }] };
const result = update(`peoples[id!=1]`, { id: 100, name: 'john' }, object);
expect(result).toEqual({ peoples: [{ id: 100, name: 'john' }, { id: 2, other: true }] });
});
it('should update relevant item when type is not identical when conditions satisfied', () => {
const object = { peoples: [{ id: '2' }, { id: '3' }] };
const result = update(`peoples[id!=2]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 10, name: 'islam' }, { id: '3' }] });
});
it('should not update array when condition do not match', () => {
const object = { peoples: [{ id: 1 } ] };
const result = update(`peoples[id!=1]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 1 } ] });
});
it('should update array deep property when conditions satisfied', () => {
const object = { peoples: [{ id: 2, name: 'islam' }, { id: 3, name: 'xx' } ] };
const result = update(`peoples[id!=1].name`, 'sabel', object);
expect(result).toEqual({ peoples: [{ id: 2, name: 'sabel' }, { id: 3, name: 'xx' }] });
});
it('should update array deep deep property when conditions satisfied', () => {
const object = { peoples: [{ name: 'islam', friends: [{ sex: 'male', name: 'max' }, { sex: 'male', name: 'Aseel' }, { sex: 'female', name: 'sabel' } ] } ] };
const result = update(`peoples[name!='john'].friends[sex!='female'].name`, 'Sohaib', object);
expect(result).toEqual({ peoples: [{ name: 'islam', friends: [{ sex: 'male', name: 'Sohaib' }, { sex: 'male', name: 'Aseel' }, { sex: 'female', name: 'sabel' } ] } ] });
});
});
describe('BiggerThan Symbol', () => {
it('should update array when conditions satisfied', () => {
const object = { peoples: [{ id: 2 } ] };
const result = update(`peoples[id>1]`, { id: 3, name: 'michael' }, object);
expect(result).toEqual({ peoples: [{ id: 3, name: 'michael' }] });
});
it('should update array when conditions satisfied when value is hashed', () => {
const object = { peoples: [{ id: 2 } ] };
const result = update(`peoples[id>${v(1)}]`, { id: 3, name: 'michael' }, object);
expect(result).toEqual({ peoples: [{ id: 3, name: 'michael' }] });
});
it('should update first existence when conditions satisfied for singular queries', () => {
const object = { peoples: [{ id: 2 }, { id: 2, other: true }] };
const result = update(`peoples[id>1]`, { id: 100, name: 'john' }, object);
expect(result).toEqual({ peoples: [{ id: 100, name: 'john' }, { id: 2, other: true }] });
});
it('should not update array when condition do not match', () => {
const object = { peoples: [{ id: 1 } ] };
const result = update(`peoples[age>30]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 1 } ] });
});
it('should update array deep property when conditions satisfied', () => {
const object = { peoples: [{ id: 2, name: 'islam' }, { id: 3, name: 'xx' } ] };
const result = update(`peoples[id>1].name`, 'sabel', object);
expect(result).toEqual({ peoples: [{ id: 2, name: 'sabel' }, { id: 3, name: 'xx' }] });
});
it('should update array deep deep property when conditions satisfied', () => {
const object = { peoples: [{ name: 'islam', friends: [{ age: 20, name: 'max' }, { age: 30, name: 'Aseel' }, { age: 40, name: 'sabel' } ] } ] };
const result = update(`peoples[name='islam'].friends[age>29].name`, 'Sohaib', object);
expect(result).toEqual({ peoples: [{ name: 'islam', friends: [{ age: 20, name: 'max' }, { age: 30, name: 'Sohaib' }, { age: 40, name: 'sabel' } ] } ] });
});
});
describe('BiggerThanEquals Symbol', () => {
it('should update array when conditions satisfied', () => {
const object = { peoples: [{ id: 2 } ] };
const result = update(`peoples[id>=1]`, { id: 3, name: 'michael' }, object);
expect(result).toEqual({ peoples: [{ id: 3, name: 'michael' }] });
});
it('should update array when conditions satisfied when value is hashed', () => {
const object = { peoples: [{ id: 2 } ] };
const result = update(`peoples[id>=${v(1)}]`, { id: 3, name: 'michael' }, object);
expect(result).toEqual({ peoples: [{ id: 3, name: 'michael' }] });
});
it('should update first existence when conditions satisfied for singular queries', () => {
const object = { peoples: [{ id: 2 }, { id: 2, other: true }] };
const result = update(`peoples[id>=2]`, { id: 100, name: 'john' }, object);
expect(result).toEqual({ peoples: [{ id: 100, name: 'john' }, { id: 2, other: true }] });
});
it('should not update array when condition do not match', () => {
const object = { peoples: [{ id: 1 } ] };
const result = update(`peoples[id>=10]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 1 } ] });
});
it('should update array deep property when conditions satisfied', () => {
const object = { peoples: [{ id: 2, name: 'islam' }, { id: 3, name: 'xx' } ] };
const result = update(`peoples[id>=2].name`, 'sabel', object);
expect(result).toEqual({ peoples: [{ id: 2, name: 'sabel' }, { id: 3, name: 'xx' }] });
});
it('should update array deep deep property when conditions satisfied', () => {
const object = { peoples: [{ name: 'islam', friends: [{ age: 20, name: 'max' }, { age: 30, name: 'Aseel' }, { age: 40, name: 'sabel' } ] } ] };
const result = update(`peoples[name='islam'].friends[age>=30].name`, 'Sohaib', object);
expect(result).toEqual({ peoples: [{ name: 'islam', friends: [{ age: 20, name: 'max' }, { age: 30, name: 'Sohaib' }, { age: 40, name: 'sabel' } ] } ] });
});
});
describe('SmallerThan Symbol', () => {
it('should update array when conditions satisfied', () => {
const object = { peoples: [{ id: 2 } ] };
const result = update(`peoples[id<3]`, { id: 3, name: 'michael' }, object);
expect(result).toEqual({ peoples: [{ id: 3, name: 'michael' }] });
});
it('should update array when conditions satisfied when value is hashed', () => {
const object = { peoples: [{ id: 2 } ] };
const result = update(`peoples[id<${v(3)}]`, { id: 3, name: 'michael' }, object);
expect(result).toEqual({ peoples: [{ id: 3, name: 'michael' }] });
});
it('should update first existence when conditions satisfied for singular queries', () => {
const object = { peoples: [{ id: 2 }, { id: 2, other: true }] };
const result = update(`peoples[id<12]`, { id: 100, name: 'john' }, object);
expect(result).toEqual({ peoples: [{ id: 100, name: 'john' }, { id: 2, other: true }] });
});
it('should not update array when condition do not match', () => {
const object = { peoples: [{ id: 1 } ] };
const result = update(`peoples[id<-2]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 1 } ] });
});
it('should update array deep property when conditions satisfied', () => {
const object = { peoples: [{ id: 2, name: 'islam' }, { id: 3, name: 'xx' } ] };
const result = update(`peoples[id<3].name`, 'sabel', object);
expect(result).toEqual({ peoples: [{ id: 2, name: 'sabel' }, { id: 3, name: 'xx' }] });
});
it('should update array deep deep property when conditions satisfied', () => {
const object = { peoples: [{ name: 'islam', friends: [{ age: 20, name: 'max' }, { age: 30, name: 'Aseel' }, { age: 40, name: 'sabel' } ] } ] };
const result = update(`peoples[name='islam'].friends[age<30].name`, 'Sohaib', object);
expect(result).toEqual({ peoples: [{ name: 'islam', friends: [{ age: 20, name: 'Sohaib' }, { age: 30, name: 'Aseel' }, { age: 40, name: 'sabel' } ] } ] });
});
});
describe('SmallerThanEquals Symbol', () => {
it('should update array when conditions satisfied', () => {
const object = { peoples: [{ id: 2 } ] };
const result = update(`peoples[id<=2]`, { id: 3, name: 'michael' }, object);
expect(result).toEqual({ peoples: [{ id: 3, name: 'michael' }] });
});
it('should update array when conditions satisfied when value is hashed', () => {
const object = { peoples: [{ id: 2 } ] };
const result = update(`peoples[id<=${v(2)}]`, { id: 3, name: 'michael' }, object);
expect(result).toEqual({ peoples: [{ id: 3, name: 'michael' }] });
});
it('should update first existence when conditions satisfied for singular queries', () => {
const object = { peoples: [{ id: 2 }, { id: 2, other: true }] };
const result = update(`peoples[id<=2]`, { id: 100, name: 'john' }, object);
expect(result).toEqual({ peoples: [{ id: 100, name: 'john' }, { id: 2, other: true }] });
});
it('should not update array when condition do not match', () => {
const object = { peoples: [{ id: 1 } ] };
const result = update(`peoples[id<=-100]`, { id: 10, name: 'islam' }, object);
expect(result).toEqual({ peoples: [{ id: 1 } ] });
});
it('should update array deep property when conditions satisfied', () => {
const object = { peoples: [{ id: 2, name: 'islam' }, { id: 3, name: 'xx' } ] };
const result = update(`peoples[id<=2].name`, 'sabel', object);
expect(result).toEqual({ peoples: [{ id: 2, name: 'sabel' }, { id: 3, name: 'xx' }] });
});
it('should update array deep deep property when conditions satisfied', () => {
const object = { peoples: [{ name: 'islam', friends: [{ age: 20, name: 'max' }, { age: 30, name: 'Aseel' }, { age: 40, name: 'sabel' } ] } ] };
const result = update(`peoples[name='islam'].friends[age<=30].name`, 'Sohaib', object);
expect(result).toEqual({ peoples: [{ name: 'islam', friends: [{ age: 20, name: 'Sohaib' }, { age: 30, name: 'Aseel' }, { age: 40, name: 'sabel' } ] } ] });
});
});
});
it('should show readable error when failing', () => {
const object = { islam: 1 };
const path = 'islam[].[]';
const value = 'sabel';
expect(() => {
update(path, value, object);
}).toThrow(`Golden Path :: Error while resolving the path "${path}" - Please check the Golden Path Syntax`);
});
});