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": {
|
||||
"@apidevtools/swagger-parser": "10.1.0",
|
||||
"@babel/core": "7.23.0",
|
||||
"@swc/core": "1.3.92",
|
||||
"@biomejs/biome": "1.2.2",
|
||||
"@swc/core": "1.3.92",
|
||||
"@swc/jest": "0.2.29",
|
||||
"@types/bcryptjs": "2.4.4",
|
||||
"@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 { DependentFeaturesService } from '../dependent-features/dependent-features-service';
|
||||
import isEqual from 'lodash.isequal';
|
||||
import { deepDiff } from './deep-diff';
|
||||
|
||||
interface IFeatureContext {
|
||||
featureName: string;
|
||||
@ -1067,12 +1068,17 @@ class FeatureToggleService {
|
||||
);
|
||||
|
||||
if (!equal) {
|
||||
const difference = deepDiff(
|
||||
featuresFromClientStore,
|
||||
featuresFromFeatureToggleStore,
|
||||
);
|
||||
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
|
||||
: featuresFromClientStore;
|
||||
|
||||
@ -1113,12 +1119,17 @@ class FeatureToggleService {
|
||||
);
|
||||
|
||||
if (!equal) {
|
||||
const difference = deepDiff(
|
||||
featuresFromClientStore,
|
||||
featuresFromFeatureToggleStore,
|
||||
);
|
||||
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
|
||||
: 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