Skip to content

Commit 85ee82e

Browse files
authored
chore: add the categorizeChanges function (#24)
* fix previous types * refactor types * add categorizer function * fix code smell * change type name * fix conflicts * change types name
1 parent 5609741 commit 85ee82e

File tree

6 files changed

+111
-26
lines changed

6 files changed

+111
-26
lines changed

src/categorizeChanges.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import classifier from './classifier';
2+
import { Output, DiffOutput, DiffOutputItem } from './types';
3+
4+
/**
5+
* Categorize the changes
6+
* @param standard The standard object
7+
* @param diffs The array of diff changes
8+
* @returns The final output containing the diff changes as well as the type of change
9+
*/
10+
export default function categorizeChanges(
11+
standard: any,
12+
diffs: DiffOutput[]
13+
): Output {
14+
// the final output
15+
const output: Output = {
16+
changes: [],
17+
};
18+
19+
for (const diff of diffs) {
20+
const newDiffObject = { ...diff } as DiffOutputItem;
21+
const classifierObject = classifier(standard, diff.path);
22+
newDiffObject.type = classifierObject[diff.action] || 'unclassified';
23+
output.changes.push(newDiffObject);
24+
}
25+
26+
return output;
27+
}

src/classifier.ts

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,7 @@
33
// Also, since we are just using this object to access properties, its safe to disable security check for now.
44

55
import { generateClassifierPath } from './helpers/ClassifierHelpers';
6-
7-
const breaking = 'breaking';
8-
const nonBreaking = 'non-breaking';
9-
const unclassified = 'unclassified';
10-
11-
type ChangeTypes = typeof breaking | typeof nonBreaking | typeof unclassified;
12-
13-
interface Classifier {
14-
add: ChangeTypes;
15-
remove: ChangeTypes;
16-
edit: ChangeTypes;
17-
}
6+
import { Classifier } from './types';
187

198
/**
209
* Gets the classifier object from the standard object using the provided path
@@ -26,9 +15,9 @@ export default function classifier(standard: any, path: string): Classifier {
2615
const classifierPath = generateClassifierPath(standard, path);
2716
if (!classifierPath) {
2817
return {
29-
add: unclassified,
30-
remove: unclassified,
31-
edit: unclassified,
18+
add: 'unclassified',
19+
remove: 'unclassified',
20+
edit: 'unclassified',
3221
};
3322
}
3423
return standard[classifierPath];

src/helpers/DiffHelpers.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import { Operation, getValueByPointer } from 'fast-json-patch';
22

3-
import { DiffOutput, ValueOperation } from '../types';
3+
import { DiffOutput, ValueOperation, ActionType } from '../types';
44

55
/**
66
* Formats the action to have one of `add`, `remove` or `edit` values
77
* @param {String} action The action performed by the diff library
88
* @returns {String} The formatted action output
99
*/
10-
export function formatAction(action: string): string {
10+
export function formatAction(action: string): ActionType {
1111
if (action === 'replace') {
1212
return 'edit';
1313
}
1414
// since `add` and `remove` are already provided by the library, we don't need to change that.
15-
return action;
15+
return action as ActionType;
1616
}
1717

1818
/**

src/types.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,33 @@
11
import { ReplaceOperation, AddOperation } from 'fast-json-patch';
22

3-
type ChangeType = 'breaking' | 'non-breaking' | 'unclassified';
3+
export type ActionType = 'add' | 'remove' | 'edit';
4+
5+
export type ChangeType = 'breaking' | 'non-breaking' | 'unclassified';
6+
7+
export interface Classifier {
8+
add: ChangeType;
9+
remove: ChangeType;
10+
edit: ChangeType;
11+
}
12+
13+
export interface OverrideObject {
14+
[key: string]: Classifier;
15+
}
416

517
export interface DiffOutput {
6-
action: string;
18+
action: ActionType;
719
path: string;
820
isArrayIndex?: boolean;
921
before?: any;
1022
after?: any;
1123
}
1224

13-
export type OverrideObject = {
14-
[key: string]: {
15-
add: ChangeType;
16-
remove: ChangeType;
17-
edit: ChangeType;
18-
};
25+
export type DiffOutputItem = DiffOutput & {
26+
type: ChangeType;
1927
};
2028

29+
export interface Output {
30+
changes: DiffOutputItem[];
31+
}
32+
2133
export type ValueOperation = ReplaceOperation<any> | AddOperation<any>;

test/categorizeChanges.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import categorizeChanges from '../src/categorizeChanges';
2+
import { DiffOutput } from '../src/types';
3+
4+
import {
5+
standard,
6+
inputDiffOutput,
7+
finalDiffOutput,
8+
finalDiffOutputAsUnclassified,
9+
} from './fixtures/categorizeChanges.fixtures';
10+
11+
describe('categorizeChanges', () => {
12+
test('checks the final output', () => {
13+
expect(
14+
categorizeChanges(standard, inputDiffOutput as DiffOutput[])
15+
).toStrictEqual(finalDiffOutput);
16+
});
17+
18+
test('returns unclassified when passed with empty standard', () => {
19+
expect(
20+
categorizeChanges({}, inputDiffOutput as DiffOutput[])
21+
).toStrictEqual(finalDiffOutputAsUnclassified);
22+
});
23+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
export const standard = {
2+
'/servers': {
3+
add: 'non-breaking',
4+
remove: 'breaking',
5+
edit: 'breaking',
6+
},
7+
};
8+
9+
export const inputDiffOutput = [
10+
{
11+
action: 'remove',
12+
path: '/servers',
13+
},
14+
];
15+
16+
export const finalDiffOutput = {
17+
changes: [
18+
{
19+
action: 'remove',
20+
path: '/servers',
21+
type: 'breaking',
22+
},
23+
],
24+
};
25+
26+
export const finalDiffOutputAsUnclassified = {
27+
changes: [
28+
{
29+
action: 'remove',
30+
path: '/servers',
31+
type: 'unclassified',
32+
},
33+
],
34+
};

0 commit comments

Comments
 (0)