Merge pull request #251 from gibson042/gh-247

Properly handle "rest of line" statements
This commit is contained in:
Knut Sveidqvist 2015-11-06 07:23:23 +01:00
commit ecca3588bc
3 changed files with 150 additions and 95 deletions

View File

@ -19,7 +19,7 @@ var funs = [];
* @param style
*/
exports.addClass = function (id) {
console.log('Adding: '+id);
log.log('Adding: '+id);
if(typeof classes.get(id) === 'undefined'){
classes.set(id, {
id:id,
@ -46,7 +46,7 @@ module.exports.getRelations = function () {
};
exports.addRelation = function (relation) {
console.log('Adding relation: ' + JSON.stringify(relation));
log.log('Adding relation: ' + JSON.stringify(relation));
exports.addClass(relation.id1);
exports.addClass(relation.id2);
@ -76,4 +76,4 @@ exports.relationType = {
EXTENSION:1,
COMPOSITION:2,
DEPENDENCY:3
};
};

View File

@ -12,26 +12,23 @@
%options case-insensitive
%{
// Pre-lexer code can go here
%}
// A special state for grabbing text up to the first comment/newline
%x LINE
%%
[\n]+ return 'NL';
[\-][x] { return 'SOLID_CROSS';}
[\-][\-][x] { return 'DOTTED_CROSS';}
[\-][>][>] { return 'SOLID_ARROW';}
[\-][\-][>][>] { return 'DOTTED_ARROW';}
\s+ /* skip whitespace */
\#[^\n]* /* skip comments */
\%%[^\n]* /* skip comments */
[\n]+ return 'NL';
\s+ /* skip all whitespace */
<LINE>((?!\n)\s)+ /* skip same-line whitespace */
<INITIAL,LINE>\#[^\n]* /* skip comments */
\%%[^\n]* /* skip comments */
"participant" return 'participant';
"opt" return 'opt';
"loop" return 'loop';
"alt" return 'alt';
"else" return 'else';
"end" return 'end';
"loop" { this.begin('LINE'); return 'loop'; }
"opt" { this.begin('LINE'); return 'opt'; }
"alt" { this.begin('LINE'); return 'alt'; }
"else" { this.begin('LINE'); return 'else'; }
<LINE>[^#\n;]* { this.popState(); return 'restOfLine'; }
"end" return 'end';
"left of" return 'left_of';
"right of" return 'right_of';
"over" return 'over';
@ -40,12 +37,14 @@
"sequenceDiagram" return 'SD';
"," return ',';
";" return 'NL';
[^\->:\n,;]+ return 'ACTOR';
"->" return 'SOLID_OPEN_ARROW';
"-->" return 'DOTTED_OPEN_ARROW';
"->>" return 'SOLID_ARROW';
[^\->:\n,;]+ return 'ACTOR';
"->>" return 'SOLID_ARROW';
"-->>" return 'DOTTED_ARROW';
":"[^#\n;]+ return 'TXT';
"->" return 'SOLID_OPEN_ARROW';
"-->" return 'DOTTED_OPEN_ARROW';
\-[x] return 'SOLID_CROSS';
\-\-[x] return 'DOTTED_CROSS';
":"[^#\n;]+ return 'TXT';
<<EOF>> return 'EOF';
. return 'INVALID';
@ -78,23 +77,23 @@ statement
| signal 'NL'
| note_statement 'NL'
| 'title' SPACE text 'NL'
| 'loop' actor document end
| 'loop' restOfLine document end
{
$3.unshift({type: 'loopStart', loopText:$2.actor, signalType: yy.LINETYPE.LOOP_START});
$3.unshift({type: 'loopStart', loopText:$2, signalType: yy.LINETYPE.LOOP_START});
$3.push({type: 'loopEnd', loopText:$2, signalType: yy.LINETYPE.LOOP_END});
$$=$3;}
| opt actor document end
| opt restOfLine document end
{
$3.unshift({type: 'optStart', optText:$2.actor, signalType: yy.LINETYPE.OPT_START});
$3.push({type: 'optEnd', optText:$2.actor, signalType: yy.LINETYPE.OPT_END});
$3.unshift({type: 'optStart', optText:$2, signalType: yy.LINETYPE.OPT_START});
$3.push({type: 'optEnd', optText:$2, signalType: yy.LINETYPE.OPT_END});
$$=$3;}
| alt actor document else actor document end
| alt restOfLine document else restOfLine document end
{
// Alt start
$3.unshift({type: 'altStart', altText:$2.actor, signalType: yy.LINETYPE.ALT_START});
$3.unshift({type: 'altStart', altText:$2, signalType: yy.LINETYPE.ALT_START});
// Content in alt is already in $3
// Else
$3.push({type: 'else', altText:$5.actor, signalType: yy.LINETYPE.ALT_ELSE});
$3.push({type: 'else', altText:$5, signalType: yy.LINETYPE.ALT_ELSE});
// Content in other alt
$3 = $3.concat($6);
// End
@ -145,4 +144,4 @@ signaltype
text2: TXT {$$ = $1.substring(1).trim().replace(/\\n/gm, "\n");} ;
%%
%%

View File

@ -29,7 +29,6 @@ describe('when parsing a sequenceDiagram',function() {
//};
//sq.yy.parseError = parseError;
});
it('it should handle a sequenceDiagram defintion', function () {
str = 'sequenceDiagram\n' +
'Alice->Bob:Hello Bob, how are you?\n' +
@ -44,7 +43,6 @@ describe('when parsing a sequenceDiagram',function() {
var messages = sq.yy.getMessages();
expect(messages.length).toBe(3);
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
@ -61,7 +59,6 @@ describe('when parsing a sequenceDiagram',function() {
var messages = sq.yy.getMessages();
expect(messages.length).toBe(2);
expect(messages[0].from).toBe('Alice');
expect(messages[1].from).toBe('Bob');
});
@ -71,15 +68,12 @@ describe('when parsing a sequenceDiagram',function() {
sq.parse(str);
var actors = sq.yy.getActors();
//log.debug(actors);
expect(actors.Alice.description).toBe('Alice');
expect(actors.Bob.description).toBe('Bob');
var messages = sq.yy.getMessages();
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(sq.yy.LINETYPE.SOLID_CROSS);
});
it('it should handle in async dotted messages', function () {
@ -88,15 +82,12 @@ describe('when parsing a sequenceDiagram',function() {
sq.parse(str);
var actors = sq.yy.getActors();
//log.debug(actors);
expect(actors.Alice.description).toBe('Alice');
expect(actors.Bob.description).toBe('Bob');
var messages = sq.yy.getMessages();
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(sq.yy.LINETYPE.DOTTED_CROSS);
});
it('it should handle in arrow messages', function () {
@ -109,11 +100,8 @@ describe('when parsing a sequenceDiagram',function() {
expect(actors.Bob.description).toBe('Bob');
var messages = sq.yy.getMessages();
//log.debug(messages);
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(sq.yy.LINETYPE.SOLID);
});
it('it should handle in arrow messages', function () {
@ -126,11 +114,8 @@ describe('when parsing a sequenceDiagram',function() {
expect(actors.Bob.description).toBe('Bob');
var messages = sq.yy.getMessages();
//log.debug(messages);
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(sq.yy.LINETYPE.DOTTED);
});
it('it should handle comments in a sequenceDiagram', function () {
@ -148,11 +133,9 @@ describe('when parsing a sequenceDiagram',function() {
var messages = sq.yy.getMessages();
expect(messages.length).toBe(3);
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
it('it should handle new lines in a sequenceDiagram', function () {
str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
@ -168,11 +151,26 @@ describe('when parsing a sequenceDiagram',function() {
var messages = sq.yy.getMessages();
expect(messages.length).toBe(3);
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
it('it should handle semicolons', function () {
str = 'sequenceDiagram;' +
'Alice->Bob: Hello Bob, how are you?;' +
'Note right of Bob: Bob thinks;' +
'Bob-->Alice: I am good thanks!;';
sq.parse(str);
var actors = sq.yy.getActors();
expect(actors.Alice.description).toBe('Alice');
actors.Bob.description = 'Bob';
var messages = sq.yy.getMessages();
expect(messages.length).toBe(3);
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
it('it should handle one leading space in lines in a sequenceDiagram', function () {
str = 'sequenceDiagram\n' +
' Alice->Bob: Hello Bob, how are you?\n\n' +
@ -188,7 +186,6 @@ describe('when parsing a sequenceDiagram',function() {
var messages = sq.yy.getMessages();
expect(messages.length).toBe(3);
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
@ -207,7 +204,6 @@ describe('when parsing a sequenceDiagram',function() {
var messages = sq.yy.getMessages();
expect(messages.length).toBe(3);
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
@ -232,11 +228,9 @@ describe('when parsing a sequenceDiagram',function() {
var messages = sq.yy.getMessages();
expect(messages.length).toBe(8);
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('John');
});
it('it should handle loop statements a sequenceDiagram', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
@ -248,20 +242,15 @@ describe('when parsing a sequenceDiagram',function() {
sq.parse(str);
var actors = sq.yy.getActors();
//log.debug(actors);
expect(actors.Alice.description).toBe('Alice');
actors.Bob.description = 'Bob';
var messages = sq.yy.getMessages();
//log.debug(messages);
expect(messages.length).toBe(5);
expect(messages[0].from).toBe('Alice');
expect(messages[1].from).toBe('Bob');
});
it('it should handle opt statements a sequenceDiagram', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
@ -273,39 +262,15 @@ describe('when parsing a sequenceDiagram',function() {
sq.parse(str);
var actors = sq.yy.getActors();
//log.debug(actors);
expect(actors.Alice.description).toBe('Alice');
actors.Bob.description = 'Bob';
var messages = sq.yy.getMessages();
//log.debug(messages);
expect(messages.length).toBe(5);
expect(messages[0].from).toBe('Alice');
expect(messages[1].from).toBe('Bob');
});
it('it should handle opt statements a sequenceDiagram', function () {
var str = 'sequenceDiagram;Alice->Bob: Hello Bob, how are you?;opt Perhaps a happy response;Bob-->Alice: I am good thanks!;end;';
sq.parse(str);
var actors = sq.yy.getActors();
//log.debug(actors);
expect(actors.Alice.description).toBe('Alice');
actors.Bob.description = 'Bob';
var messages = sq.yy.getMessages();
//log.debug(messages);
expect(messages.length).toBe(4);
expect(messages[0].from).toBe('Alice');
expect(messages[1].type).toBe(sq.yy.LINETYPE.OPT_START);
expect(messages[2].from).toBe('Bob');
});
it('it should handle alt statements a sequenceDiagram', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
@ -324,14 +289,113 @@ describe('when parsing a sequenceDiagram',function() {
actors.Bob.description = 'Bob';
var messages = sq.yy.getMessages();
//log.debug(messages);
expect(messages.length).toBe(7);
expect(messages[0].from).toBe('Alice');
expect(messages[1].from).toBe('Bob');
});
it('it should handle special characters in signals', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: -:<>,;# comment';
sq.parse(str);
});});
var messages = sq.yy.getMessages();
expect(messages[0].message).toBe('-:<>,');
});
it('it should handle special characters in notes', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Note right of Bob: -:<>,;# comment';
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages[1].message).toBe('-:<>,');
});
it('it should handle special characters in loop', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'loop -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end';
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages[1].message).toBe('-:<>,');
});
it('it should handle special characters in opt', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'opt -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end';
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages[1].message).toBe('-:<>,');
});
it('it should handle special characters in alt', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'alt -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'else ,<>:-#; comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end';
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages[1].message).toBe('-:<>,');
expect(messages[3].message).toBe(',<>:-');
});
it('it should handle no-label loop', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'loop\n' +
'Bob-->Alice: I am good thanks!\n' +
'end';
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages[1].message).toBe('');
expect(messages[2].message).toBe('I am good thanks!');
});
it('it should handle no-label opt', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'opt # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end';
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages[1].message).toBe('');
expect(messages[2].message).toBe('I am good thanks!');
});
it('it should handle no-label alt', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'alt;' +
'Bob-->Alice: I am good thanks!\n' +
'else # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end';
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages[1].message).toBe('');
expect(messages[2].message).toBe('I am good thanks!');
expect(messages[3].message).toBe('');
expect(messages[4].message).toBe('I am good thanks!');
});
});
describe('when checking the bounds in a sequenceDiagram',function() {
var conf;
@ -398,7 +462,6 @@ describe('when checking the bounds in a sequenceDiagram',function() {
expect(bounds.stopy ).toBe(400);
});
it('it should handle a loop without expanding the area', function () {
sd.bounds.init();
@ -422,8 +485,6 @@ describe('when checking the bounds in a sequenceDiagram',function() {
expect(bounds.stopx ).toBe(300);
expect(bounds.stopy ).toBe(400);
});
it('it should handle multiple loops withtout expanding the bounds', function () {
sd.bounds.init();
@ -457,7 +518,6 @@ describe('when checking the bounds in a sequenceDiagram',function() {
expect(bounds.stopx ).toBe(1000);
expect(bounds.stopy ).toBe(1000);
});
it('it should handle a loop that expands the area', function () {
sd.bounds.init();
@ -610,7 +670,6 @@ describe('when rendering a sequenceDiagram',function() {
expect(bounds.stopy ).toBe(0 + conf.messageMargin + conf.height);
});
it('it should draw two actors and two messages', function () {
sd.bounds.init();
var str = 'sequenceDiagram\n' +
@ -627,8 +686,6 @@ describe('when rendering a sequenceDiagram',function() {
expect(bounds.stopy ).toBe(0 + 2*conf.messageMargin + conf.height);
});
it('it should draw two actors notes to the right', function () {
sd.bounds.init();
var str = 'sequenceDiagram\n' +
@ -667,7 +724,6 @@ describe('when rendering a sequenceDiagram',function() {
expect(bounds.stopy ).toBe( 2*conf.messageMargin + conf.height + conf.boxMargin +10+ 2*conf.noteMargin);
});
it('it should draw two loops', function () {
sd.bounds.init();
var str = 'sequenceDiagram\n' +
@ -762,4 +818,4 @@ describe('when rendering a sequenceDiagram with actor mirror activated',function
expect(bounds.stopy ).toBe(2*conf.height+2*conf.boxMargin);
});
});
});