Skip to content

Commit

Permalink
Test against tiny-get's test suite
Browse files Browse the repository at this point in the history
It already covers many complex edge cases
  • Loading branch information
spautz committed Aug 22, 2020
1 parent 9d8da2b commit 2eda822
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 2 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
},
"dependencies": {},
"devDependencies": {
"@ngard/tiny-get": "^1.2.2",
"@types/jest": "^26.0.10",
"@types/node": "^14.6.0",
"coveralls": "^3.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-env jest */
import set from '.';
import { set } from '.';

describe('basic functionality', () => {
describe('shallow objects', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@ const set = <T = ObjectOrArray>(
return newRoot;
};

export default set;
export { set };
7 changes: 7 additions & 0 deletions src/tiny-get.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare module '@ngard/tiny-get' {
export function get(
object: any,
path: string | number | Array<string | number>,
defaultValue?: any,
): any;
}
159 changes: 159 additions & 0 deletions src/tiny-get.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/* eslint-env jest */
import { get } from '@ngard/tiny-get';

import { set } from '.';

/*
* This is adapted from the test suite from tiny-get, which this library is inspired by.
* https://github.com/NickGard/tiny-get
*
* It was converted to Typescript, and each case was changed to perform a set() using the same paths
* that it tests for get()
*/
describe('set object properties', () => {
const weirdKeys = [
' ',
"'",
'"',
']',
'[',
"['a']",
"['a",
'{}',
' a',
' a.b',
'a.b',
'%$^',
'😱',
'0',
0,
' 0 ',
'"0"',
];
const obj = {
az: {
b: 'success',
},
};
const validNestedAccessors = [
'["az"]["b"]',
"['az']['b']",
`['az']["b"]`,
`["az"]['b']`,
'az["b"]',
"az['b']",
`['az'].b`,
`["az"].b`,
'az.b',
' az . b ',
' [ "az" ] [ "b" ] ',
" [ 'az' ] [ 'b' ] ",
` [ 'az' ] [ "b" ] `,
` [ "az" ] [ 'b' ] `,
' az [ "b" ] ',
" az [ 'b' ] ",
` [ 'az' ] . b `,
` [ "az" ] . b `,
];

validNestedAccessors.forEach((key) => {
it(`should properly set property <<${key}>>`, () => {
const newObj = set(obj, key, 'new-value');
// Original unchanged
expect(get(obj, key, 'default')).toEqual('success');
// New has value
expect(get(newObj, key, 'default')).toEqual('new-value');
// New !== old
expect(newObj).not.toEqual(obj);
});
});

weirdKeys.forEach((key) => {
it(`should set the value at <<${key}>> rather than a nested value`, () => {
const obj = weirdKeys.reduce<Record<string, string>>((o, k) => {
o[k] = 'success';
return o;
}, {});
const newObj = set(obj, key, 'new-value');

// Original unchanged
expect(get(obj, key)).toEqual('success');
// New has value
expect(get(newObj, key)).toEqual('new-value');
// New !== old
expect(newObj).not.toEqual(obj);
expect(newObj[key]).not.toEqual(obj[key]);
});
});

it('should set a top-level weird key before following the same path', () => {
const obj = { a: { b: 'fail' }, 'a.b': 'success' };
const newObj = set(obj, 'a.b', 'new-value');

// Original unchanged
expect(get(obj, 'a.b')).toEqual('success');
// New has value
expect(get(newObj, 'a.b')).toEqual('new-value');
// New !== old, except the unchanged paths
expect(newObj).not.toEqual(obj);
expect(newObj['a.b']).not.toEqual(obj['a.b']);
expect(newObj.a).toStrictEqual(obj.a);
});
});

describe('set object property with an array path', () => {
it('should set an object property with sane key names', () => {
const obj = {
foo: {
bar: {
baz: 'success',
},
},
};
const newObj = set(obj, "['foo']['bar']['baz']", 'new-value');

// Original unchanged
expect(get(obj, "['foo']['bar']['baz']")).toEqual('success');
expect(obj['foo']['bar']['baz']).toEqual('success');
// New has value
expect(get(newObj, "['foo']['bar']['baz']")).toEqual('new-value');
// New !== old
expect(newObj).not.toEqual(obj);
});
it('should set an object property with weird key names', () => {
const obj = {
'[fo': {
'o]': 'success',
},
foo: { result: 'failure' },
};
const newObj = set(obj, "['[fo']['o]']", 'new-value');

// Original unchanged
expect(get(obj, "['[fo']['o]']")).toEqual('success');
// New has value
expect(get(newObj, "['[fo']['o]']")).toEqual('new-value');
// New !== old, except the parts that we left alone
expect(newObj).not.toEqual(obj);
expect(newObj['[fo']).not.toEqual(obj['[fo']);
expect(newObj.foo).toStrictEqual(obj.foo);
});
});

describe('set array values', () => {
const arr = ['one', { two: ['success'], twoB: [] }, { three: 3 }] as const;
it('should handle array indexes as part of a path', () => {
const newArr = set(arr, '[1].two[0]', 'new-value');

// Original unchanged
expect(get(arr, '[1].two[0]')).toEqual('success');
// New has value
expect(get(newArr, '[1].two[0]')).toEqual('new-value');
// New !== old, except the parts that we left alone
expect(newArr).not.toEqual(arr);
expect(newArr[1]).not.toEqual(arr[1]);
expect(newArr[1].two).not.toEqual(arr[1].two);
expect(newArr[1].twoB).toStrictEqual(arr[1].twoB);
expect(newArr[2]).toStrictEqual(arr[2]);
});
});
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,11 @@
"@types/yargs" "^15.0.0"
chalk "^3.0.0"

"@ngard/tiny-get@^1.2.2":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@ngard/tiny-get/-/tiny-get-1.2.2.tgz#3784ea1fdd852a59a44d50c144f070529422d7a7"
integrity sha512-+B2yx8KGWPxi/z0fqCgA+gNEWGwoVJZ8v98DFHIEVtEfn5BHXV8Wcr9NfracmrZa2dqekyXduPFcw2sL1HUw6Q==

"@rollup/plugin-commonjs@^11.0.0":
version "11.1.0"
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-11.1.0.tgz#60636c7a722f54b41e419e1709df05c7234557ef"
Expand Down

0 comments on commit 2eda822

Please sign in to comment.