diff --git a/.changeset/tired-rockets-rule.md b/.changeset/tired-rockets-rule.md new file mode 100644 index 00000000000..5d850562222 --- /dev/null +++ b/.changeset/tired-rockets-rule.md @@ -0,0 +1,5 @@ +--- +'mermaid': patch +--- + +Fix invalid syntax between state and '{' diff --git a/packages/mermaid/src/diagrams/state/parser/state-parser.spec.js b/packages/mermaid/src/diagrams/state/parser/state-parser.spec.js index c498b4b1a3d..a9964b84d52 100644 --- a/packages/mermaid/src/diagrams/state/parser/state-parser.spec.js +++ b/packages/mermaid/src/diagrams/state/parser/state-parser.spec.js @@ -14,6 +14,40 @@ describe('state parser can parse...', () => { stateDiagram.parser.yy.clear(); }); + describe('invalid name between state and curly bracket', () => { + describe('valid syntax', () => { + it('should only accept 1 word', () => { + const diagramText = `stateDiagram-v2 + state valid { X }`; + + stateDiagram.parser.parse(diagramText); + + const states = stateDiagram.parser.yy.getStates(); + expect(states.get('valid')).not.toBeUndefined(); + }); + }); + + describe('invalid syntax', () => { + it('should throw error with 2 words', () => { + const diagramText = `stateDiagram-v2 + state invalid syntax { Y }`; + + expect(() => { + stateDiagram.parser.parse(diagramText); + }).toThrow('Error: State name must be a single word.'); + }); + + it('should also throw with more than 2 words', () => { + const diagramText = `stateDiagram-v2 + state invalid syntax with more than 2 words { Z }`; + + expect(() => { + stateDiagram.parser.parse(diagramText); + }).toThrow('Error: State name must be a single word.'); + }); + }); + }); + describe('states with id displayed as a (name)', () => { describe('syntax 1: stateID as "name in quotes"', () => { it('stateID as "some name"', () => { diff --git a/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison b/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison index 59cb3cd11b8..604111c2350 100644 --- a/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison +++ b/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison @@ -130,6 +130,7 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili [^\n\{]* { if (!processId()) return; this.popState(); /* console.log('STATE_ID', yytext); */ return "ID"; } ["] { this.popState(); } [^"]* { /* console.log('Long description:', yytext); */ return "STATE_DESCR"; } +\w+\s+\w+.*?\{ { throw new Error('Error: State name must be a single word. Found: "' + yytext.trim() + '"'); } [^\n\s\{]+ { /* console.log('COMPOSIT_STATE', yytext); */ return 'COMPOSIT_STATE'; } \n { this.popState(); } \{ { this.popState(); this.pushState('struct'); /* console.log('begin struct', yytext); */ return 'STRUCT_START'; } @@ -349,4 +350,4 @@ notePosition | right_of ; -%% +%% \ No newline at end of file