From c8091c61c0366424436847e80def4e0162fd1829 Mon Sep 17 00:00:00 2001 From: Alexander Sage Date: Mon, 22 Jul 2019 22:47:49 -0700 Subject: [PATCH 1/7] feat: sequence diagram background rect --- dist/index.html | 7 + .../sequence/parser/sequenceDiagram.jison | 6 + .../sequence/parser/sequenceDiagram.js | 167 ++++++++++-------- src/diagrams/sequence/sequenceDb.js | 10 +- src/diagrams/sequence/sequenceDiagram.spec.js | 22 +++ src/diagrams/sequence/sequenceRenderer.js | 26 +++ src/diagrams/sequence/svgDraw.js | 5 +- 7 files changed, 163 insertions(+), 80 deletions(-) diff --git a/dist/index.html b/dist/index.html index d33127fe2..5e4c51554 100644 --- a/dist/index.html +++ b/dist/index.html @@ -305,12 +305,16 @@ sequenceDiagram participant Alice participant Bob participant John as John
Second Line +rect rgb(200, 220, 100) +rect rgb(200, 255, 200) Alice ->> Bob: Hello Bob, how are you? Bob-->>John: How about you John? +end Bob--x Alice: I am good thanks! Bob-x John: I am good thanks! Note right of John: Bob thinks a long
long time, so long
that the text does
not fit on a row. Bob-->Alice: Checking with John... +end alt either this Alice->>John: Yes else or this @@ -322,6 +326,9 @@ par this happens in parallel Alice -->> Bob: Parallel message 1 and Alice -->> John: Parallel message 2 +end +loop awesome +A -> B: foo end diff --git a/src/diagrams/sequence/parser/sequenceDiagram.jison b/src/diagrams/sequence/parser/sequenceDiagram.jison index 9437248e3..90e09a0f9 100644 --- a/src/diagrams/sequence/parser/sequenceDiagram.jison +++ b/src/diagrams/sequence/parser/sequenceDiagram.jison @@ -31,6 +31,7 @@ "as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; } (?:) { this.popState(); this.popState(); return 'NL'; } "loop" { this.begin('LINE'); return 'loop'; } +"rect" { this.begin('LINE'); return 'rect'; } "opt" { this.begin('LINE'); return 'opt'; } "alt" { this.begin('LINE'); return 'alt'; } "else" { this.begin('LINE'); return 'else'; } @@ -99,6 +100,11 @@ statement $3.unshift({type: 'loopStart', loopText:$2, signalType: yy.LINETYPE.LOOP_START}); $3.push({type: 'loopEnd', loopText:$2, signalType: yy.LINETYPE.LOOP_END}); $$=$3;} + | 'rect' restOfLine document end + { + $3.unshift({type: 'rectStart', color:$2, signalType: yy.LINETYPE.RECT_START }); + $3.push({type: 'rectEnd', color:$2, signalType: yy.LINETYPE.RECT_END }); + $$=$3;} | opt restOfLine document end { $3.unshift({type: 'optStart', optText:$2, signalType: yy.LINETYPE.OPT_START}); diff --git a/src/diagrams/sequence/parser/sequenceDiagram.js b/src/diagrams/sequence/parser/sequenceDiagram.js index 7b484f4ce..c3331f2af 100644 --- a/src/diagrams/sequence/parser/sequenceDiagram.js +++ b/src/diagrams/sequence/parser/sequenceDiagram.js @@ -71,13 +71,13 @@ recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) } */ -var sequenceDiagram = (function(){ -var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,2],$V1=[1,3],$V2=[1,4],$V3=[2,4],$V4=[1,9],$V5=[1,11],$V6=[1,12],$V7=[1,14],$V8=[1,15],$V9=[1,17],$Va=[1,18],$Vb=[1,19],$Vc=[1,20],$Vd=[1,21],$Ve=[1,23],$Vf=[1,24],$Vg=[1,4,5,10,15,16,18,20,21,22,23,25,27,28,29,40],$Vh=[1,32],$Vi=[4,5,10,15,16,18,20,21,22,23,25,29,40],$Vj=[4,5,10,15,16,18,20,21,22,23,25,28,29,40],$Vk=[4,5,10,15,16,18,20,21,22,23,25,27,29,40],$Vl=[38,39,40]; +var parser = (function(){ +var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,2],$V1=[1,3],$V2=[1,4],$V3=[2,4],$V4=[1,9],$V5=[1,11],$V6=[1,12],$V7=[1,14],$V8=[1,15],$V9=[1,17],$Va=[1,18],$Vb=[1,19],$Vc=[1,20],$Vd=[1,21],$Ve=[1,22],$Vf=[1,24],$Vg=[1,25],$Vh=[1,4,5,10,15,16,18,20,21,22,23,24,26,28,29,30,41],$Vi=[1,33],$Vj=[4,5,10,15,16,18,20,21,22,23,24,26,30,41],$Vk=[4,5,10,15,16,18,20,21,22,23,24,26,29,30,41],$Vl=[4,5,10,15,16,18,20,21,22,23,24,26,28,30,41],$Vm=[39,40,41]; var parser = {trace: function trace () { }, yy: {}, -symbols_: {"error":2,"start":3,"SPACE":4,"NL":5,"SD":6,"document":7,"line":8,"statement":9,"participant":10,"actor":11,"AS":12,"restOfLine":13,"signal":14,"activate":15,"deactivate":16,"note_statement":17,"title":18,"text2":19,"loop":20,"end":21,"opt":22,"alt":23,"else_sections":24,"par":25,"par_sections":26,"and":27,"else":28,"note":29,"placement":30,"over":31,"actor_pair":32,"spaceList":33,",":34,"left_of":35,"right_of":36,"signaltype":37,"+":38,"-":39,"ACTOR":40,"SOLID_OPEN_ARROW":41,"DOTTED_OPEN_ARROW":42,"SOLID_ARROW":43,"DOTTED_ARROW":44,"SOLID_CROSS":45,"DOTTED_CROSS":46,"TXT":47,"$accept":0,"$end":1}, -terminals_: {2:"error",4:"SPACE",5:"NL",6:"SD",10:"participant",12:"AS",13:"restOfLine",15:"activate",16:"deactivate",18:"title",20:"loop",21:"end",22:"opt",23:"alt",25:"par",27:"and",28:"else",29:"note",31:"over",34:",",35:"left_of",36:"right_of",38:"+",39:"-",40:"ACTOR",41:"SOLID_OPEN_ARROW",42:"DOTTED_OPEN_ARROW",43:"SOLID_ARROW",44:"DOTTED_ARROW",45:"SOLID_CROSS",46:"DOTTED_CROSS",47:"TXT"}, -productions_: [0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,5],[9,3],[9,2],[9,3],[9,3],[9,2],[9,3],[9,4],[9,4],[9,4],[9,4],[26,1],[26,4],[24,1],[24,4],[17,4],[17,4],[33,2],[33,1],[32,3],[32,1],[30,1],[30,1],[14,5],[14,5],[14,4],[11,1],[37,1],[37,1],[37,1],[37,1],[37,1],[37,1],[19,1]], +symbols_: {"error":2,"start":3,"SPACE":4,"NL":5,"SD":6,"document":7,"line":8,"statement":9,"participant":10,"actor":11,"AS":12,"restOfLine":13,"signal":14,"activate":15,"deactivate":16,"note_statement":17,"title":18,"text2":19,"loop":20,"end":21,"rect":22,"opt":23,"alt":24,"else_sections":25,"par":26,"par_sections":27,"and":28,"else":29,"note":30,"placement":31,"over":32,"actor_pair":33,"spaceList":34,",":35,"left_of":36,"right_of":37,"signaltype":38,"+":39,"-":40,"ACTOR":41,"SOLID_OPEN_ARROW":42,"DOTTED_OPEN_ARROW":43,"SOLID_ARROW":44,"DOTTED_ARROW":45,"SOLID_CROSS":46,"DOTTED_CROSS":47,"TXT":48,"$accept":0,"$end":1}, +terminals_: {2:"error",4:"SPACE",5:"NL",6:"SD",10:"participant",12:"AS",13:"restOfLine",15:"activate",16:"deactivate",18:"title",20:"loop",21:"end",22:"rect",23:"opt",24:"alt",26:"par",28:"and",29:"else",30:"note",32:"over",35:",",36:"left_of",37:"right_of",39:"+",40:"-",41:"ACTOR",42:"SOLID_OPEN_ARROW",43:"DOTTED_OPEN_ARROW",44:"SOLID_ARROW",45:"DOTTED_ARROW",46:"SOLID_CROSS",47:"DOTTED_CROSS",48:"TXT"}, +productions_: [0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,5],[9,3],[9,2],[9,3],[9,3],[9,2],[9,3],[9,4],[9,4],[9,4],[9,4],[9,4],[27,1],[27,4],[25,1],[25,4],[17,4],[17,4],[34,2],[34,1],[33,3],[33,1],[31,1],[31,1],[14,5],[14,5],[14,4],[11,1],[38,1],[38,1],[38,1],[38,1],[38,1],[38,1],[19,1]], performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { /* this == yyval */ @@ -121,11 +121,17 @@ case 16: break; case 17: + $$[$0-1].unshift({type: 'rectStart', color:$$[$0-2], signalType: yy.LINETYPE.RECT_START }); + $$[$0-1].push({type: 'rectEnd', color:$$[$0-2], signalType: yy.LINETYPE.RECT_END }); + this.$=$$[$0-1]; +break; +case 18: + $$[$0-1].unshift({type: 'optStart', optText:$$[$0-2], signalType: yy.LINETYPE.OPT_START}); $$[$0-1].push({type: 'optEnd', optText:$$[$0-2], signalType: yy.LINETYPE.OPT_END}); this.$=$$[$0-1]; break; -case 18: +case 19: // Alt start $$[$0-1].unshift({type: 'altStart', altText:$$[$0-2], signalType: yy.LINETYPE.ALT_START}); @@ -134,7 +140,7 @@ case 18: $$[$0-1].push({type: 'altEnd', signalType: yy.LINETYPE.ALT_END}); this.$=$$[$0-1]; break; -case 19: +case 20: // Parallel start $$[$0-1].unshift({type: 'parStart', parText:$$[$0-2], signalType: yy.LINETYPE.PAR_START}); @@ -143,17 +149,17 @@ case 19: $$[$0-1].push({type: 'parEnd', signalType: yy.LINETYPE.PAR_END}); this.$=$$[$0-1]; break; -case 21: +case 22: this.$ = $$[$0-3].concat([{type: 'and', parText:$$[$0-1], signalType: yy.LINETYPE.PAR_AND}, $$[$0]]); break; -case 23: +case 24: this.$ = $$[$0-3].concat([{type: 'else', altText:$$[$0-1], signalType: yy.LINETYPE.ALT_ELSE}, $$[$0]]); break; -case 24: +case 25: this.$ = [$$[$0-1], {type:'addNote', placement:$$[$0-2], actor:$$[$0-1].actor, text:$$[$0]}]; break; -case 25: +case 26: // Coerce actor_pair into a [to, from, ...] array $$[$0-2] = [].concat($$[$0-1], $$[$0-1]).slice(0, 2); @@ -161,59 +167,59 @@ case 25: $$[$0-2][1] = $$[$0-2][1].actor; this.$ = [$$[$0-1], {type:'addNote', placement:yy.PLACEMENT.OVER, actor:$$[$0-2].slice(0, 2), text:$$[$0]}]; break; -case 28: +case 29: this.$ = [$$[$0-2], $$[$0]]; break; -case 29: +case 30: this.$ = $$[$0]; break; -case 30: +case 31: this.$ = yy.PLACEMENT.LEFTOF; break; -case 31: +case 32: this.$ = yy.PLACEMENT.RIGHTOF; break; -case 32: +case 33: this.$ = [$$[$0-4],$$[$0-1],{type: 'addMessage', from:$$[$0-4].actor, to:$$[$0-1].actor, signalType:$$[$0-3], msg:$$[$0]}, {type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $$[$0-1]} ] break; -case 33: +case 34: this.$ = [$$[$0-4],$$[$0-1],{type: 'addMessage', from:$$[$0-4].actor, to:$$[$0-1].actor, signalType:$$[$0-3], msg:$$[$0]}, {type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $$[$0-4]} ] break; -case 34: +case 35: this.$ = [$$[$0-3],$$[$0-1],{type: 'addMessage', from:$$[$0-3].actor, to:$$[$0-1].actor, signalType:$$[$0-2], msg:$$[$0]}] break; -case 35: +case 36: this.$={type: 'addActor', actor:$$[$0]} break; -case 36: +case 37: this.$ = yy.LINETYPE.SOLID_OPEN; break; -case 37: +case 38: this.$ = yy.LINETYPE.DOTTED_OPEN; break; -case 38: +case 39: this.$ = yy.LINETYPE.SOLID; break; -case 39: +case 40: this.$ = yy.LINETYPE.DOTTED; break; -case 40: +case 41: this.$ = yy.LINETYPE.SOLID_CROSS; break; -case 41: +case 42: this.$ = yy.LINETYPE.DOTTED_CROSS; break; -case 42: +case 43: this.$ = $$[$0].substring(1).trim().replace(/\\n/gm, "\n"); break; } }, -table: [{3:1,4:$V0,5:$V1,6:$V2},{1:[3]},{3:5,4:$V0,5:$V1,6:$V2},{3:6,4:$V0,5:$V1,6:$V2},o([1,4,5,10,15,16,18,20,22,23,25,29,40],$V3,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},o($Vg,[2,5]),{9:25,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},o($Vg,[2,7]),o($Vg,[2,8]),{11:26,40:$Vf},{5:[1,27]},{11:28,40:$Vf},{11:29,40:$Vf},{5:[1,30]},{19:31,47:$Vh},{13:[1,33]},{13:[1,34]},{13:[1,35]},{13:[1,36]},{37:37,41:[1,38],42:[1,39],43:[1,40],44:[1,41],45:[1,42],46:[1,43]},{30:44,31:[1,45],35:[1,46],36:[1,47]},o([5,12,34,41,42,43,44,45,46,47],[2,35]),o($Vg,[2,6]),{5:[1,49],12:[1,48]},o($Vg,[2,11]),{5:[1,50]},{5:[1,51]},o($Vg,[2,14]),{5:[1,52]},{5:[2,42]},o($Vi,$V3,{7:53}),o($Vi,$V3,{7:54}),o($Vj,$V3,{24:55,7:56}),o($Vk,$V3,{26:57,7:58}),{11:61,38:[1,59],39:[1,60],40:$Vf},o($Vl,[2,36]),o($Vl,[2,37]),o($Vl,[2,38]),o($Vl,[2,39]),o($Vl,[2,40]),o($Vl,[2,41]),{11:62,40:$Vf},{11:64,32:63,40:$Vf},{40:[2,30]},{40:[2,31]},{13:[1,65]},o($Vg,[2,10]),o($Vg,[2,12]),o($Vg,[2,13]),o($Vg,[2,15]),{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[1,66],22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[1,67],22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},{21:[1,68]},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[2,22],22:$Vb,23:$Vc,25:$Vd,28:[1,69],29:$Ve,40:$Vf},{21:[1,70]},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[2,20],22:$Vb,23:$Vc,25:$Vd,27:[1,71],29:$Ve,40:$Vf},{11:72,40:$Vf},{11:73,40:$Vf},{19:74,47:$Vh},{19:75,47:$Vh},{19:76,47:$Vh},{34:[1,77],47:[2,29]},{5:[1,78]},o($Vg,[2,16]),o($Vg,[2,17]),o($Vg,[2,18]),{13:[1,79]},o($Vg,[2,19]),{13:[1,80]},{19:81,47:$Vh},{19:82,47:$Vh},{5:[2,34]},{5:[2,24]},{5:[2,25]},{11:83,40:$Vf},o($Vg,[2,9]),o($Vj,$V3,{7:56,24:84}),o($Vk,$V3,{7:58,26:85}),{5:[2,32]},{5:[2,33]},{47:[2,28]},{21:[2,23]},{21:[2,21]}], -defaultActions: {5:[2,1],6:[2,2],32:[2,42],46:[2,30],47:[2,31],74:[2,34],75:[2,24],76:[2,25],81:[2,32],82:[2,33],83:[2,28],84:[2,23],85:[2,21]}, +table: [{3:1,4:$V0,5:$V1,6:$V2},{1:[3]},{3:5,4:$V0,5:$V1,6:$V2},{3:6,4:$V0,5:$V1,6:$V2},o([1,4,5,10,15,16,18,20,22,23,24,26,30,41],$V3,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:$V4,5:$V5,8:8,9:10,10:$V6,11:23,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,22:$Vb,23:$Vc,24:$Vd,26:$Ve,30:$Vf,41:$Vg},o($Vh,[2,5]),{9:26,10:$V6,11:23,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,22:$Vb,23:$Vc,24:$Vd,26:$Ve,30:$Vf,41:$Vg},o($Vh,[2,7]),o($Vh,[2,8]),{11:27,41:$Vg},{5:[1,28]},{11:29,41:$Vg},{11:30,41:$Vg},{5:[1,31]},{19:32,48:$Vi},{13:[1,34]},{13:[1,35]},{13:[1,36]},{13:[1,37]},{13:[1,38]},{38:39,42:[1,40],43:[1,41],44:[1,42],45:[1,43],46:[1,44],47:[1,45]},{31:46,32:[1,47],36:[1,48],37:[1,49]},o([5,12,35,42,43,44,45,46,47,48],[2,36]),o($Vh,[2,6]),{5:[1,51],12:[1,50]},o($Vh,[2,11]),{5:[1,52]},{5:[1,53]},o($Vh,[2,14]),{5:[1,54]},{5:[2,43]},o($Vj,$V3,{7:55}),o($Vj,$V3,{7:56}),o($Vj,$V3,{7:57}),o($Vk,$V3,{25:58,7:59}),o($Vl,$V3,{27:60,7:61}),{11:64,39:[1,62],40:[1,63],41:$Vg},o($Vm,[2,37]),o($Vm,[2,38]),o($Vm,[2,39]),o($Vm,[2,40]),o($Vm,[2,41]),o($Vm,[2,42]),{11:65,41:$Vg},{11:67,33:66,41:$Vg},{41:[2,31]},{41:[2,32]},{13:[1,68]},o($Vh,[2,10]),o($Vh,[2,12]),o($Vh,[2,13]),o($Vh,[2,15]),{4:$V4,5:$V5,8:8,9:10,10:$V6,11:23,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[1,69],22:$Vb,23:$Vc,24:$Vd,26:$Ve,30:$Vf,41:$Vg},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:23,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[1,70],22:$Vb,23:$Vc,24:$Vd,26:$Ve,30:$Vf,41:$Vg},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:23,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[1,71],22:$Vb,23:$Vc,24:$Vd,26:$Ve,30:$Vf,41:$Vg},{21:[1,72]},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:23,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[2,23],22:$Vb,23:$Vc,24:$Vd,26:$Ve,29:[1,73],30:$Vf,41:$Vg},{21:[1,74]},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:23,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[2,21],22:$Vb,23:$Vc,24:$Vd,26:$Ve,28:[1,75],30:$Vf,41:$Vg},{11:76,41:$Vg},{11:77,41:$Vg},{19:78,48:$Vi},{19:79,48:$Vi},{19:80,48:$Vi},{35:[1,81],48:[2,30]},{5:[1,82]},o($Vh,[2,16]),o($Vh,[2,17]),o($Vh,[2,18]),o($Vh,[2,19]),{13:[1,83]},o($Vh,[2,20]),{13:[1,84]},{19:85,48:$Vi},{19:86,48:$Vi},{5:[2,35]},{5:[2,25]},{5:[2,26]},{11:87,41:$Vg},o($Vh,[2,9]),o($Vk,$V3,{7:59,25:88}),o($Vl,$V3,{7:61,27:89}),{5:[2,33]},{5:[2,34]},{48:[2,29]},{21:[2,24]},{21:[2,22]}], +defaultActions: {5:[2,1],6:[2,2],33:[2,43],48:[2,31],49:[2,32],78:[2,35],79:[2,25],80:[2,26],85:[2,33],86:[2,34],87:[2,29],88:[2,24],89:[2,22]}, parseError: function parseError (str, hash) { if (hash.recoverable) { this.trace(str); @@ -252,15 +258,18 @@ parse: function parse(input) { vstack.length = vstack.length - n; lstack.length = lstack.length - n; } - _token_stack: - var lex = function () { + function lex() { var token; - token = lexer.lex() || EOF; + token = tstack.pop() || lexer.lex() || EOF; if (typeof token !== 'number') { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } token = self.symbols_[token] || token; } return token; - }; + } var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; while (true) { state = stack[stack.length - 1]; @@ -272,27 +281,27 @@ parse: function parse(input) { } action = table[state] && table[state][symbol]; } - if (typeof action === 'undefined' || !action.length || !action[0]) { - var errStr = ''; - expected = []; - for (p in table[state]) { - if (this.terminals_[p] && p > TERROR) { - expected.push('\'' + this.terminals_[p] + '\''); - } + if (typeof action === 'undefined' || !action.length || !action[0]) { + var errStr = ''; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push('\'' + this.terminals_[p] + '\''); } - if (lexer.showPosition) { - errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; - } else { - errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); - } - this.parseError(errStr, { - text: lexer.match, - token: this.terminals_[symbol] || symbol, - line: lexer.yylineno, - loc: yyloc, - expected: expected - }); } + if (lexer.showPosition) { + errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; + } else { + errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); + } + this.parseError(errStr, { + text: lexer.match, + token: this.terminals_[symbol] || symbol, + line: lexer.yylineno, + loc: yyloc, + expected: expected + }); + } if (action[0] instanceof Array && action.length > 1) { throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); } @@ -701,7 +710,7 @@ case 4:/* skip comments */ break; case 5: this.begin('ID'); return 10; break; -case 6: yy_.yytext = yy_.yytext.trim(); this.begin('ALIAS'); return 40; +case 6: yy_.yytext = yy_.yytext.trim(); this.begin('ALIAS'); return 41; break; case 7: this.popState(); this.popState(); this.begin('LINE'); return 12; break; @@ -713,64 +722,66 @@ case 10: this.begin('LINE'); return 22; break; case 11: this.begin('LINE'); return 23; break; -case 12: this.begin('LINE'); return 28; +case 12: this.begin('LINE'); return 24; break; -case 13: this.begin('LINE'); return 25; +case 13: this.begin('LINE'); return 29; break; -case 14: this.begin('LINE'); return 27; +case 14: this.begin('LINE'); return 26; break; -case 15: this.popState(); return 13; +case 15: this.begin('LINE'); return 28; break; -case 16:return 21; +case 16: this.popState(); return 13; break; -case 17:return 35; +case 17:return 21; break; case 18:return 36; break; -case 19:return 31; +case 19:return 37; break; -case 20:return 29; +case 20:return 32; break; -case 21: this.begin('ID'); return 15; +case 21:return 30; break; -case 22: this.begin('ID'); return 16; +case 22: this.begin('ID'); return 15; break; -case 23:return 18; +case 23: this.begin('ID'); return 16; break; -case 24:return 6; +case 24:return 18; break; -case 25:return 34; +case 25:return 6; break; -case 26:return 5; +case 26:return 35; break; -case 27: yy_.yytext = yy_.yytext.trim(); return 40; +case 27:return 5; break; -case 28:return 43; +case 28: yy_.yytext = yy_.yytext.trim(); return 41; break; case 29:return 44; break; -case 30:return 41; +case 30:return 45; break; case 31:return 42; break; -case 32:return 45; +case 32:return 43; break; case 33:return 46; break; case 34:return 47; break; -case 35:return 38; +case 35:return 48; break; case 36:return 39; break; -case 37:return 5; +case 37:return 40; break; -case 38:return 'INVALID'; +case 38:return 5; +break; +case 39:return 'INVALID'; break; } }, -rules: [/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:participant\b)/i,/^(?:[^\->:\n,;]+?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:and\b)/i,/^(?:[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\b)/i,/^(?:sequenceDiagram\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?::[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i], -conditions: {"LINE":{"rules":[2,3,15],"inclusive":false},"ALIAS":{"rules":[2,3,7,8],"inclusive":false},"ID":{"rules":[2,3,6],"inclusive":false},"INITIAL":{"rules":[0,1,3,4,5,9,10,11,12,13,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"inclusive":true}} +rules: [/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:participant\b)/i,/^(?:[^\->:\n,;]+?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:and\b)/i,/^(?:[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\b)/i,/^(?:sequenceDiagram\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?::[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i], +conditions: {"LINE":{"rules":[2,3,16],"inclusive":false},"ALIAS":{"rules":[2,3,7,8],"inclusive":false},"ID":{"rules":[2,3,6],"inclusive":false},"INITIAL":{"rules":[0,1,3,4,5,9,10,11,12,13,14,15,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],"inclusive":true}} }); return lexer; })(); @@ -784,9 +795,9 @@ return new Parser; if (typeof require !== 'undefined' && typeof exports !== 'undefined') { -exports.parser = sequenceDiagram; -exports.Parser = sequenceDiagram.Parser; -exports.parse = function () { return sequenceDiagram.parse.apply(sequenceDiagram, arguments); }; +exports.parser = parser; +exports.Parser = parser.Parser; +exports.parse = function () { return parser.parse.apply(parser, arguments); }; exports.main = function commonjsMain (args) { if (!args[1]) { console.log('Usage: '+args[0]+' FILE'); diff --git a/src/diagrams/sequence/sequenceDb.js b/src/diagrams/sequence/sequenceDb.js index 665ca820d..e531ed2f9 100644 --- a/src/diagrams/sequence/sequenceDb.js +++ b/src/diagrams/sequence/sequenceDb.js @@ -66,7 +66,9 @@ export const LINETYPE = { ACTIVE_END: 18, PAR_START: 19, PAR_AND: 20, - PAR_END: 21 + PAR_END: 21, + RECT_START: 22, + RECT_END: 23 } export const ARROWTYPE = { @@ -122,6 +124,12 @@ export const apply = function (param) { case 'loopEnd': addSignal(undefined, undefined, undefined, param.signalType) break + case 'rectStart': + addSignal(undefined, undefined, param.color, param.signalType) + break + case 'rectEnd': + addSignal(undefined, undefined, undefined, param.signalType) + break case 'optStart': addSignal(undefined, undefined, param.optText, param.signalType) break diff --git a/src/diagrams/sequence/sequenceDiagram.spec.js b/src/diagrams/sequence/sequenceDiagram.spec.js index f1f6b47c1..ed0f8047d 100644 --- a/src/diagrams/sequence/sequenceDiagram.spec.js +++ b/src/diagrams/sequence/sequenceDiagram.spec.js @@ -369,6 +369,28 @@ describe('when parsing a sequenceDiagram', function () { expect(messages[0].from).toBe('Alice') expect(messages[1].from).toBe('Bob') }) + it('it should handle rect statements', function () { + const str = ` + sequenceDiagram + Alice->Bob: Hello Bob, how are you? + %% Comment + Note right of Bob: Bob thinks + rect rgb(200, 255, 200) + Bob-->Alice: I am good thanks + end + ` + + parser.parse(str) + const actors = parser.yy.getActors() + expect(actors.Alice.description).toBe('Alice') + actors.Bob.description = 'Bob' + + const messages = parser.yy.getMessages() + + expect(messages.length).toBe(5) + expect(messages[0].from).toBe('Alice') + expect(messages[1].from).toBe('Bob') + }) it('it should handle opt statements', function () { const str = 'sequenceDiagram\n' + 'Alice->Bob: Hello Bob, how are you?\n\n' + diff --git a/src/diagrams/sequence/sequenceRenderer.js b/src/diagrams/sequence/sequenceRenderer.js index deaf9f65b..2421df9fa 100644 --- a/src/diagrams/sequence/sequenceRenderer.js +++ b/src/diagrams/sequence/sequenceRenderer.js @@ -138,6 +138,13 @@ export const bounds = { const loop = this.sequenceItems.pop() return loop }, + newRect: function (color) { + this.sequenceItems.push({ startx: undefined, starty: this.verticalPos, stopx: undefined, stopy: undefined, color: color }) + }, + endRect: function () { + const rect = this.sequenceItems.pop() + return rect + }, addSectionToLoop: function (message) { const loop = this.sequenceItems.pop() loop.sections = loop.sections || [] @@ -410,6 +417,25 @@ export const draw = function (text, id) { svgDraw.drawLoop(diagram, loopData, 'loop', conf) bounds.bumpVerticalPos(conf.boxMargin) break + case parser.yy.LINETYPE.RECT_START: + bounds.bumpVerticalPos(conf.boxMargin) + bounds.newRect(msg.message) + bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin) + break + case parser.yy.LINETYPE.RECT_END: + const rectData = bounds.endRect() + svgDraw.drawRect(diagram, { + x: rectData.startx, + y: rectData.starty, + width: rectData.stopx - rectData.startx, + height: rectData.stopy - rectData.starty, + fill: rectData.color, + class: 'rect', + rx: 0, + ry: 0 + }, true) + bounds.bumpVerticalPos(conf.boxMargin) + break case parser.yy.LINETYPE.OPT_START: bounds.bumpVerticalPos(conf.boxMargin) bounds.newLoop(msg.message) diff --git a/src/diagrams/sequence/svgDraw.js b/src/diagrams/sequence/svgDraw.js index c9a335f21..6d5836683 100644 --- a/src/diagrams/sequence/svgDraw.js +++ b/src/diagrams/sequence/svgDraw.js @@ -1,5 +1,8 @@ -export const drawRect = function (elem, rectData) { +export const drawRect = function (elem, rectData, insertBeforeLastChild) { const rectElem = elem.append('rect') + if (insertBeforeLastChild) { + rectElem.lower() + } rectElem.attr('x', rectData.x) rectElem.attr('y', rectData.y) rectElem.attr('fill', rectData.fill) From 1b001cf1e822175d16d7cf9ebfdb3c3056131cab Mon Sep 17 00:00:00 2001 From: Alexander Sage Date: Tue, 23 Jul 2019 19:11:31 -0700 Subject: [PATCH 2/7] chore: Added unit tests around drawBackgroundRect and drawRect --- __mocks__/d3.js | 20 ++++++ src/diagrams/sequence/sequenceRenderer.js | 26 ++------ src/diagrams/sequence/svgDraw.js | 23 +++++-- src/diagrams/sequence/svgDraw.spec.js | 75 +++++++++++++++++++++++ 4 files changed, 119 insertions(+), 25 deletions(-) create mode 100644 src/diagrams/sequence/svgDraw.spec.js diff --git a/__mocks__/d3.js b/__mocks__/d3.js index 218ed9754..be43b1bd7 100644 --- a/__mocks__/d3.js +++ b/__mocks__/d3.js @@ -1,3 +1,4 @@ + let NewD3 = function () { return { append: function () { @@ -36,3 +37,22 @@ export const selectAll = function () { export const curveBasis = 'basis' export const curveLinear = 'linear' export const curveCardinal = 'cardinal' + +export const MockD3 = (name, parent) => { + const children = [] + const elem = { + get __children () { return children }, + get __name () { return name }, + get __parent () { return parent } + } + elem.append = (name) => { + const mockElem = MockD3(name, elem) + children.push(mockElem) + return mockElem + } + elem.lower = jest.fn(() => elem) + elem.attr = jest.fn(() => elem) + elem.text = jest.fn(() => elem) + elem.style = jest.fn(() => elem) + return elem +} diff --git a/src/diagrams/sequence/sequenceRenderer.js b/src/diagrams/sequence/sequenceRenderer.js index 2421df9fa..776fc103e 100644 --- a/src/diagrams/sequence/sequenceRenderer.js +++ b/src/diagrams/sequence/sequenceRenderer.js @@ -131,20 +131,13 @@ export const bounds = { const activation = this.activations.splice(lastActorActivationIdx, 1)[0] return activation }, - newLoop: function (title) { - this.sequenceItems.push({ startx: undefined, starty: this.verticalPos, stopx: undefined, stopy: undefined, title: title }) + newLoop: function (title, fill) { + this.sequenceItems.push({ startx: undefined, starty: this.verticalPos, stopx: undefined, stopy: undefined, title: title, fill: fill }) }, endLoop: function () { const loop = this.sequenceItems.pop() return loop }, - newRect: function (color) { - this.sequenceItems.push({ startx: undefined, starty: this.verticalPos, stopx: undefined, stopy: undefined, color: color }) - }, - endRect: function () { - const rect = this.sequenceItems.pop() - return rect - }, addSectionToLoop: function (message) { const loop = this.sequenceItems.pop() loop.sections = loop.sections || [] @@ -419,21 +412,12 @@ export const draw = function (text, id) { break case parser.yy.LINETYPE.RECT_START: bounds.bumpVerticalPos(conf.boxMargin) - bounds.newRect(msg.message) + bounds.newLoop(undefined, msg.message) bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin) break case parser.yy.LINETYPE.RECT_END: - const rectData = bounds.endRect() - svgDraw.drawRect(diagram, { - x: rectData.startx, - y: rectData.starty, - width: rectData.stopx - rectData.startx, - height: rectData.stopy - rectData.starty, - fill: rectData.color, - class: 'rect', - rx: 0, - ry: 0 - }, true) + const rectData = bounds.endLoop() + svgDraw.drawBackgroundRect(diagram, rectData); bounds.bumpVerticalPos(conf.boxMargin) break case parser.yy.LINETYPE.OPT_START: diff --git a/src/diagrams/sequence/svgDraw.js b/src/diagrams/sequence/svgDraw.js index 6d5836683..1c5c8fd28 100644 --- a/src/diagrams/sequence/svgDraw.js +++ b/src/diagrams/sequence/svgDraw.js @@ -1,8 +1,6 @@ -export const drawRect = function (elem, rectData, insertBeforeLastChild) { +export const drawRect = function (elem, rectData) { const rectElem = elem.append('rect') - if (insertBeforeLastChild) { - rectElem.lower() - } + rectElem.attr('x', rectData.x) rectElem.attr('y', rectData.y) rectElem.attr('fill', rectData.fill) @@ -170,6 +168,22 @@ export const drawLoop = function (elem, bounds, labelText, conf) { } } + +/** + * Draws a background rectangle + * @param color - The fill color for the background + */ +export const drawBackgroundRect = function (elem, bounds) { + const rectElem = drawRect(elem, { + x: bounds.startx, + y: bounds.starty, + width: bounds.stopx - bounds.startx, + height: bounds.stopy - bounds.starty, + fill: bounds.fill, + class: 'rect' + }); + rectElem.lower(); +} /** * Setup arrow head and define the marker. The result is appended to the svg. */ @@ -334,6 +348,7 @@ export default { anchorElement, drawActivation, drawLoop, + drawBackgroundRect, insertArrowHead, insertSequenceNumber, insertArrowCrossHead, diff --git a/src/diagrams/sequence/svgDraw.spec.js b/src/diagrams/sequence/svgDraw.spec.js new file mode 100644 index 000000000..8845321a0 --- /dev/null +++ b/src/diagrams/sequence/svgDraw.spec.js @@ -0,0 +1,75 @@ +const svgDraw = require('./svgDraw') +const { MockD3 } = require('d3') +console.log(MockD3) +describe('svgDraw', function () { + describe('drawRect', function () { + it('it should append a rectangle', function () { + const svg = MockD3('svg') + svgDraw.drawRect(svg, { + x: 10, + y: 10, + fill: '#ccc', + stroke: 'red', + width: '20', + height: '20', + rx: '10', + ry: '10', + class: 'unitTestRectangleClass', + }) + expect(svg.__children.length).toBe(1) + const rect = svg.__children[0] + expect(rect.__name).toBe('rect') + expect(rect.attr).toHaveBeenCalledWith('x', 10) + expect(rect.attr).toHaveBeenCalledWith('y', 10) + expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc') + expect(rect.attr).toHaveBeenCalledWith('stroke', 'red') + expect(rect.attr).toHaveBeenCalledWith('width', '20') + expect(rect.attr).toHaveBeenCalledWith('height', '20') + expect(rect.attr).toHaveBeenCalledWith('rx', '10') + expect(rect.attr).toHaveBeenCalledWith('ry', '10') + expect(rect.attr).toHaveBeenCalledWith('class', 'unitTestRectangleClass') + }) + it('it should not add the class attribute if a class isn`t provided', () => { + const svg = MockD3('svg') + svgDraw.drawRect(svg, { + x: 10, + y: 10, + fill: '#ccc', + stroke: 'red', + width: '20', + height: '20', + rx: '10', + ry: '10', + }) + expect(svg.__children.length).toBe(1) + const rect = svg.__children[0] + expect(rect.__name).toBe('rect') + expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc') + expect(rect.attr).not.toHaveBeenCalledWith('class', expect.anything()) + }) + }) + describe('drawBackgroundRect', function () { + it('it should append a rect before the previous element within a given bound', function () { + const svg = MockD3('svg') + const boundingRect = { + startx: 50, + starty: 200, + stopx: 150, + stopy: 260, + title: undefined, + fill: '#ccc', + } + svgDraw.drawBackgroundRect(svg, boundingRect) + expect(svg.__children.length).toBe(1) + const rect = svg.__children[0] + expect(rect.__name).toBe('rect') + expect(rect.attr).toHaveBeenCalledWith('x', 50) + expect(rect.attr).toHaveBeenCalledWith('y', 200) + expect(rect.attr).toHaveBeenCalledWith('width', 100) + expect(rect.attr).toHaveBeenCalledWith('height', 60) + expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc') + expect(rect.attr).toHaveBeenCalledWith('class', 'rect') + expect(rect.lower).toHaveBeenCalled() + }) + }) +}) From 8b05eeaa59cdbffae03de8d4e7616fd751132c01 Mon Sep 17 00:00:00 2001 From: Alexander Sage Date: Tue, 23 Jul 2019 19:15:54 -0700 Subject: [PATCH 3/7] chore: Added unit tests around drawBackgroundRect and drawRect --- __mocks__/d3.js | 8 +- src/diagrams/sequence/sequenceRenderer.js | 2 +- src/diagrams/sequence/svgDraw.js | 5 +- src/diagrams/sequence/svgDraw.spec.js | 139 +++++++++++----------- 4 files changed, 77 insertions(+), 77 deletions(-) diff --git a/__mocks__/d3.js b/__mocks__/d3.js index be43b1bd7..ca3a2822a 100644 --- a/__mocks__/d3.js +++ b/__mocks__/d3.js @@ -1,4 +1,4 @@ - +/* eslint-env jest */ let NewD3 = function () { return { append: function () { @@ -41,9 +41,9 @@ export const curveCardinal = 'cardinal' export const MockD3 = (name, parent) => { const children = [] const elem = { - get __children () { return children }, - get __name () { return name }, - get __parent () { return parent } + get __children () { return children }, + get __name () { return name }, + get __parent () { return parent } } elem.append = (name) => { const mockElem = MockD3(name, elem) diff --git a/src/diagrams/sequence/sequenceRenderer.js b/src/diagrams/sequence/sequenceRenderer.js index 776fc103e..203ae1398 100644 --- a/src/diagrams/sequence/sequenceRenderer.js +++ b/src/diagrams/sequence/sequenceRenderer.js @@ -417,7 +417,7 @@ export const draw = function (text, id) { break case parser.yy.LINETYPE.RECT_END: const rectData = bounds.endLoop() - svgDraw.drawBackgroundRect(diagram, rectData); + svgDraw.drawBackgroundRect(diagram, rectData) bounds.bumpVerticalPos(conf.boxMargin) break case parser.yy.LINETYPE.OPT_START: diff --git a/src/diagrams/sequence/svgDraw.js b/src/diagrams/sequence/svgDraw.js index 1c5c8fd28..495150609 100644 --- a/src/diagrams/sequence/svgDraw.js +++ b/src/diagrams/sequence/svgDraw.js @@ -168,7 +168,6 @@ export const drawLoop = function (elem, bounds, labelText, conf) { } } - /** * Draws a background rectangle * @param color - The fill color for the background @@ -181,8 +180,8 @@ export const drawBackgroundRect = function (elem, bounds) { height: bounds.stopy - bounds.starty, fill: bounds.fill, class: 'rect' - }); - rectElem.lower(); + }) + rectElem.lower() } /** * Setup arrow head and define the marker. The result is appended to the svg. diff --git a/src/diagrams/sequence/svgDraw.spec.js b/src/diagrams/sequence/svgDraw.spec.js index 8845321a0..efb541e78 100644 --- a/src/diagrams/sequence/svgDraw.spec.js +++ b/src/diagrams/sequence/svgDraw.spec.js @@ -1,75 +1,76 @@ +/* eslint-env jasmine */ const svgDraw = require('./svgDraw') const { MockD3 } = require('d3') -console.log(MockD3) + describe('svgDraw', function () { - describe('drawRect', function () { - it('it should append a rectangle', function () { - const svg = MockD3('svg') - svgDraw.drawRect(svg, { - x: 10, - y: 10, - fill: '#ccc', - stroke: 'red', - width: '20', - height: '20', - rx: '10', - ry: '10', - class: 'unitTestRectangleClass', - }) - expect(svg.__children.length).toBe(1) - const rect = svg.__children[0] - expect(rect.__name).toBe('rect') - expect(rect.attr).toHaveBeenCalledWith('x', 10) - expect(rect.attr).toHaveBeenCalledWith('y', 10) - expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc') - expect(rect.attr).toHaveBeenCalledWith('stroke', 'red') - expect(rect.attr).toHaveBeenCalledWith('width', '20') - expect(rect.attr).toHaveBeenCalledWith('height', '20') - expect(rect.attr).toHaveBeenCalledWith('rx', '10') - expect(rect.attr).toHaveBeenCalledWith('ry', '10') - expect(rect.attr).toHaveBeenCalledWith('class', 'unitTestRectangleClass') - }) - it('it should not add the class attribute if a class isn`t provided', () => { - const svg = MockD3('svg') - svgDraw.drawRect(svg, { - x: 10, - y: 10, - fill: '#ccc', - stroke: 'red', - width: '20', - height: '20', - rx: '10', - ry: '10', - }) - expect(svg.__children.length).toBe(1) - const rect = svg.__children[0] - expect(rect.__name).toBe('rect') - expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc') - expect(rect.attr).not.toHaveBeenCalledWith('class', expect.anything()) - }) + describe('drawRect', function () { + it('it should append a rectangle', function () { + const svg = MockD3('svg') + svgDraw.drawRect(svg, { + x: 10, + y: 10, + fill: '#ccc', + stroke: 'red', + width: '20', + height: '20', + rx: '10', + ry: '10', + class: 'unitTestRectangleClass' + }) + expect(svg.__children.length).toBe(1) + const rect = svg.__children[0] + expect(rect.__name).toBe('rect') + expect(rect.attr).toHaveBeenCalledWith('x', 10) + expect(rect.attr).toHaveBeenCalledWith('y', 10) + expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc') + expect(rect.attr).toHaveBeenCalledWith('stroke', 'red') + expect(rect.attr).toHaveBeenCalledWith('width', '20') + expect(rect.attr).toHaveBeenCalledWith('height', '20') + expect(rect.attr).toHaveBeenCalledWith('rx', '10') + expect(rect.attr).toHaveBeenCalledWith('ry', '10') + expect(rect.attr).toHaveBeenCalledWith('class', 'unitTestRectangleClass') }) - describe('drawBackgroundRect', function () { - it('it should append a rect before the previous element within a given bound', function () { - const svg = MockD3('svg') - const boundingRect = { - startx: 50, - starty: 200, - stopx: 150, - stopy: 260, - title: undefined, - fill: '#ccc', - } - svgDraw.drawBackgroundRect(svg, boundingRect) - expect(svg.__children.length).toBe(1) - const rect = svg.__children[0] - expect(rect.__name).toBe('rect') - expect(rect.attr).toHaveBeenCalledWith('x', 50) - expect(rect.attr).toHaveBeenCalledWith('y', 200) - expect(rect.attr).toHaveBeenCalledWith('width', 100) - expect(rect.attr).toHaveBeenCalledWith('height', 60) - expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc') - expect(rect.attr).toHaveBeenCalledWith('class', 'rect') - expect(rect.lower).toHaveBeenCalled() - }) + it('it should not add the class attribute if a class isn`t provided', () => { + const svg = MockD3('svg') + svgDraw.drawRect(svg, { + x: 10, + y: 10, + fill: '#ccc', + stroke: 'red', + width: '20', + height: '20', + rx: '10', + ry: '10' + }) + expect(svg.__children.length).toBe(1) + const rect = svg.__children[0] + expect(rect.__name).toBe('rect') + expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc') + expect(rect.attr).not.toHaveBeenCalledWith('class', expect.anything()) }) + }) + describe('drawBackgroundRect', function () { + it('it should append a rect before the previous element within a given bound', function () { + const svg = MockD3('svg') + const boundingRect = { + startx: 50, + starty: 200, + stopx: 150, + stopy: 260, + title: undefined, + fill: '#ccc' + } + svgDraw.drawBackgroundRect(svg, boundingRect) + expect(svg.__children.length).toBe(1) + const rect = svg.__children[0] + expect(rect.__name).toBe('rect') + expect(rect.attr).toHaveBeenCalledWith('x', 50) + expect(rect.attr).toHaveBeenCalledWith('y', 200) + expect(rect.attr).toHaveBeenCalledWith('width', 100) + expect(rect.attr).toHaveBeenCalledWith('height', 60) + expect(rect.attr).toHaveBeenCalledWith('fill', '#ccc') + expect(rect.attr).toHaveBeenCalledWith('class', 'rect') + expect(rect.lower).toHaveBeenCalled() + }) + }) }) From 5c25c5563a4d4c54a4e28a72878b9ee15f51b63b Mon Sep 17 00:00:00 2001 From: Alexander Sage Date: Tue, 23 Jul 2019 21:07:01 -0700 Subject: [PATCH 4/7] chore: Added e2e snapshot tests --- dist/index.html | 3 - ...ender-a-single-and-nested-rects-1-snap.png | Bin 0 -> 18460 bytes ...der-rect-around-and-inside-alts-1-snap.png | Bin 0 -> 12476 bytes ...er-rect-around-and-inside-loops-1-snap.png | Bin 0 -> 18175 bytes ...der-rect-around-and-inside-opts-1-snap.png | Bin 0 -> 18985 bytes e2e/spec/sequencediagram.spec.js | 86 ++++++++++++++++++ .../sequence/parser/sequenceDiagram.jison | 2 +- src/diagrams/sequence/sequenceDiagram.spec.js | 39 +++++++- src/diagrams/sequence/sequenceRenderer.js | 2 +- src/diagrams/sequence/svgDraw.js | 1 - 10 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 e2e/spec/__image_snapshots__/sequencediagram-spec-js-sequencediagram-background-rects-should-render-a-single-and-nested-rects-1-snap.png create mode 100644 e2e/spec/__image_snapshots__/sequencediagram-spec-js-sequencediagram-background-rects-should-render-rect-around-and-inside-alts-1-snap.png create mode 100644 e2e/spec/__image_snapshots__/sequencediagram-spec-js-sequencediagram-background-rects-should-render-rect-around-and-inside-loops-1-snap.png create mode 100644 e2e/spec/__image_snapshots__/sequencediagram-spec-js-sequencediagram-background-rects-should-render-rect-around-and-inside-opts-1-snap.png diff --git a/dist/index.html b/dist/index.html index 5e4c51554..61c6be7ad 100644 --- a/dist/index.html +++ b/dist/index.html @@ -326,9 +326,6 @@ par this happens in parallel Alice -->> Bob: Parallel message 1 and Alice -->> John: Parallel message 2 -end -loop awesome -A -> B: foo end diff --git a/e2e/spec/__image_snapshots__/sequencediagram-spec-js-sequencediagram-background-rects-should-render-a-single-and-nested-rects-1-snap.png b/e2e/spec/__image_snapshots__/sequencediagram-spec-js-sequencediagram-background-rects-should-render-a-single-and-nested-rects-1-snap.png new file mode 100644 index 0000000000000000000000000000000000000000..efb67e0992fb2c644f5ab4b8e70ab73a31668db7 GIT binary patch literal 18460 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 Y>OT1y=d1bvl>mW0Q-7NO*!<7`1_d7_lmGw# literal 0 HcmV?d00001 diff --git a/e2e/spec/__image_snapshots__/sequencediagram-spec-js-sequencediagram-background-rects-should-render-rect-around-and-inside-alts-1-snap.png b/e2e/spec/__image_snapshots__/sequencediagram-spec-js-sequencediagram-background-rects-should-render-rect-around-and-inside-alts-1-snap.png new file mode 100644 index 0000000000000000000000000000000000000000..ca157f2591984f407a642929a81904da3f341545 GIT binary patch literal 12476 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 B4Y>dS literal 0 HcmV?d00001 diff --git a/e2e/spec/sequencediagram.spec.js b/e2e/spec/sequencediagram.spec.js index 61572d2d9..73ae8e728 100644 --- a/e2e/spec/sequencediagram.spec.js +++ b/e2e/spec/sequencediagram.spec.js @@ -32,4 +32,90 @@ describe('Sequencediagram', () => { `, {}) }) + describe('background rects', async () => { + it('should render a single and nested rects', async () => { + await imgSnapshotTest(page, ` + sequenceDiagram + participant A + participant B + participant C + participant D + participant E + participant G + + A ->>+ B: Task 1 + rect rgb(178, 102, 255) + B ->>+ C: Task 2 + C -->>- B: Return + end + + A ->> D: Task 3 + rect rgb(0, 128, 255) + D ->>+ E: Task 4 + rect rgb(0, 204, 0) + E ->>+ G: Task 5 + G -->>- E: Return + end + E ->> E: Task 6 + end + D -->> A: Complete + `, {}) + }) + it('should render rect around and inside loops', async () => { + await imgSnapshotTest(page, ` + sequenceDiagram + A ->> B: 1 + rect rgb(204, 0, 102) + loop check C + C ->> C: Every 10 seconds + end + end + A ->> B: 2 + loop check D + C ->> D: 3 + rect rgb(153, 153, 255) + D -->> D: 5 + D --> C: 4 + end + end + `, {}) + }) + it('should render rect around and inside alts', async () => { + await imgSnapshotTest(page, ` + sequenceDiagram + A ->> B: 1 + rect rgb(204, 0, 102) + alt yes + C ->> C: 1 + else no + rect rgb(0, 204, 204) + C ->> C: 0 + end + end + end + B ->> A: Return + `, {}) + }) + it('should render rect around and inside opts', async () => { + await imgSnapshotTest(page, ` + sequenceDiagram + A ->> B: 1 + rect rgb(204, 0, 102) + opt maybe + C -->> D: Do something + rect rgb(0, 204, 204) + C ->> C: 0 + end + end + end + + opt possibly + rect rgb(0, 204, 204) + C ->> C: 0 + end + end + B ->> A: Return + `, {}) + }) + }) }) diff --git a/src/diagrams/sequence/parser/sequenceDiagram.jison b/src/diagrams/sequence/parser/sequenceDiagram.jison index 90e09a0f9..37ec693ec 100644 --- a/src/diagrams/sequence/parser/sequenceDiagram.jison +++ b/src/diagrams/sequence/parser/sequenceDiagram.jison @@ -31,7 +31,7 @@ "as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; } (?:) { this.popState(); this.popState(); return 'NL'; } "loop" { this.begin('LINE'); return 'loop'; } -"rect" { this.begin('LINE'); return 'rect'; } +"rect" { this.begin('LINE'); return 'rect'; } "opt" { this.begin('LINE'); return 'opt'; } "alt" { this.begin('LINE'); return 'alt'; } "else" { this.begin('LINE'); return 'else'; } diff --git a/src/diagrams/sequence/sequenceDiagram.spec.js b/src/diagrams/sequence/sequenceDiagram.spec.js index ed0f8047d..2489616a3 100644 --- a/src/diagrams/sequence/sequenceDiagram.spec.js +++ b/src/diagrams/sequence/sequenceDiagram.spec.js @@ -369,13 +369,13 @@ describe('when parsing a sequenceDiagram', function () { expect(messages[0].from).toBe('Alice') expect(messages[1].from).toBe('Bob') }) - it('it should handle rect statements', function () { + it.only('it should add a rect around sequence', function () { const str = ` sequenceDiagram Alice->Bob: Hello Bob, how are you? %% Comment - Note right of Bob: Bob thinks rect rgb(200, 255, 200) + Note right of Bob: Bob thinks Bob-->Alice: I am good thanks end ` @@ -386,10 +386,39 @@ describe('when parsing a sequenceDiagram', function () { actors.Bob.description = 'Bob' const messages = parser.yy.getMessages() + expect(messages[1].type).toEqual(parser.yy.LINETYPE.RECT_START) + expect(messages[1].message).toBe('rgb(200, 255, 200)') + expect(messages[2].type).toEqual(parser.yy.LINETYPE.NOTE) + expect(messages[3].type).toEqual(parser.yy.LINETYPE.DOTTED_OPEN) + expect(messages[4].type).toEqual(parser.yy.LINETYPE.RECT_END) + }) - expect(messages.length).toBe(5) - expect(messages[0].from).toBe('Alice') - expect(messages[1].from).toBe('Bob') + it.only('it should allow for nested rects', function () { + const str = ` + sequenceDiagram + Alice->Bob: Hello Bob, how are you? + %% Comment + rect rgb(200, 255, 200) + rect rgb(0, 0, 0) + Note right of Bob: Bob thinks + end + Bob-->Alice: I am good thanks + end + ` + parser.parse(str) + const actors = parser.yy.getActors() + expect(actors.Alice.description).toBe('Alice') + actors.Bob.description = 'Bob' + + const messages = parser.yy.getMessages() + expect(messages[1].type).toEqual(parser.yy.LINETYPE.RECT_START) + expect(messages[1].message).toBe('rgb(200, 255, 200)') + expect(messages[2].type).toEqual(parser.yy.LINETYPE.RECT_START) + expect(messages[2].message).toBe('rgb(0, 0, 0)') + expect(messages[3].type).toEqual(parser.yy.LINETYPE.NOTE) + expect(messages[4].type).toEqual(parser.yy.LINETYPE.RECT_END) + expect(messages[5].type).toEqual(parser.yy.LINETYPE.DOTTED_OPEN) + expect(messages[6].type).toEqual(parser.yy.LINETYPE.RECT_END) }) it('it should handle opt statements', function () { const str = 'sequenceDiagram\n' + diff --git a/src/diagrams/sequence/sequenceRenderer.js b/src/diagrams/sequence/sequenceRenderer.js index 203ae1398..4e4b0f74d 100644 --- a/src/diagrams/sequence/sequenceRenderer.js +++ b/src/diagrams/sequence/sequenceRenderer.js @@ -413,7 +413,7 @@ export const draw = function (text, id) { case parser.yy.LINETYPE.RECT_START: bounds.bumpVerticalPos(conf.boxMargin) bounds.newLoop(undefined, msg.message) - bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin) + bounds.bumpVerticalPos(conf.boxMargin) break case parser.yy.LINETYPE.RECT_END: const rectData = bounds.endLoop() diff --git a/src/diagrams/sequence/svgDraw.js b/src/diagrams/sequence/svgDraw.js index 495150609..c33e470cc 100644 --- a/src/diagrams/sequence/svgDraw.js +++ b/src/diagrams/sequence/svgDraw.js @@ -1,6 +1,5 @@ export const drawRect = function (elem, rectData) { const rectElem = elem.append('rect') - rectElem.attr('x', rectData.x) rectElem.attr('y', rectData.y) rectElem.attr('fill', rectData.fill) From 671a892b52490873d5188bb530bf017fbec64c54 Mon Sep 17 00:00:00 2001 From: Alexander Sage Date: Tue, 23 Jul 2019 21:08:33 -0700 Subject: [PATCH 5/7] fix: removed it.only --- src/diagrams/sequence/sequenceDiagram.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagrams/sequence/sequenceDiagram.spec.js b/src/diagrams/sequence/sequenceDiagram.spec.js index 2489616a3..50a801e7b 100644 --- a/src/diagrams/sequence/sequenceDiagram.spec.js +++ b/src/diagrams/sequence/sequenceDiagram.spec.js @@ -369,7 +369,7 @@ describe('when parsing a sequenceDiagram', function () { expect(messages[0].from).toBe('Alice') expect(messages[1].from).toBe('Bob') }) - it.only('it should add a rect around sequence', function () { + it('it should add a rect around sequence', function () { const str = ` sequenceDiagram Alice->Bob: Hello Bob, how are you? @@ -393,7 +393,7 @@ describe('when parsing a sequenceDiagram', function () { expect(messages[4].type).toEqual(parser.yy.LINETYPE.RECT_END) }) - it.only('it should allow for nested rects', function () { + it('it should allow for nested rects', function () { const str = ` sequenceDiagram Alice->Bob: Hello Bob, how are you? From 8f6d1484817d3293df666e84d5973d34d57404a8 Mon Sep 17 00:00:00 2001 From: Alexander Sage Date: Tue, 23 Jul 2019 21:28:48 -0700 Subject: [PATCH 6/7] chore: added test for background rect dimensions --- __mocks__/d3.js | 3 +++ src/diagrams/sequence/sequenceDiagram.spec.js | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/__mocks__/d3.js b/__mocks__/d3.js index ca3a2822a..73e5482bd 100644 --- a/__mocks__/d3.js +++ b/__mocks__/d3.js @@ -4,6 +4,9 @@ let NewD3 = function () { append: function () { return NewD3() }, + lower: function () { + return this + }, attr: function () { return this }, diff --git a/src/diagrams/sequence/sequenceDiagram.spec.js b/src/diagrams/sequence/sequenceDiagram.spec.js index 50a801e7b..d9039e6c5 100644 --- a/src/diagrams/sequence/sequenceDiagram.spec.js +++ b/src/diagrams/sequence/sequenceDiagram.spec.js @@ -980,6 +980,24 @@ describe('when rendering a sequenceDiagram', function () { expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin) expect(bounds.stopy).toBe(0 + 2 * conf.messageMargin + conf.height + 3 * conf.boxMargin + conf.boxTextMargin) }) + it('it should draw background rect', function () { + renderer.bounds.init() + const str = ` + sequenceDiagram + Alice->Bob: Hello Bob, are you alright? + rect rgb(0, 0, 0) + Bob->Alice: I feel surrounded by darkness + end + ` + parser.parse(str) + renderer.draw(str, 'tst') + const bounds = renderer.bounds.getBounds() + expect(bounds.startx).toBe(0) + expect(bounds.starty).toBe(0) + + expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin) + expect(bounds.stopy).toBe(0 + 2 * conf.messageMargin + conf.height + 3 * conf.boxMargin) + }) }) describe('when rendering a sequenceDiagram with actor mirror activated', function () { From b5e3323a936026a530cc563d2bd3928ebe37fa8a Mon Sep 17 00:00:00 2001 From: Alexander Sage Date: Tue, 23 Jul 2019 21:33:03 -0700 Subject: [PATCH 7/7] fix: workaround for function 25 line limit --- __mocks__/d3.js | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/__mocks__/d3.js b/__mocks__/d3.js index 73e5482bd..caee810ad 100644 --- a/__mocks__/d3.js +++ b/__mocks__/d3.js @@ -1,21 +1,16 @@ /* eslint-env jest */ let NewD3 = function () { + function returnThis () { + return this + } return { append: function () { return NewD3() }, - lower: function () { - return this - }, - attr: function () { - return this - }, - style: function () { - return this - }, - text: function () { - return this - }, + lower: returnThis, + attr: returnThis, + style: returnThis, + text: returnThis, 0: { 0: { getBBox: function () {