Add an equality function for `Graph` (#61)

Summary:
We need this for testing graph equality: deep-equality is not sufficient
because two graphs can be logically equal even if, say, two nodes are
added in different orders.

This commit adds a dependency on `lodash.isequal` for deep equality.

Test Plan:
New unit tests added. Run `yarn flow && yarn test`.

wchargin-branch: graph-equals
This commit is contained in:
William Chargin 2018-03-02 21:13:30 -08:00 committed by GitHub
parent 5a2380d486
commit 82dbf64a2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 0 deletions

View File

@ -31,6 +31,7 @@
"husky": "^0.14.3",
"jest": "20.0.4",
"lint-staged": "^6.1.1",
"lodash.isequal": "^4.5.0",
"object-assign": "4.1.1",
"postcss-flexbugs-fixes": "3.2.0",
"postcss-loader": "2.0.8",

View File

@ -1,5 +1,7 @@
// @flow
import deepEqual from "lodash.isequal";
export type Address = {|
+repositoryName: string,
+pluginName: string,
@ -37,6 +39,12 @@ export class Graph {
this._inEdges = {};
}
equals(that: Graph): boolean {
return (
deepEqual(this._nodes, that._nodes) && deepEqual(this._edges, that._edges)
);
}
addNode(node: Node<mixed>) {
if (node == null) {
throw new Error(`node is ${String(node)}`);

View File

@ -388,6 +388,46 @@ describe("graph", () => {
}).toThrow(/no node for address/);
});
});
describe("#equals", () => {
it("returns true for identity-equal graphs", () => {
const g = advancedMealGraph();
expect(g.equals(g)).toBe(true);
});
it("returns true for deep-equal graphs", () => {
expect(advancedMealGraph().equals(advancedMealGraph())).toBe(true);
});
it("returns false when the LHS has nodes missing in the RHS", () => {
expect(advancedMealGraph().equals(simpleMealGraph())).toBe(false);
});
it("returns false when the RHS has nodes missing in the LHS", () => {
expect(simpleMealGraph().equals(advancedMealGraph())).toBe(false);
});
const extraNode1 = () => ({
address: makeAddress("octorok"),
payload: {},
});
const extraNode2 = () => ({
address: makeAddress("hinox"),
payload: {status: "sleeping"},
});
it("returns false when the LHS has edges missing in the RHS", () => {
const g1 = advancedMealGraph();
const g2 = advancedMealGraph().addNode(extraNode1());
expect(g1.equals(g2)).toBe(false);
});
it("returns false when the LHS has edges missing in the RHS", () => {
const g1 = advancedMealGraph().addNode(extraNode1());
const g2 = advancedMealGraph();
expect(g1.equals(g2)).toBe(false);
});
it("returns true when nodes are added in different orders", () => {
const g1 = new Graph().addNode(extraNode1()).addNode(extraNode2());
const g2 = new Graph().addNode(extraNode2()).addNode(extraNode1());
expect(g1.equals(g2)).toBe(true);
expect(g2.equals(g1)).toBe(true);
});
});
});
describe("string functions", () => {

View File

@ -4163,6 +4163,10 @@ lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"