Add virtual side agents for blocks, simplify generator logic
This commit is contained in:
parent
1449d73194
commit
8cbdddec20
|
@ -17,103 +17,74 @@ define(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return class Generator {
|
return class Generator {
|
||||||
findAgents(stages) {
|
constructor() {
|
||||||
const agents = ['['];
|
this.agentStates = new Map();
|
||||||
stages.forEach((stage) => {
|
this.blockCount = 0;
|
||||||
if(stage.agents) {
|
this.nesting = [];
|
||||||
mergeSets(agents, stage.agents);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(agents.indexOf(']') !== -1) {
|
this.stageHandlers = {
|
||||||
agents.splice(agents.indexOf(']'), 1);
|
'agent define': this.handleAgentDefine.bind(this),
|
||||||
}
|
'agent begin': this.handleAgentBegin.bind(this),
|
||||||
agents.push(']');
|
'agent end': this.handleAgentEnd.bind(this),
|
||||||
|
'block begin': this.handleBlockBegin.bind(this),
|
||||||
return agents;
|
'block split': this.handleBlockSplit.bind(this),
|
||||||
}
|
'block end': this.handleBlockEnd.bind(this),
|
||||||
|
|
||||||
generate({meta = {}, stages}) {
|
|
||||||
const agents = this.findAgents(stages);
|
|
||||||
|
|
||||||
const agentStates = new Map();
|
|
||||||
agents.forEach((agent) => {
|
|
||||||
agentStates.set(agent, {visible: false, locked: false});
|
|
||||||
});
|
|
||||||
agentStates.get('[').locked = true;
|
|
||||||
agentStates.get(']').locked = true;
|
|
||||||
|
|
||||||
const rootStages = [];
|
|
||||||
let currentSection = {
|
|
||||||
mode: 'global',
|
|
||||||
label: '',
|
|
||||||
stages: rootStages,
|
|
||||||
};
|
};
|
||||||
let currentNest = {
|
this.handleStage = this.handleStage.bind(this);
|
||||||
type: 'block',
|
|
||||||
agents: [],
|
|
||||||
root: true,
|
|
||||||
sections: [currentSection],
|
|
||||||
};
|
|
||||||
const nesting = [currentNest];
|
|
||||||
|
|
||||||
function beginNested(stage) {
|
|
||||||
currentSection = {
|
|
||||||
mode: stage.mode,
|
|
||||||
label: stage.label,
|
|
||||||
stages: [],
|
|
||||||
};
|
|
||||||
currentNest = {
|
|
||||||
type: 'block',
|
|
||||||
agents: [],
|
|
||||||
sections: [currentSection],
|
|
||||||
};
|
|
||||||
nesting.push(currentNest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function splitNested(stage) {
|
addStage(stage) {
|
||||||
if(currentNest.sections[0].mode !== 'if') {
|
this.currentSection.stages.push(stage);
|
||||||
throw new Error('Invalid block nesting');
|
mergeSets(this.currentNest.agents, stage.agents);
|
||||||
}
|
|
||||||
currentSection = {
|
|
||||||
mode: stage.mode,
|
|
||||||
label: stage.label,
|
|
||||||
stages: [],
|
|
||||||
};
|
|
||||||
currentNest.sections.push(currentSection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStage(stage) {
|
addColumnBounds(target, agentL, agentR, involvedAgents = []) {
|
||||||
currentSection.stages.push(stage);
|
const oldL = target.indexOf(agentL);
|
||||||
mergeSets(currentNest.agents, stage.agents);
|
if(oldL !== -1) {
|
||||||
|
target.splice(oldL, 1);
|
||||||
|
}
|
||||||
|
const oldR = target.indexOf(agentR);
|
||||||
|
if(oldR !== -1) {
|
||||||
|
target.splice(oldR, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function endNested() {
|
let indexL = 0;
|
||||||
if(currentNest.root) {
|
let indexR = target.length;
|
||||||
throw new Error('Invalid block nesting');
|
if(involvedAgents.length > 0) {
|
||||||
}
|
const found = (involvedAgents
|
||||||
const subNest = nesting.pop();
|
.map((agent) => target.indexOf(agent))
|
||||||
currentNest = lastElement(nesting);
|
.filter((p) => (p !== -1))
|
||||||
currentSection = lastElement(currentNest.sections);
|
);
|
||||||
if(subNest.agents.length > 0) {
|
indexL = found.reduce((a, b) => Math.min(a, b), target.length);
|
||||||
addStage(subNest);
|
indexR = found.reduce((a, b) => Math.max(a, b), indexL) + 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addAgentMod(stageAgents, markVisible, mode) {
|
target.splice(indexL, 0, agentL);
|
||||||
|
target.splice(indexR + 1, 0, agentR);
|
||||||
|
}
|
||||||
|
|
||||||
|
addAgentMod(stageAgents, markVisible, mode) {
|
||||||
if(stageAgents.length === 0) {
|
if(stageAgents.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stageAgents.forEach((agent) => {
|
stageAgents.forEach((agent) => {
|
||||||
agentStates.get(agent).visible = markVisible;
|
const state = this.agentStates.get(agent);
|
||||||
|
if(state) {
|
||||||
|
state.visible = markVisible;
|
||||||
|
} else {
|
||||||
|
this.agentStates.set(agent, {
|
||||||
|
visible: markVisible,
|
||||||
|
locked: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
const type = (markVisible ? 'agent begin' : 'agent end');
|
const type = (markVisible ? 'agent begin' : 'agent end');
|
||||||
const existing = lastElement(currentSection.stages) || {};
|
const existing = lastElement(this.currentSection.stages) || {};
|
||||||
if(existing.type === type && existing.mode === mode) {
|
if(existing.type === type && existing.mode === mode) {
|
||||||
mergeSets(existing.agents, stageAgents);
|
mergeSets(existing.agents, stageAgents);
|
||||||
mergeSets(currentNest.agents, stageAgents);
|
mergeSets(this.currentNest.agents, stageAgents);
|
||||||
} else {
|
} else {
|
||||||
addStage({
|
this.addStage({
|
||||||
type,
|
type,
|
||||||
agents: stageAgents,
|
agents: stageAgents,
|
||||||
mode,
|
mode,
|
||||||
|
@ -121,10 +92,12 @@ define(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterVis(stageAgents, visible, implicit = false) {
|
filterVis(stageAgents, visible, implicit = false) {
|
||||||
return stageAgents.filter((agent) => {
|
return stageAgents.filter((agent) => {
|
||||||
const state = agentStates.get(agent);
|
const state = this.agentStates.get(agent);
|
||||||
if(!state.locked) {
|
if(!state) {
|
||||||
|
return !visible;
|
||||||
|
} else if(!state.locked) {
|
||||||
return state.visible === visible;
|
return state.visible === visible;
|
||||||
} else if(!implicit) {
|
} else if(!implicit) {
|
||||||
throw new Error('Cannot modify agent ' + agent);
|
throw new Error('Cannot modify agent ' + agent);
|
||||||
|
@ -134,61 +107,128 @@ define(() => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
stages.forEach((stage) => {
|
beginNested(mode, label, name) {
|
||||||
/* jshint -W074 */ // It's only a switch statement
|
const agents = [];
|
||||||
switch(stage.type) {
|
const stages = [];
|
||||||
case 'agent define':
|
this.currentSection = {
|
||||||
break;
|
mode,
|
||||||
case 'agent begin':
|
label,
|
||||||
addAgentMod(
|
stages,
|
||||||
filterVis(stage.agents, false),
|
};
|
||||||
true,
|
this.currentNest = {
|
||||||
stage.mode
|
type: 'block',
|
||||||
|
agents,
|
||||||
|
sections: [this.currentSection],
|
||||||
|
leftColumn: name + '[',
|
||||||
|
rightColumn: name + ']',
|
||||||
|
};
|
||||||
|
this.agentStates.set(name + '[', {visible: false, locked: true});
|
||||||
|
this.agentStates.set(name + ']', {visible: false, locked: true});
|
||||||
|
this.nesting.push(this.currentNest);
|
||||||
|
|
||||||
|
return {agents, stages};
|
||||||
|
}
|
||||||
|
|
||||||
|
handleAgentDefine() {
|
||||||
|
}
|
||||||
|
|
||||||
|
handleAgentBegin({agents, mode}) {
|
||||||
|
this.addAgentMod(this.filterVis(agents, false), true, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleAgentEnd({agents, mode}) {
|
||||||
|
this.addAgentMod(this.filterVis(agents, true), false, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBlockBegin({mode, label}) {
|
||||||
|
const name = '__BLOCK' + this.blockCount;
|
||||||
|
this.beginNested(mode, label, name);
|
||||||
|
++ this.blockCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBlockSplit({mode, label}) {
|
||||||
|
if(this.currentNest.sections[0].mode !== 'if') {
|
||||||
|
throw new Error('Invalid block nesting');
|
||||||
|
}
|
||||||
|
this.currentSection = {
|
||||||
|
mode,
|
||||||
|
label,
|
||||||
|
stages: [],
|
||||||
|
};
|
||||||
|
this.currentNest.sections.push(this.currentSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBlockEnd() {
|
||||||
|
if(this.nesting.length <= 1) {
|
||||||
|
throw new Error('Invalid block nesting');
|
||||||
|
}
|
||||||
|
const subNest = this.nesting.pop();
|
||||||
|
this.currentNest = lastElement(this.nesting);
|
||||||
|
this.currentSection = lastElement(this.currentNest.sections);
|
||||||
|
if(subNest.agents.length > 0) {
|
||||||
|
this.addStage(subNest);
|
||||||
|
this.addColumnBounds(
|
||||||
|
this.currentNest.agents,
|
||||||
|
subNest.leftColumn,
|
||||||
|
subNest.rightColumn,
|
||||||
|
subNest.agents
|
||||||
);
|
);
|
||||||
break;
|
this.addColumnBounds(
|
||||||
case 'agent end':
|
subNest.agents,
|
||||||
addAgentMod(
|
subNest.leftColumn,
|
||||||
filterVis(stage.agents, true),
|
subNest.rightColumn
|
||||||
false,
|
|
||||||
stage.mode
|
|
||||||
);
|
);
|
||||||
break;
|
}
|
||||||
case 'block begin':
|
}
|
||||||
beginNested(stage);
|
|
||||||
break;
|
handleUnknownStage(stage) {
|
||||||
case 'block split':
|
this.addAgentMod(
|
||||||
splitNested(stage);
|
this.filterVis(stage.agents, false, true),
|
||||||
break;
|
|
||||||
case 'block end':
|
|
||||||
endNested(stage);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
addAgentMod(
|
|
||||||
filterVis(stage.agents, false, true),
|
|
||||||
true,
|
true,
|
||||||
'box'
|
'box'
|
||||||
);
|
);
|
||||||
addStage(stage);
|
this.addStage(stage);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if(nesting.length !== 1) {
|
handleStage(stage) {
|
||||||
|
const handler = this.stageHandlers[stage.type];
|
||||||
|
if(handler) {
|
||||||
|
handler(stage);
|
||||||
|
} else {
|
||||||
|
this.handleUnknownStage(stage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
generate({stages, meta = {}}) {
|
||||||
|
this.agentStates.clear();
|
||||||
|
this.blockCount = 0;
|
||||||
|
this.nesting.length = 0;
|
||||||
|
const globals = this.beginNested('global', '', '');
|
||||||
|
|
||||||
|
stages.forEach(this.handleStage);
|
||||||
|
|
||||||
|
if(this.nesting.length !== 1) {
|
||||||
throw new Error('Invalid block nesting');
|
throw new Error('Invalid block nesting');
|
||||||
}
|
}
|
||||||
|
|
||||||
addAgentMod(
|
this.addAgentMod(
|
||||||
filterVis(agents, true, true),
|
this.filterVis(globals.agents, true, true),
|
||||||
false,
|
false,
|
||||||
meta.terminators || 'none'
|
meta.terminators || 'none'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.addColumnBounds(
|
||||||
|
globals.agents,
|
||||||
|
this.currentNest.leftColumn,
|
||||||
|
this.currentNest.rightColumn
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
meta: {
|
meta: {
|
||||||
title: meta.title,
|
title: meta.title,
|
||||||
},
|
},
|
||||||
agents,
|
agents: globals.agents,
|
||||||
stages: rootStages,
|
stages: globals.stages,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -162,7 +162,6 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
|
||||||
|
|
||||||
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: [
|
||||||
{type: AGENT_DEFINE, agents: ['E']},
|
|
||||||
{type: AGENT_BEGIN, agents: ['C', 'D'], mode: 'box'},
|
{type: AGENT_BEGIN, agents: ['C', 'D'], mode: 'box'},
|
||||||
{type: '->', agents: ['A', 'B']},
|
{type: '->', agents: ['A', 'B']},
|
||||||
{type: AGENT_END, agents: ['A', 'B', 'C'], mode: 'cross'},
|
{type: AGENT_END, agents: ['A', 'B', 'C'], mode: 'cross'},
|
||||||
|
@ -175,7 +174,62 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('records all involved agents in block begin statements', () => {
|
it('creates virtual agents for block statements', () => {
|
||||||
|
const sequence = generator.generate({stages: [
|
||||||
|
{type: BLOCK_BEGIN, mode: 'if', label: 'abc'},
|
||||||
|
{type: '->', agents: ['A', 'B']},
|
||||||
|
{type: BLOCK_END},
|
||||||
|
]});
|
||||||
|
|
||||||
|
expect(sequence.agents).toEqual(
|
||||||
|
['[', '__BLOCK0[', 'A', 'B', '__BLOCK0]', ']']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('positions virtual block agents near involved agents', () => {
|
||||||
|
const sequence = generator.generate({stages: [
|
||||||
|
{type: '->', agents: ['A', 'B']},
|
||||||
|
{type: BLOCK_BEGIN, mode: 'if', label: 'abc'},
|
||||||
|
{type: '->', agents: ['C', 'D']},
|
||||||
|
{type: BLOCK_BEGIN, mode: 'if', label: 'abc'},
|
||||||
|
{type: '->', agents: ['E', 'F']},
|
||||||
|
{type: BLOCK_END},
|
||||||
|
{type: BLOCK_END},
|
||||||
|
{type: '->', agents: ['G', 'H']},
|
||||||
|
]});
|
||||||
|
|
||||||
|
expect(sequence.agents).toEqual([
|
||||||
|
'[',
|
||||||
|
'A',
|
||||||
|
'B',
|
||||||
|
'__BLOCK0[',
|
||||||
|
'C',
|
||||||
|
'D',
|
||||||
|
'__BLOCK1[',
|
||||||
|
'E',
|
||||||
|
'F',
|
||||||
|
'__BLOCK1]',
|
||||||
|
'__BLOCK0]',
|
||||||
|
'G',
|
||||||
|
'H',
|
||||||
|
']',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('records virtual block column names in blocks', () => {
|
||||||
|
const sequence = generator.generate({stages: [
|
||||||
|
{type: BLOCK_BEGIN, mode: 'if', label: 'abc'},
|
||||||
|
{type: '->', agents: ['A', 'B']},
|
||||||
|
{type: BLOCK_END},
|
||||||
|
]});
|
||||||
|
|
||||||
|
const block0 = sequence.stages[0];
|
||||||
|
expect(block0.type).toEqual('block');
|
||||||
|
expect(block0.leftColumn).toEqual('__BLOCK0[');
|
||||||
|
expect(block0.rightColumn).toEqual('__BLOCK0]');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('records all involved agents in blocks', () => {
|
||||||
const sequence = generator.generate({stages: [
|
const sequence = generator.generate({stages: [
|
||||||
{type: BLOCK_BEGIN, mode: 'if', label: 'abc'},
|
{type: BLOCK_BEGIN, mode: 'if', label: 'abc'},
|
||||||
{type: '->', agents: ['A', 'B']},
|
{type: '->', agents: ['A', 'B']},
|
||||||
|
@ -184,8 +238,23 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
|
||||||
{type: BLOCK_END},
|
{type: BLOCK_END},
|
||||||
]});
|
]});
|
||||||
|
|
||||||
expect(sequence.stages).toEqual([
|
const block0 = sequence.stages[0];
|
||||||
{type: 'block', agents: ['A', 'B', 'C'], sections: [
|
expect(block0.agents).toEqual(
|
||||||
|
['__BLOCK0[', 'A', 'B', 'C', '__BLOCK0]']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('records all sections within blocks', () => {
|
||||||
|
const sequence = generator.generate({stages: [
|
||||||
|
{type: BLOCK_BEGIN, mode: 'if', label: 'abc'},
|
||||||
|
{type: '->', agents: ['A', 'B']},
|
||||||
|
{type: BLOCK_SPLIT, mode: 'else', label: 'xyz'},
|
||||||
|
{type: '->', agents: ['A', 'C']},
|
||||||
|
{type: BLOCK_END},
|
||||||
|
]});
|
||||||
|
|
||||||
|
const block0 = sequence.stages[0];
|
||||||
|
expect(block0.sections).toEqual([
|
||||||
{mode: 'if', label: 'abc', stages: [
|
{mode: 'if', label: 'abc', stages: [
|
||||||
{type: AGENT_BEGIN, agents: ['A', 'B'], mode: 'box'},
|
{type: AGENT_BEGIN, agents: ['A', 'B'], mode: 'box'},
|
||||||
{type: '->', agents: ['A', 'B']},
|
{type: '->', agents: ['A', 'B']},
|
||||||
|
@ -194,8 +263,6 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
|
||||||
{type: AGENT_BEGIN, agents: ['C'], mode: 'box'},
|
{type: AGENT_BEGIN, agents: ['C'], mode: 'box'},
|
||||||
{type: '->', agents: ['A', 'C']},
|
{type: '->', agents: ['A', 'C']},
|
||||||
]},
|
]},
|
||||||
]},
|
|
||||||
{type: AGENT_END, agents: ['A', 'B', 'C'], mode: 'none'},
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -210,23 +277,30 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
|
||||||
{type: BLOCK_END},
|
{type: BLOCK_END},
|
||||||
]});
|
]});
|
||||||
|
|
||||||
expect(sequence.stages).toEqual([
|
const block0 = sequence.stages[0];
|
||||||
{type: 'block', agents: ['A', 'B', 'C'], sections: [
|
expect(block0.type).toEqual('block');
|
||||||
{mode: 'if', label: 'abc', stages: [
|
expect(block0.agents).toEqual([
|
||||||
{type: AGENT_BEGIN, agents: ['A', 'B'], mode: 'box'},
|
'__BLOCK0[',
|
||||||
{type: '->', agents: ['A', 'B']},
|
'__BLOCK1[',
|
||||||
]},
|
'A',
|
||||||
{mode: 'else', label: 'xyz', stages: [
|
'B',
|
||||||
{type: 'block', agents: ['C', 'A'], sections: [
|
'C',
|
||||||
{mode: 'if', label: 'def', stages: [
|
'__BLOCK1]',
|
||||||
{type: AGENT_BEGIN, agents: ['C'], mode: 'box'},
|
'__BLOCK0]',
|
||||||
{type: '->', agents: ['A', 'C']},
|
|
||||||
]},
|
|
||||||
]},
|
|
||||||
]},
|
|
||||||
]},
|
|
||||||
{type: AGENT_END, agents: ['A', 'B', 'C'], mode: 'none'},
|
|
||||||
]);
|
]);
|
||||||
|
expect(block0.leftColumn).toEqual('__BLOCK0[');
|
||||||
|
expect(block0.rightColumn).toEqual('__BLOCK0]');
|
||||||
|
|
||||||
|
const block1 = block0.sections[1].stages[0];
|
||||||
|
expect(block1.type).toEqual('block');
|
||||||
|
expect(block1.agents).toEqual([
|
||||||
|
'__BLOCK1[',
|
||||||
|
'C',
|
||||||
|
'A',
|
||||||
|
'__BLOCK1]',
|
||||||
|
]);
|
||||||
|
expect(block1.leftColumn).toEqual('__BLOCK1[');
|
||||||
|
expect(block1.rightColumn).toEqual('__BLOCK1]');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows empty block parts after split', () => {
|
it('allows empty block parts after split', () => {
|
||||||
|
@ -237,15 +311,13 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
|
||||||
{type: BLOCK_END},
|
{type: BLOCK_END},
|
||||||
]});
|
]});
|
||||||
|
|
||||||
expect(sequence.stages).toEqual([
|
const block0 = sequence.stages[0];
|
||||||
{type: 'block', agents: ['A', 'B'], sections: [
|
expect(block0.sections).toEqual([
|
||||||
{mode: 'if', label: 'abc', stages: [
|
{mode: 'if', label: 'abc', stages: [
|
||||||
{type: AGENT_BEGIN, agents: ['A', 'B'], mode: 'box'},
|
{type: AGENT_BEGIN, agents: ['A', 'B'], mode: 'box'},
|
||||||
{type: '->', agents: ['A', 'B']},
|
{type: '->', agents: ['A', 'B']},
|
||||||
]},
|
]},
|
||||||
{mode: 'else', label: 'xyz', stages: []},
|
{mode: 'else', label: 'xyz', stages: []},
|
||||||
]},
|
|
||||||
{type: AGENT_END, agents: ['A', 'B'], mode: 'none'},
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -257,15 +329,13 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
|
||||||
{type: BLOCK_END},
|
{type: BLOCK_END},
|
||||||
]});
|
]});
|
||||||
|
|
||||||
expect(sequence.stages).toEqual([
|
const block0 = sequence.stages[0];
|
||||||
{type: 'block', agents: ['A', 'B'], sections: [
|
expect(block0.sections).toEqual([
|
||||||
{mode: 'if', label: 'abc', stages: []},
|
{mode: 'if', label: 'abc', stages: []},
|
||||||
{mode: 'else', label: 'xyz', stages: [
|
{mode: 'else', label: 'xyz', stages: [
|
||||||
{type: AGENT_BEGIN, agents: ['A', 'B'], mode: 'box'},
|
{type: AGENT_BEGIN, agents: ['A', 'B'], mode: 'box'},
|
||||||
{type: '->', agents: ['A', 'B']},
|
{type: '->', agents: ['A', 'B']},
|
||||||
]},
|
]},
|
||||||
]},
|
|
||||||
{type: AGENT_END, agents: ['A', 'B'], mode: 'none'},
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -281,6 +351,18 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
|
||||||
expect(sequence.stages).toEqual([]);
|
expect(sequence.stages).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not create virtual agents for empty blocks', () => {
|
||||||
|
const sequence = generator.generate({stages: [
|
||||||
|
{type: BLOCK_BEGIN, mode: 'if', label: 'abc'},
|
||||||
|
{type: BLOCK_SPLIT, mode: 'else', label: 'xyz'},
|
||||||
|
{type: BLOCK_BEGIN, mode: 'if', label: 'abc'},
|
||||||
|
{type: BLOCK_END},
|
||||||
|
{type: BLOCK_END},
|
||||||
|
]});
|
||||||
|
|
||||||
|
expect(sequence.agents).toEqual(['[', ']']);
|
||||||
|
});
|
||||||
|
|
||||||
it('removes entirely empty nested blocks', () => {
|
it('removes entirely empty nested blocks', () => {
|
||||||
const sequence = generator.generate({stages: [
|
const sequence = generator.generate({stages: [
|
||||||
{type: BLOCK_BEGIN, mode: 'if', label: 'abc'},
|
{type: BLOCK_BEGIN, mode: 'if', label: 'abc'},
|
||||||
|
@ -291,16 +373,13 @@ defineDescribe('Sequence Generator', ['./Generator'], (Generator) => {
|
||||||
{type: BLOCK_END},
|
{type: BLOCK_END},
|
||||||
]});
|
]});
|
||||||
|
|
||||||
|
const block0 = sequence.stages[0];
|
||||||
expect(sequence.stages).toEqual([
|
expect(block0.sections).toEqual([
|
||||||
{type: 'block', agents: ['A', 'B'], sections: [
|
|
||||||
{mode: 'if', label: 'abc', stages: [
|
{mode: 'if', label: 'abc', stages: [
|
||||||
{type: AGENT_BEGIN, agents: ['A', 'B'], mode: 'box'},
|
{type: AGENT_BEGIN, agents: ['A', 'B'], mode: 'box'},
|
||||||
{type: '->', agents: ['A', 'B']},
|
{type: '->', agents: ['A', 'B']},
|
||||||
]},
|
]},
|
||||||
{mode: 'else', label: 'xyz', stages: []},
|
{mode: 'else', label: 'xyz', stages: []},
|
||||||
]},
|
|
||||||
{type: AGENT_END, agents: ['A', 'B'], mode: 'none'},
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue