Add `getAllNodes` and `getAllEdges` functions (#53)

Summary:
Without these functions, it is not possible to meaningfully operate on
an arbitrary graph.

Paired with @dandelionmane.

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

wchargin-branch: get-all
This commit is contained in:
William Chargin 2018-03-02 11:33:45 -08:00 committed by GitHub
parent 01510ca63f
commit cae3a92dc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 12 deletions

View File

@ -99,6 +99,20 @@ export class Graph {
}
return addresses.map((e) => this.getEdge(e));
}
/**
* Gets all nodes in the graph, in unspecified order.
*/
getAllNodes(): Node<mixed>[] {
return Object.keys(this._nodes).map((k) => this._nodes[k]);
}
/**
* Gets all edges in the graph, in unspecified order.
*/
getAllEdges(): Edge<mixed>[] {
return Object.keys(this._edges).map((k) => this._edges[k]);
}
}
export function addressToString(address: Address) {

View File

@ -5,6 +5,22 @@ import {Graph, addressToString, stringToAddress} from "./graph";
describe("graph", () => {
describe("#Graph", () => {
// Some Graph functions return a set of results represented as an
// array with undefined order. We use these functions to
// canonicalize the ordering so that we can then test equality with
// `expect(...).toEqual(...)`.
function sortedByAddress<T: {address: Address}>(xs: T[]) {
function cmp(x1: T, x2: T) {
const a1 = addressToString(x1.address);
const a2 = addressToString(x2.address);
return a1 > a2 ? 1 : a1 < a2 ? -1 : 0;
}
return [...xs].sort(cmp);
}
function expectSameSorted<T: {address: Address}>(xs: T[], ys: T[]) {
expect(sortedByAddress(xs)).toEqual(sortedByAddress(ys));
}
// A Seafood Fruit Mix is made by cooking Mighty Bananas (picked
// from a tree) and a Razorclaw Crab (grabbed from the beach). In
// this graph, an edge from `u` to `v` means that `u` thanks `v` for
@ -206,6 +222,25 @@ describe("graph", () => {
});
});
it("gets all nodes", () => {
const expected = [heroNode(), bananasNode(), crabNode(), mealNode()];
const actual = mealGraph().getAllNodes();
expectSameSorted(expected, actual);
});
it("gets all edges", () => {
const expected = [
pickEdge(),
grabEdge(),
cookEdge(),
bananasIngredientEdge(),
crabIngredientEdge(),
eatEdge(),
];
const actual = mealGraph().getAllEdges();
expectSameSorted(expected, actual);
});
// For the next two test cases: we're documenting this behavior,
// though we're not sure if it's the right behavior. Perhaps we want
// the namespaces to be forced to be disjoint. In that case, we can
@ -227,18 +262,6 @@ describe("graph", () => {
});
describe("in- and out-edges", () => {
function sortedByAddress<T: {address: Address}>(xs: T[]) {
function cmp(x1: T, x2: T) {
const a1 = addressToString(x1.address);
const a2 = addressToString(x2.address);
return a1 > a2 ? 1 : a1 < a2 ? -1 : 0;
}
return [...xs].sort(cmp);
}
function expectSameSorted<T: {address: Address}>(xs: T[], ys: T[]) {
expect(sortedByAddress(xs)).toEqual(sortedByAddress(ys));
}
it("gets out-edges", () => {
const nodeAndExpectedEdgePairs = [
[heroNode(), [eatEdge()]],