Skip to content

Commit

Permalink
rm old diff
Browse files Browse the repository at this point in the history
  • Loading branch information
neSpecc committed Jan 25, 2025
1 parent 78f9204 commit 00088be
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 344 deletions.
158 changes: 0 additions & 158 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const _ = require('lodash');
const https = require('https');

/**
Expand All @@ -9,163 +8,6 @@ const https = require('https');
*/
module.exports.sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

/**
* Make `deepDiff` exportable
* return {object}
*/
module.exports.deepDiff = deepDiff;

/**
* Make `deepMerge` exportable
* return {object}
*/
module.exports.deepMerge = deepMerge;

/**
* Recursively scans two variables and returns another object with diffs
*
* @param {object|Array} source - source object
* @param {object|Array} target - target object
* @returns {object}
*/
function deepDiff(source, target) {
const sourceType = typeOf(source);
const targetType = typeOf(target);

/**
* If we'll compare NOTHING with SOMETHING, the diff will be SOMETHING
*/
if (source === undefined) {
return target;
}

/**
* If we'll compare SOMETHING with NOTHING, the diff will be NOTHING
*/
if (targetType === undefined) {
return undefined;
}

/**
* We CAN'T compare apples with dogs
*/
if (sourceType !== targetType) {
return undefined;
}

if (targetType === 'array') {
return arrayDiff(source, target);
} else if (targetType === 'object') {
return objectDiff(source, target);
} else if (source !== target) {
return target;
} else {
return source;
}
}

/**
* Returns two arrays difference as an new array
*
* @param {Array} source - source object
* @param {Array} target - target object
* @returns {Array}
*/
function arrayDiff(source, target) {
const diffArray = [];

for (let i = 0; i < target.length; i++) {
if (source === null) {
diffArray[i] = target[i];
} else {
diffArray[i] = deepDiff(source[i], target[i]);
}
}

return diffArray;
}

/**
* Returns two objects difference as new object
*
* @param {object} objectA - first object for comparing
* @param {object} objectB - second object for comparing
*
* @returns {object}
*/
function objectDiff(objectA, objectB) {
const diffObject = {};

/**
* objectA is a subject,
* we compare objectB patches
*
* For that we enumerate objectB props and assume that
* target object has any changes
*
* But target object might have additional patches that might not be in subject
* This corner case says us that whole property is a patch
*/
if (!objectA) {
return objectB;
}

Object.keys(objectB).forEach((prop) => {
const objectAItem = objectA[prop];
const objectBItem = objectB[prop];

if (objectAItem === undefined) {
diffObject[prop] = objectBItem;

return;
}

if (objectAItem === objectBItem) {
return;
}

diffObject[prop] = deepDiff(objectAItem, objectBItem);
});

return diffObject;
}

/**
* Merge to objects recursively
*
* @param {object} target - target object
* @param {object[]} sources - sources for mering
* @returns {object}
*/
function deepMerge(target, ...sources) {
const isObject = (item) => item && typeOf(item) === 'object';

return _.mergeWith({}, target, ...sources, function (_subject, _target) {
if (_.isArray(_subject) && _.isArray(_target)) {
const biggerArray = _subject.length > _target.length ? _subject : _target;
const lesser = _subject.length > _target.length ? _target : _subject;

return biggerArray.map((el, i) => {
if (isObject(el) && isObject(lesser[i])) {
return _.mergeWith({}, el, lesser[i]);
} else {
return el;
}
});
}
});
}

/**
* Returns real type of passed variable
*
* @param {*} obj - value to check
* @returns {string}
*/
function typeOf(obj) {
return Object.prototype.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
}

/**
* Sends alert to the Slack/Telegram
*
Expand Down
166 changes: 2 additions & 164 deletions lib/utils.test.js
Original file line number Diff line number Diff line change
@@ -1,170 +1,6 @@
const utils = require('./utils');

describe('Utils', () => {
const dataProvider = [
{
sourceObject: {
a: 3,
d: 1,
b: {
c: {
d: 6,
e: [],
},
},
},
targetObject: {
a: 2,
b: {
c: {
d: 5,
e: [1, 1, 2],
},
},
},
expectedDiff: {
a: 2,
b: {
c: {
d: 5,
e: [1, 1, 2],
},
},
},
expectedMerge: {
a: 2,
d: 1,
b: {
c: {
d: 5,
e: [1, 1, 2],
},
},
},
},
{
sourceObject: {
a: 3,
d: 1,
b: {
c: {
d: 6,
e: [],
},
},
},
targetObject: {
a: 3,
b: {
c: {
d: 6,
e: [],
},
},
},
expectedDiff: {
b: {
c: {
e: [],
},
},
},
expectedMerge: {
a: 3,
d: 1,
b: {
c: {
d: 6,
e: [],
},
},
},
},
/**
* First and Second object has array-property with different number of items
* First has less items count.
*/

{
sourceObject: {
files: [ { line: 1 }, { line: 2 } ],
},
targetObject: {
files: [ { line: 1 }, { line: 2 }, { line: 3 } ],
},
expectedDiff: {
files: [ {}, {}, { line: 3 } ],
},
expectedMerge: {
files: [ { line: 1 }, { line: 2 }, { line: 3 } ],
},
},
/**
* First and Second object has array-property with different number of items
* First has more items count.
*/
{
sourceObject: {
files: [ { line: 1 }, { line: 2 }, { line: 3 } ],
},
targetObject: {
files: [ { line: 1 }, { line: 2 } ],
},
expectedDiff: {
files: [ {}, {} ],
},
expectedMerge: {
files: [ { line: 1 }, { line: 2 }, { line: 3 } ],
},
},

/**
* The first - an empty array
* The second - array with the children non-empty array
*/
{
sourceObject: {
prop: [],
},
targetObject: {
prop: [ [ 'i am not empty' ] ],
},
expectedDiff: {
prop: [ [ 'i am not empty' ] ],
},
expectedMerge: {
prop: [ [ 'i am not empty' ] ],
},
},

/**
* Trying to compare two things of different type
*/
{
sourceObject: [],
targetObject: {},
expectedDiff: undefined,
expectedMerge: {},
},
];

test('should return right object diff', () => {
dataProvider.forEach((testCase) => {
const diff = utils.deepDiff(testCase.sourceObject, testCase.targetObject);

expect(diff).toEqual(testCase.expectedDiff);
});
});

test('should return right object merge', () => {
dataProvider.forEach((testCase) => {
const diff = utils.deepDiff(testCase.sourceObject, testCase.targetObject);
const merge = utils.deepMerge(testCase.sourceObject, diff);

expect(merge).toEqual(testCase.expectedMerge);
});
});

/**
* This test is a temporary solution to handle case with invalid events format sent by the PHP catcher
*
Expand All @@ -178,6 +14,8 @@ describe('Utils', () => {
*
* PHP Catcher issue:
* https://github.com/codex-team/hawk.php/issues/39
*
* @todo move this test to the grouper tests and remove usage of utils.deepDiff
*/
test('should not throw error comparing events with incompatible format', () => {
const originalStackTrace = [
Expand Down
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,29 @@
"codex-accounting-sdk": "codex-team/codex-accounting-sdk",
"debug": "^4.1.1",
"dotenv": "^8.2.0",
"lodash.mergewith": "^4.6.2",
"migrate-mongo": "^7.2.1",
"mockdate": "^3.0.2",
"mongodb": "^3.5.7",
"nanoid": "^3.1.31",
"node-cache": "^5.1.2",
"prom-client": "^12.0.0",
"prometheus-gc-stats": "^0.6.2",
"redis": "^4.7.0",
"short-number": "^1.0.7",
"ts-node": "^8.10.1",
"typescript": "^3.8.3",
"uuid": "^8.3.0",
"winston": "^3.2.1",
"yup": "^0.28.5",
"redis": "^4.7.0"
"yup": "^0.28.5"
},
"devDependencies": {
"@shelf/jest-mongodb": "^1.2.3",
"testcontainers": "^3.0.0",
"eslint": "^7.14.0",
"eslint-config-codex": "^1.6.1",
"jest": "25.5.4",
"nodemon": "^2.0.3",
"random-words": "^1.1.1",
"testcontainers": "^3.0.0",
"ts-jest": "25.4.0",
"wait-for-expect": "^3.0.2",
"webpack": "^4.43.0",
Expand Down
Loading

0 comments on commit 00088be

Please sign in to comment.