Compare commits

..

7 Commits

Author SHA1 Message Date
cef87ba4a5 lint
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-25 14:17:58 +01:00
78556c6c98 node shape
Some checks failed
continuous-integration/drone/push Build is failing
2023-03-25 14:12:10 +01:00
019647b04a formatting, update
Some checks failed
continuous-integration/drone/push Build is failing
2021-05-02 11:30:21 +02:00
fa8e0d25c6 bump version
All checks were successful
continuous-integration/drone/push Build is passing
2020-10-05 20:16:10 +02:00
af7bd4e00e additional test for expected states
Some checks failed
continuous-integration/drone/push Build is failing
2020-10-05 20:15:22 +02:00
9a2c2ce14c remove obsolete enum type 2020-10-05 19:32:29 +02:00
59542eb7b1 use jasmine 2020-10-05 19:16:09 +02:00
22 changed files with 1349 additions and 1990 deletions

View File

@ -1,5 +1,9 @@
# Changelog
## 1.4.0
Allow specifying shapes for nodes
## 1.3.0
Stream:

View File

@ -1,6 +1,6 @@
# @sapphirecode/graphviz-builder
version: 1.3.x
version: 1.4.x
constructing graphviz files using an easy typescript interface

14
jasmine.json Normal file
View File

@ -0,0 +1,14 @@
{
"spec_dir": "test",
"spec_files": [
"spec/*.js",
"spec/*.ts"
],
"helpers": [
"helpers/*.js",
"helpers/*.ts"
],
"stopSpecOnExpectationFailure": false,
"random": false
}

View File

@ -5,20 +5,13 @@
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
import { GraphStyles, NodeStyles } from '../enums/Styles';
import { GraphStyles } from '../enums/Styles';
import { GraphLayouts } from '../enums/GraphLayouts';
import { Element } from './Element';
import { Edge } from './Edge';
import { Node } from './Node';
import { Color } from './Color';
interface NodeOptions {
name: string;
label: string;
style: NodeStyles;
color: Color;
}
export class Graph extends Element {
public children: Array<Graph> = [];
public nodes: Array<Node> = [];
@ -83,7 +76,7 @@ export class Graph extends Element {
.replace (/^\s+$/gmu, '');
}
public add_node (constructor: ((n: Node) => void) | string): string {
public add_node (constructor: string | ((n: Node) => void)): string {
const node = new Node ('unnamed', this.full_name);
if (typeof constructor === 'string') {
@ -96,7 +89,7 @@ export class Graph extends Element {
return node.full_name;
}
public add_graph (constructor: ((g: Graph) => void) | string): string {
public add_graph (constructor: string | ((g: Graph) => void)): string {
const graph = new Graph ('unnamed', this.full_name);
graph.directional = this.directional;

View File

@ -168,7 +168,7 @@ export class GraphStream extends Transform {
// this.write ({ type: 'en', args: [] });
}
public create_graph (name: string, type: 'u'|'d'|'s' = 's'): void {
public create_graph (name: string, type: 'd' | 's' | 'u' = 's'): void {
const instr_type = `c${type}g` as GraphStreamCommand;
this.write ({ type: instr_type, args: [ validate_name (name) ] });
}

View File

@ -6,6 +6,7 @@
*/
import { NodeStyles } from '../enums/Styles';
import { NodeShapes } from '../enums/Shapes';
import { Element } from './Element';
import { Color } from './Color';
@ -15,6 +16,7 @@ export class Node extends Element {
public table_contents?: Array<Array<string>>;
public style?: NodeStyles;
public color?: Color;
public shape?: NodeShapes;
public constructor (name: string, parent: string, label?: string) {
super (name, parent);
@ -47,6 +49,8 @@ export class Node extends Element {
}
if (this.style)
attributes.push ({ name: 'style', value: this.style.toString () });
if (this.shape)
attributes.push ({ name: 'shape', value: this.shape.toString () });
if (this.color)
attributes.push ({ name: 'color', value: this.color.toString () });

View File

@ -6,11 +6,4 @@
*/
export type GraphLayouts =
'neato'
| 'dot'
| 'circo'
| 'fdp'
| 'sfdp'
| 'osage'
| 'twopi'
| 'patchwork'
'circo' | 'dot' | 'fdp' | 'neato' | 'osage' | 'patchwork' | 'sfdp' | 'twopi'

View File

@ -8,19 +8,11 @@
/* eslint-disable line-comment-position */
/* eslint-disable no-inline-comments */
type GraphStreamCommand =
'cn'|
'en'|
'cug'|
'cdg'|
'csg'|
'eg'|
'at'|
'ce'
'at' | 'cdg' | 'ce' | 'cn' | 'csg' | 'cug' | 'eg'
function translate_command (cmd: GraphStreamCommand|''): string {
const translations = {
cn: 'create node',
en: 'end node',
cug: 'create unordered graph',
cdg: 'create directional graph',
csg: 'create subgraph',

14
lib/enums/Shapes.ts Normal file
View File

@ -0,0 +1,14 @@
type NodeShapes =
'' | 'assembly' | 'box' | 'box3d' | 'cds' | 'circle' | 'component'
| 'cylinder' | 'diamond' | 'doublecircle' | 'doubleoctagon' | 'egg'
| 'ellipse' | 'fivepoverhang' | 'folder' | 'hexagon' | 'house'
| 'insulator' | 'invhouse' | 'invtrapezium' | 'invtriangle' | 'larrow'
| 'lpromoter' | 'Mcircle' | 'Mdiamond' | 'Msquare' | 'none' | 'note'
| 'noverhang' | 'octagon' | 'oval' | 'parallelogram' | 'pentagon'
| 'plain' | 'plaintext' | 'point' | 'polygon' | 'primersite' | 'promoter'
| 'proteasesite' | 'proteinstab' | 'rarrow' | 'rect' | 'rectangle'
| 'restrictionsite' | 'ribosite' | 'rnastab' | 'rpromoter' | 'septagon'
| 'signature' | 'square' | 'star' | 'tab' | 'terminator' | 'threepoverhang'
| 'trapezium' | 'triangle' | 'tripleoctagon' | 'underline' | 'utr'
export { NodeShapes };

View File

@ -6,34 +6,15 @@
*/
type EdgeStyles =
''
|'solid'
|'dashed'
|'dotted'
|'bold'
'' | 'bold' | 'dashed' | 'dotted' | 'solid'
type NodeStyles =
''
|'solid'
|'dashed'
|'dotted'
|'bold'
|'rounded'
|'diagonals'
|'filled'
|'striped'
|'wedged'
|'invis'
'' | 'bold' | 'dashed' | 'diagonals' | 'dotted'
| 'filled' | 'invis' | 'rounded' | 'solid' | 'striped' | 'wedged'
type GraphStyles =
'solid'
| 'dashed'
| 'dotted'
| 'bold'
| 'rounded'
| 'filled'
| 'striped'
'bold' | 'dashed' | 'dotted' | 'filled' | 'rounded' | 'solid' | 'striped'
export { EdgeStyles, NodeStyles, GraphStyles };

View File

@ -1,7 +1,7 @@
{
"name": "@sapphirecode/graphviz-builder",
"main": "dist/lib/index.js",
"version": "1.3.3",
"version": "1.4.0",
"author": {
"name": "Timo Hocker",
"email": "timo@scode.ovh"
@ -14,16 +14,19 @@
},
"license": "MIT",
"devDependencies": {
"@ava/typescript": "^1.1.1",
"@sapphirecode/eslint-config-ts": "^1.1.4",
"ava": "^3.8.2",
"@types/jasmine": "^3.5.14",
"@types/node": "^14.11.2",
"eslint": "^7.0.0",
"jasmine": "^3.6.1",
"jasmine-ts": "^0.3.0",
"nyc": "^15.0.1",
"ts-node": "^9.0.0",
"typescript": "^4.0.2"
},
"scripts": {
"lint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue,.mjs",
"test": "tsc && nyc ava",
"test": "nyc jasmine-ts --config=\"jasmine.json\"",
"compile": "tsc"
},
"files": [

View File

@ -1,17 +0,0 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of graphviz-builder which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
import test from 'ava';
import { Color } from '../lib';
test ('serialize', (t) => {
const wh = Color.white;
const tr = Color.transparent;
t.is (wh.toString (), '#ffffff');
t.is (tr.toString (), '#00000000');
});

View File

@ -1,29 +0,0 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of graphviz-builder which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
import test from 'ava';
import { Edge, Color } from '../lib';
test ('serialize', (t) => {
const e = new Edge ('foo', 'bar', false);
e.color = Color.white;
e.style = 'dashed';
const serialized = e.toString ();
t.is (serialized, 'foo -- bar [style="dashed",color="#ffffff"]');
});
test ('serialize directional', (t) => {
const e = new Edge ('foo', 'bar', true);
e.color = Color.white;
e.style = 'dashed';
const serialized = e.toString ();
t.is (serialized, 'foo -> bar [style="dashed",color="#ffffff"]');
});

View File

@ -1,128 +0,0 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of graphviz-builder which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
import test from 'ava';
import { Graph, Color } from '../lib';
const result = `digraph foo {
subgraph cluster_foo_baz {
color = #ff0000
style = bold
subgraph cluster_foo_baz_nested {
color = #808080
style = dotted
subgraph cluster_foo_baz_nested_unnamed {
color = #808080
style = dotted
}
}
foo_baz_asd [label="asd"]
foo_baz_test [style="bold", color="#808080"]
}
foo_baz [label="baz"]
foo_foo [label="foo"]
foo_foo -> foo_baz
}`;
const non_directional = `graph foo {
subgraph cluster_foo_bar {
foo_bar_baz [label="baz"]
foo_bar_asd [label="asd"]
foo_bar_baz -- foo_bar_asd
}
foo_foo [label="foo"]
foo_bar_baz -- foo_foo
}`;
const attributes = `digraph attr {
color = #000000
style = bold
overlap = false
splines = true
layout = neato
}`;
test ('serialize', (t) => {
const g = new Graph ('foo');
t.is (g.full_name, 'foo');
g.add_graph ((graph) => {
graph.name = 'baz';
graph.add_node ('asd');
graph.add_node ((n) => {
n.name = 'test';
n.style = 'bold';
n.color = Color.gray;
});
// eslint-disable-next-line no-shadow
graph.add_graph ((g) => {
g.style = 'dotted';
g.color = Color.gray;
g.name = 'nested';
// eslint-disable-next-line no-shadow, max-nested-callbacks
g.add_graph ((g) => {
g.style = 'dotted';
g.color = Color.gray;
});
});
graph.style = 'bold';
graph.color = Color.red;
});
const baz = g.add_node ('baz');
const foo = g.add_node ('foo');
g.add_edge (foo, baz);
const serialized = g.toString ();
t.is (serialized, result);
});
test ('non directional', (t) => {
const g = new Graph ('foo');
g.directional = false;
let n = '';
g.add_graph ((sub) => {
sub.name = 'bar';
n = sub.add_node ('baz');
const n2 = sub.add_node ('asd');
sub.add_edge (n, n2);
});
const f = g.add_node ('foo');
g.add_edge (n, f);
t.is (g.toString (), non_directional);
});
test ('attributes', (t) => {
const g = new Graph ('attr');
g.layout = 'neato';
g.overlap = false;
g.splines = true;
g.color = Color.black;
g.style = 'bold';
t.is (g.toString (), attributes);
});

View File

@ -1,77 +0,0 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of graphviz-builder which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
import test from 'ava';
import { Node, Color } from '../lib';
const serialized_simple
= 'bar_foo [label="baz", style="dashed", color="#00ff00"]';
const serialized_table = `bar_foo [label=<<table>
<tr><td>foo</td><td>bar</td><td>baz</td></tr>
<tr><td>bar</td><td>baz</td><td>foo</td></tr>
<tr><td>baz</td><td>foo</td><td>bar</td></tr>
</table>>, style="invis", color="#00ff00"]`;
test ('serialize simple', (t) => {
const g = new Node ('foo', 'bar', 'baz');
g.color = Color.green;
g.style = 'dashed';
const serialized = g.toString ();
t.is (g.full_name, 'bar_foo');
t.is (serialized, serialized_simple);
});
test ('serialize table', (t) => {
const g = new Node ('foo', 'bar', 'baz');
g.color = Color.green;
g.style = 'invis';
g.table_contents = [
[
'foo',
'bar',
'baz'
],
[
'bar',
'baz',
'foo'
],
[
'baz',
'foo',
'bar'
]
];
g.is_table = true;
const serialized = g.toString ();
t.is (g.full_name, 'bar_foo');
t.is (serialized, serialized_table);
});
test ('adhere to naming convention', (t) => {
const n = new Node ('invalid.name', 'parent');
t.is (n.name, 'invalidname');
});
test ('throw on invalid name', (t) => {
t.throws (() => {
const n = new Node ('564#+-.,/@', 'parent');
return n.toString ();
}, { message: 'invalid node name 564#+-.,/@' });
});
test ('leave numbers after the first letter', (t) => {
const n = new Node ('i123nvalid.name', 'parent');
t.is (n.name, 'i123nvalidname');
});

View File

@ -1,95 +0,0 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of graphviz-builder which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, June 2020
*/
import test from 'ava';
import { GraphStream, Color } from '../lib/index';
const simple = `graph foo {
}
`;
const complex = `digraph foo {
subgraph cluster_foo_baz {
color = #ff0000
style = bold
subgraph cluster_foo_baz_nested {
color = #808080
style = dotted
subgraph cluster_foo_baz_nested_unnamed {
color = #808080
style = dotted
}
}
foo_baz_asd [label = "asd"]
foo_baz_test [style = "bold", color = "#808080"]
}
foo_baz [label = "baz"]
foo_foo [label = "foo"]
foo_foo -> foo_baz
foo_foo -> foo_baz_asd [label = "edge attr"]
}
`;
test ('stream graph', (t) => new Promise ((resolve) => {
let output = '';
const stream = (new GraphStream);
stream.on ('data', (data) => {
output += data;
});
stream.on ('end', () => {
t.is (output, simple);
resolve ();
});
stream.create_graph ('foo', 'u');
stream.end_graph ();
stream.end ();
}));
// eslint-disable-next-line max-statements
test ('complex stream graph', (t) => new Promise ((resolve) => {
let output = '';
const stream = (new GraphStream);
stream.on ('data', (data) => {
output += data;
});
stream.on ('end', () => {
t.is (output, complex);
resolve ();
});
stream.create_graph ('foo', 'd');
stream.create_graph ('baz');
stream.attributes ({ color: Color.red, style: 'bold' });
stream.create_graph ('nested');
stream.attributes ({ color: Color.gray, style: 'dotted' });
stream.create_graph ('unnamed');
stream.attributes ({ color: Color.gray, style: 'dotted' });
stream.end_graph ();
stream.end_graph ();
const asd = stream.create_node ('asd');
stream.attributes ({ label: 'asd' });
stream.end_node ();
stream.create_node ('test');
stream.attributes ({ style: 'bold', color: Color.gray });
stream.end_graph ();
const baz = stream.create_node ('baz');
stream.attributes ({ label: 'baz' });
const foo = stream.create_node ('foo');
stream.attributes ({ label: 'foo' });
stream.create_edge (foo, baz);
stream.create_edge (foo, asd);
stream.attributes ({ label: 'edge attr' });
stream.end_graph ();
stream.end ();
}));

20
test/spec/Color.ts Normal file
View File

@ -0,0 +1,20 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of graphviz-builder which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
import { Color } from '../../lib';
describe ('color', () => {
it ('should serialize', () => {
const wh = Color.white;
const tr = Color.transparent;
expect (wh.toString ())
.toEqual ('#ffffff');
expect (tr.toString ())
.toEqual ('#00000000');
});
});

32
test/spec/Edge.ts Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of graphviz-builder which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
import { Edge, Color } from '../../lib';
describe ('edge', () => {
it ('should serialize', () => {
const e = new Edge ('foo', 'bar', false);
e.color = Color.white;
e.style = 'dashed';
const serialized = e.toString ();
expect (serialized)
.toEqual ('foo -- bar [style="dashed",color="#ffffff"]');
});
it ('should serialize directional', () => {
const e = new Edge ('foo', 'bar', true);
e.color = Color.white;
e.style = 'dashed';
const serialized = e.toString ();
expect (serialized)
.toEqual ('foo -> bar [style="dashed",color="#ffffff"]');
});
});

135
test/spec/Graph.ts Normal file
View File

@ -0,0 +1,135 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of graphviz-builder which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
/* eslint-disable max-nested-callbacks */
import { Graph, Color } from '../../lib';
// eslint-disable-next-line max-lines-per-function
describe ('graph', () => {
const result = `digraph foo {
subgraph cluster_foo_baz {
color = #ff0000
style = bold
subgraph cluster_foo_baz_nested {
color = #808080
style = dotted
subgraph cluster_foo_baz_nested_unnamed {
color = #808080
style = dotted
}
}
foo_baz_asd [label="asd"]
foo_baz_test [style="bold", color="#808080"]
}
foo_baz [label="baz"]
foo_foo [label="foo"]
foo_foo -> foo_baz
}`;
const non_directional = `graph foo {
subgraph cluster_foo_bar {
foo_bar_baz [label="baz"]
foo_bar_asd [label="asd"]
foo_bar_baz -- foo_bar_asd
}
foo_foo [label="foo"]
foo_bar_baz -- foo_foo
}`;
const attributes = `digraph attr {
color = #000000
style = bold
overlap = false
splines = true
layout = neato
}`;
it ('should serialize', () => {
const g = new Graph ('foo');
expect (g.full_name)
.toEqual ('foo');
g.add_graph ((graph) => {
graph.name = 'baz';
graph.add_node ('asd');
graph.add_node ((n) => {
n.name = 'test';
n.style = 'bold';
n.color = Color.gray;
});
// eslint-disable-next-line no-shadow
graph.add_graph ((g) => {
g.style = 'dotted';
g.color = Color.gray;
g.name = 'nested';
// eslint-disable-next-line no-shadow
g.add_graph ((g) => {
g.style = 'dotted';
g.color = Color.gray;
});
});
graph.style = 'bold';
graph.color = Color.red;
});
const baz = g.add_node ('baz');
const foo = g.add_node ('foo');
g.add_edge (foo, baz);
const serialized = g.toString ();
expect (serialized)
.toEqual (result);
});
it ('non directional', () => {
const g = new Graph ('foo');
g.directional = false;
let n = '';
g.add_graph ((sub) => {
sub.name = 'bar';
n = sub.add_node ('baz');
const n2 = sub.add_node ('asd');
sub.add_edge (n, n2);
});
const f = g.add_node ('foo');
g.add_edge (n, f);
expect (g.toString ())
.toEqual (non_directional);
});
it ('attributes', () => {
const g = new Graph ('attr');
g.layout = 'neato';
g.overlap = false;
g.splines = true;
g.color = Color.black;
g.style = 'bold';
expect (g.toString ())
.toEqual (attributes);
});
});

87
test/spec/Node.ts Normal file
View File

@ -0,0 +1,87 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of graphviz-builder which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
import { Node, Color } from '../../lib';
const serialized_simple
= 'bar_foo [label="baz", style="dashed",'
+ ' shape="tripleoctagon", color="#00ff00"]';
const serialized_table = `bar_foo [label=<<table>
<tr><td>foo</td><td>bar</td><td>baz</td></tr>
<tr><td>bar</td><td>baz</td><td>foo</td></tr>
<tr><td>baz</td><td>foo</td><td>bar</td></tr>
</table>>, style="invis", color="#00ff00"]`;
// eslint-disable-next-line max-lines-per-function
describe ('node', () => {
it ('should serialize simple', () => {
const g = new Node ('foo', 'bar', 'baz');
g.color = Color.green;
g.style = 'dashed';
g.shape = 'tripleoctagon';
const serialized = g.toString ();
expect (g.full_name)
.toEqual ('bar_foo');
expect (serialized)
.toEqual (serialized_simple);
});
it ('should serialize table', () => {
const g = new Node ('foo', 'bar', 'baz');
g.color = Color.green;
g.style = 'invis';
g.table_contents = [
[
'foo',
'bar',
'baz'
],
[
'bar',
'baz',
'foo'
],
[
'baz',
'foo',
'bar'
]
];
g.is_table = true;
const serialized = g.toString ();
expect (g.full_name)
.toEqual ('bar_foo');
expect (serialized)
.toEqual (serialized_table);
});
it ('should adhere to naming convention', () => {
const n = new Node ('invalid.name', 'parent');
expect (n.name)
.toEqual ('invalidname');
});
it ('should throw on invalid name', () => {
expect (() => {
const n = new Node ('564#+-.,/@', 'parent');
return n.toString ();
})
.toThrowError ('invalid node name 564#+-.,/@');
});
it ('should leave numbers after the first letter', () => {
const n = new Node ('i123nvalid.name', 'parent');
expect (n.name)
.toEqual ('i123nvalidname');
});
});

217
test/spec/Stream.ts Normal file
View File

@ -0,0 +1,217 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of graphviz-builder which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, June 2020
*/
import { GraphStream, Color } from '../../lib/index';
const simple = `graph foo {
}
`;
const complex = `digraph foo {
subgraph cluster_foo_baz {
color = #ff0000
style = bold
subgraph cluster_foo_baz_nested {
color = #808080
style = dotted
subgraph cluster_foo_baz_nested_unnamed {
color = #808080
style = dotted
}
}
foo_baz_asd [label = "asd"]
foo_baz_test [style = "bold", color = "#808080"]
}
foo_baz [label = "baz"]
foo_foo [label = "foo"]
foo_foo -> foo_baz
foo_foo -> foo_baz_asd [label = "edge attr"]
}
`;
// eslint-disable-next-line max-lines-per-function
describe ('stream', () => {
it ('stream graph', () => new Promise<void> ((resolve) => {
let output = '';
const stream = (new GraphStream);
stream.on ('data', (data) => {
output += data;
});
stream.on ('end', () => {
expect (output)
.toEqual (simple);
resolve ();
});
stream.create_graph ('foo', 'u');
stream.end_graph ();
stream.end ();
}));
// eslint-disable-next-line max-statements
it ('complex stream graph', () => new Promise<void> ((resolve) => {
let output = '';
const stream = (new GraphStream);
stream.on ('data', (data) => {
output += data;
});
stream.on ('end', () => {
expect (output)
.toEqual (complex);
resolve ();
});
stream.create_graph ('foo', 'd');
stream.create_graph ('baz');
stream.attributes ({ color: Color.red, style: 'bold' });
stream.create_graph ('nested');
stream.attributes ({ color: Color.gray, style: 'dotted' });
stream.create_graph ('unnamed');
stream.attributes ({ color: Color.gray, style: 'dotted' });
stream.end_graph ();
stream.end_graph ();
const asd = stream.create_node ('asd');
stream.attributes ({ label: 'asd' });
stream.end_node ();
stream.create_node ('test');
stream.attributes ({ style: 'bold', color: Color.gray });
stream.end_graph ();
const baz = stream.create_node ('baz');
stream.attributes ({ label: 'baz' });
const foo = stream.create_node ('foo');
stream.attributes ({ label: 'foo' });
stream.create_edge (foo, baz);
stream.create_edge (foo, asd);
stream.attributes ({ label: 'edge attr' });
stream.end_graph ();
stream.end ();
}));
// eslint-disable-next-line max-lines-per-function
it ('should reject invalid command sequences', () => {
/**
* command valid invalid
* [s] cug, cdg eg, cn, csg, ce, at
* cn eg, cn, csg, ce, at cug, cdg
* cug eg, cn, csg, ce, at cug, cdg
* cdg eg, cn, csg, ce, at cug, cdg
* csg eg, cn, csg, ce, at cug, cdg
* eg eg, cn, csg, ce cug, cdg, at
* at eg, cn, csg, ce cug, cdg, at
* ce eg, cn, csg, ce, at cug, cdg
*/
const cn = (g: GraphStream) => {
g.create_node ('foo');
};
const cug = (g: GraphStream) => {
g.create_graph ('foo', 'u');
};
const cdg = (g: GraphStream) => {
g.create_graph ('foo', 'd');
};
const csg = (g: GraphStream) => {
g.create_graph ('foo', 's');
};
const eg = (g: GraphStream) => {
g.end_graph ();
};
const at = (g: GraphStream) => {
g.attributes ({ color: 'red' });
};
const ce = (g: GraphStream) => {
g.create_edge ('foo', 'bar');
};
const combinations = [
{
primary: (g: GraphStream) => {
cug (g);
cn (g);
},
secondary: [
cug,
cdg
]
},
{
primary: cug,
secondary: [
cug,
cdg
]
},
{
primary: cdg,
secondary: [
cug,
cdg
]
},
{
primary: (g: GraphStream) => {
cug (g);
csg (g);
},
secondary: [
cug,
cdg
]
},
{
primary: (g: GraphStream) => {
cug (g);
csg (g);
eg (g);
},
secondary: [
cug,
cdg,
at
]
},
{
primary: (g: GraphStream) => {
cug (g);
at (g);
},
secondary: [
cug,
cdg,
at
]
},
{
primary: (g: GraphStream) => {
cug (g);
ce (g);
},
secondary: [
cug,
cdg
]
}
];
for (const comb of combinations) {
for (const secondary of comb.secondary) {
const g = (new GraphStream);
comb.primary (g);
expect (() => secondary (g))
.toThrowError (
/invalid state to execute command.*?expected:.*?actual:/uis
);
}
}
});
});

2390
yarn.lock

File diff suppressed because it is too large Load Diff