GraphStream
This commit is contained in:
parent
acf8004497
commit
8d6d91e562
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -5,7 +5,7 @@ pipeline {
|
|||||||
VERSION = VersionNumber([
|
VERSION = VersionNumber([
|
||||||
versionNumberString:
|
versionNumberString:
|
||||||
'${BUILDS_ALL_TIME}',
|
'${BUILDS_ALL_TIME}',
|
||||||
versionPrefix: '1.0.',
|
versionPrefix: '1.1.',
|
||||||
worstResultForIncrement: 'SUCCESS'
|
worstResultForIncrement: 'SUCCESS'
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
export enum GraphLayouts {
|
|
||||||
neato = 'neato',
|
|
||||||
dot = 'dot',
|
|
||||||
circo = 'circo',
|
|
||||||
fdp = 'fdp',
|
|
||||||
sfdp = 'sfdp',
|
|
||||||
osage = 'osage',
|
|
||||||
twopi = 'twopi',
|
|
||||||
patchwork = 'patchwork'
|
|
||||||
}
|
|
10
lib/Helper.ts
Normal file
10
lib/Helper.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
function validate_name (name: string): string {
|
||||||
|
const new_name = name
|
||||||
|
.replace (/[^a-z0-9]/giu, '')
|
||||||
|
.replace (/^[0-9]+/iu, '');
|
||||||
|
if (new_name === '')
|
||||||
|
throw new Error (`invalid node name ${name}`);
|
||||||
|
return new_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { validate_name };
|
@ -1,33 +0,0 @@
|
|||||||
enum EdgeStyles {
|
|
||||||
default = '',
|
|
||||||
solid = 'solid',
|
|
||||||
dashed = 'dashed',
|
|
||||||
dotted='dotted',
|
|
||||||
bold='bold'
|
|
||||||
}
|
|
||||||
|
|
||||||
enum NodeStyles {
|
|
||||||
default = '',
|
|
||||||
solid='solid',
|
|
||||||
dashed='dashed',
|
|
||||||
dotted='dotted',
|
|
||||||
bold='bold',
|
|
||||||
rounded='rounded',
|
|
||||||
diagonals='diagonals',
|
|
||||||
filled='filled',
|
|
||||||
striped='striped',
|
|
||||||
wedged='wedged',
|
|
||||||
invisible='invis'
|
|
||||||
}
|
|
||||||
|
|
||||||
enum GraphStyles {
|
|
||||||
solid = 'solid',
|
|
||||||
dashed = 'dashed',
|
|
||||||
dotted = 'dotted',
|
|
||||||
bold = 'bold',
|
|
||||||
rounded = 'rounded',
|
|
||||||
filled = 'filled',
|
|
||||||
striped = 'striped'
|
|
||||||
}
|
|
||||||
|
|
||||||
export { EdgeStyles, NodeStyles, GraphStyles };
|
|
@ -1,4 +1,4 @@
|
|||||||
import { EdgeStyles } from './Styles';
|
import { EdgeStyles } from '../enums/Styles';
|
||||||
import { Color } from './Color';
|
import { Color } from './Color';
|
||||||
|
|
||||||
export class Edge {
|
export class Edge {
|
@ -1,3 +1,5 @@
|
|||||||
|
import { validate_name } from '../Helper';
|
||||||
|
|
||||||
export class Element {
|
export class Element {
|
||||||
private _name = '';
|
private _name = '';
|
||||||
protected parent_name: string;
|
protected parent_name: string;
|
||||||
@ -13,11 +15,7 @@ export class Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public set name (val: string) {
|
public set name (val: string) {
|
||||||
const new_name = val.replace (/[^a-z0-9]/giu, '')
|
this._name = validate_name (val);
|
||||||
.replace (/^[0-9]+/iu, '');
|
|
||||||
if (new_name === '')
|
|
||||||
throw new Error (`invalid node name ${val}`);
|
|
||||||
this._name = new_name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public get parent (): string {
|
public get parent (): string {
|
@ -1,9 +1,9 @@
|
|||||||
|
import { GraphStyles, NodeStyles } from '../enums/Styles';
|
||||||
|
import { GraphLayouts } from '../enums/GraphLayouts';
|
||||||
import { Element } from './Element';
|
import { Element } from './Element';
|
||||||
import { Edge } from './Edge';
|
import { Edge } from './Edge';
|
||||||
import { Node } from './Node';
|
import { Node } from './Node';
|
||||||
import { GraphStyles, NodeStyles } from './Styles';
|
|
||||||
import { Color } from './Color';
|
import { Color } from './Color';
|
||||||
import { GraphLayouts } from './GraphLayouts';
|
|
||||||
|
|
||||||
interface NodeOptions {
|
interface NodeOptions {
|
||||||
name: string;
|
name: string;
|
160
lib/classes/GraphStream.ts
Normal file
160
lib/classes/GraphStream.ts
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/* eslint-disable line-comment-position */
|
||||||
|
/* eslint-disable no-inline-comments */
|
||||||
|
import { Transform } from 'stream';
|
||||||
|
import { GraphStreamJSON } from '../interfaces/GraphStreamJSON';
|
||||||
|
import { GraphStreamCommand } from '../enums/GraphStreamCommand';
|
||||||
|
|
||||||
|
interface Stringable {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
toString(): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GraphStream extends Transform {
|
||||||
|
private _path: string[] = [];
|
||||||
|
private _state = '';
|
||||||
|
private _directional = false;
|
||||||
|
|
||||||
|
public get path (): string {
|
||||||
|
return this._path.join ('_');
|
||||||
|
}
|
||||||
|
|
||||||
|
private get level (): string {
|
||||||
|
return ' '.repeat (this._path.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private expect_state (instr: GraphStreamCommand): void {
|
||||||
|
const states = [];
|
||||||
|
if ([
|
||||||
|
'cug',
|
||||||
|
'cdg'
|
||||||
|
].includes (instr))
|
||||||
|
states.push ('');
|
||||||
|
|
||||||
|
if ([
|
||||||
|
'eg',
|
||||||
|
'cn',
|
||||||
|
'csg',
|
||||||
|
'ce'
|
||||||
|
].includes (instr))
|
||||||
|
states.push ('en', 'at', 'eg', 'cug', 'cdg', 'csg', 'ce');
|
||||||
|
|
||||||
|
switch (instr) {
|
||||||
|
case 'en':
|
||||||
|
states.push ('cn', 'at');
|
||||||
|
break;
|
||||||
|
case 'at':
|
||||||
|
states.push ('cn', 'cug', 'cdg', 'csg');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!states.includes (this._state)) {
|
||||||
|
throw new Error (`invalid state to execute command ${instr}
|
||||||
|
expected: ${states.join (', ')}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention, complexity, max-lines-per-function
|
||||||
|
public _transform (
|
||||||
|
chunk: string,
|
||||||
|
encoding: string,
|
||||||
|
callback: ((error?: Error) => unknown)
|
||||||
|
): void {
|
||||||
|
const instr = JSON.parse (chunk) as GraphStreamJSON;
|
||||||
|
this.expect_state (instr.type);
|
||||||
|
switch (instr.type) {
|
||||||
|
case 'cug': // create unordered graph
|
||||||
|
this._path.push (instr.args[0]);
|
||||||
|
this.push (`graph ${this.path} {\n`);
|
||||||
|
this._directional = false;
|
||||||
|
break;
|
||||||
|
case 'cdg': // create directional graph
|
||||||
|
this._path.push (instr.args[0]);
|
||||||
|
this.push (`digraph ${this.path} {\n`);
|
||||||
|
this._directional = true;
|
||||||
|
break;
|
||||||
|
case 'csg': // create subgraph
|
||||||
|
this.push (
|
||||||
|
`${this.level}subgraph cluster_${this.path}_${instr.args[0]} {\n`
|
||||||
|
);
|
||||||
|
this._path.push (instr.args[0]);
|
||||||
|
break;
|
||||||
|
case 'eg': // end graph
|
||||||
|
this._path.pop ();
|
||||||
|
this.push (`${this.level}}\n\n`);
|
||||||
|
break;
|
||||||
|
case 'cn': // create node
|
||||||
|
this.push (`${this.level}${this.path}_${instr.args[0]}`);
|
||||||
|
break;
|
||||||
|
case 'en': // end node
|
||||||
|
this.push ('\n');
|
||||||
|
break;
|
||||||
|
case 'at': // add attributes
|
||||||
|
if (this._state === 'cn') {
|
||||||
|
this.push (` [${instr.args.join (', ')}]`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.push (`${this.level}${
|
||||||
|
instr.args.join (`\n${this.level}`)
|
||||||
|
.replace (/"/gu, '')
|
||||||
|
}\n\n`);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'ce':
|
||||||
|
this.push (`${this.level}${
|
||||||
|
instr.args[0]
|
||||||
|
} -${this._directional ? '>' : '-'} ${instr.args[1]}\n`);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this._state = instr.type;
|
||||||
|
callback ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public write (
|
||||||
|
instr: GraphStreamJSON
|
||||||
|
): boolean {
|
||||||
|
return super.write (JSON.stringify (instr), 'utf-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
public create_node (name: string): boolean {
|
||||||
|
return this.write ({ type: 'cn', args: [ name ] });
|
||||||
|
}
|
||||||
|
|
||||||
|
public end_node (): boolean {
|
||||||
|
return this.write ({ type: 'en', args: [] });
|
||||||
|
}
|
||||||
|
|
||||||
|
public create_graph (name: string, type: 'u'|'d'|'s' = 's'): boolean {
|
||||||
|
const instr_type = `c${type}g` as GraphStreamCommand;
|
||||||
|
return this.write ({ type: instr_type, args: [ name ] });
|
||||||
|
}
|
||||||
|
|
||||||
|
public end_graph (): boolean {
|
||||||
|
return this.write ({ type: 'eg', args: [] });
|
||||||
|
}
|
||||||
|
|
||||||
|
public attributes (attrs: Record<string, Stringable>): boolean {
|
||||||
|
const solved = [];
|
||||||
|
for (const attr of Object.keys (attrs)) {
|
||||||
|
const val = attrs[attr].toString ();
|
||||||
|
if ((/\n/u).test (val))
|
||||||
|
solved.push (`${attr} = <${val}>`);
|
||||||
|
else
|
||||||
|
solved.push (`${attr} = "${val}"`);
|
||||||
|
}
|
||||||
|
return this.write ({ type: 'at', args: solved });
|
||||||
|
}
|
||||||
|
|
||||||
|
public create_edge (origin: string, target: string): boolean {
|
||||||
|
return this.write ({
|
||||||
|
type: 'ce',
|
||||||
|
args: [
|
||||||
|
origin,
|
||||||
|
target
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
|
import { NodeStyles } from '../enums/Styles';
|
||||||
import { Element } from './Element';
|
import { Element } from './Element';
|
||||||
import { NodeStyles } from './Styles';
|
|
||||||
import { Color } from './Color';
|
import { Color } from './Color';
|
||||||
|
|
||||||
export class Node extends Element {
|
export class Node extends Element {
|
9
lib/enums/GraphLayouts.ts
Normal file
9
lib/enums/GraphLayouts.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export type GraphLayouts =
|
||||||
|
'neato'
|
||||||
|
| 'dot'
|
||||||
|
| 'circo'
|
||||||
|
| 'fdp'
|
||||||
|
| 'sfdp'
|
||||||
|
| 'osage'
|
||||||
|
| 'twopi'
|
||||||
|
| 'patchwork'
|
11
lib/enums/GraphStreamCommand.ts
Normal file
11
lib/enums/GraphStreamCommand.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/* eslint-disable line-comment-position */
|
||||||
|
/* eslint-disable no-inline-comments */
|
||||||
|
export type GraphStreamCommand =
|
||||||
|
'cn'| // create node
|
||||||
|
'en'| // end node
|
||||||
|
'cug'| // create unordered graph
|
||||||
|
'cdg'| // create directional graph
|
||||||
|
'csg'| // create subgraph
|
||||||
|
'eg'| // end graph
|
||||||
|
'at'| // add attributes
|
||||||
|
'ce' // create edge
|
32
lib/enums/Styles.ts
Normal file
32
lib/enums/Styles.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
type EdgeStyles =
|
||||||
|
''
|
||||||
|
|'solid'
|
||||||
|
|'dashed'
|
||||||
|
|'dotted'
|
||||||
|
|'bold'
|
||||||
|
|
||||||
|
|
||||||
|
type NodeStyles =
|
||||||
|
''
|
||||||
|
|'solid'
|
||||||
|
|'dashed'
|
||||||
|
|'dotted'
|
||||||
|
|'bold'
|
||||||
|
|'rounded'
|
||||||
|
|'diagonals'
|
||||||
|
|'filled'
|
||||||
|
|'striped'
|
||||||
|
|'wedged'
|
||||||
|
|'invis'
|
||||||
|
|
||||||
|
|
||||||
|
type GraphStyles =
|
||||||
|
'solid'
|
||||||
|
| 'dashed'
|
||||||
|
| 'dotted'
|
||||||
|
| 'bold'
|
||||||
|
| 'rounded'
|
||||||
|
| 'filled'
|
||||||
|
| 'striped'
|
||||||
|
|
||||||
|
export { EdgeStyles, NodeStyles, GraphStyles };
|
20
lib/index.ts
20
lib/index.ts
@ -1,8 +1,12 @@
|
|||||||
export { Graph } from './Graph';
|
import { Graph } from './classes/Graph';
|
||||||
export { Node } from './Node';
|
|
||||||
export { Element } from './Element';
|
export * from './classes/Color';
|
||||||
export { Edge } from './Edge';
|
export * from './classes/Edge';
|
||||||
export { Color } from './Color';
|
export * from './classes/Element';
|
||||||
export { EdgeStyles, NodeStyles, GraphStyles } from './Styles';
|
export { Graph };
|
||||||
export { GraphLayouts } from './GraphLayouts';
|
export * from './classes/GraphStream';
|
||||||
export { Graphable } from './Graphable';
|
export * from './classes/Node';
|
||||||
|
export * from './enums/GraphLayouts';
|
||||||
|
export * from './enums/Styles';
|
||||||
|
export * from './interfaces/Graphable';
|
||||||
|
export default Graph;
|
||||||
|
6
lib/interfaces/GraphStreamJSON.ts
Normal file
6
lib/interfaces/GraphStreamJSON.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { GraphStreamCommand } from '../enums/GraphStreamCommand';
|
||||||
|
|
||||||
|
export interface GraphStreamJSON {
|
||||||
|
type: GraphStreamCommand;
|
||||||
|
args: string[];
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { Graph } from './Graph';
|
import { Graph } from '../classes/Graph';
|
||||||
|
|
||||||
export interface Graphable {
|
export interface Graphable {
|
||||||
to_graph(g: Graph, ...args: unknown[]): unknown;
|
to_graph(g: Graph, ...args: unknown[]): unknown;
|
@ -1,11 +1,11 @@
|
|||||||
import test from 'ava';
|
import test from 'ava';
|
||||||
import { Edge, Color, EdgeStyles } from '../lib';
|
import { Edge, Color } from '../lib';
|
||||||
|
|
||||||
test ('serialize', (t) => {
|
test ('serialize', (t) => {
|
||||||
const e = new Edge ('foo', 'bar', false);
|
const e = new Edge ('foo', 'bar', false);
|
||||||
|
|
||||||
e.color = Color.white;
|
e.color = Color.white;
|
||||||
e.style = EdgeStyles.dashed;
|
e.style = 'dashed';
|
||||||
const serialized = e.toString ();
|
const serialized = e.toString ();
|
||||||
|
|
||||||
t.is (serialized, 'foo -- bar [style="dashed",color="#ffffff"]');
|
t.is (serialized, 'foo -- bar [style="dashed",color="#ffffff"]');
|
||||||
@ -15,7 +15,7 @@ test ('serialize directional', (t) => {
|
|||||||
const e = new Edge ('foo', 'bar', true);
|
const e = new Edge ('foo', 'bar', true);
|
||||||
|
|
||||||
e.color = Color.white;
|
e.color = Color.white;
|
||||||
e.style = EdgeStyles.dashed;
|
e.style = 'dashed';
|
||||||
const serialized = e.toString ();
|
const serialized = e.toString ();
|
||||||
|
|
||||||
t.is (serialized, 'foo -> bar [style="dashed",color="#ffffff"]');
|
t.is (serialized, 'foo -> bar [style="dashed",color="#ffffff"]');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import test from 'ava';
|
import test from 'ava';
|
||||||
import { Graph, GraphStyles, Color, NodeStyles, GraphLayouts } from '../lib';
|
import { Graph, Color } from '../lib';
|
||||||
|
|
||||||
const result = `digraph foo {
|
const result = `digraph foo {
|
||||||
subgraph cluster_foo_baz {
|
subgraph cluster_foo_baz {
|
||||||
@ -56,23 +56,23 @@ test ('serialize', (t) => {
|
|||||||
graph.add_node ('asd');
|
graph.add_node ('asd');
|
||||||
graph.add_node ((n) => {
|
graph.add_node ((n) => {
|
||||||
n.name = 'test';
|
n.name = 'test';
|
||||||
n.style = NodeStyles.bold;
|
n.style = 'bold';
|
||||||
n.color = Color.gray;
|
n.color = Color.gray;
|
||||||
});
|
});
|
||||||
|
|
||||||
// eslint-disable-next-line no-shadow
|
// eslint-disable-next-line no-shadow
|
||||||
graph.add_graph ((g) => {
|
graph.add_graph ((g) => {
|
||||||
g.style = GraphStyles.dotted;
|
g.style = 'dotted';
|
||||||
g.color = Color.gray;
|
g.color = Color.gray;
|
||||||
g.name = 'nested';
|
g.name = 'nested';
|
||||||
|
|
||||||
// eslint-disable-next-line no-shadow, max-nested-callbacks
|
// eslint-disable-next-line no-shadow, max-nested-callbacks
|
||||||
g.add_graph ((g) => {
|
g.add_graph ((g) => {
|
||||||
g.style = GraphStyles.dotted;
|
g.style = 'dotted';
|
||||||
g.color = Color.gray;
|
g.color = Color.gray;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
graph.style = GraphStyles.bold;
|
graph.style = 'bold';
|
||||||
graph.color = Color.red;
|
graph.color = Color.red;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -111,11 +111,11 @@ test ('non directional', (t) => {
|
|||||||
test ('attributes', (t) => {
|
test ('attributes', (t) => {
|
||||||
const g = new Graph ('attr');
|
const g = new Graph ('attr');
|
||||||
|
|
||||||
g.layout = GraphLayouts.neato;
|
g.layout = 'neato';
|
||||||
g.overlap = false;
|
g.overlap = false;
|
||||||
g.splines = true;
|
g.splines = true;
|
||||||
g.color = Color.black;
|
g.color = Color.black;
|
||||||
g.style = GraphStyles.bold;
|
g.style = 'bold';
|
||||||
|
|
||||||
t.is (g.toString (), attributes);
|
t.is (g.toString (), attributes);
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import test from 'ava';
|
import test from 'ava';
|
||||||
import { NodeStyles, Node, Color } from '../lib';
|
import { Node, Color } from '../lib';
|
||||||
|
|
||||||
const serialized_simple
|
const serialized_simple
|
||||||
= 'bar_foo [label="baz", style="dashed", color="#00ff00"]';
|
= 'bar_foo [label="baz", style="dashed", color="#00ff00"]';
|
||||||
@ -13,7 +13,7 @@ test ('serialize simple', (t) => {
|
|||||||
const g = new Node ('foo', 'bar', 'baz');
|
const g = new Node ('foo', 'bar', 'baz');
|
||||||
|
|
||||||
g.color = Color.green;
|
g.color = Color.green;
|
||||||
g.style = NodeStyles.dashed;
|
g.style = 'dashed';
|
||||||
|
|
||||||
const serialized = g.toString ();
|
const serialized = g.toString ();
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ test ('serialize table', (t) => {
|
|||||||
const g = new Node ('foo', 'bar', 'baz');
|
const g = new Node ('foo', 'bar', 'baz');
|
||||||
|
|
||||||
g.color = Color.green;
|
g.color = Color.green;
|
||||||
g.style = NodeStyles.invisible;
|
g.style = 'invis';
|
||||||
|
|
||||||
g.table_contents = [
|
g.table_contents = [
|
||||||
[
|
[
|
||||||
|
89
test/Stream.ts
Normal file
89
test/Stream.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
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);
|
||||||
|
t.log (output);
|
||||||
|
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 ();
|
||||||
|
stream.create_node ('asd');
|
||||||
|
stream.attributes ({ label: 'asd' });
|
||||||
|
stream.end_node ();
|
||||||
|
stream.create_node ('test');
|
||||||
|
stream.attributes ({ style: 'bold', color: Color.gray });
|
||||||
|
stream.end_node ();
|
||||||
|
stream.end_graph ();
|
||||||
|
stream.create_node ('baz');
|
||||||
|
stream.attributes ({ label: 'baz' });
|
||||||
|
stream.end_node ();
|
||||||
|
stream.create_node ('foo');
|
||||||
|
stream.attributes ({ label: 'foo' });
|
||||||
|
stream.end_node ();
|
||||||
|
stream.create_edge (`${stream.path}_foo`, `${stream.path}_baz`);
|
||||||
|
stream.end_graph ();
|
||||||
|
stream.end ();
|
||||||
|
}));
|
12
yarn.lock
12
yarn.lock
@ -241,18 +241,18 @@
|
|||||||
eslint-plugin-import "^2.20.1"
|
eslint-plugin-import "^2.20.1"
|
||||||
|
|
||||||
"@sapphirecode/eslint-config-ts@^1.0.22":
|
"@sapphirecode/eslint-config-ts@^1.0.22":
|
||||||
version "1.0.38"
|
version "1.0.40"
|
||||||
resolved "https://registry.yarnpkg.com/@sapphirecode/eslint-config-ts/-/eslint-config-ts-1.0.38.tgz#9c2c80be2b6bee6a0c8dc2a9d0504869d46f5882"
|
resolved "https://registry.yarnpkg.com/@sapphirecode/eslint-config-ts/-/eslint-config-ts-1.0.40.tgz#e646383a933ff64d2604bd6ddd2f89e1aa7dfb1a"
|
||||||
integrity sha512-sOzBGUmpc12/j5Z2opMTqpU/XztZOdRQy+/+0wLMLATs9PVHW55oprvWLDQoWttH763v2DwU3PNvoXILq1eHGw==
|
integrity sha512-h0m5ohVZB8jKubT567gjykpkVN/ybVkbKNWT9q5GhltECVB9g/Y6Jh6E9Fqg1pTz+DE+iHqr7CO9+stVVLwc4w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@sapphirecode/eslint-config-es6" "^1.0.1"
|
"@sapphirecode/eslint-config-es6" "^1.0.1"
|
||||||
"@typescript-eslint/eslint-plugin" "^2.26.0"
|
"@typescript-eslint/eslint-plugin" "^2.26.0"
|
||||||
"@typescript-eslint/parser" "^2.26.0"
|
"@typescript-eslint/parser" "^2.26.0"
|
||||||
|
|
||||||
"@sapphirecode/eslint-config@^2.0.1":
|
"@sapphirecode/eslint-config@^2.0.1":
|
||||||
version "2.0.23"
|
version "2.0.24"
|
||||||
resolved "https://registry.yarnpkg.com/@sapphirecode/eslint-config/-/eslint-config-2.0.23.tgz#1669742219dab81ac83914d8826d88f06492ba2c"
|
resolved "https://registry.yarnpkg.com/@sapphirecode/eslint-config/-/eslint-config-2.0.24.tgz#e9a033767ce0ab1242dc3af700abb58b1c68ab65"
|
||||||
integrity sha512-GO5KDZ58z59raCUkX7CzlATkqGETsOts2S/kOoxNhZR6+rdXQqkrA8BI4/degzZiWnKYn3KkQhyYvXv7fXKkFg==
|
integrity sha512-Fk5opga9EEMT4mXhmcg2KVKV1bnB8JAQWklMQay7ROw3QK5oP7A0KIJMlamYhXmHgctjGjlEEuJeFi10pO5QuA==
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint-plugin-node "^11.0.0"
|
eslint-plugin-node "^11.0.0"
|
||||||
eslint-plugin-sort-requires-by-path "^1.0.2"
|
eslint-plugin-sort-requires-by-path "^1.0.2"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user