Skip to content

Commit

Permalink
chore: split tests into suites
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeed committed Jan 27, 2021
1 parent 2245341 commit fc1c385
Showing 1 changed file with 212 additions and 55 deletions.
267 changes: 212 additions & 55 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,231 @@
// @ts-check
import { test } from 'uvu';
import { suite } from 'uvu';
import * as assert from 'uvu/assert';
import dset from '../dist/dset';

test('dset', () => {
assert.type(dset, 'function', 'exports a function');
const API = suite('API');

let foo = { a:1, b:2 };
let out = dset(foo, 'c', 3); // add c
assert.is(out, undefined, 'does not return output');
assert.equal(foo, { a:1, b:2, c:3 }, 'mutates; adds simple key:val');
API('should export a function', () => {
assert.type(dset, 'function');
});

API.run();

// ---

const usage = suite('usage');

usage('should not give return value', () => {
let output = dset({}, 'c', 3); // add c
assert.is(output, undefined);
});

usage('should mutate original object', () => {
let item = { foo: 1 };
dset(item, 'bar', 123);
assert.ok(item === item);
assert.equal(item, {
foo: 1,
bar: 123
});
});

usage.run();

// ---

const keys = suite('keys');

keys('should add value to key path :: shallow :: string', () => {
let input = {};
dset(input, 'abc', 123);
assert.equal(input, { abc: 123 });
});

keys('should add value to key path :: shallow :: array', () => {
let input = {};
dset(input, ['abc'], 123);
assert.equal(input, { abc: 123 });
});

keys('should add value to key path :: nested :: string', () => {
let input = {};
dset(input, 'a.b.c', 123);
assert.equal(input, {
a: {
b: {
c: 123
}
}
});
});

keys('should add value to key path :: nested :: array', () => {
let input = {};
dset(input, ['a', 'b', 'c'], 123);
assert.equal(input, {
a: {
b: {
c: 123
}
}
});
});

keys.run();

foo = {};
dset(foo, 'a.b.c', 999); // add deep
assert.equal(foo, { a:{ b:{ c:999 } } }, 'mutates; adds deeply nested key:val');
// ---

foo = {};
dset(foo, ['a', 'b', 'c'], 123); // change via array
assert.equal(foo, { a:{ b:{ c:123 } } }, 'mutates; changes the value via array-type keys');
const arrays = suite('arrays');

arrays('should create array instead of object via numeric key :: simple', () => {
let input = { a: 1 };
dset(input, 'e.0', 2);
assert.instance(input.e, Array);
assert.is(input.e[0], 2);
assert.equal(input, {
a: 1,
e: [2]
});
});

arrays('should create array instead of object via numeric key :: nested', () => {
let input = { a: 1 };
dset(input, 'e.0.0', 123);
assert.instance(input.e, Array);
assert.is(input.e[0][0], 123);
assert.equal(input, {
a: 1,
e: [ [123] ]
});
});

foo = { a:1 };
dset(foo, 'e.0.0', 2); // create arrays instead of objects
assert.is(foo.e[0][0], 2, 'mutates; can create arrays when key is numeric');
assert.equal(foo, { a: 1, e:[[2]] });
assert.instance(foo.e, Array);
arrays('should be able to create object inside of array', () => {
let input = {};
dset(input, ['x', '0', 'z'], 123);
assert.instance(input.x, Array);
assert.equal(input, {
x: [{ z:123 }]
});
});

foo = { a:{ b:{ c:123 } } };
dset(foo, 'a.b.x.y', 456); // preserve existing structure
assert.equal(foo, { a:{ b:{ c:123, x:{ y:456 } }} }, 'mutates; writes into/preserves existing object');
arrays('should create arrays with hole(s) if needed', () => {
let input = {};
dset(input, ['x', '1', 'z'], 123);
assert.instance(input.x, Array);
assert.equal(input, {
x: [, { z:123 }]
});
});

foo = { a: { b:123 } };
dset(foo, 'a.b.c', 'hello'); // preserve non-object value, won't alter
assert.is(foo.a.b, 123, 'refuses to convert existing non-object value into object');
assert.equal(foo, { a: { b:123 }});
arrays('should create object from decimal-like key :: array :: zero', () => {
let input = {};
dset(input, ['x', '10.0', 'z'], 123);
assert.not.instance(input.x, Array);
assert.equal(input, {
x: {
'10.0': {
z: 123
}
}
});
});

foo = { a:{ b:{ c:123, d:{ e:5 } } } };
dset(foo, 'a.b.d.z', [1,2,3,4]); // preserve object tree, with array value
assert.equal(foo.a.b.d, { e:5, z:[1,2,3,4] }, 'mutates; writes into existing object w/ array value');
arrays('should create object from decimal-like key :: array :: nonzero', () => {
let input = {};
dset(input, ['x', '10.2', 'z'], 123);
assert.not.instance(input.x, Array);
assert.equal(input, {
x: {
'10.2': {
z: 123
}
}
});
});

foo = { b:123 };
assert.not.throws(_ => dset(foo, 'b.c.d.e', 123), 'silently preserves existing non-null value');
assert.is(foo.b, 123, 'preserves existing value');
arrays.run();

// ---

const preserves = suite('preserves');

preserves('should preserve existing object structure', () => {
let input = {
a: {
b: {
c: 123
}
}
};

dset(input, 'a.b.x.y', 456);

assert.equal(input, {
a: {
b: {
c: 123,
x: {
y:456
}
}
}
});
});

foo = { b:0 };
assert.not.throws(_ => dset(foo, 'b.a.s.d', 123), 'silently preserves `0` as existing non-null value');
assert.equal(foo, { b:0 }, 'preserves existing object values');
preserves('should not convert existing non-object values into object', () => {
let input = {
a: {
b: 123
}
};

foo = {};
dset(foo, ['x', 'y', 'z'], 123);
assert.equal(foo, { x:{ y:{ z:123 } } });
let before = JSON.stringify(input);
dset(input, 'a.b.c', 'hello');

foo = {};
dset(foo, ['x', '0', 'z'], 123);
assert.equal(foo, { x:[{ z:123 }] });
assert.instance(foo.x, Array);
assert.is(
JSON.stringify(input),
before
);
});

foo = {};
dset(foo, ['x', '1', 'z'], 123);
assert.equal(foo, { x:[,{ z:123 }] });
assert.instance(foo.x, Array);
preserves('should preserve existing object tree w/ array value', () => {
let input = {
a: {
b: {
c: 123,
d: {
e: 5
}
}
}
};

dset(input, 'a.b.d.z', [1,2,3,4]);

assert.equal(input.a.b.d, {
e: 5,
z: [1,2,3,4]
});
});

foo = {};
dset(foo, ['x', '10.0', 'z'], 123);
assert.equal(foo, { x:{ '10.0':{ z:123 } } });
assert.not.instance(foo.x, Array);
preserves('should not throw when refusing to convert non-object into object', () => {
try {
let input = { b:123 };
dset(input, 'b.c.d.e', 123);
assert.is(input.b, 123);
} catch (err) {
assert.unreachable('should not have thrown');
}
});

foo = {};
dset(foo, ['x', '10.2', 'z'], 123);
assert.equal(foo, { x:{ '10.2':{ z:123 } } });
assert.not.instance(foo.x, Array);
preserves('should not throw when refusing to convert `0` into object', () => {
try {
let input = { b:0 };
dset(input, 'b.a.s.d', 123);
assert.equal(input, { b: 0 });
} catch (err) {
assert.unreachable('should not have thrown');
}
});

test.run();
preserves.run();

0 comments on commit fc1c385

Please sign in to comment.