mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-23 00:22:19 +01:00
fix: log diff (#5072)
Add a deep diff function to investigate diff in logs
This commit is contained in:
parent
75b131162e
commit
3ac8ab898a
@ -151,8 +151,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@apidevtools/swagger-parser": "10.1.0",
|
"@apidevtools/swagger-parser": "10.1.0",
|
||||||
"@babel/core": "7.23.0",
|
"@babel/core": "7.23.0",
|
||||||
"@swc/core": "1.3.92",
|
|
||||||
"@biomejs/biome": "1.2.2",
|
"@biomejs/biome": "1.2.2",
|
||||||
|
"@swc/core": "1.3.92",
|
||||||
"@swc/jest": "0.2.29",
|
"@swc/jest": "0.2.29",
|
||||||
"@types/bcryptjs": "2.4.4",
|
"@types/bcryptjs": "2.4.4",
|
||||||
"@types/cors": "2.8.14",
|
"@types/cors": "2.8.14",
|
||||||
|
66
src/lib/features/feature-toggle/deep-diff.ts
Normal file
66
src/lib/features/feature-toggle/deep-diff.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
interface Difference {
|
||||||
|
index: (string | number)[];
|
||||||
|
reason: string;
|
||||||
|
valueA: any;
|
||||||
|
valueB: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deepDiff(arr1: any[], arr2: any[]): Difference[] | null {
|
||||||
|
const diff: Difference[] = [];
|
||||||
|
|
||||||
|
function compare(a: any, b: any, parentIndex: (string | number)[]): void {
|
||||||
|
if (Array.isArray(a) && Array.isArray(b)) {
|
||||||
|
if (a.length !== b.length) {
|
||||||
|
diff.push({
|
||||||
|
index: parentIndex,
|
||||||
|
reason: 'Different lengths',
|
||||||
|
valueA: a,
|
||||||
|
valueB: b,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < a.length; i++) {
|
||||||
|
compare(a[i], b[i], parentIndex.concat(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
typeof a === 'object' &&
|
||||||
|
a !== null &&
|
||||||
|
typeof b === 'object' &&
|
||||||
|
b !== null
|
||||||
|
) {
|
||||||
|
const keysA = Object.keys(a);
|
||||||
|
const keysB = Object.keys(b);
|
||||||
|
|
||||||
|
if (!arraysEqual(keysA, keysB)) {
|
||||||
|
diff.push({
|
||||||
|
index: parentIndex,
|
||||||
|
reason: 'Different keys',
|
||||||
|
valueA: a,
|
||||||
|
valueB: b,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
for (const key of keysA) {
|
||||||
|
compare(a[key], b[key], parentIndex.concat(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (a !== b) {
|
||||||
|
diff.push({
|
||||||
|
index: parentIndex,
|
||||||
|
reason: 'Different values',
|
||||||
|
valueA: a,
|
||||||
|
valueB: b,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function arraysEqual(a: any[], b: any[]): boolean {
|
||||||
|
return (
|
||||||
|
a.length === b.length &&
|
||||||
|
a.sort().every((val, index) => val === b.sort()[index])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
compare(arr1, arr2, []);
|
||||||
|
|
||||||
|
return diff.length > 0 ? diff : null;
|
||||||
|
}
|
@ -103,6 +103,7 @@ import { IDependentFeaturesReadModel } from '../dependent-features/dependent-fea
|
|||||||
import EventService from '../../services/event-service';
|
import EventService from '../../services/event-service';
|
||||||
import { DependentFeaturesService } from '../dependent-features/dependent-features-service';
|
import { DependentFeaturesService } from '../dependent-features/dependent-features-service';
|
||||||
import isEqual from 'lodash.isequal';
|
import isEqual from 'lodash.isequal';
|
||||||
|
import { deepDiff } from './deep-diff';
|
||||||
|
|
||||||
interface IFeatureContext {
|
interface IFeatureContext {
|
||||||
featureName: string;
|
featureName: string;
|
||||||
@ -1067,12 +1068,17 @@ class FeatureToggleService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!equal) {
|
if (!equal) {
|
||||||
|
const difference = deepDiff(
|
||||||
|
featuresFromClientStore,
|
||||||
|
featuresFromFeatureToggleStore,
|
||||||
|
);
|
||||||
this.logger.warn(
|
this.logger.warn(
|
||||||
'features from client-feature-toggle-store is not equal to features from feature-toggle-store',
|
'getPlaygroundFeatures: features from client-feature-toggle-store is not equal to features from feature-toggle-store',
|
||||||
|
difference,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const features = this.flagResolver.isEnabled('useLastSeenRefactor')
|
const features = this.flagResolver.isEnabled('separateAdminClientApi')
|
||||||
? featuresFromFeatureToggleStore
|
? featuresFromFeatureToggleStore
|
||||||
: featuresFromClientStore;
|
: featuresFromClientStore;
|
||||||
|
|
||||||
@ -1113,12 +1119,17 @@ class FeatureToggleService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!equal) {
|
if (!equal) {
|
||||||
|
const difference = deepDiff(
|
||||||
|
featuresFromClientStore,
|
||||||
|
featuresFromFeatureToggleStore,
|
||||||
|
);
|
||||||
this.logger.warn(
|
this.logger.warn(
|
||||||
'features from client-feature-toggle-store is not equal to features from feature-toggle-store diff',
|
'getFeatureToggles: features from client-feature-toggle-store is not equal to features from feature-toggle-store diff',
|
||||||
|
difference,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const features = this.flagResolver.isEnabled('useLastSeenRefactor')
|
const features = this.flagResolver.isEnabled('separateAdminClientApi')
|
||||||
? featuresFromFeatureToggleStore
|
? featuresFromFeatureToggleStore
|
||||||
: featuresFromClientStore;
|
: featuresFromClientStore;
|
||||||
|
|
||||||
|
61
src/lib/features/feature-toggle/tests/deep-diff.test.ts
Normal file
61
src/lib/features/feature-toggle/tests/deep-diff.test.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import { deepDiff } from '../deep-diff'; // Import the deepDiff function
|
||||||
|
|
||||||
|
describe('deepDiff', () => {
|
||||||
|
it('should return null for equal arrays', () => {
|
||||||
|
const arr1 = [1, 2, 3];
|
||||||
|
const arr2 = [1, 2, 3];
|
||||||
|
expect(deepDiff(arr1, arr2)).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find differences in arrays with different lengths', () => {
|
||||||
|
const arr1 = [1, 2, 3];
|
||||||
|
const arr2 = [1, 2, 3, 4];
|
||||||
|
expect(deepDiff(arr1, arr2)).toEqual([
|
||||||
|
{
|
||||||
|
index: [],
|
||||||
|
reason: 'Different lengths',
|
||||||
|
valueA: arr1,
|
||||||
|
valueB: arr2,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find differences in arrays with different values', () => {
|
||||||
|
const arr1 = [1, 2, 3];
|
||||||
|
const arr2 = [1, 4, 3];
|
||||||
|
expect(deepDiff(arr1, arr2)).toEqual([
|
||||||
|
{
|
||||||
|
index: [1],
|
||||||
|
reason: 'Different values',
|
||||||
|
valueA: 2,
|
||||||
|
valueB: 4,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find differences in arrays with different keys in objects', () => {
|
||||||
|
const arr1 = [{ a: 1 }, { b: 2 }];
|
||||||
|
const arr2 = [{ a: 1 }, { c: 2 }];
|
||||||
|
expect(deepDiff(arr1, arr2)).toEqual([
|
||||||
|
{
|
||||||
|
index: [1],
|
||||||
|
reason: 'Different keys',
|
||||||
|
valueA: { b: 2 },
|
||||||
|
valueB: { c: 2 },
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle nested differences in objects', () => {
|
||||||
|
const arr1 = [{ a: { b: 1 } }, { c: { d: 2 } }];
|
||||||
|
const arr2 = [{ a: { b: 1 } }, { c: { d: 3 } }];
|
||||||
|
expect(deepDiff(arr1, arr2)).toEqual([
|
||||||
|
{
|
||||||
|
index: [1, 'c', 'd'],
|
||||||
|
reason: 'Different values',
|
||||||
|
valueA: 2,
|
||||||
|
valueB: 3,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user