Consistent agent flag handling in parser

This commit is contained in:
David Evans 2017-11-03 22:56:48 +00:00
parent 93c1e9cb8e
commit dc3d930544
6 changed files with 298 additions and 290 deletions

View File

@ -49,7 +49,7 @@ define(['core/ArrayUtilities'], (array) => {
'agent define': this.handleAgentDefine.bind(this), 'agent define': this.handleAgentDefine.bind(this),
'agent begin': this.handleAgentBegin.bind(this), 'agent begin': this.handleAgentBegin.bind(this),
'agent end': this.handleAgentEnd.bind(this), 'agent end': this.handleAgentEnd.bind(this),
'connection': this.handleConnection.bind(this), 'connect': this.handleConnect.bind(this),
'note over': this.handleNote.bind(this), 'note over': this.handleNote.bind(this),
'note left': this.handleNote.bind(this), 'note left': this.handleNote.bind(this),
'note right': this.handleNote.bind(this), 'note right': this.handleNote.bind(this),
@ -171,13 +171,13 @@ define(['core/ArrayUtilities'], (array) => {
this.addStage({type: 'async', target}, false); this.addStage({type: 'async', target}, false);
} }
handleConnection({agents, label, options}) { handleConnect({agents, label, options}) {
const colAgents = agents.map(convertAgent); const colAgents = agents.map(convertAgent);
this.setAgentVis(colAgents, true, 'box'); this.setAgentVis(colAgents, true, 'box');
this.defineAgents(colAgents); this.defineAgents(colAgents);
this.addStage({ this.addStage({
type: 'connection', type: 'connect',
agentNames: agents.map(getAgentName), agentNames: agents.map(getAgentName),
label, label,
options, options,

View File

@ -3,7 +3,7 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
const generator = new Generator(); const generator = new Generator();
const parsed = { const PARSED = {
blockBegin: (mode, label) => { blockBegin: (mode, label) => {
return {type: 'block begin', mode, label}; return {type: 'block begin', mode, label};
}, },
@ -19,14 +19,14 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
defineAgents: (agentNames) => { defineAgents: (agentNames) => {
return { return {
type: 'agent define', type: 'agent define',
agents: agentNames.map((name) => ({name})), agents: agentNames.map((name) => ({name, flags: []})),
}; };
}, },
beginAgents: (agentNames, {mode = 'box'} = {}) => { beginAgents: (agentNames, {mode = 'box'} = {}) => {
return { return {
type: 'agent begin', type: 'agent begin',
agents: agentNames.map((name) => ({name})), agents: agentNames.map((name) => ({name, flags: []})),
mode, mode,
}; };
}, },
@ -34,7 +34,7 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
endAgents: (agentNames, {mode = 'cross'} = {}) => { endAgents: (agentNames, {mode = 'cross'} = {}) => {
return { return {
type: 'agent end', type: 'agent end',
agents: agentNames.map((name) => ({name})), agents: agentNames.map((name) => ({name, flags: []})),
mode, mode,
}; };
}, },
@ -46,8 +46,8 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
right = false, right = false,
} = {}) => { } = {}) => {
return { return {
type: 'connection', type: 'connect',
agents: agentNames.map((name) => ({name})), agents: agentNames.map((name) => ({name, flags: []})),
label, label,
options: { options: {
line, line,
@ -64,14 +64,14 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
} = {}) => { } = {}) => {
return { return {
type, type,
agents: agentNames.map((name) => ({name})), agents: agentNames.map((name) => ({name, flags: []})),
mode, mode,
label, label,
}; };
}, },
}; };
const generated = { const GENERATED = {
beginAgents: (agentNames, { beginAgents: (agentNames, {
mode = jasmine.anything(), mode = jasmine.anything(),
} = {}) => { } = {}) => {
@ -99,7 +99,7 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
right = jasmine.anything(), right = jasmine.anything(),
} = {}) => { } = {}) => {
return { return {
type: 'connection', type: 'connect',
agentNames, agentNames,
label, label,
options: { options: {
@ -169,9 +169,9 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('returns aggregated agents', () => { it('returns aggregated agents', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.connect(['C', 'D']), PARSED.connect(['C', 'D']),
parsed.beginAgents(['E']), PARSED.beginAgents(['E']),
]}); ]});
expect(sequence.agents).toEqual([ expect(sequence.agents).toEqual([
{name: '[', anchorRight: true}, {name: '[', anchorRight: true},
@ -186,7 +186,7 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('always puts the implicit right agent on the right', () => { it('always puts the implicit right agent on the right', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.connect([']', 'B']), PARSED.connect([']', 'B']),
]}); ]});
expect(sequence.agents).toEqual([ expect(sequence.agents).toEqual([
{name: '[', anchorRight: true}, {name: '[', anchorRight: true},
@ -197,8 +197,8 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('accounts for define calls when ordering agents', () => { it('accounts for define calls when ordering agents', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.defineAgents(['B']), PARSED.defineAgents(['B']),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
]}); ]});
expect(sequence.agents).toEqual([ expect(sequence.agents).toEqual([
{name: '[', anchorRight: true}, {name: '[', anchorRight: true},
@ -210,32 +210,32 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('creates implicit begin stages for agents when used', () => { it('creates implicit begin stages for agents when used', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.connect(['B', 'C']), PARSED.connect(['B', 'C']),
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
generated.beginAgents(['A', 'B']), GENERATED.beginAgents(['A', 'B']),
jasmine.anything(), jasmine.anything(),
generated.beginAgents(['C']), GENERATED.beginAgents(['C']),
jasmine.anything(), jasmine.anything(),
jasmine.anything(), jasmine.anything(),
]); ]);
}); });
it('passes connections through', () => { it('passes connects through', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
jasmine.anything(), jasmine.anything(),
generated.connect(['A', 'B']), GENERATED.connect(['A', 'B']),
jasmine.anything(), jasmine.anything(),
]); ]);
}); });
it('propagates connection information', () => { it('propagates connect information', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.connect(['A', 'B'], { PARSED.connect(['A', 'B'], {
label: 'foo', label: 'foo',
line: 'bar', line: 'bar',
left: true, left: true,
@ -244,7 +244,7 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
jasmine.anything(), jasmine.anything(),
generated.connect(['A', 'B'], { GENERATED.connect(['A', 'B'], {
label: 'foo', label: 'foo',
line: 'bar', line: 'bar',
left: true, left: true,
@ -260,65 +260,65 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
terminators: 'foo', terminators: 'foo',
}, },
stages: [ stages: [
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
], ],
}); });
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
jasmine.anything(), jasmine.anything(),
jasmine.anything(), jasmine.anything(),
generated.endAgents(['A', 'B'], {mode: 'foo'}), GENERATED.endAgents(['A', 'B'], {mode: 'foo'}),
]); ]);
}); });
it('defaults to mode "none" for implicit end stages', () => { it('defaults to mode "none" for implicit end stages', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
jasmine.anything(), jasmine.anything(),
jasmine.anything(), jasmine.anything(),
generated.endAgents(['A', 'B'], {mode: 'none'}), GENERATED.endAgents(['A', 'B'], {mode: 'none'}),
]); ]);
}); });
it('defaults to mode "cross" for explicit end stages', () => { it('defaults to mode "cross" for explicit end stages', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.endAgents(['A', 'B']), PARSED.endAgents(['A', 'B']),
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
jasmine.anything(), jasmine.anything(),
jasmine.anything(), jasmine.anything(),
generated.endAgents(['A', 'B'], {mode: 'cross'}), GENERATED.endAgents(['A', 'B'], {mode: 'cross'}),
]); ]);
}); });
it('does not create duplicate begin stages', () => { it('does not create duplicate begin stages', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.beginAgents(['A', 'B', 'C']), PARSED.beginAgents(['A', 'B', 'C']),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.connect(['B', 'C']), PARSED.connect(['B', 'C']),
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
generated.beginAgents(['A', 'B', 'C']), GENERATED.beginAgents(['A', 'B', 'C']),
generated.connect(jasmine.anything()), GENERATED.connect(jasmine.anything()),
generated.connect(jasmine.anything()), GENERATED.connect(jasmine.anything()),
generated.endAgents(['A', 'B', 'C']), GENERATED.endAgents(['A', 'B', 'C']),
]); ]);
}); });
it('redisplays agents if they have been hidden', () => { it('redisplays agents if they have been hidden', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.beginAgents(['A', 'B']), PARSED.beginAgents(['A', 'B']),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.endAgents(['B']), PARSED.endAgents(['B']),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
jasmine.anything(), jasmine.anything(),
jasmine.anything(), jasmine.anything(),
generated.endAgents(['B']), GENERATED.endAgents(['B']),
generated.beginAgents(['B']), GENERATED.beginAgents(['B']),
jasmine.anything(), jasmine.anything(),
jasmine.anything(), jasmine.anything(),
]); ]);
@ -326,69 +326,69 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('collapses adjacent begin statements', () => { it('collapses adjacent begin statements', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.beginAgents(['D']), PARSED.beginAgents(['D']),
parsed.connect(['B', 'C']), PARSED.connect(['B', 'C']),
parsed.connect(['C', 'D']), PARSED.connect(['C', 'D']),
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
generated.beginAgents(['A', 'B']), GENERATED.beginAgents(['A', 'B']),
generated.connect(jasmine.anything()), GENERATED.connect(jasmine.anything()),
generated.beginAgents(['D', 'C']), GENERATED.beginAgents(['D', 'C']),
generated.connect(jasmine.anything()), GENERATED.connect(jasmine.anything()),
generated.connect(jasmine.anything()), GENERATED.connect(jasmine.anything()),
jasmine.anything(), jasmine.anything(),
]); ]);
}); });
it('removes superfluous begin statements', () => { it('removes superfluous begin statements', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.beginAgents(['A', 'C', 'D']), PARSED.beginAgents(['A', 'C', 'D']),
parsed.beginAgents(['C', 'E']), PARSED.beginAgents(['C', 'E']),
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
generated.beginAgents(['A', 'B']), GENERATED.beginAgents(['A', 'B']),
generated.connect(jasmine.anything()), GENERATED.connect(jasmine.anything()),
generated.beginAgents(['C', 'D', 'E']), GENERATED.beginAgents(['C', 'D', 'E']),
jasmine.anything(), jasmine.anything(),
]); ]);
}); });
it('removes superfluous end statements', () => { it('removes superfluous end statements', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.defineAgents(['E']), PARSED.defineAgents(['E']),
parsed.beginAgents(['C', 'D']), PARSED.beginAgents(['C', 'D']),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.endAgents(['A', 'B', 'C']), PARSED.endAgents(['A', 'B', 'C']),
parsed.endAgents(['A', 'D', 'E']), PARSED.endAgents(['A', 'D', 'E']),
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
jasmine.anything(), jasmine.anything(),
generated.connect(jasmine.anything()), GENERATED.connect(jasmine.anything()),
generated.endAgents(['A', 'B', 'C', 'D']), GENERATED.endAgents(['A', 'B', 'C', 'D']),
]); ]);
}); });
it('does not merge different modes of end', () => { it('does not merge different modes of end', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.beginAgents(['C', 'D']), PARSED.beginAgents(['C', 'D']),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.endAgents(['A', 'B', 'C']), PARSED.endAgents(['A', 'B', 'C']),
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
jasmine.anything(), jasmine.anything(),
generated.connect(jasmine.anything()), GENERATED.connect(jasmine.anything()),
generated.endAgents(['A', 'B', 'C'], {mode: 'cross'}), GENERATED.endAgents(['A', 'B', 'C'], {mode: 'cross'}),
generated.endAgents(['D'], {mode: 'none'}), GENERATED.endAgents(['D'], {mode: 'none'}),
]); ]);
}); });
it('creates virtual agents for block statements', () => { it('creates virtual agents for block statements', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockEnd(), PARSED.blockEnd(),
]}); ]});
expect(sequence.agents).toEqual([ expect(sequence.agents).toEqual([
@ -403,14 +403,14 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('positions virtual block agents near involved agents', () => { it('positions virtual block agents near involved agents', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.connect(['C', 'D']), PARSED.connect(['C', 'D']),
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.connect(['E', 'F']), PARSED.connect(['E', 'F']),
parsed.blockEnd(), PARSED.blockEnd(),
parsed.blockEnd(), PARSED.blockEnd(),
parsed.connect(['G', 'H']), PARSED.connect(['G', 'H']),
]}); ]});
expect(sequence.agents).toEqual([ expect(sequence.agents).toEqual([
@ -433,9 +433,9 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('records virtual block agent names in blocks', () => { it('records virtual block agent names in blocks', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockEnd(), PARSED.blockEnd(),
]}); ]});
const block0 = sequence.stages[0]; const block0 = sequence.stages[0];
@ -446,35 +446,35 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('records all sections within blocks', () => { it('records all sections within blocks', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockSplit('else', 'xyz'), PARSED.blockSplit('else', 'xyz'),
parsed.connect(['A', 'C']), PARSED.connect(['A', 'C']),
parsed.blockEnd(), PARSED.blockEnd(),
]}); ]});
const block0 = sequence.stages[0]; const block0 = sequence.stages[0];
expect(block0.sections).toEqual([ expect(block0.sections).toEqual([
{mode: 'if', label: 'abc', stages: [ {mode: 'if', label: 'abc', stages: [
generated.beginAgents(['A', 'B']), GENERATED.beginAgents(['A', 'B']),
generated.connect(['A', 'B']), GENERATED.connect(['A', 'B']),
]}, ]},
{mode: 'else', label: 'xyz', stages: [ {mode: 'else', label: 'xyz', stages: [
generated.beginAgents(['C']), GENERATED.beginAgents(['C']),
generated.connect(['A', 'C']), GENERATED.connect(['A', 'C']),
]}, ]},
]); ]);
}); });
it('records virtual block agents in nested blocks', () => { it('records virtual block agents in nested blocks', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockSplit('else', 'xyz'), PARSED.blockSplit('else', 'xyz'),
parsed.blockBegin('if', 'def'), PARSED.blockBegin('if', 'def'),
parsed.connect(['A', 'C']), PARSED.connect(['A', 'C']),
parsed.blockEnd(), PARSED.blockEnd(),
parsed.blockEnd(), PARSED.blockEnd(),
]}); ]});
expect(sequence.agents).toEqual([ expect(sequence.agents).toEqual([
@ -501,12 +501,12 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('preserves block boundaries when agents exist outside', () => { it('preserves block boundaries when agents exist outside', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.blockBegin('if', 'def'), PARSED.blockBegin('if', 'def'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockEnd(), PARSED.blockEnd(),
parsed.blockEnd(), PARSED.blockEnd(),
]}); ]});
expect(sequence.agents).toEqual([ expect(sequence.agents).toEqual([
@ -532,10 +532,10 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('allows empty block parts after split', () => { it('allows empty block parts after split', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockSplit('else', 'xyz'), PARSED.blockSplit('else', 'xyz'),
parsed.blockEnd(), PARSED.blockEnd(),
]}); ]});
const block0 = sequence.stages[0]; const block0 = sequence.stages[0];
@ -550,10 +550,10 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('allows empty block parts before split', () => { it('allows empty block parts before split', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.blockSplit('else', 'xyz'), PARSED.blockSplit('else', 'xyz'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockEnd(), PARSED.blockEnd(),
]}); ]});
const block0 = sequence.stages[0]; const block0 = sequence.stages[0];
@ -568,11 +568,11 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('removes entirely empty blocks', () => { it('removes entirely empty blocks', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.blockSplit('else', 'xyz'), PARSED.blockSplit('else', 'xyz'),
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.blockEnd(), PARSED.blockEnd(),
parsed.blockEnd(), PARSED.blockEnd(),
]}); ]});
expect(sequence.stages).toEqual([]); expect(sequence.stages).toEqual([]);
@ -580,10 +580,10 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('removes blocks containing only define statements / markers', () => { it('removes blocks containing only define statements / markers', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.defineAgents(['A']), PARSED.defineAgents(['A']),
{type: 'mark', name: 'foo'}, {type: 'mark', name: 'foo'},
parsed.blockEnd(), PARSED.blockEnd(),
]}); ]});
expect(sequence.stages).toEqual([]); expect(sequence.stages).toEqual([]);
@ -591,11 +591,11 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('does not create virtual agents for empty blocks', () => { it('does not create virtual agents for empty blocks', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.blockSplit('else', 'xyz'), PARSED.blockSplit('else', 'xyz'),
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.blockEnd(), PARSED.blockEnd(),
parsed.blockEnd(), PARSED.blockEnd(),
]}); ]});
expect(sequence.agents).toEqual([ expect(sequence.agents).toEqual([
@ -606,12 +606,12 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('removes entirely empty nested blocks', () => { it('removes entirely empty nested blocks', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockSplit('else', 'xyz'), PARSED.blockSplit('else', 'xyz'),
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.blockEnd(), PARSED.blockEnd(),
parsed.blockEnd(), PARSED.blockEnd(),
]}); ]});
const block0 = sequence.stages[0]; const block0 = sequence.stages[0];
@ -626,56 +626,56 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('rejects unterminated blocks', () => { it('rejects unterminated blocks', () => {
expect(() => generator.generate({stages: [ expect(() => generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
]})).toThrow(); ]})).toThrow();
expect(() => generator.generate({stages: [ expect(() => generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.blockBegin('if', 'def'), PARSED.blockBegin('if', 'def'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockEnd(), PARSED.blockEnd(),
]})).toThrow(); ]})).toThrow();
}); });
it('rejects extra block terminations', () => { it('rejects extra block terminations', () => {
expect(() => generator.generate({stages: [ expect(() => generator.generate({stages: [
parsed.blockEnd(), PARSED.blockEnd(),
]})).toThrow(); ]})).toThrow();
expect(() => generator.generate({stages: [ expect(() => generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockEnd(), PARSED.blockEnd(),
parsed.blockEnd(), PARSED.blockEnd(),
]})).toThrow(); ]})).toThrow();
}); });
it('rejects block splitting without a block', () => { it('rejects block splitting without a block', () => {
expect(() => generator.generate({stages: [ expect(() => generator.generate({stages: [
parsed.blockSplit('else', 'xyz'), PARSED.blockSplit('else', 'xyz'),
]})).toThrow(); ]})).toThrow();
expect(() => generator.generate({stages: [ expect(() => generator.generate({stages: [
parsed.blockBegin('if', 'abc'), PARSED.blockBegin('if', 'abc'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockEnd(), PARSED.blockEnd(),
parsed.blockSplit('else', 'xyz'), PARSED.blockSplit('else', 'xyz'),
]})).toThrow(); ]})).toThrow();
}); });
it('rejects block splitting in non-splittable blocks', () => { it('rejects block splitting in non-splittable blocks', () => {
expect(() => generator.generate({stages: [ expect(() => generator.generate({stages: [
parsed.blockBegin('repeat', 'abc'), PARSED.blockBegin('repeat', 'abc'),
parsed.blockSplit('else', 'xyz'), PARSED.blockSplit('else', 'xyz'),
parsed.connect(['A', 'B']), PARSED.connect(['A', 'B']),
parsed.blockEnd(), PARSED.blockEnd(),
]})).toThrow(); ]})).toThrow();
}); });
it('passes notes through', () => { it('passes notes through', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.note(['A', 'B'], { PARSED.note(['A', 'B'], {
type: 'note right', type: 'note right',
mode: 'foo', mode: 'foo',
label: 'bar', label: 'bar',
@ -683,7 +683,7 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
jasmine.anything(), jasmine.anything(),
generated.note(['A', 'B'], { GENERATED.note(['A', 'B'], {
type: 'note right', type: 'note right',
mode: 'foo', mode: 'foo',
label: 'bar', label: 'bar',
@ -694,32 +694,32 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
it('defaults to showing notes around the entire diagram', () => { it('defaults to showing notes around the entire diagram', () => {
const sequence = generator.generate({stages: [ const sequence = generator.generate({stages: [
parsed.note([], {type: 'note right'}), PARSED.note([], {type: 'note right'}),
parsed.note([], {type: 'note left'}), PARSED.note([], {type: 'note left'}),
parsed.note([], {type: 'note over'}), PARSED.note([], {type: 'note over'}),
]}); ]});
expect(sequence.stages).toEqual([ expect(sequence.stages).toEqual([
generated.note([']'], {type: 'note right'}), GENERATED.note([']'], {type: 'note right'}),
generated.note(['['], {type: 'note left'}), GENERATED.note(['['], {type: 'note left'}),
generated.note(['[', ']'], {type: 'note over'}), GENERATED.note(['[', ']'], {type: 'note over'}),
]); ]);
}); });
it('rejects attempts to change implicit agents', () => { it('rejects attempts to change implicit agents', () => {
expect(() => generator.generate({stages: [ expect(() => generator.generate({stages: [
parsed.beginAgents(['[']), PARSED.beginAgents(['[']),
]})).toThrow(); ]})).toThrow();
expect(() => generator.generate({stages: [ expect(() => generator.generate({stages: [
parsed.beginAgents([']']), PARSED.beginAgents([']']),
]})).toThrow(); ]})).toThrow();
expect(() => generator.generate({stages: [ expect(() => generator.generate({stages: [
parsed.endAgents(['[']), PARSED.endAgents(['[']),
]})).toThrow(); ]})).toThrow();
expect(() => generator.generate({stages: [ expect(() => generator.generate({stages: [
parsed.endAgents([']']), PARSED.endAgents([']']),
]})).toThrow(); ]})).toThrow();
}); });
}); });

View File

@ -16,7 +16,7 @@ define([
'repeat': {type: 'block begin', mode: 'repeat', skip: []}, 'repeat': {type: 'block begin', mode: 'repeat', skip: []},
}; };
const CONNECTION_TYPES = { const CONNECT_TYPES = {
'->': {line: 'solid', left: false, right: true}, '->': {line: 'solid', left: false, right: true},
'<-': {line: 'solid', left: true, right: false}, '<-': {line: 'solid', left: true, right: false},
'<->': {line: 'solid', left: true, right: true}, '<->': {line: 'solid', left: true, right: true},
@ -25,7 +25,7 @@ define([
'<-->': {line: 'dash', left: true, right: true}, '<-->': {line: 'dash', left: true, right: true},
}; };
const AGENT_OPTIONS = { const CONNECT_AGENT_FLAGS = {
'+': 'start', '+': 'start',
'-': 'stop', '-': 'stop',
}; };
@ -112,50 +112,43 @@ define([
return -1; return -1;
} }
function parseAgentList(line, start, end) { function readAgent(line, start, end, flagTypes = {}) {
const list = []; const flags = [];
let current = ''; let p = start;
let first = true;
for(let i = start; i < end; ++ i) {
const token = line[i];
if(tokenKeyword(token) === ',') {
if(current) {
list.push({name: current});
current = '';
first = true;
}
} else {
if(!first) {
current += token.s;
} else {
first = false;
}
current += token.v;
}
}
if(current) {
list.push({name: current});
}
return list;
}
function readAgentDetails(line, begin, end) {
const options = [];
let p = begin;
for(; p < end; ++ p) { for(; p < end; ++ p) {
const option = AGENT_OPTIONS[tokenKeyword(line[p])]; const flag = flagTypes[tokenKeyword(line[p])];
if(option) { if(flag) {
options.push(option); flags.push(flag);
} else { } else {
break; break;
} }
} }
return { return {
agent: {name: joinLabel(line, p, end)}, name: joinLabel(line, p, end),
options, flags,
}; };
} }
function readAgentList(line, start, end, flagTypes) {
const list = [];
let currentStart = -1;
for(let i = start; i < end; ++ i) {
const token = line[i];
if(tokenKeyword(token) === ',') {
if(currentStart !== -1) {
list.push(readAgent(line, currentStart, i, flagTypes));
currentStart = -1;
}
} else if(currentStart === -1) {
currentStart = i;
}
}
if(currentStart !== -1) {
list.push(readAgent(line, currentStart, end, flagTypes));
}
return list;
}
const PARSERS = [ const PARSERS = [
(line, meta) => { // title (line, meta) => { // title
if(tokenKeyword(line[0]) !== 'title') { if(tokenKeyword(line[0]) !== 'title') {
@ -206,7 +199,7 @@ define([
return null; return null;
} }
return Object.assign({ return Object.assign({
agents: parseAgentList(line, 1, line.length), agents: readAgentList(line, 1, line.length),
}, type); }, type);
}, },
@ -232,8 +225,8 @@ define([
(line) => { // note (line) => { // note
const mode = NOTE_TYPES[tokenKeyword(line[0])]; const mode = NOTE_TYPES[tokenKeyword(line[0])];
const labelSplit = findToken(line, ':'); const labelSep = findToken(line, ':');
if(!mode || labelSplit === -1) { if(!mode || labelSep === -1) {
return null; return null;
} }
const type = mode.types[tokenKeyword(line[1])]; const type = mode.types[tokenKeyword(line[1])];
@ -242,7 +235,7 @@ define([
} }
let skip = 2; let skip = 2;
skip = skipOver(line, skip, type.skip); skip = skipOver(line, skip, type.skip);
const agents = parseAgentList(line, skip, labelSplit); const agents = readAgentList(line, skip, labelSep);
if( if(
agents.length < type.min || agents.length < type.min ||
(type.max !== null && agents.length > type.max) (type.max !== null && agents.length > type.max)
@ -256,37 +249,35 @@ define([
type: type.type, type: type.type,
agents, agents,
mode: mode.mode, mode: mode.mode,
label: joinLabel(line, labelSplit + 1), label: joinLabel(line, labelSep + 1),
}; };
}, },
(line) => { // connection (line) => { // connect
let labelSplit = findToken(line, ':'); let labelSep = findToken(line, ':');
if(labelSplit === -1) { if(labelSep === -1) {
labelSplit = line.length; labelSep = line.length;
} }
let typeSplit = -1; let typePos = -1;
let options = null; let options = null;
for(let j = 0; j < line.length; ++ j) { for(let j = 0; j < line.length; ++ j) {
const opts = CONNECTION_TYPES[tokenKeyword(line[j])]; const opts = CONNECT_TYPES[tokenKeyword(line[j])];
if(opts) { if(opts) {
typeSplit = j; typePos = j;
options = opts; options = opts;
break; break;
} }
} }
if(typeSplit <= 0 || typeSplit >= labelSplit - 1) { if(typePos <= 0 || typePos >= labelSep - 1) {
return null; return null;
} }
const from = readAgentDetails(line, 0, typeSplit);
const to = readAgentDetails(line, typeSplit + 1, labelSplit);
return { return {
type: 'connection', type: 'connect',
agents: [ agents: [
from.agent, readAgent(line, 0, typePos, CONNECT_AGENT_FLAGS),
to.agent, readAgent(line, typePos + 1, labelSep, CONNECT_AGENT_FLAGS),
], ],
label: joinLabel(line, labelSplit + 1), label: joinLabel(line, labelSep + 1),
options, options,
}; };
}, },

View File

@ -4,15 +4,15 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
const parser = new Parser(); const parser = new Parser();
const PARSED = { const PARSED = {
connection: (agentNames, { connect: (agentNames, {
line = jasmine.anything(), line = jasmine.anything(),
left = jasmine.anything(), left = jasmine.anything(),
right = jasmine.anything(), right = jasmine.anything(),
label = jasmine.anything(), label = jasmine.anything(),
} = {}) => { } = {}) => {
return { return {
type: 'connection', type: 'connect',
agents: agentNames.map((name) => ({name})), agents: agentNames.map((name) => ({name, flags: []})),
label, label,
options: { options: {
line, line,
@ -53,44 +53,59 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
it('converts entries into abstract form', () => { it('converts entries into abstract form', () => {
const parsed = parser.parse('A -> B'); const parsed = parser.parse('A -> B');
expect(parsed.stages).toEqual([ expect(parsed.stages).toEqual([
PARSED.connection(['A', 'B']), PARSED.connect(['A', 'B']),
]); ]);
}); });
it('combines multiple tokens into single entries', () => { it('combines multiple tokens into single entries', () => {
const parsed = parser.parse('A B -> C D'); const parsed = parser.parse('A B -> C D');
expect(parsed.stages).toEqual([ expect(parsed.stages).toEqual([
PARSED.connection(['A B', 'C D']), PARSED.connect(['A B', 'C D']),
]); ]);
}); });
it('respects spacing within agent names', () => { it('respects spacing within agent names', () => {
const parsed = parser.parse('A+B -> C D'); const parsed = parser.parse('A+B -> C D');
expect(parsed.stages).toEqual([ expect(parsed.stages).toEqual([
PARSED.connection(['A+B', 'C D']), PARSED.connect(['A+B', 'C D']),
]); ]);
}); });
it('parses optional labels', () => { it('parses optional labels', () => {
const parsed = parser.parse('A B -> C D: foo bar'); const parsed = parser.parse('A B -> C D: foo bar');
expect(parsed.stages).toEqual([ expect(parsed.stages).toEqual([
PARSED.connection(['A B', 'C D'], {label: 'foo bar'}), PARSED.connect(['A B', 'C D'], {label: 'foo bar'}),
]);
});
it('parses optional flags', () => {
const parsed = parser.parse('+A -> -B');
expect(parsed.stages).toEqual([
{
type: 'connect',
agents: [
{name: 'A', flags: ['start']},
{name: 'B', flags: ['stop']},
],
label: jasmine.anything(),
options: jasmine.anything(),
},
]); ]);
}); });
it('converts multiple entries', () => { it('converts multiple entries', () => {
const parsed = parser.parse('A -> B\nB -> A'); const parsed = parser.parse('A -> B\nB -> A');
expect(parsed.stages).toEqual([ expect(parsed.stages).toEqual([
PARSED.connection(['A', 'B']), PARSED.connect(['A', 'B']),
PARSED.connection(['B', 'A']), PARSED.connect(['B', 'A']),
]); ]);
}); });
it('ignores blank lines', () => { it('ignores blank lines', () => {
const parsed = parser.parse('A -> B\n\nB -> A\n'); const parsed = parser.parse('A -> B\n\nB -> A\n');
expect(parsed.stages).toEqual([ expect(parsed.stages).toEqual([
PARSED.connection(['A', 'B']), PARSED.connect(['A', 'B']),
PARSED.connection(['B', 'A']), PARSED.connect(['B', 'A']),
]); ]);
}); });
@ -104,37 +119,37 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
'A <--> B\n' 'A <--> B\n'
); );
expect(parsed.stages).toEqual([ expect(parsed.stages).toEqual([
PARSED.connection(['A', 'B'], { PARSED.connect(['A', 'B'], {
line: 'solid', line: 'solid',
left: false, left: false,
right: true, right: true,
label: '', label: '',
}), }),
PARSED.connection(['A', 'B'], { PARSED.connect(['A', 'B'], {
line: 'solid', line: 'solid',
left: true, left: true,
right: false, right: false,
label: '', label: '',
}), }),
PARSED.connection(['A', 'B'], { PARSED.connect(['A', 'B'], {
line: 'solid', line: 'solid',
left: true, left: true,
right: true, right: true,
label: '', label: '',
}), }),
PARSED.connection(['A', 'B'], { PARSED.connect(['A', 'B'], {
line: 'dash', line: 'dash',
left: false, left: false,
right: true, right: true,
label: '', label: '',
}), }),
PARSED.connection(['A', 'B'], { PARSED.connect(['A', 'B'], {
line: 'dash', line: 'dash',
left: true, left: true,
right: false, right: false,
label: '', label: '',
}), }),
PARSED.connection(['A', 'B'], { PARSED.connect(['A', 'B'], {
line: 'dash', line: 'dash',
left: true, left: true,
right: true, right: true,
@ -149,13 +164,13 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
'A -> B: B <- A\n' 'A -> B: B <- A\n'
); );
expect(parsed.stages).toEqual([ expect(parsed.stages).toEqual([
PARSED.connection(['A', 'B'], { PARSED.connect(['A', 'B'], {
line: 'solid', line: 'solid',
left: true, left: true,
right: false, right: false,
label: 'B -> A', label: 'B -> A',
}), }),
PARSED.connection(['A', 'B'], { PARSED.connect(['A', 'B'], {
line: 'solid', line: 'solid',
left: false, left: false,
right: true, right: true,
@ -168,7 +183,7 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
const parsed = parser.parse('note over A: hello there'); const parsed = parser.parse('note over A: hello there');
expect(parsed.stages).toEqual([{ expect(parsed.stages).toEqual([{
type: 'note over', type: 'note over',
agents: [{name: 'A'}], agents: [{name: 'A', flags: []}],
mode: 'note', mode: 'note',
label: 'hello there', label: 'hello there',
}]); }]);
@ -185,31 +200,31 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
expect(parsed.stages).toEqual([ expect(parsed.stages).toEqual([
{ {
type: 'note left', type: 'note left',
agents: [{name: 'A'}], agents: [{name: 'A', flags: []}],
mode: 'note', mode: 'note',
label: 'hello there', label: 'hello there',
}, },
{ {
type: 'note left', type: 'note left',
agents: [{name: 'A'}], agents: [{name: 'A', flags: []}],
mode: 'note', mode: 'note',
label: 'hello there', label: 'hello there',
}, },
{ {
type: 'note right', type: 'note right',
agents: [{name: 'A'}], agents: [{name: 'A', flags: []}],
mode: 'note', mode: 'note',
label: 'hello there', label: 'hello there',
}, },
{ {
type: 'note right', type: 'note right',
agents: [{name: 'A'}], agents: [{name: 'A', flags: []}],
mode: 'note', mode: 'note',
label: 'hello there', label: 'hello there',
}, },
{ {
type: 'note between', type: 'note between',
agents: [{name: 'A'}, {name: 'B'}], agents: [{name: 'A', flags: []}, {name: 'B', flags: []}],
mode: 'note', mode: 'note',
label: 'hi', label: 'hi',
}, },
@ -220,7 +235,7 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
const parsed = parser.parse('note over A B, C D: hi'); const parsed = parser.parse('note over A B, C D: hi');
expect(parsed.stages).toEqual([{ expect(parsed.stages).toEqual([{
type: 'note over', type: 'note over',
agents: [{name: 'A B'}, {name: 'C D'}], agents: [{name: 'A B', flags: []}, {name: 'C D', flags: []}],
mode: 'note', mode: 'note',
label: 'hi', label: 'hi',
}]); }]);
@ -234,7 +249,7 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
const parsed = parser.parse('state over A: doing stuff'); const parsed = parser.parse('state over A: doing stuff');
expect(parsed.stages).toEqual([{ expect(parsed.stages).toEqual([{
type: 'note over', type: 'note over',
agents: [{name: 'A'}], agents: [{name: 'A', flags: []}],
mode: 'state', mode: 'state',
label: 'doing stuff', label: 'doing stuff',
}]); }]);
@ -248,7 +263,7 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
const parsed = parser.parse('text right of A: doing stuff'); const parsed = parser.parse('text right of A: doing stuff');
expect(parsed.stages).toEqual([{ expect(parsed.stages).toEqual([{
type: 'note right', type: 'note right',
agents: [{name: 'A'}], agents: [{name: 'A', flags: []}],
mode: 'text', mode: 'text',
label: 'doing stuff', label: 'doing stuff',
}]); }]);
@ -263,16 +278,16 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
expect(parsed.stages).toEqual([ expect(parsed.stages).toEqual([
{ {
type: 'agent define', type: 'agent define',
agents: [{name: 'A'}, {name: 'B'}], agents: [{name: 'A', flags: []}, {name: 'B', flags: []}],
}, },
{ {
type: 'agent begin', type: 'agent begin',
agents: [{name: 'A'}, {name: 'B'}], agents: [{name: 'A', flags: []}, {name: 'B', flags: []}],
mode: 'box', mode: 'box',
}, },
{ {
type: 'agent end', type: 'agent end',
agents: [{name: 'A'}, {name: 'B'}], agents: [{name: 'A', flags: []}, {name: 'B', flags: []}],
mode: 'cross', mode: 'cross',
}, },
]); ]);
@ -315,12 +330,12 @@ defineDescribe('Sequence Parser', ['./Parser'], (Parser) => {
); );
expect(parsed.stages).toEqual([ expect(parsed.stages).toEqual([
{type: 'block begin', mode: 'if', label: 'something happens'}, {type: 'block begin', mode: 'if', label: 'something happens'},
PARSED.connection(['A', 'B']), PARSED.connect(['A', 'B']),
{type: 'block split', mode: 'else', label: 'something else'}, {type: 'block split', mode: 'else', label: 'something else'},
PARSED.connection(['A', 'C']), PARSED.connect(['A', 'C']),
PARSED.connection(['C', 'B']), PARSED.connect(['C', 'B']),
{type: 'block split', mode: 'else', label: ''}, {type: 'block split', mode: 'else', label: ''},
PARSED.connection(['A', 'D']), PARSED.connect(['A', 'D']),
{type: 'block end'}, {type: 'block end'},
]); ]);
}); });

View File

@ -67,7 +67,7 @@ define([
'async': this.separationAsync.bind(this), 'async': this.separationAsync.bind(this),
'agent begin': this.separationAgent.bind(this), 'agent begin': this.separationAgent.bind(this),
'agent end': this.separationAgent.bind(this), 'agent end': this.separationAgent.bind(this),
'connection': this.separationConnection.bind(this), 'connect': this.separationConnect.bind(this),
'note over': this.separationNoteOver.bind(this), 'note over': this.separationNoteOver.bind(this),
'note left': this.separationNoteSide.bind(this, false), 'note left': this.separationNoteSide.bind(this, false),
'note right': this.separationNoteSide.bind(this, true), 'note right': this.separationNoteSide.bind(this, true),
@ -86,7 +86,7 @@ define([
'async': this.renderAsync.bind(this), 'async': this.renderAsync.bind(this),
'agent begin': this.renderAgentBegin.bind(this), 'agent begin': this.renderAgentBegin.bind(this),
'agent end': this.renderAgentEnd.bind(this), 'agent end': this.renderAgentEnd.bind(this),
'connection': this.renderConnection.bind(this), 'connect': this.renderConnect.bind(this),
'note over': this.renderNoteOver.bind(this), 'note over': this.renderNoteOver.bind(this),
'note left': this.renderNoteLeft.bind(this), 'note left': this.renderNoteLeft.bind(this),
'note right': this.renderNoteRight.bind(this), 'note right': this.renderNoteRight.bind(this),
@ -263,7 +263,7 @@ define([
} }
} }
separationConnection({agentNames, label}) { separationConnect({agentNames, label}) {
const config = this.theme.connect; const config = this.theme.connect;
const labelWidth = ( const labelWidth = (
@ -528,7 +528,7 @@ define([
this.markAgentRange(agentNames); this.markAgentRange(agentNames);
} }
renderSelfConnection({label, agentNames, options}) { renderSelfConnect({label, agentNames, options}) {
const config = this.theme.connect; const config = this.theme.connect;
const from = this.agentInfos.get(agentNames[0]); const from = this.agentInfos.get(agentNames[0]);
@ -601,7 +601,7 @@ define([
this.currentY = y1 + dy + this.theme.actionMargin; this.currentY = y1 + dy + this.theme.actionMargin;
} }
renderSimpleConnection({label, agentNames, options}) { renderSimpleConnect({label, agentNames, options}) {
const config = this.theme.connect; const config = this.theme.connect;
const from = this.agentInfos.get(agentNames[0]); const from = this.agentInfos.get(agentNames[0]);
const to = this.agentInfos.get(agentNames[1]); const to = this.agentInfos.get(agentNames[1]);
@ -659,12 +659,12 @@ define([
this.currentY = y + dy + this.theme.actionMargin; this.currentY = y + dy + this.theme.actionMargin;
} }
renderConnection(stage) { renderConnect(stage) {
this.checkAgentRange(stage.agentNames); this.checkAgentRange(stage.agentNames);
if(stage.agentNames[0] === stage.agentNames[1]) { if(stage.agentNames[0] === stage.agentNames[1]) {
this.renderSelfConnection(stage); this.renderSelfConnect(stage);
} else { } else {
this.renderSimpleConnection(stage); this.renderSimpleConnect(stage);
} }
this.markAgentRange(stage.agentNames); this.markAgentRange(stage.agentNames);
} }

View File

@ -25,9 +25,10 @@ defineDescribe('Sequence Renderer', [
}); });
}); });
function connectionStage(agentNames, label = '') { const GENERATED = {
connect: (agentNames, label = '') => {
return { return {
type: 'connection', type: 'connect',
agentNames, agentNames,
label, label,
options: { options: {
@ -36,7 +37,8 @@ defineDescribe('Sequence Renderer', [
right: true, right: true,
}, },
}; };
} },
};
describe('.render', () => { describe('.render', () => {
it('populates the SVG with content', () => { it('populates the SVG with content', () => {
@ -70,7 +72,7 @@ defineDescribe('Sequence Renderer', [
], ],
stages: [ stages: [
{type: 'agent begin', agentNames: ['A', 'B'], mode: 'box'}, {type: 'agent begin', agentNames: ['A', 'B'], mode: 'box'},
connectionStage(['A', 'B']), GENERATED.connect(['A', 'B']),
{type: 'agent end', agentNames: ['A', 'B'], mode: 'none'}, {type: 'agent end', agentNames: ['A', 'B'], mode: 'none'},
], ],
}); });
@ -105,10 +107,10 @@ defineDescribe('Sequence Renderer', [
agentNames: ['A', 'B', 'C'], agentNames: ['A', 'B', 'C'],
mode: 'box', mode: 'box',
}, },
connectionStage(['[', 'A']), GENERATED.connect(['[', 'A']),
connectionStage(['A', 'B']), GENERATED.connect(['A', 'B']),
connectionStage(['B', 'C']), GENERATED.connect(['B', 'C']),
connectionStage(['C', ']']), GENERATED.connect(['C', ']']),
{ {
type: 'agent end', type: 'agent end',
agentNames: ['A', 'B', 'C'], agentNames: ['A', 'B', 'C'],
@ -151,13 +153,13 @@ defineDescribe('Sequence Renderer', [
], ],
stages: [ stages: [
{type: 'agent begin', agentNames: ['A', 'B'], mode: 'box'}, {type: 'agent begin', agentNames: ['A', 'B'], mode: 'box'},
connectionStage(['A', 'B'], 'short'), GENERATED.connect(['A', 'B'], 'short'),
{type: 'agent end', agentNames: ['B'], mode: 'cross'}, {type: 'agent end', agentNames: ['B'], mode: 'cross'},
{type: 'agent begin', agentNames: ['C'], mode: 'box'}, {type: 'agent begin', agentNames: ['C'], mode: 'box'},
connectionStage(['A', 'C'], 'long description here'), GENERATED.connect(['A', 'C'], 'long description here'),
{type: 'agent end', agentNames: ['C'], mode: 'cross'}, {type: 'agent end', agentNames: ['C'], mode: 'cross'},
{type: 'agent begin', agentNames: ['D'], mode: 'box'}, {type: 'agent begin', agentNames: ['D'], mode: 'box'},
connectionStage(['A', 'D'], 'short again'), GENERATED.connect(['A', 'D'], 'short again'),
{type: 'agent end', agentNames: ['A', 'D'], mode: 'cross'}, {type: 'agent end', agentNames: ['A', 'D'], mode: 'cross'},
], ],
}); });