mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-25 00:11:06 +00:00
c1e6dadeb4
This sets up the new `test/unit` and `test/integration` folders and starts classification of some of the test files. Note that unit tests include, `fs-utils` and `system-info` tests. While these tests interact with the filesystem, the implementation of these modules is simple enough, and the tests are fast enough to allow these tests to fall under the `unit` test category (according to test/README) Change-type: patch
160 lines
5.1 KiB
TypeScript
160 lines
5.1 KiB
TypeScript
import { expect } from 'chai';
|
|
import { equals, diff, prune, shallowDiff } from '~/lib/json';
|
|
|
|
describe('JSON utils', () => {
|
|
describe('equals', () => {
|
|
it('should compare non-objects', () => {
|
|
expect(equals(0, 1)).to.be.false;
|
|
expect(equals(1111, 'a' as any)).to.be.false;
|
|
expect(equals(1111, 2222)).to.be.false;
|
|
expect(equals('aaa', 'bbb')).to.be.false;
|
|
expect(equals('aaa', 'aaa')).to.be.true;
|
|
expect(equals(null, null)).to.be.true;
|
|
expect(equals(null, undefined)).to.be.false;
|
|
expect(equals([], [])).to.be.true;
|
|
expect(equals([1, 2, 3], [1, 2, 3])).to.be.true;
|
|
expect(equals([1, 2, 3], [1, 2])).to.be.false;
|
|
expect(equals([], []), 'empty arrays').to.be.true;
|
|
});
|
|
|
|
it('should compare objects recursively', () => {
|
|
expect(equals({}, {}), 'empty objects').to.be.true;
|
|
expect(equals({ a: 1 }, { a: 1 }), 'single level objects').to.be.true;
|
|
expect(equals({ a: 1 }, { a: 2 }), 'differing value single level objects')
|
|
.to.be.false;
|
|
expect(equals({ a: 1 }, { b: 1 }), 'differing keys single level objects');
|
|
expect(
|
|
equals({ a: 1 }, { b: 1, c: 2 }),
|
|
'differing keys single level objects',
|
|
).to.be.false;
|
|
expect(equals({ a: { b: 1 } }, { a: { b: 1 } }), 'multiple level objects')
|
|
.to.be.true;
|
|
expect(
|
|
equals({ a: { b: 1 } }, { a: { b: 1, c: 2 } }),
|
|
'extra keys in multiple level objects',
|
|
).to.be.false;
|
|
expect(
|
|
equals({ a: { b: 1 }, c: 2 }, { a: { b: 1 } }),
|
|
'source object with extra keys',
|
|
).to.be.false;
|
|
expect(
|
|
equals({ a: { b: 1 } }, { a: { b: 1 }, c: 2 }),
|
|
'other object with extra keys',
|
|
).to.be.false;
|
|
expect(
|
|
equals({ a: { b: 1 }, c: 2 }, { a: { b: 1 }, c: 2 }),
|
|
'multiple level objects with extra keys',
|
|
).to.be.true;
|
|
expect(
|
|
equals({ a: { b: 1 }, d: 2 }, { a: { b: 1 }, c: 2 }),
|
|
'multiple level objects with same number of keys',
|
|
).to.be.false;
|
|
});
|
|
});
|
|
|
|
describe('diff', () => {
|
|
it('when comparing non-objects or arrays, always returns the target value', () => {
|
|
expect(diff(1, 2)).to.equal(2);
|
|
expect(diff(1, 'a' as any)).to.equal('a');
|
|
expect(diff(1.1, 2)).to.equal(2);
|
|
expect(diff('aaa', 'bbb')).to.equal('bbb');
|
|
expect(diff({}, 'bbb' as any)).to.equal('bbb');
|
|
expect(diff([1, 2, 3], [3, 4, 5])).to.deep.equal([3, 4, 5]);
|
|
});
|
|
|
|
it('when comparing objects, calculates differences recursively', () => {
|
|
// Reports all changes
|
|
expect(diff({ a: 1 }, { b: 1 })).to.deep.equal({ a: undefined, b: 1 });
|
|
|
|
// Only reports array changes if arrays are different
|
|
expect(diff({ a: [1, 2] }, { a: [1, 2] })).to.deep.equal({});
|
|
|
|
// Multiple key comparisons
|
|
expect(diff({ a: 1, b: 1 }, { b: 2 })).to.deep.equal({
|
|
a: undefined,
|
|
b: 2,
|
|
});
|
|
|
|
// Multiple target keys
|
|
expect(diff({ a: 1 }, { b: 2, c: 1 })).to.deep.equal({
|
|
a: undefined,
|
|
b: 2,
|
|
c: 1,
|
|
});
|
|
|
|
// Removing a branch
|
|
expect(diff({ a: 1, b: { c: 1 } }, { a: 1 })).to.deep.equal({
|
|
b: undefined,
|
|
});
|
|
|
|
// If the arrays are different, return target array
|
|
expect(diff({ a: [1, 2] }, { a: [2, 3] })).to.deep.equal({ a: [2, 3] });
|
|
|
|
// Value to object
|
|
expect(diff({ a: 1 }, { a: { c: 1 }, b: 2 })).to.deep.equal({
|
|
a: { c: 1 },
|
|
b: 2,
|
|
});
|
|
|
|
// Changes in nested object
|
|
expect(diff({ a: { c: 1 } }, { a: { c: 1, d: 2 }, b: 3 })).to.deep.equal({
|
|
a: { d: 2 },
|
|
b: 3,
|
|
});
|
|
|
|
// Multiple level nested objects with value removal
|
|
expect(
|
|
diff({ a: { c: { f: 1, g: 2 } } }, { a: { c: { f: 2 }, d: 2 }, b: 3 }),
|
|
).to.deep.equal({
|
|
a: { c: { f: 2, g: undefined }, d: 2 },
|
|
b: 3,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('shallowDiff', () => {
|
|
it('compares objects only to the given depth', () => {
|
|
expect(shallowDiff({ a: 1 }, { a: 1 }, 0)).to.deep.equal({ a: 1 });
|
|
expect(shallowDiff({ a: 1 }, { a: 1 }, 1)).to.deep.equal({});
|
|
expect(shallowDiff({ a: 1 }, { a: 1 }, 2)).to.deep.equal({});
|
|
expect(shallowDiff({ a: 1, b: 1 }, { a: 1 }, 1)).to.deep.equal({
|
|
b: undefined,
|
|
});
|
|
expect(
|
|
shallowDiff({ a: 1, b: { c: 2 } }, { a: 1, b: { c: 2 } }, 1),
|
|
).to.deep.equal({});
|
|
expect(
|
|
shallowDiff({ a: 1, b: { c: 2 } }, { a: 1, b: { c: 2, d: 3 } }, 1),
|
|
).to.deep.equal({ b: { c: 2, d: 3 } });
|
|
expect(
|
|
shallowDiff({ a: 1, b: { c: 2 } }, { a: 1, b: { c: 2, d: 3 } }, 2),
|
|
).to.deep.equal({ b: { d: 3 } });
|
|
});
|
|
});
|
|
|
|
describe('prune', () => {
|
|
it('does not remove empty arrays or other "empty values"', () => {
|
|
expect(prune([])).to.deep.equal([]);
|
|
expect(prune([0])).to.deep.equal([0]);
|
|
expect(prune(0)).to.deep.equal(0);
|
|
expect(prune({ a: 0 })).to.deep.equal({ a: 0 });
|
|
expect(prune({ a: [] })).to.deep.equal({ a: [] });
|
|
expect(prune({ a: [], b: 0 })).to.deep.equal({ a: [], b: 0 });
|
|
});
|
|
it('removes empty branches from a json object', () => {
|
|
expect(prune({})).to.deep.equal({});
|
|
expect(prune({ a: {} })).to.deep.equal({});
|
|
expect(prune({ a: { b: {} } })).to.deep.equal({});
|
|
expect(prune({ a: 1, b: {} })).to.deep.equal({ a: 1 });
|
|
expect(prune({ a: 1, b: {}, c: { d: 2, e: {} } })).to.deep.equal({
|
|
a: 1,
|
|
c: { d: 2 },
|
|
});
|
|
expect(prune({ a: 1, b: {}, c: { d: 2, e: [] } })).to.deep.equal({
|
|
a: 1,
|
|
c: { d: 2, e: [] },
|
|
});
|
|
});
|
|
});
|
|
});
|