Skip to content

Commit

Permalink
feat(data-point-tracers): add mermaid support (#420)
Browse files Browse the repository at this point in the history
closes #419
  • Loading branch information
acatl authored Sep 11, 2019
1 parent e8065cd commit 8816144
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 0 deletions.
66 changes: 66 additions & 0 deletions documentation/examples/mermaid-graph/mermaid-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* eslint-disable */

const path = require("path");

const DataPoint = require("@data-point/core");
const DPModel = require("@data-point/core/model");
const DPIfThenElse = require("@data-point/core/ifThenElse");
const DPMap = require("@data-point/core/map");

const DPMermaidTracer = require("@data-point/tracers/mermaid");

const myModel = DPModel({
name: "myModel",

uid: acc => `${acc.reducer.id}${acc.value.a.b}`,

value: [
"$a.b",
input => input.toUpperCase(),
DPIfThenElse({
if: input => input === "FOO",
then: () => {
// return "yes foo!!";
throw new Error("ohh");
},
else: input => `foo no! got ${input}`
})
],

catch(acc) {
return "its all ok";
}
});

async function main() {
const datapoint = DataPoint();

const input = [
{
a: {
b: "foo"
}
},
{
a: {
b: "bar"
}
},
{
a: {
b: "baz"
}
}
];

const tracer = DPMermaidTracer();

result = await datapoint.resolve(input, DPMap(myModel), {
tracer
});

// save to disk
tracer.report(path.join(__dirname, "datapoint-trace-example.mermaid"));
}

main();
10 changes: 10 additions & 0 deletions documentation/examples/mermaid-graph/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "@data-point/mermaid-example",
"main": "mermaid-example.js",
"private": true,
"version": "1.0.0",
"devDependencies": {
"@data-point/core": "^6.0.0",
"@data-point/tracers": "^1.0.0"
}
}
1 change: 1 addition & 0 deletions packages/data-point-tracers/mermaid/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("./mermaid").Mermaid.create;
48 changes: 48 additions & 0 deletions packages/data-point-tracers/mermaid/mermaid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const fs = require("fs").promises;

function getParent(span) {
return span.root ? "root" : span.parent;
}

function getName(span) {
return span === "root" ? "root" : `${span.name}${span.context.pid}`;
}

function graphTD(spans) {
const nodes = spans.map(span => {
return ` ${getName(getParent(span))}-->${getName(span)}`;
});

return `graph TD;\n${nodes.join("\n")}`;
}

class Mermaid {
constructor() {
this.spans = [];
}

static create() {
return new Mermaid();
}

start(dpSpan) {
this.spans.push(dpSpan);
}

async report(destinationPath) {
const report = graphTD(this.spans);

if (destinationPath) {
await fs.writeFile(destinationPath, report);
}

return report;
}
}

module.exports = {
getParent,
getName,
graphTD,
Mermaid
};
98 changes: 98 additions & 0 deletions packages/data-point-tracers/mermaid/mermaid.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const fs = require("fs").promises;
const { getParent, getName, graphTD, Mermaid } = require("./mermaid");

function createChildSpan(name, pid, parent) {
return {
name,
parent,
context: {
pid
}
};
}

function createSampleSpans() {
const aa = createChildSpan("aa", 1);
aa.root = true;
const bb = createChildSpan("bb", 2, aa);
const cc = createChildSpan("cc", 3, aa);
const dd = createChildSpan("dd", 4, bb);

const spans = [aa, bb, cc, dd];

return spans;
}

const graphResult = `graph TD;
root-->aa1
aa1-->bb2
aa1-->cc3
bb2-->dd4`;

describe("getParent", () => {
it("should return `root` if root flag is true", () => {
expect(getParent({ root: true })).toEqual("root");
});
it("should return parent if root flag not true", () => {
expect(getParent({ parent: "parent" })).toEqual("parent");
});
});

describe("getName", () => {
it("should return 'root' if span is root", () => {
expect(getName("root")).toEqual("root");
});
it("should return constructed name if span is not root", () => {
const span = createChildSpan("name", 1);
expect(getName(span)).toEqual("name1");
});
});

describe("graphTD", () => {
it("should create graph tree", () => {
const result = graphTD(createSampleSpans());
expect(result).toEqual(graphResult);
});
});

describe("Mermaid", () => {
describe("constructor", () => {
it("should create spans array", () => {
const result = new Mermaid();
expect(result).toHaveProperty("spans", []);
});
});

describe("create", () => {
it("should have static method to create new instance", () => {
const result = Mermaid.create();
expect(result).toBeInstanceOf(Mermaid);
});
});

describe("start", () => {
it("should track spans", () => {
const result = new Mermaid();
result.start("span");
expect(result.spans).toEqual(["span"]);
});
});

describe("report", () => {
it("should create and return mermaid graph", async () => {
const result = new Mermaid();
result.spans = createSampleSpans();
expect(await result.report()).toEqual(graphResult);
});

it("should save to file", async () => {
const result = new Mermaid();
result.spans = createSampleSpans();

const spyWriteFile = jest.spyOn(fs, "writeFile").mockResolvedValue(true);

await result.report("/test.mer");
expect(spyWriteFile).toBeCalledWith("/test.mer", graphResult);
});
});
});

0 comments on commit 8816144

Please sign in to comment.