Cleanup test code

Replace multiple ad-hoc Node classes with single builder class

Test: yarn run test
Change-Id: Iebe76c59fbc3bcccdf89885f7d4cdbaa0d6a0576
This commit is contained in:
Kean Mariotti
2022-05-13 06:36:12 +00:00
parent 987d8af036
commit 111237a5a6
3 changed files with 270 additions and 231 deletions

View File

@@ -1,18 +1,19 @@
import { DiffGenerator, DiffType } from "../src/utils/diff.js";
import { NodeBuilder, Node, DiffNode, toPlainObject } from "./utils/tree.js";
import { NodeBuilder, toPlainObject } from "./utils/tree.js";
const treeOne = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, []),
new Node({ id: 4 }, []),
]);
const treeTwo = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, [
new Node({ id: 5 }, []),
]),
new Node({ id: 4 }, []),
]);
const treeOne = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).build(),
new NodeBuilder().setId(3).build(),
new NodeBuilder().setId(4).build(),
]).build();
const treeTwo = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).build(),
new NodeBuilder().setId(3).setChildren([
new NodeBuilder().setId(5).build(),
]).build(),
new NodeBuilder().setId(4).build(),
]).build();
function checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree) {
const diffTree = new DiffGenerator(newTree)
@@ -30,13 +31,13 @@ describe("DiffGenerator", () => {
const newTree = treeTwo;
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, []),
new DiffNode({ id: 3 }, DiffType.NONE, [
new DiffNode({ id: 5 }, DiffType.ADDED, []),
]),
new DiffNode({ id: 4 }, DiffType.NONE, []),
])
new NodeBuilder().setId(1).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(2).setDiffType(DiffType.NONE).build(),
new NodeBuilder().setId(3).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(5).setDiffType(DiffType.ADDED).build(),
]).build(),
new NodeBuilder().setId(4).setDiffType(DiffType.NONE).build(),
]).build()
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
@@ -47,13 +48,13 @@ describe("DiffGenerator", () => {
const newTree = treeOne;
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, []),
new DiffNode({ id: 3 }, DiffType.NONE, [
new DiffNode({ id: 5 }, DiffType.DELETED, []),
]),
new DiffNode({ id: 4 }, DiffType.NONE, []),
])
new NodeBuilder().setId(1).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(2).setDiffType(DiffType.NONE).build(),
new NodeBuilder().setId(3).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(5).setDiffType(DiffType.DELETED).build(),
]).build(),
new NodeBuilder().setId(4).setDiffType(DiffType.NONE).build(),
]).build()
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
@@ -62,45 +63,45 @@ describe("DiffGenerator", () => {
it("can generate a simple move diff", () => {
const oldTree = treeTwo;
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, []),
new Node({ id: 4 }, [
new Node({ id: 5 }, []),
]),
]);
const newTree = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).build(),
new NodeBuilder().setId(3).build(),
new NodeBuilder().setId(4).setChildren([
new NodeBuilder().setId(5).build(),
]).build(),
]).build();
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, []),
new DiffNode({ id: 3 }, DiffType.NONE, [
new DiffNode({ id: 5 }, DiffType.DELETED_MOVE, []),
]),
new DiffNode({ id: 4 }, DiffType.NONE, [
new DiffNode({ id: 5 }, DiffType.ADDED_MOVE, []),
]),
])
new NodeBuilder().setId(1).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(2).setDiffType(DiffType.NONE).build(),
new NodeBuilder().setId(3).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(5).setDiffType(DiffType.DELETED_MOVE).build(),
]).build(),
new NodeBuilder().setId(4).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(5).setDiffType(DiffType.ADDED_MOVE).build(),
]).build(),
]).build()
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("can generate a simple modified diff", () => {
const oldTree = new Node({ id: 1, data: "xyz" }, [
new Node({ id: 2, data: "abc" }, []),
new Node({ id: 3, data: "123" }, []),
]);
const oldTree = new NodeBuilder().setId(1).setData("xyz").setChildren([
new NodeBuilder().setId(2).setData("abc").build(),
new NodeBuilder().setId(3).setData("123").build(),
]).build();
const newTree = new Node({ id: 1, data: "xyz" }, [
new Node({ id: 2, data: "def" }, []),
new Node({ id: 3, data: "123" }, []),
]);
const newTree = new NodeBuilder().setId(1).setData("xyz").setChildren([
new NodeBuilder().setId(2).setData("def").build(),
new NodeBuilder().setId(3).setData("123").build(),
]).build();
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1, data: "xyz" }, DiffType.NONE, [
new DiffNode({ id: 2, data: "def" }, DiffType.MODIFIED, []),
new DiffNode({ id: 3, data: "123" }, DiffType.NONE, []),
])
new NodeBuilder().setId(1).setData("xyz").setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(2).setData("def").setDiffType(DiffType.MODIFIED).build(),
new NodeBuilder().setId(3).setData("123").setDiffType(DiffType.NONE).build(),
]).build()
);
const diffTree = new DiffGenerator(newTree)
@@ -114,132 +115,132 @@ describe("DiffGenerator", () => {
});
it("can handle move and inner addition diff", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, [
new Node({ id: 4 }, []),
]),
]);
const oldTree = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).build(),
new NodeBuilder().setId(3).setChildren([
new NodeBuilder().setId(4).build(),
]).build(),
]).build();
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, [
new Node({ id: 4 }, [
new Node({ id: 5 }, []),
]),
]),
new Node({ id: 3 }, []),
]);
const newTree = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).setChildren([
new NodeBuilder().setId(4).setChildren([
new NodeBuilder().setId(5).build(),
]).build(),
]).build(),
new NodeBuilder().setId(3).build(),
]).build();
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, [
new DiffNode({ id: 4 }, DiffType.ADDED_MOVE, [
new DiffNode({ id: 5 }, DiffType.ADDED, []),
]),
]),
new DiffNode({ id: 3 }, DiffType.NONE, [
new DiffNode({ id: 4 }, DiffType.DELETED_MOVE, []),
]),
])
new NodeBuilder().setId(1).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(2).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(4).setDiffType(DiffType.ADDED_MOVE).setChildren([
new NodeBuilder().setId(5).setDiffType(DiffType.ADDED).build(),
]).build(),
]).build(),
new NodeBuilder().setId(3).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(4).setDiffType(DiffType.DELETED_MOVE).build(),
]).build(),
]).build()
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("can handle move within same level", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, []),
]);
const oldTree = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).build(),
new NodeBuilder().setId(3).build(),
]).build();
const newTree = new Node({ id: 1 }, [
new Node({ id: 3 }, []),
new Node({ id: 2 }, []),
]);
const newTree = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(3).build(),
new NodeBuilder().setId(2).build(),
]).build();
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 3 }, DiffType.NONE, []),
new DiffNode({ id: 2 }, DiffType.NONE, []),
])
new NodeBuilder().setId(1).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(3).setDiffType(DiffType.NONE).build(),
new NodeBuilder().setId(2).setDiffType(DiffType.NONE).build(),
]).build()
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("can handle addition within middle of level", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, []),
]);
const oldTree = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).build(),
new NodeBuilder().setId(3).build(),
]).build();
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 4 }, []),
new Node({ id: 3 }, []),
]);
const newTree = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).build(),
new NodeBuilder().setId(4).build(),
new NodeBuilder().setId(3).build(),
]).build();
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, []),
new DiffNode({ id: 4 }, DiffType.ADDED, []),
new DiffNode({ id: 3 }, DiffType.NONE, []),
])
new NodeBuilder().setId(1).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(2).setDiffType(DiffType.NONE).build(),
new NodeBuilder().setId(4).setDiffType(DiffType.ADDED).build(),
new NodeBuilder().setId(3).setDiffType(DiffType.NONE).build(),
]).build()
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("can handle deletion within middle of level", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, []),
new Node({ id: 4 }, []),
]);
const oldTree = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).build(),
new NodeBuilder().setId(3).build(),
new NodeBuilder().setId(4).build(),
]).build();
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 4 }, []),
]);
const newTree = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).build(),
new NodeBuilder().setId(4).build(),
]).build();
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, []),
new DiffNode({ id: 3 }, DiffType.DELETED, []),
new DiffNode({ id: 4 }, DiffType.NONE, []),
])
new NodeBuilder().setId(1).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(2).setDiffType(DiffType.NONE).build(),
new NodeBuilder().setId(3).setDiffType(DiffType.DELETED).build(),
new NodeBuilder().setId(4).setDiffType(DiffType.NONE).build(),
]).build()
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("fully visits deletes nodes", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, [
new Node({ id: 3 }, [
new Node({ id: 4 }, []),
]),
]),
]);
const oldTree = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).setChildren([
new NodeBuilder().setId(3).setChildren([
new NodeBuilder().setId(4).build(),
]).build(),
]).build(),
]).build();
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, [
new Node({ id: 4 }, []),
]),
]);
const newTree = new NodeBuilder().setId(1).setChildren([
new NodeBuilder().setId(2).build(),
new NodeBuilder().setId(3).setChildren([
new NodeBuilder().setId(4).build(),
]).build(),
]).build();
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, [
new DiffNode({ id: 3 }, DiffType.DELETED_MOVE, [
new DiffNode({ id: 4 }, DiffType.DELETED_MOVE, []),
]),
]),
new DiffNode({ id: 3 }, DiffType.ADDED_MOVE, [
new DiffNode({ id: 4 }, DiffType.NONE, []),
]),
])
new NodeBuilder().setId(1).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(2).setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setId(3).setDiffType(DiffType.DELETED_MOVE).setChildren([
new NodeBuilder().setId(4).setDiffType(DiffType.DELETED_MOVE).build(),
]).build(),
]).build(),
new NodeBuilder().setId(3).setDiffType(DiffType.ADDED_MOVE).setChildren([
new NodeBuilder().setId(4).setDiffType(DiffType.NONE).build(),
]).build(),
]).build()
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);

View File

@@ -1,6 +1,6 @@
import { DiffType } from "../src/utils/diff.js";
import { ObjectTransformer } from "../src/transform.js";
import { ObjNode, ObjDiffNode, toPlainObject } from "./utils/tree.js";
import { NodeBuilder, toPlainObject } from "./utils/tree.js";
describe("ObjectTransformer", () => {
it("can transform a simple object", () => {
@@ -18,18 +18,26 @@ describe("ObjectTransformer", () => {
};
const expectedTransformedObj = toPlainObject(
new ObjNode('root', [
new ObjNode('obj', [
new ObjNode('string: string', [], true, 'root.obj.string'),
new ObjNode('number: 3', [], true, 'root.obj.number'),
], undefined, 'root.obj'),
new ObjNode('array', [
new ObjNode('0', [
new ObjNode('nested: item', [], true, 'root.array.0.nested'),
], undefined, 'root.array.0'),
new ObjNode("1: two", [], true, 'root.array.1'),
], undefined, 'root.array'),
], undefined, 'root')
new NodeBuilder().setTransformed().setName('root')
.setStableId('root').setChildren([
new NodeBuilder().setTransformed().setName('obj')
.setStableId('root.obj').setChildren([
new NodeBuilder().setTransformed().setName('string: string')
.setStableId('root.obj.string').setCombined().build(),
new NodeBuilder().setTransformed().setName('number: 3')
.setStableId('root.obj.number').setCombined().build(),
]).build(),
new NodeBuilder().setTransformed().setName('array')
.setStableId('root.array').setChildren([
new NodeBuilder().setTransformed().setName('0')
.setStableId('root.array.0').setChildren([
new NodeBuilder().setTransformed().setName('nested: item')
.setStableId('root.array.0.nested').setCombined().build(),
]).build(),
new NodeBuilder().setTransformed().setName("1: two")
.setStableId('root.array.1').setCombined().build(),
]).build()
]).build()
);
const transformedObj = new ObjectTransformer(obj, 'root', 'root')
@@ -47,11 +55,14 @@ describe("ObjectTransformer", () => {
}
const expectedTransformedObj = toPlainObject(
new ObjNode('root', [
new ObjNode('obj', [
new ObjNode('null: null', [], true, 'root.obj.null'),
], undefined, 'root.obj'),
], undefined, 'root')
new NodeBuilder().setTransformed().setName('root')
.setStableId('root').setChildren([
new NodeBuilder().setTransformed().setName('obj')
.setStableId('root.obj').setChildren([
new NodeBuilder().setTransformed().setName('null: null')
.setStableId('root.obj.null').setCombined().build(),
]).build(),
]).build()
);
const transformedObj = new ObjectTransformer(obj, 'root', 'root')
@@ -78,13 +89,17 @@ describe("ObjectTransformer", () => {
};
const expectedTransformedObj = toPlainObject(
new ObjDiffNode('root', DiffType.NONE, [
new ObjDiffNode('a', DiffType.NONE, [
new ObjDiffNode('b: 1', DiffType.NONE, [], true, 'root.a.b'),
new ObjDiffNode('d: 3', DiffType.ADDED, [], true, 'root.a.d'),
], false, 'root.a'),
new ObjDiffNode('c: 2', DiffType.NONE, [], true, 'root.c'),
], false, 'root')
new NodeBuilder().setTransformed().setName('root')
.setStableId('root').setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setTransformed().setName('a')
.setStableId('root.a').setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setTransformed().setName('b: 1')
.setStableId('root.a.b').setDiffType(DiffType.NONE).setCombined().build(),
new NodeBuilder().setTransformed().setName('d: 3')
.setStableId('root.a.d').setDiffType(DiffType.ADDED).setCombined().build(),
]).build(),
new NodeBuilder().setTransformed().setName('c: 2').setStableId('root.c').setDiffType(DiffType.NONE).setCombined().build(),
]).build()
);
const transformedObj = new ObjectTransformer(newObj, 'root', 'root')
@@ -105,12 +120,16 @@ describe("ObjectTransformer", () => {
};
const expectedTransformedObj = toPlainObject(
new ObjDiffNode('root', DiffType.NONE, [
new ObjDiffNode('a', DiffType.NONE, [
new ObjDiffNode('1', DiffType.ADDED, [], false, 'root.a.1'),
new ObjDiffNode('null', DiffType.DELETED, [], false, 'root.a.null'),
], false, 'root.a'),
], false, 'root')
new NodeBuilder().setTransformed().setName('root')
.setStableId('root').setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setTransformed().setName('a')
.setStableId('root.a').setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setTransformed().setName('1')
.setStableId('root.a.1').setDiffType(DiffType.ADDED).build(),
new NodeBuilder().setTransformed().setName('null')
.setStableId('root.a.null').setDiffType(DiffType.DELETED).build(),
]).build(),
]).build()
);
const transformedObj = new ObjectTransformer(newObj, 'root', 'root')
@@ -137,15 +156,21 @@ describe("ObjectTransformer", () => {
};
const expectedTransformedObj = toPlainObject(
new ObjDiffNode('root', DiffType.NONE, [
new ObjDiffNode('a', DiffType.NONE, [
new ObjDiffNode('b', DiffType.NONE, [
new ObjDiffNode('1', DiffType.ADDED, [], false, 'root.a.b.1'),
new ObjDiffNode('null', DiffType.DELETED, [], false, 'root.a.b.null'),
], false, 'root.a.b'),
], false, 'root.a'),
new ObjDiffNode('c: 2', DiffType.NONE, [], true, 'root.c'),
], false, 'root')
new NodeBuilder().setTransformed().setName('root')
.setStableId('root').setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setTransformed().setName('a')
.setStableId('root.a').setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setTransformed().setName('b')
.setStableId('root.a.b').setDiffType(DiffType.NONE).setChildren([
new NodeBuilder().setTransformed().setName('1')
.setStableId('root.a.b.1').setDiffType(DiffType.ADDED).build(),
new NodeBuilder().setTransformed().setName('null')
.setStableId('root.a.b.null').setDiffType(DiffType.DELETED).build(),
]).build(),
]).build(),
new NodeBuilder().setTransformed().setName('c: 2')
.setStableId('root.c').setDiffType(DiffType.NONE).setCombined().build(),
]).build()
);
const transformedObj = new ObjectTransformer(newObj, 'root', 'root')

View File

@@ -1,12 +1,32 @@
class NodeBuilder {
setId(id) {
this.id = id;
this.chips = [];
constructor() {
this.isTransformed = false;
}
setTransformed() {
this.isTransformed = true;
return this;
}
setChildren(children) {
this.children = children;
setId(id) {
this.id = id;
this.chips = [];
this.combined = false;
return this;
}
setStableId(stableId) {
this.stableId = stableId;
return this;
}
setName(name) {
this.name = name;
return this;
}
setData(data) {
this.data = data;
return this;
}
@@ -15,76 +35,69 @@ class NodeBuilder {
return this;
}
setCombined() {
this.combined = true;
return this;
}
setDiffType(diffType) {
this.diffType = diffType;
return this;
}
setChildren(children) {
this.children = children;
return this;
}
build() {
var node = {
name: undefined,
shortName: undefined,
stableId: undefined,
kind: undefined,
shortName: undefined
};
if (this.isTransformed)
{
delete node.shortName;
node.kind = ''
}
if ('id' in this) {
node.id = this.id;
}
node.children = 'children' in this ? this.children : [];
if ('stableId' in this) {
node.stableId = this.stableId;
}
if ('name' in this) {
node.name = this.name;
}
if ('data' in this) {
node.data = this.data;
}
if ('chips' in this) {
node.chips = this.chips;
}
if ('diffType' in this) {
node.diff = { type: this.diffType }
if (this.combined) {
node.combined = true;
}
if ('diffType' in this) {
node.diff = { type: this.diffType };
}
node.children = 'children' in this ? this.children : [];
return node;
}
}
class Node {
constructor(nodeDef, children) {
Object.assign(this, nodeDef);
this.children = children;
}
}
class DiffNode extends Node {
constructor(nodeDef, diffType, children) {
super(nodeDef, children);
this.diff = { type: diffType };
this.name = undefined;
this.stableId = undefined;
this.kind = undefined;
this.shortName = undefined;
}
}
class ObjNode extends Node {
constructor(name, children, combined, stableId) {
const nodeDef = {
kind: '',
name: name,
stableId: stableId,
};
if (combined) {
nodeDef.combined = true;
}
super(nodeDef, children);
}
}
class ObjDiffNode extends ObjNode {
constructor(name, diffType, children, combined, stableId) {
super(name, children, combined, stableId);
this.diff = { type: diffType };
}
}
function isPrimitive(test) {
return test !== Object(test);
};
@@ -103,4 +116,4 @@ function toPlainObject(theClass) {
}
}
export { NodeBuilder, Node, DiffNode, ObjNode, ObjDiffNode, toPlainObject };
export { NodeBuilder, toPlainObject };