Skip to content

Commit

Permalink
define ENTITY_NAME that allows some non-alphanumeric chars; spec re-a…
Browse files Browse the repository at this point in the history
…rrange
  • Loading branch information
weedySeaDragon committed Sep 23, 2022
1 parent 338ba70 commit 4bedc49
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 33 deletions.
6 changes: 4 additions & 2 deletions src/diagrams/er/parser/erDiagram.jison
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
[\n]+ return 'NEWLINE';
\s+ /* skip whitespace */
[\s]+ return 'SPACE';
\"[A-Za-z0-9\!\@\#\$\^\&\*\(\)\-_\=\+\[\]\{\};:\.\?]+\" return 'ENTITY_NAME';
\"[^"]*\" return 'WORD';
"erDiagram" return 'ER_DIAGRAM';
"{" { this.begin("block"); return 'BLOCK_START'; }
Expand Down Expand Up @@ -102,8 +103,8 @@ statement
;

entityName
: 'ALPHANUM' { $$ = $1; /*console.log('Entity: ' + $1);*/ }
| 'ALPHANUM' '.' entityName { $$ = $1 + $2 + $3; }
: 'ALPHANUM' { $$ = $1; }
| 'ENTITY_NAME' { $$ = $1.replace(/"/g, ''); }
;

attributes
Expand Down Expand Up @@ -156,6 +157,7 @@ relType

role
: 'WORD' { $$ = $1.replace(/"/g, ''); }
| 'ENTITY_NAME' { $$ = $1.replace(/"/g, ''); }
| 'ALPHANUM' { $$ = $1; }
;

Expand Down
156 changes: 125 additions & 31 deletions src/diagrams/er/parser/erDiagram.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { setConfig } from '../../../config';
import erDb from '../erDb';
import erDiagram from './erDiagram';
import erDiagram from './erDiagram'; // jison file

setConfig({
securityLevel: 'strict',
Expand All @@ -21,14 +21,112 @@ describe('when parsing ER diagram it...', function () {
expect(erDb.getRelationships().length).toBe(0);
});

it('should allow hyphens and underscores in entity names', function () {
const line1 = 'DUCK-BILLED-PLATYPUS';
const line2 = 'CHARACTER_SET';
erDiagram.parser.parse(`erDiagram\n${line1}\n${line2}`);

const entities = erDb.getEntities();
expect(entities.hasOwnProperty('DUCK-BILLED-PLATYPUS')).toBe(true);
expect(entities.hasOwnProperty('CHARACTER_SET')).toBe(true);
describe('entity name', () => {
it('cannot be empty quotes ""', function () {
const name = '""';
expect(() => {
erDiagram.parser.parse(`erDiagram\n ${name}\n`);
const entities = erDb.getEntities();
expect(entities.hasOwnProperty(name)).toBe(false);
}).toThrow();
});
describe('has non A-Za-z0-9_- chars', function () {
const allowed = [
'!',
'@',
'#',
'$',
'^',
'&',
'*',
'(',
')',
'-',
'_',
'=',
'+',
'[',
']',
'{',
'}',
';',
':',
'.',
'?',
];

allowed.forEach((allowedChar) => {
const singleOccurrence = `Blo${allowedChar}rf`;
const repeatedOccurrence = `Blo${allowedChar}${allowedChar}rf`;
const cannontStartWith = `${allowedChar}Blorf`;
const endsWith = `Blorf${allowedChar}`;

it(`${singleOccurrence} fails if not surrounded by quotes`, function () {
const name = singleOccurrence;
expect(() => {
erDiagram.parser.parse(`erDiagram\n ${name}\n`);
const entities = erDb.getEntities();
expect(entities.hasOwnProperty(name)).toBe(false);
}).toThrow();
});

it(`"${singleOccurrence}" single occurrence`, function () {
const name = singleOccurrence;
erDiagram.parser.parse(`erDiagram\n "${name}"\n`);
const entities = erDb.getEntities();
expect(entities.hasOwnProperty(name)).toBe(true);
});

it(`"${repeatedOccurrence}" repeated occurrence`, function () {
const name = repeatedOccurrence;
erDiagram.parser.parse(`erDiagram\n "${name}"\n`);
const entities = erDb.getEntities();
expect(entities.hasOwnProperty(name)).toBe(true);
});

it(`"${singleOccurrence}" ends with`, function () {
const name = endsWith;
erDiagram.parser.parse(`erDiagram\n "${name}"\n`);
const entities = erDb.getEntities();
expect(entities.hasOwnProperty(name)).toBe(true);
});

it(`"${cannontStartWith}" cannot start with the character`, function () {
const name = repeatedOccurrence;
expect(() => {
erDiagram.parser.parse(`erDiagram\n "${name}"\n`);
const entities = erDb.getEntities();
expect(entities.hasOwnProperty(name)).toBe(false);
}).toThrow();
});
});

const allCombined = allowed.join('');

it(`a${allCombined} (all non-alphanumerics) in one, starting with 'a'`, function () {
const name = 'a' + allCombined;
erDiagram.parser.parse(`erDiagram\n "${name}"\n`);
const entities = erDb.getEntities();
expect(entities.hasOwnProperty(name)).toBe(true);
});
});

it('cannot contain % because it interfers with parsing comments', function () {
expect(() => {
erDiagram.parser.parse(`erDiagram\n "Blo%rf"\n`);
const entities = erDb.getEntities();
expect(entities.hasOwnProperty(name)).toBe(false);
}).toThrow();
});

it('can contain - _ ', function () {
const hyphens = 'DUCK-BILLED-PLATYPUS';
const underscores = 'CHARACTER_SET';
erDiagram.parser.parse(`erDiagram\n${hyphens}\n${underscores}\n`);
const entities = erDb.getEntities();
expect(entities.hasOwnProperty('DUCK-BILLED-PLATYPUS')).toBe(true);
expect(entities.hasOwnProperty('CHARACTER_SET')).toBe(true);
});
});

it('should allow an entity with a single attribute to be defined', function () {
Expand Down Expand Up @@ -447,27 +545,23 @@ describe('when parsing ER diagram it...', function () {
}).toThrowError();
});

it('should allow an empty quoted label', function () {
erDiagram.parser.parse('erDiagram\nCUSTOMER ||--|{ ORDER : ""');
const rels = erDb.getRelationships();
expect(rels[0].roleA).toBe('');
});

it('should allow an non-empty quoted label', function () {
erDiagram.parser.parse('erDiagram\nCUSTOMER ||--|{ ORDER : "places"');
const rels = erDb.getRelationships();
expect(rels[0].roleA).toBe('places');
});

it('should allow an non-empty unquoted label', function () {
erDiagram.parser.parse('erDiagram\nCUSTOMER ||--|{ ORDER : places');
const rels = erDb.getRelationships();
expect(rels[0].roleA).toBe('places');
});

it('should allow an entity name with a dot', function () {
erDiagram.parser.parse('erDiagram\nCUSTOMER.PROP ||--|{ ORDER : places');
const rels = erDb.getRelationships();
expect(rels[0].entityA).toBe('CUSTOMER.PROP');
describe('relationship labels', function () {
it('should allow an empty quoted label', function () {
erDiagram.parser.parse('erDiagram\nCUSTOMER ||--|{ ORDER : ""');
const rels = erDb.getRelationships();
expect(rels[0].roleA).toBe('');
});

it('should allow an non-empty quoted label', function () {
erDiagram.parser.parse('erDiagram\nCUSTOMER ||--|{ ORDER : "places"');
const rels = erDb.getRelationships();
expect(rels[0].roleA).toBe('places');
});

it('should allow an non-empty unquoted label', function () {
erDiagram.parser.parse('erDiagram\nCUSTOMER ||--|{ ORDER : places');
const rels = erDb.getRelationships();
expect(rels[0].roleA).toBe('places');
});
});
});

0 comments on commit 4bedc49

Please sign in to comment.