Add richer types to graphDemoData (#146)

In preparation for using type info in the Graph apis, it is helpful to
have richer type info in the graph demo data.

Test plan: Check that the snapshot changes only consist of type changes,
and that CI passes.
This commit is contained in:
Dandelion Mané 2018-04-26 16:44:34 -07:00 committed by GitHub
parent 18ce9982d2
commit c635034dab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 107 additions and 76 deletions

View File

@ -3,12 +3,12 @@
exports[`graph #Graph JSON functions should serialize a simple graph 1`] = `
Object {
"edges": Object {
"{\\"id\\":\\"crab-self-assessment\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"crab-self-assessment\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"SILLY\\"}": Object {
"dst": Object {
"id": "razorclaw_crab#2",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "FOOD",
},
"payload": Object {
"evaluation": "not effective at avoiding hero",
@ -17,15 +17,15 @@ Object {
"id": "razorclaw_crab#2",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "FOOD",
},
},
"{\\"id\\":\\"hero_of_time#0@again_cooks@seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"hero_of_time#0@again_cooks@seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"ACTION\\"}": Object {
"dst": Object {
"id": "hero_of_time#0",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "PC",
},
"payload": Object {
"crit": true,
@ -35,15 +35,15 @@ Object {
"id": "seafood_fruit_mix#3",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "FOOD",
},
},
"{\\"id\\":\\"hero_of_time#0@cooks@seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"hero_of_time#0@cooks@seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"ACTION\\"}": Object {
"dst": Object {
"id": "hero_of_time#0",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "PC",
},
"payload": Object {
"crit": false,
@ -52,96 +52,96 @@ Object {
"id": "seafood_fruit_mix#3",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "FOOD",
},
},
"{\\"id\\":\\"hero_of_time#0@eats@seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"hero_of_time#0@eats@seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"ACTION\\"}": Object {
"dst": Object {
"id": "seafood_fruit_mix#3",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "FOOD",
},
"payload": Object {},
"src": Object {
"id": "hero_of_time#0",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "PC",
},
},
"{\\"id\\":\\"hero_of_time#0@grabs@razorclaw_crab#2\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"hero_of_time#0@grabs@razorclaw_crab#2\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"ACTION\\"}": Object {
"dst": Object {
"id": "hero_of_time#0",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "PC",
},
"payload": Object {},
"src": Object {
"id": "razorclaw_crab#2",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "FOOD",
},
},
"{\\"id\\":\\"hero_of_time#0@picks@mighty_bananas#1\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"hero_of_time#0@picks@mighty_bananas#1\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"ACTION\\"}": Object {
"dst": Object {
"id": "hero_of_time#0",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "PC",
},
"payload": Object {},
"src": Object {
"id": "mighty_bananas#1",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "FOOD",
},
},
"{\\"id\\":\\"mighty_bananas#1@included_in@seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"mighty_bananas#1@included_in@seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"INGREDIENT\\"}": Object {
"dst": Object {
"id": "mighty_bananas#1",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "FOOD",
},
"payload": Object {},
"src": Object {
"id": "seafood_fruit_mix#3",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "FOOD",
},
},
"{\\"id\\":\\"razorclaw_crab#2@included_in@seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"razorclaw_crab#2@included_in@seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"INGREDIENT\\"}": Object {
"dst": Object {
"id": "razorclaw_crab#2",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "FOOD",
},
"payload": Object {},
"src": Object {
"id": "seafood_fruit_mix#3",
"pluginName": "hill_cooking_pot",
"repositoryName": "sourcecred/eventide",
"type": "demoType",
"type": "FOOD",
},
},
},
"nodes": Object {
"{\\"id\\":\\"hero_of_time#0\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"hero_of_time#0\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"PC\\"}": Object {
"payload": Object {},
},
"{\\"id\\":\\"mighty_bananas#1\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"mighty_bananas#1\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"FOOD\\"}": Object {
"payload": Object {},
},
"{\\"id\\":\\"razorclaw_crab#2\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"razorclaw_crab#2\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"FOOD\\"}": Object {
"payload": Object {},
},
"{\\"id\\":\\"seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"demoType\\"}": Object {
"{\\"id\\":\\"seafood_fruit_mix#3\\",\\"pluginName\\":\\"hill_cooking_pot\\",\\"repositoryName\\":\\"sourcecred/eventide\\",\\"type\\":\\"FOOD\\"}": Object {
"payload": Object {
"effect": Array [
"attack_power",

View File

@ -133,7 +133,7 @@ describe("graph", () => {
expect(
demoData
.simpleMealGraph()
.getNode(demoData.makeAddress("treasure_octorok#5"))
.getNode(demoData.makeAddress("treasure_octorok#5", "NPC"))
).toBeUndefined();
});
@ -143,7 +143,8 @@ describe("graph", () => {
.simpleMealGraph()
.getNode(
demoData.makeAddress(
"treasure_octorok#5@helps_cook@seafood_fruit_mix#3"
"treasure_octorok#5@helps_cook@seafood_fruit_mix#3",
"ACTION"
)
)
).toBeUndefined();
@ -180,10 +181,11 @@ describe("graph", () => {
it("allows adding an edge with dangling `dst`", () => {
const edge = () => ({
address: demoData.makeAddress(
"treasure_octorok#5@helps_cook@seafood_fruit_mix#3"
"treasure_octorok#5@helps_cook@seafood_fruit_mix#3",
"ACTION"
),
src: demoData.mealNode().address,
dst: demoData.makeAddress("treasure_octorok#5"),
dst: demoData.makeAddress("treasure_octorok#5", "NPC"),
payload: {},
});
const g = demoData.simpleMealGraph().addEdge(edge());
@ -193,9 +195,10 @@ describe("graph", () => {
it("allows adding an edge with dangling `src`", () => {
const edge = () => ({
address: demoData.makeAddress(
"health_bar#6@healed_by@seafood_fruit_mix#3"
"health_bar#6@healed_by@seafood_fruit_mix#3",
"PLAYER_EFFECT"
),
src: demoData.makeAddress("health_bar#6"),
src: demoData.makeAddress("health_bar#6", "PLAYER_STATE"),
dst: demoData.mealNode().address,
payload: {},
});
@ -365,24 +368,24 @@ describe("graph", () => {
it("gets empty out-edges for a nonexistent node", () => {
const result = demoData
.simpleMealGraph()
.getOutEdges(demoData.makeAddress("hinox"));
.getOutEdges(demoData.makeAddress("hinox", "NPC"));
expect(result).toEqual([]);
});
it("gets empty in-edges for a nonexistent node", () => {
const result = demoData
.simpleMealGraph()
.getInEdges(demoData.makeAddress("hinox"));
.getInEdges(demoData.makeAddress("hinox", "NPC"));
expect(result).toEqual([]);
});
{
const danglingSrc = () => ({
address: demoData.makeAddress("meaty_rice_balls#8"),
address: demoData.makeAddress("meaty_rice_balls#8", "FOOD"),
payload: {meaty: true},
});
const danglingDst = () => ({
address: demoData.makeAddress("treasure_octorok#5"),
address: demoData.makeAddress("treasure_octorok#5", "NPC"),
payload: {meaty: false},
});
@ -390,7 +393,8 @@ describe("graph", () => {
// demo meal graph.
const fullyDanglingEdge = () => ({
address: demoData.makeAddress(
"treasure_octorok#5@helps_cook@meaty_rice_balls#8"
"treasure_octorok#5@helps_cook@meaty_rice_balls#8",
"ACTION"
),
src: danglingSrc().address,
dst: danglingDst().address,
@ -526,11 +530,11 @@ describe("graph", () => {
).toBe(false);
});
const extraNode1 = () => ({
address: demoData.makeAddress("octorok"),
address: demoData.makeAddress("octorok", "NPC"),
payload: {},
});
const extraNode2 = () => ({
address: demoData.makeAddress("hinox"),
address: demoData.makeAddress("hinox", "NPC"),
payload: {status: "sleeping"},
});
it("returns false when the LHS has edges missing in the RHS", () => {
@ -626,20 +630,32 @@ describe("graph", () => {
it("conservatively merges graphs of different payload types", () => {
const data = {
a: () => ({address: demoData.makeAddress("a"), payload: "alpha"}),
b: () => ({address: demoData.makeAddress("b"), payload: "bravo"}),
a: () => ({
address: demoData.makeAddress("a", "EXPERIMENT"),
payload: "alpha",
}),
b: () => ({
address: demoData.makeAddress("b", "EXPERIMENT"),
payload: "bravo",
}),
u: () => ({
address: demoData.makeAddress("u"),
src: demoData.makeAddress("a"),
dst: demoData.makeAddress("b"),
address: demoData.makeAddress("u", "EXPERIMENT"),
src: demoData.makeAddress("a", "EXPERIMENT"),
dst: demoData.makeAddress("b", "EXPERIMENT"),
payload: 21,
}),
c: () => ({address: demoData.makeAddress("c"), payload: true}),
d: () => ({address: demoData.makeAddress("d"), payload: false}),
c: () => ({
address: demoData.makeAddress("c", "EXPERIMENT"),
payload: true,
}),
d: () => ({
address: demoData.makeAddress("d", "EXPERIMENT"),
payload: false,
}),
v: () => ({
address: demoData.makeAddress("v"),
src: demoData.makeAddress("c"),
dst: demoData.makeAddress("d"),
address: demoData.makeAddress("v", "EXPERIMENT"),
src: demoData.makeAddress("c", "EXPERIMENT"),
dst: demoData.makeAddress("d", "EXPERIMENT"),
payload: null,
}),
};
@ -666,7 +682,7 @@ describe("graph", () => {
it("conservatively rejects a graph with conflicting nodes", () => {
const makeGraph: (nodePayload: string) => Graph<*, *> = (nodePayload) =>
new Graph().addNode({
address: demoData.makeAddress("conflicting-node"),
address: demoData.makeAddress("conflicting-node", "EXPERIMENT"),
payload: nodePayload,
});
const g1 = makeGraph("one");
@ -677,14 +693,14 @@ describe("graph", () => {
});
it("conservatively rejects a graph with conflicting edges", () => {
const srcAddress = demoData.makeAddress("src");
const dstAddress = demoData.makeAddress("dst");
const srcAddress = demoData.makeAddress("src", "EXPERIMENT");
const dstAddress = demoData.makeAddress("dst", "EXPERIMENT");
const makeGraph: (edgePayload: string) => Graph<*, *> = (edgePayload) =>
new Graph()
.addNode({address: srcAddress, payload: {}})
.addNode({address: dstAddress, payload: {}})
.addEdge({
address: demoData.makeAddress("conflicting-edge"),
address: demoData.makeAddress("conflicting-edge", "EXPERIMENT"),
src: srcAddress,
dst: dstAddress,
payload: edgePayload,
@ -775,11 +791,11 @@ describe("graph", () => {
it("allows adding explicitly typed nodes", () => {
expect(() => {
const stringNode: Node<string> = {
address: demoData.makeAddress("hello"),
address: demoData.makeAddress("hello", "EXPERIMENT"),
payload: "hello",
};
const numberNode: Node<number> = {
address: demoData.makeAddress("hello"),
address: demoData.makeAddress("hello", "EXPERIMENT"),
payload: 17,
};
// This will be a Graph<string | number, *>.
@ -789,16 +805,22 @@ describe("graph", () => {
it("allows adding explicitly typed edges", () => {
expect(() => {
const src = {address: demoData.makeAddress("src"), payload: {}};
const dst = {address: demoData.makeAddress("dst"), payload: {}};
const src = {
address: demoData.makeAddress("src", "EXPERIMENT"),
payload: {},
};
const dst = {
address: demoData.makeAddress("dst", "EXPERIMENT"),
payload: {},
};
const stringEdge: Edge<string> = {
address: demoData.makeAddress("hello"),
address: demoData.makeAddress("hello", "EXPERIMENT"),
src: src.address,
dst: dst.address,
payload: "hello",
};
const numberEdge: Edge<number> = {
address: demoData.makeAddress("hello"),
address: demoData.makeAddress("hello", "EXPERIMENT"),
src: src.address,
dst: dst.address,
payload: 18,
@ -818,7 +840,7 @@ describe("graph", () => {
const g1 = demoData.advancedMealGraph();
const g2 = g1.copy();
const newNode = () => ({
address: demoData.makeAddress("brand-new"),
address: demoData.makeAddress("brand-new", "EXPERIMENT"),
payload: 777,
});
g2.addNode(newNode());

View File

@ -7,46 +7,46 @@
import type {Address} from "./address";
import {Graph} from "./graph";
export function makeAddress(id: string): Address {
export function makeAddress(id: string, type: string): Address {
return {
repositoryName: "sourcecred/eventide",
pluginName: "hill_cooking_pot",
type: "demoType",
id,
type,
};
}
export const heroNode = () => ({
address: makeAddress("hero_of_time#0"),
address: makeAddress("hero_of_time#0", "PC"),
payload: {},
});
export const bananasNode = () => ({
address: makeAddress("mighty_bananas#1"),
address: makeAddress("mighty_bananas#1", "FOOD"),
payload: {},
});
export const crabNode = () => ({
address: makeAddress("razorclaw_crab#2"),
address: makeAddress("razorclaw_crab#2", "FOOD"),
payload: {},
});
export const mealNode = () => ({
address: makeAddress("seafood_fruit_mix#3"),
address: makeAddress("seafood_fruit_mix#3", "FOOD"),
payload: {
effect: ["attack_power", 1],
},
});
export const pickEdge = () => ({
address: makeAddress("hero_of_time#0@picks@mighty_bananas#1"),
address: makeAddress("hero_of_time#0@picks@mighty_bananas#1", "ACTION"),
src: bananasNode().address,
dst: heroNode().address,
payload: {},
});
export const grabEdge = () => ({
address: makeAddress("hero_of_time#0@grabs@razorclaw_crab#2"),
address: makeAddress("hero_of_time#0@grabs@razorclaw_crab#2", "ACTION"),
src: crabNode().address,
dst: heroNode().address,
payload: {},
});
export const cookEdge = () => ({
address: makeAddress("hero_of_time#0@cooks@seafood_fruit_mix#3"),
address: makeAddress("hero_of_time#0@cooks@seafood_fruit_mix#3", "ACTION"),
src: mealNode().address,
dst: heroNode().address,
payload: {
@ -54,19 +54,25 @@ export const cookEdge = () => ({
},
});
export const bananasIngredientEdge = () => ({
address: makeAddress("mighty_bananas#1@included_in@seafood_fruit_mix#3"),
address: makeAddress(
"mighty_bananas#1@included_in@seafood_fruit_mix#3",
"INGREDIENT"
),
src: mealNode().address,
dst: bananasNode().address,
payload: {},
});
export const crabIngredientEdge = () => ({
address: makeAddress("razorclaw_crab#2@included_in@seafood_fruit_mix#3"),
address: makeAddress(
"razorclaw_crab#2@included_in@seafood_fruit_mix#3",
"INGREDIENT"
),
src: mealNode().address,
dst: crabNode().address,
payload: {},
});
export const eatEdge = () => ({
address: makeAddress("hero_of_time#0@eats@seafood_fruit_mix#3"),
address: makeAddress("hero_of_time#0@eats@seafood_fruit_mix#3", "ACTION"),
src: heroNode().address,
dst: mealNode().address,
payload: {},
@ -85,14 +91,17 @@ export const simpleMealGraph = () =>
.addEdge(eatEdge());
export const crabLoopEdge = () => ({
address: makeAddress("crab-self-assessment"),
address: makeAddress("crab-self-assessment", "SILLY"),
src: crabNode().address,
dst: crabNode().address,
payload: {evaluation: "not effective at avoiding hero"},
});
export const duplicateCookEdge = () => ({
address: makeAddress("hero_of_time#0@again_cooks@seafood_fruit_mix#3"),
address: makeAddress(
"hero_of_time#0@again_cooks@seafood_fruit_mix#3",
"ACTION"
),
src: mealNode().address,
dst: heroNode().address,
payload: {