diff --git a/src/v3/core/_address.js b/src/v3/core/_address.js index bae7c8c..09778e4 100644 --- a/src/v3/core/_address.js +++ b/src/v3/core/_address.js @@ -130,3 +130,15 @@ export function edgeAppend( assertAddressArray(components); return base + nullDelimited(components); } + +export function nodeToString(a: NodeAddress): string { + assertNodeAddress(a); + const parts = toParts(a); + return `nodeAddress(${stringify(parts)})`; +} + +export function edgeToString(a: EdgeAddress): string { + assertEdgeAddress(a); + const parts = toParts(a); + return `edgeAddress(${stringify(parts)})`; +} diff --git a/src/v3/core/_address.test.js b/src/v3/core/_address.test.js index 94bf477..a205dda 100644 --- a/src/v3/core/_address.test.js +++ b/src/v3/core/_address.test.js @@ -6,8 +6,10 @@ import { assertEdgeAddress, edgeAddress, edgeAppend, + edgeToString, nodeAddress, nodeAppend, + nodeToString, toParts, } from "./_address"; @@ -144,6 +146,42 @@ describe("core/address", () => { checkAppend(nodeAppend, nodeAddress, edgeAddress); checkAppend(edgeAppend, edgeAddress, nodeAddress); + function checkToString< + Good: NodeAddress | EdgeAddress, + Bad: NodeAddress | EdgeAddress + >( + f: (Good) => string, + kind: "NodeAddress" | "EdgeAddress", + goodConstructor: (string[]) => Good, + badConstructor: (string[]) => Bad + ) { + describe(f.name, () => { + describe("errors on", () => { + [null, undefined].forEach((bad) => { + it(`${String(bad)} base input`, () => { + // $ExpectFlowError + expect(() => f(bad)).toThrow(String(bad)); + }); + }); + it("wrong kind", () => { + // $ExpectFlowError + expect(() => f(badConstructor(["foo"]))).toThrow(`expected ${kind}`); + }); + }); + + describe("works on", () => { + const camelKind = kind.charAt(0).toLowerCase() + kind.substring(1); + expect(f(goodConstructor([]))).toEqual(`${camelKind}([])`); + expect(f(goodConstructor([""]))).toEqual(`${camelKind}([""])`); + expect(f(goodConstructor(["one", "", "two"]))).toEqual( + `${camelKind}(["one","","two"])` + ); + }); + }); + } + checkToString(nodeToString, "NodeAddress", nodeAddress, edgeAddress); + checkToString(edgeToString, "EdgeAddress", edgeAddress, nodeAddress); + describe("type assertions", () => { function checkAssertion(f, good, bad, badMsg) { describe(f.name, () => { diff --git a/src/v3/core/graph.js b/src/v3/core/graph.js index 0b9489d..6a0ef20 100644 --- a/src/v3/core/graph.js +++ b/src/v3/core/graph.js @@ -110,3 +110,10 @@ export class Graph { throw new Error("merge"); } } + +export function edgeToString(edge: Edge): string { + const address = Address.edgeToString(edge.address); + const src = Address.nodeToString(edge.src); + const dst = Address.nodeToString(edge.dst); + return `{address: ${address}, src: ${src}, dst: ${dst}}`; +} diff --git a/src/v3/core/graph.test.js b/src/v3/core/graph.test.js index e88e879..09a61da 100644 --- a/src/v3/core/graph.test.js +++ b/src/v3/core/graph.test.js @@ -1,6 +1,6 @@ // @flow -import {Address, Graph} from "./graph"; +import {Address, Graph, edgeToString} from "./graph"; import type {NodeAddress, EdgeAddress} from "./graph"; describe("core/graph", () => { @@ -105,4 +105,21 @@ describe("core/graph", () => { }); }); }); + + describe("edgeToString", () => { + it("works", () => { + const edge = { + address: Address.edgeAddress(["one", "two"]), + dst: Address.nodeAddress(["five", "six"]), + src: Address.nodeAddress(["three", "four"]), + }; + const expected = + "{" + + 'address: edgeAddress(["one","two"]), ' + + 'src: nodeAddress(["three","four"]), ' + + 'dst: nodeAddress(["five","six"])' + + "}"; + expect(edgeToString(edge)).toEqual(expected); + }); + }); });