Skip to content

Commit

Permalink
Merge pull request #19 from blackflux/dev
Browse files Browse the repository at this point in the history
[Gally]: master <- dev
  • Loading branch information
simlu committed Jan 27, 2021
2 parents 5c35373 + 605983f commit 692b0e0
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 31 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"eslint-plugin-markdown": "1.0.2",
"eslint-plugin-mocha": "8.0.0",
"js-gardener": "2.0.184",
"lodash.clonedeep": "4.5.0",
"node-tdd": "2.19.1",
"nyc": "15.1.0",
"semantic-release": "17.3.7"
Expand Down
49 changes: 26 additions & 23 deletions src/core/align.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,39 @@
const align = (target, ref) => {
if (
!(target instanceof Object)
|| !(ref instanceof Object)
) {
return;
}
if (Array.isArray(target) !== Array.isArray(ref)) {
return;
}

if (Array.isArray(target)) {
for (let idx = 0, len = Math.min(target.length, ref.length); idx < len; idx += 1) {
align(target[idx], ref[idx]);
}
return;
}
const objectScan = require('object-scan');

const align = (target, ref) => {
const keysTarget = Object.keys(target);
const keysRef = Object.keys(ref);
keysTarget
.map((k) => [k, keysRef.indexOf(k)])
.map(([k, idx]) => (idx === -1 ? [k, Number.MAX_VALUE] : [k, idx]))
.sort(([k1, idx1], [k2, idx2]) => idx1 - idx2)
.forEach(([k, idx]) => {
.sort((e1, e2) => e1[1] - e2[1])
.forEach(([k]) => {
const value = target[k];
if (idx !== Number.MAX_VALUE) {
align(value, ref[k]);
}
// eslint-disable-next-line no-param-reassign
delete target[k];
// eslint-disable-next-line no-param-reassign
target[k] = value;
});
};
module.exports = align;

const scanner = objectScan(['', '**'], {
breakFn: ({ property, context }) => {
const last = context[context.length - 1];
if (last instanceof Object) {
context.push(property === undefined ? last : last[property]);
return false;
}
context.push(null);
return true;
},
filterFn: ({ value, context }) => {
const last = context.pop();
if (last instanceof Object && value instanceof Object) {
align(last, value);
}
}
});

module.exports = (tree, ref) => {
scanner(ref, [tree]);
};
24 changes: 22 additions & 2 deletions test/core/align.spec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
const expect = require('chai').expect;
const cloneDeep = require('lodash.clonedeep');
const { describe } = require('node-tdd');
const align = require('../../src/core/align');
const genData = require('./gen-data');

describe('Testing align', () => {
const convert = (input) => {
if (input === undefined) {
return input;
}
return JSON.stringify(input, null, 2).split('\n');
};
const runTest = (input, template, expected) => {
align(input, template);
expect(JSON.stringify(input, null, 2).split('\n'))
.to.deep.equal(JSON.stringify(expected, null, 2).split('\n'));
expect(convert(input)).to.deep.equal(convert(expected));
};

it('Batch test', ({ fixture }) => {
const alignRec = fixture('align-rec');
for (let x = 0; x < 10000; x += 1) {
const tree1 = genData();
const tree2 = cloneDeep(tree1);
const ref = genData();
align(tree1, ref);
alignRec(tree2, ref);
expect(convert(tree1)).to.deep.equal(convert(tree2));
}
});

it('Testing Basic Ordering', () => {
const obj = { key1: 'value1', key2: 'value2' };
const ref = { key2: 'value2', key1: 'value1' };
Expand Down
36 changes: 36 additions & 0 deletions test/core/align.spec.js__fixtures/align-rec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const align = (target, ref) => {
if (
!(target instanceof Object)
|| !(ref instanceof Object)
) {
return;
}
if (Array.isArray(target) !== Array.isArray(ref)) {
return;
}

if (Array.isArray(target)) {
for (let idx = 0, len = Math.min(target.length, ref.length); idx < len; idx += 1) {
align(target[idx], ref[idx]);
}
return;
}

const keysTarget = Object.keys(target);
const keysRef = Object.keys(ref);
keysTarget
.map((k) => [k, keysRef.indexOf(k)])
.map(([k, idx]) => (idx === -1 ? [k, Number.MAX_VALUE] : [k, idx]))
.sort(([k1, idx1], [k2, idx2]) => idx1 - idx2)
.forEach(([k, idx]) => {
const value = target[k];
if (idx !== Number.MAX_VALUE) {
align(value, ref[k]);
}
// eslint-disable-next-line no-param-reassign
delete target[k];
// eslint-disable-next-line no-param-reassign
target[k] = value;
});
};
module.exports = align;
6 changes: 3 additions & 3 deletions test/core/contains.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const expect = require('chai').expect;
const { describe } = require('node-tdd');
const contains = require('../../src/core/contains');
const genData = require('./gen-data');

describe('Testing contains', { timeout: 100000 }, () => {
it('Batch test', ({ fixture }) => {
const gen = fixture('gen');
const containsRec = fixture('contains-rec');
for (let x = 0; x < 10000; x += 1) {
const tree = gen();
const subtree = gen();
const tree = genData();
const subtree = genData();
expect(contains(tree, subtree)).to.equal(containsRec(tree, subtree));
}
});
Expand Down
2 changes: 1 addition & 1 deletion test/core/contains.spec.js__fixtures/contains-rec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const containsRec = (haystack, needle) => {
return needle.every((e, idx) => containsRec(haystack[idx], e));
}
// subset match for object
return Object.keys(needle).every((key) => containsRec(haystack[key], needle[key]));
return Object.keys(needle).every((key) => key in haystack && containsRec(haystack[key], needle[key]));
}
// default comparison
return haystack === needle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ const rand = (values) => Math.floor(Math.random() * values);
const gen = (depth) => {
const v = rand(3);
if (v === 0 || depth >= 3) {
return rand(3);
return rand(2) === 0 ? rand(3) : undefined;
}
if (v === 1) {
return Array.from({ length: rand(3) }, () => gen(depth + 1));
}
const r = {};
const keys = ['A', 'B', 'C'].sort(() => Math.random() - 0.5);
for (let idx = 0, len = gen(3) + 1; idx < len; idx += 1) {
r[['A', 'B', 'C'][idx]] = gen(depth + 1);
r[keys[idx]] = gen(depth + 1);
}
return r;
};
Expand Down

0 comments on commit 692b0e0

Please sign in to comment.