mirror of
https://github.com/status-im/sourcecred.git
synced 2025-02-05 09:14:50 +00:00
Add Graph.getAdjacentEdges
for in and out edges (#157)
Some consumers of the graph may prefer to treat it as an undirected graph. For example, when finding the author of an issue, it is wholly sufficient to find an edge with the `AUTHORS` type; the caller may prefer not to be bothered with remembering which end of the `AUTHORS` end is considered the `src` and which is the `dst`. The `getAdjacentEdges` call enables that, by combining the output of `getInEdges` and `getOutEdges`. Test plan: The new tests are pretty comprehensive.
This commit is contained in:
parent
aa071ceab3
commit
8e9ddbf9fc
@ -220,6 +220,18 @@ export class Graph<NP, EP> {
|
||||
return result;
|
||||
}
|
||||
|
||||
getAdjacentEdges(
|
||||
nodeAddress: Address,
|
||||
typeOptions?: {+nodeType?: string, +edgeType?: string}
|
||||
): Edge<EP>[] {
|
||||
const inEdges = this.getInEdges(nodeAddress, typeOptions);
|
||||
// If there are self-reference edges, avoid double counting them.
|
||||
const outEdges = this.getOutEdges(nodeAddress, typeOptions).filter(
|
||||
(e) => !deepEqual(e.src, e.dst)
|
||||
);
|
||||
return [].concat(inEdges, outEdges);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all nodes in the graph, in unspecified order.
|
||||
*/
|
||||
|
@ -1,5 +1,7 @@
|
||||
// @flow
|
||||
|
||||
import deepEqual from "lodash.isequal";
|
||||
|
||||
import type {Address, Addressable} from "./address";
|
||||
import {sortedByAddress} from "./address";
|
||||
import type {Node, Edge} from "./graph";
|
||||
@ -247,6 +249,11 @@ describe("graph", () => {
|
||||
expect(g.getInEdges(demoData.crabNode().address)).toContainEqual(
|
||||
demoData.crabLoopEdge()
|
||||
);
|
||||
const crabAdjacencies = g.getAdjacentEdges(demoData.crabNode().address);
|
||||
const crabLoops = crabAdjacencies.filter((e) =>
|
||||
deepEqual(e, demoData.crabLoopEdge())
|
||||
);
|
||||
expect(crabLoops).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("allows creating multiple edges between the same nodes", () => {
|
||||
@ -405,6 +412,88 @@ describe("graph", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("adjacentEdges", () => {
|
||||
const eg = new ExampleGraph();
|
||||
const getEdges = (opts) => eg.graph.getAdjacentEdges(eg.root, opts);
|
||||
const allEdges = [
|
||||
eg.inEdges.a1,
|
||||
eg.inEdges.a2,
|
||||
eg.inEdges.b1,
|
||||
eg.inEdges.b2,
|
||||
eg.outEdges.a1,
|
||||
eg.outEdges.a2,
|
||||
eg.outEdges.b1,
|
||||
eg.outEdges.b2,
|
||||
];
|
||||
it("typefiltering is optional", () => {
|
||||
expectSameSorted(getEdges(), allEdges);
|
||||
expectSameSorted(getEdges({}), allEdges);
|
||||
});
|
||||
it("filters on node types", () => {
|
||||
expectSameSorted(getEdges({nodeType: "A"}), [
|
||||
eg.outEdges.a1,
|
||||
eg.outEdges.a2,
|
||||
eg.inEdges.a1,
|
||||
eg.inEdges.a2,
|
||||
]);
|
||||
});
|
||||
it("filters on edge types", () => {
|
||||
expectSameSorted(getEdges({edgeType: "1"}), [
|
||||
eg.outEdges.a1,
|
||||
eg.outEdges.b1,
|
||||
eg.inEdges.a1,
|
||||
eg.inEdges.b1,
|
||||
]);
|
||||
});
|
||||
it("filters on node and edge types", () => {
|
||||
expectSameSorted(getEdges({nodeType: "A", edgeType: "1"}), [
|
||||
eg.outEdges.a1,
|
||||
eg.inEdges.a1,
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
it("gets adjacent-edges", () => {
|
||||
const nodeAndExpectedEdgePairs = [
|
||||
[
|
||||
demoData.heroNode(),
|
||||
[
|
||||
demoData.eatEdge(),
|
||||
demoData.pickEdge(),
|
||||
demoData.grabEdge(),
|
||||
demoData.cookEdge(),
|
||||
demoData.duplicateCookEdge(),
|
||||
],
|
||||
],
|
||||
[
|
||||
demoData.bananasNode(),
|
||||
[demoData.pickEdge(), demoData.bananasIngredientEdge()],
|
||||
],
|
||||
[
|
||||
demoData.crabNode(),
|
||||
[
|
||||
demoData.crabIngredientEdge(),
|
||||
demoData.grabEdge(),
|
||||
demoData.crabLoopEdge(),
|
||||
],
|
||||
],
|
||||
[
|
||||
demoData.mealNode(),
|
||||
[
|
||||
demoData.bananasIngredientEdge(),
|
||||
demoData.crabIngredientEdge(),
|
||||
demoData.cookEdge(),
|
||||
demoData.eatEdge(),
|
||||
demoData.duplicateCookEdge(),
|
||||
],
|
||||
],
|
||||
];
|
||||
nodeAndExpectedEdgePairs.forEach(([node, expectedEdges]) => {
|
||||
const actual = demoData
|
||||
.advancedMealGraph()
|
||||
.getAdjacentEdges(node.address);
|
||||
expectSameSorted(actual, expectedEdges);
|
||||
});
|
||||
});
|
||||
it("gets out-edges", () => {
|
||||
const nodeAndExpectedEdgePairs = [
|
||||
|
Loading…
x
Reference in New Issue
Block a user