Skip to content

Commit

Permalink
fix: log diff (#5072)
Browse files Browse the repository at this point in the history
Add a deep diff function to investigate diff in logs
  • Loading branch information
FredrikOseberg authored Oct 18, 2023
1 parent 75b1311 commit 3ac8ab8
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 5 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
66 changes: 66 additions & 0 deletions src/lib/features/feature-toggle/deep-diff.ts
Original file line number Diff line number Diff line change
@@ -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;
}
19 changes: 15 additions & 4 deletions src/lib/features/feature-toggle/feature-toggle-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down
61 changes: 61 additions & 0 deletions src/lib/features/feature-toggle/tests/deep-diff.test.ts
Original file line number Diff line number Diff line change
@@ -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,
},
]);
});
});

0 comments on commit 3ac8ab8

Please sign in to comment.