diff --git a/src/diagrams/classDiagram/classDb.js b/src/diagrams/classDiagram/classDb.js index 502ff7349..34a73dfb8 100644 --- a/src/diagrams/classDiagram/classDb.js +++ b/src/diagrams/classDiagram/classDb.js @@ -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 -}; \ No newline at end of file +}; diff --git a/src/diagrams/sequenceDiagram/parser/sequenceDiagram.jison b/src/diagrams/sequenceDiagram/parser/sequenceDiagram.jison index 6ead4c855..d15204f9a 100644 --- a/src/diagrams/sequenceDiagram/parser/sequenceDiagram.jison +++ b/src/diagrams/sequenceDiagram/parser/sequenceDiagram.jison @@ -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 */ +((?!\n)\s)+ /* skip same-line whitespace */ +\#[^\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'; } +[^#\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'; <> 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");} ; -%% \ No newline at end of file +%% diff --git a/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js b/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js index fcb1a00d2..d154e1175 100644 --- a/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js +++ b/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js @@ -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); }); -}); \ No newline at end of file +});