Add conversion functions for id (#38)
Test Plan: Run `yarn test` and note that tests pass. wchargin-branch: id-conversion
This commit is contained in:
parent
bc2377448f
commit
791cad9059
|
@ -24,3 +24,32 @@ export type Graph = {
|
|||
nodes: {[stringID: string]: GraphNode<mixed>},
|
||||
edges: {[stringID: string]: GraphEdge<mixed>},
|
||||
};
|
||||
|
||||
export function idToString(id: ID) {
|
||||
if (id.pluginName.includes("$")) {
|
||||
const escaped = JSON.stringify(id.pluginName);
|
||||
throw new Error(`id.pluginName must not include "\$": ${escaped}`);
|
||||
}
|
||||
if (id.repositoryName.includes("$")) {
|
||||
const escaped = JSON.stringify(id.repositoryName);
|
||||
throw new Error(`id.repositoryName must not include "\$": ${escaped}`);
|
||||
}
|
||||
if (id.name.includes("$")) {
|
||||
const escaped = JSON.stringify(id.name);
|
||||
throw new Error(`id.name must not include "\$": ${escaped}`);
|
||||
}
|
||||
return `${id.pluginName}\$${id.repositoryName}\$${id.name}`;
|
||||
}
|
||||
|
||||
export function stringToID(string: string) {
|
||||
const parts = string.split("$");
|
||||
if (parts.length !== 3) {
|
||||
const escaped = JSON.stringify(string);
|
||||
throw new Error(`Input should have exactly two \$s: ${escaped}`);
|
||||
}
|
||||
return {
|
||||
pluginName: parts[0],
|
||||
repositoryName: parts[1],
|
||||
name: parts[2],
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
import {idToString, stringToID} from "./graph";
|
||||
|
||||
describe("graph", () => {
|
||||
describe("idToString", () => {
|
||||
const makeSimpleID = () => ({
|
||||
pluginName: "widgets",
|
||||
repositoryName: "megacorp/megawidget",
|
||||
name: "issue#123",
|
||||
});
|
||||
it("stringifies a simple ID", () => {
|
||||
const input = makeSimpleID();
|
||||
const expected = "widgets$megacorp/megawidget$issue#123";
|
||||
expect(idToString(input)).toEqual(expected);
|
||||
});
|
||||
function expectRejection(attribute, value) {
|
||||
const input = {...makeSimpleID(), [attribute]: value};
|
||||
expect(() => idToString(input)).toThrow(RegExp(attribute));
|
||||
// (escaping regexp in JavaScript is a nightmare; ignore it)
|
||||
}
|
||||
it("rejects an ID with $-signs in plugin name", () => {
|
||||
expectRejection("pluginName", "widg$ets");
|
||||
});
|
||||
it("rejects an ID with $-signs in repository name", () => {
|
||||
expectRejection("repositoryName", "megacorp$megawidget");
|
||||
});
|
||||
it("rejects an ID with $-signs in name", () => {
|
||||
expectRejection("name", "issue$123");
|
||||
});
|
||||
});
|
||||
|
||||
describe("stringToID", () => {
|
||||
it("parses a simple ID-string", () => {
|
||||
const input = "widgets$megacorp/megawidget$issue#123";
|
||||
const expected = {
|
||||
pluginName: "widgets",
|
||||
repositoryName: "megacorp/megawidget",
|
||||
name: "issue#123",
|
||||
};
|
||||
expect(stringToID(input)).toEqual(expected);
|
||||
});
|
||||
[0, 1, 3, 4].forEach((n) => {
|
||||
it(`rejects an ID-string with ${n} occurrences of "\$"`, () => {
|
||||
const dollars = Array(n + 1).join("$");
|
||||
const input = `mega${dollars}corp`;
|
||||
expect(() => stringToID(input)).toThrow(/exactly two \$s/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("stringToID and idToString interop", () => {
|
||||
const examples = () => [
|
||||
{
|
||||
object: {
|
||||
pluginName: "widgets",
|
||||
repositoryName: "megacorp/megawidget",
|
||||
name: "issue#123",
|
||||
},
|
||||
string: "widgets$megacorp/megawidget$issue#123",
|
||||
},
|
||||
];
|
||||
examples().forEach((example, index) => {
|
||||
describe(`for example at 0-index ${index}`, () => {
|
||||
it("has stringToID a left identity for idToString", () => {
|
||||
expect(stringToID(idToString(example.object))).toEqual(
|
||||
example.object
|
||||
);
|
||||
});
|
||||
it("has stringToID a right identity for idToString", () => {
|
||||
expect(idToString(stringToID(example.string))).toEqual(
|
||||
example.string
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue