diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json index 4f56d9112..244ebe453 100644 --- a/packages/mermaid/package.json +++ b/packages/mermaid/package.json @@ -1,6 +1,6 @@ { "name": "mermaid", - "version": "10.2.0", + "version": "10.2.0-rc.2", "description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "type": "module", "module": "./dist/mermaid.core.mjs", diff --git a/packages/mermaid/src/diagrams/class/classDiagramGrammar.spec.js b/packages/mermaid/src/diagrams/class/classDiagramGrammar.spec.js deleted file mode 100644 index 4e9e99c70..000000000 --- a/packages/mermaid/src/diagrams/class/classDiagramGrammar.spec.js +++ /dev/null @@ -1,13 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -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/packages/mermaid/src/diagrams/class/classDiagramGrammar.spec.ts b/packages/mermaid/src/diagrams/class/classDiagramGrammar.spec.ts new file mode 100644 index 000000000..eb0c37969 --- /dev/null +++ b/packages/mermaid/src/diagrams/class/classDiagramGrammar.spec.ts @@ -0,0 +1,16 @@ +import { readFile } from 'node:fs/promises'; +// @ts-ignore - no types +import { LALRGenerator } from 'jison'; +import path from 'path'; + +const getAbsolutePath = (relativePath: string) => { + return new URL(path.join(path.dirname(import.meta.url), relativePath)).pathname; +}; + +describe('class diagram grammar', function () { + it('should have no conflicts', async function () { + const grammarSource = await readFile(getAbsolutePath('./parser/classDiagram.jison'), 'utf8'); + const grammarParser = new LALRGenerator(grammarSource, {}); + expect(grammarParser.conflicts).toBe(0); + }); +}); diff --git a/packages/mermaid/src/diagrams/class/classParser.spec.ts b/packages/mermaid/src/diagrams/class/classParser.spec.ts new file mode 100644 index 000000000..c479b8272 --- /dev/null +++ b/packages/mermaid/src/diagrams/class/classParser.spec.ts @@ -0,0 +1,78 @@ +import { setConfig } from '../../config.js'; +import classDB from './classDb.js'; +// @ts-ignore - no types in jison +import classDiagram from './parser/classDiagram.jison'; + +setConfig({ + securityLevel: 'strict', +}); + +describe('when parsing class diagram', function () { + beforeEach(function () { + classDiagram.parser.yy = classDB; + classDiagram.parser.yy.clear(); + }); + + it('should parse diagram with direction', () => { + classDiagram.parser.parse(`classDiagram + direction TB + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides`); + + expect(Object.keys(classDB.getClasses()).length).toBe(3); + expect(classDB.getClasses().Student).toMatchInlineSnapshot(` + { + "annotations": [], + "cssClasses": [], + "domId": "classId-Student-0", + "id": "Student", + "label": "Student", + "members": [ + "-idCard : IdCard", + ], + "methods": [], + "type": "", + } + `); + expect(classDB.getRelations().length).toBe(2); + expect(classDB.getRelations()).toMatchInlineSnapshot(` + [ + { + "id1": "Student", + "id2": "IdCard", + "relation": { + "lineType": 0, + "type1": "none", + "type2": 0, + }, + "relationTitle1": "1", + "relationTitle2": "1", + "title": "carries", + }, + { + "id1": "Student", + "id2": "Bike", + "relation": { + "lineType": 0, + "type1": "none", + "type2": 0, + }, + "relationTitle1": "1", + "relationTitle2": "1", + "title": "rides", + }, + ] + `); + }); +}); diff --git a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison index 6a7834eca..7afba66bc 100644 --- a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison +++ b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison @@ -200,9 +200,8 @@ Function arguments are optional: 'call ()' simply executes 'callb start : mermaidDoc - | statements - | direction | directive start + | statements ; direction @@ -272,7 +271,6 @@ statement | clickStatement | cssClassStatement | noteStatement - | directive | direction | acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); } | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } diff --git a/scripts/jison/lint.mts b/scripts/jison/lint.mts index 95edd4fb1..596ce308b 100644 --- a/scripts/jison/lint.mts +++ b/scripts/jison/lint.mts @@ -14,12 +14,17 @@ const lint = async (file: string): Promise => { console.log(`Linting ${file}`); const jisonCode = await readFile(file, 'utf8'); // @ts-ignore no typings - const jsCode = new jison.Generator(jisonCode, { moduleType: 'amd' }).generate(); + const generator = new jison.Generator(jisonCode, { moduleType: 'amd' }); + const jsCode = generator.generate(); const [result] = await linter.lintText(jsCode); if (result.errorCount > 0) { console.error(`Linting failed for ${file}`); console.error(result.messages); } + if (generator.conflicts > 0) { + console.error(`Linting failed for ${file}. Conflicts found in grammar`); + return false; + } return result.errorCount === 0; };