diff --git a/src/diagrams/class/classDiagram.spec.js b/src/diagrams/class/classDiagram.spec.js index baaa9ca65..75fb8699f 100644 --- a/src/diagrams/class/classDiagram.spec.js +++ b/src/diagrams/class/classDiagram.spec.js @@ -8,6 +8,14 @@ describe('class diagram, ', function () { parser.yy = classDb; }); + it('should handle backquoted class names', function() { + const str = + 'classDiagram\n' + + 'class `Car`'; + + parser.parse(str); + }); + it('should handle relation definitions', function () { const str = 'classDiagram\n' + @@ -20,6 +28,18 @@ describe('class diagram, ', function () { parser.parse(str); }); + it('should handle backquoted relation definitions', function () { + const str = + 'classDiagram\n' + + '`Class01` <|-- Class02\n' + + 'Class03 *-- Class04\n' + + 'Class05 o-- Class06\n' + + 'Class07 .. Class08\n' + + 'Class09 -- Class1'; + + parser.parse(str); + }); + it('should handle relation definition of different types and directions', function () { const str = 'classDiagram\n' + @@ -67,6 +87,17 @@ describe('class diagram, ', function () { parser.parse(str); }); + it('should handle generic class with a literal name', function() { + const str = + 'classDiagram\n' + + 'class `Car`~T~\n' + + 'Driver -- `Car` : drives >\n' + + '`Car` *-- Wheel : have 4 >\n' + + '`Car` -- Person : < owns'; + + parser.parse(str); + }); + it('should break when another `{`is encountered before closing the first one while defining generic class with brackets', function() { const str = 'classDiagram\n' + @@ -125,6 +156,22 @@ describe('class diagram, ', function () { parser.parse(str); }); + it('should handle generic class with brackets and a literal name', function() { + const str = + 'classDiagram\n' + + 'class `Dummy_Class`~T~ {\n' + + 'String data\n' + + ' void methods()\n' + + '}\n' + + '\n' + + 'class Flight {\n' + + ' flightNumber : Integer\n' + + ' departureTime : Date\n' + + '}'; + + parser.parse(str); + }); + it('should handle class definitions', function() { const str = 'classDiagram\n' + diff --git a/src/diagrams/class/classDiagramGrammar.spec.js b/src/diagrams/class/classDiagramGrammar.spec.js new file mode 100644 index 000000000..ff40b5cd2 --- /dev/null +++ b/src/diagrams/class/classDiagramGrammar.spec.js @@ -0,0 +1,13 @@ +/* eslint-env jasmine */ +const fs = require("fs"); + +import { LALRGenerator } from "jison"; + +describe('class diagram grammar', function () { + it("should introduce no new conflicts", function() { + const file = require.resolve("./parser/classDiagram.jison"); + const grammarSource = fs.readFileSync(file, "utf8"); + const grammarParser = new LALRGenerator(grammarSource, {}); + expect(grammarParser.conflicts < 16).toBe(true); + }); +}); diff --git a/src/diagrams/class/parser/classDiagram.jison b/src/diagrams/class/parser/classDiagram.jison index 9e740b47f..59fc7aa1d 100644 --- a/src/diagrams/class/parser/classDiagram.jison +++ b/src/diagrams/class/parser/classDiagram.jison @@ -7,6 +7,7 @@ /* lexical grammar */ %lex %x string +%x bqstring %x generic %x struct %x href @@ -49,6 +50,10 @@ ["] this.popState(); [^"]* return "STR"; +[`] this.begin("bqstring"); +[`] this.popState(); +[^`]+ return "BQUOTE_STR"; + /* ---interactivity command--- 'href' adds a link to the specified node. 'href' can only be specified when the @@ -215,9 +220,10 @@ statements className : alphaNumToken { $$=$1; } + | classLiteralName { $$=$1; } | alphaNumToken className { $$=$1+$2; } - | alphaNumToken GENERICTYPE className { $$=$1+'~'+$2+$3; } | alphaNumToken GENERICTYPE { $$=$1+'~'+$2; } + | classLiteralName GENERICTYPE { $$=$1+'~'+$2; } ; statement @@ -309,4 +315,6 @@ textNoTagsToken: alphaNumToken | SPACE | MINUS | keywords ; alphaNumToken : UNICODE_TEXT | NUM | ALPHA; +classLiteralName : BQUOTE_STR; + %%