⚗️ Add parser tests for architecture and other edge cases encountered

This commit is contained in:
Thomas Di Cizerone
2025-03-23 22:15:37 +01:00
parent 9795b6e089
commit 04d68e7f9a
4 changed files with 295 additions and 166 deletions

View File

@@ -0,0 +1,88 @@
import { describe, expect, it } from 'vitest';
import { Architecture } from '../src/language/index.js';
import { expectNoErrorsOrAlternatives, architectureParse as parse } from './test-util.js';
describe('architecture', () => {
describe('should handle architecture definition', () => {
it.each([
`architecture-beta`,
` architecture-beta `,
`\tarchitecture-beta\t`,
`
\tarchitecture-beta
`,
])('should handle regular architecture', (context: string) => {
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Architecture);
});
});
describe('should handle TitleAndAccessibilities', () => {
it.each([
`architecture-beta title sample title`,
` architecture-beta title sample title `,
`\tarchitecture-beta\ttitle sample title\t`,
`architecture-beta
\ttitle sample title
`,
])('should handle regular architecture + title in same line', (context: string) => {
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Architecture);
const { title } = result.value;
expect(title).toBe('sample title');
});
it.each([
`architecture-beta
title sample title`,
`architecture-beta
title sample title
`,
])('should handle regular architecture + title in next line', (context: string) => {
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Architecture);
const { title } = result.value;
expect(title).toBe('sample title');
});
it('should handle regular architecture + title + accTitle + accDescr', () => {
const context = `architecture-beta
title sample title
accTitle: sample accTitle
accDescr: sample accDescr
`;
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Architecture);
const { title, accTitle, accDescr } = result.value;
expect(title).toBe('sample title');
expect(accTitle).toBe('sample accTitle');
expect(accDescr).toBe('sample accDescr');
});
it('should handle regular architecture + title + accTitle + multi-line accDescr', () => {
const context = `architecture-beta
title sample title
accTitle: sample accTitle
accDescr {
sample accDescr
}
`;
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Architecture);
const { title, accTitle, accDescr } = result.value;
expect(title).toBe('sample title');
expect(accTitle).toBe('sample accTitle');
expect(accDescr).toBe('sample accDescr');
});
});
});

View File

@@ -63,6 +63,12 @@ describe('Parsing Branch Statements', () => {
expect(branch.name).toBe('master'); expect(branch.name).toBe('master');
}); });
it('should parse a branch name starting with numbers', () => {
const result = parse(`gitGraph\n commit\n branch 1.0.1\n`);
const branch = result.value.statements[1] as Branch;
expect(branch.name).toBe('1.0.1');
});
it('should parse a branch with an order property', () => { it('should parse a branch with an order property', () => {
const result = parse(`gitGraph\n commit\n branch feature order:1\n`); const result = parse(`gitGraph\n commit\n branch feature order:1\n`);
const branch = result.value.statements[1] as Branch; const branch = result.value.statements[1] as Branch;

View File

@@ -4,226 +4,247 @@ import { Pie } from '../src/language/index.js';
import { expectNoErrorsOrAlternatives, pieParse as parse } from './test-util.js'; import { expectNoErrorsOrAlternatives, pieParse as parse } from './test-util.js';
describe('pie', () => { describe('pie', () => {
it.each([ describe('should handle pie definition with or without showData', () => {
`pie`, it.each([
` pie `, `pie`,
`\tpie\t`, ` pie `,
` `\tpie\t`,
`
\tpie \tpie
`, `,
])('should handle regular pie', (context: string) => { ])('should handle regular pie', (context: string) => {
const result = parse(context); const result = parse(context);
expectNoErrorsOrAlternatives(result); expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie); expect(result.value.$type).toBe(Pie);
}); });
it.each([ it.each([
`pie showData`, `pie showData`,
` pie showData `, ` pie showData `,
`\tpie\tshowData\t`, `\tpie\tshowData\t`,
` `
pie\tshowData pie\tshowData
`, `,
])('should handle regular showData', (context: string) => { ])('should handle regular showData', (context: string) => {
const result = parse(context); const result = parse(context);
expectNoErrorsOrAlternatives(result); expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie); expect(result.value.$type).toBe(Pie);
const { showData } = result.value; const { showData } = result.value;
expect(showData).toBeTruthy(); expect(showData).toBeTruthy();
});
}); });
describe('should handle TitleAndAccessibilities', () => {
describe('should handle TitleAndAccessibilities without showData', () => {
it.each([
`pie title sample title`,
` pie title sample title `,
`\tpie\ttitle sample title\t`,
`pie
\ttitle sample title
`,
])('should handle regular pie + title in same line', (context: string) => {
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie);
it.each([ const { title } = result.value;
`pie title sample title`, expect(title).toBe('sample title');
` pie title sample title `, });
`\tpie\ttitle sample title\t`,
`pie
\ttitle sample title
`,
])('should handle regular pie + title in same line', (context: string) => {
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie);
const { title } = result.value;
expect(title).toBe('sample title');
});
it.each([
`pie
title sample title`,
`pie
title sample title
`,
`pie
title sample title`,
`pie
title sample title
`,
])('should handle regular pie + title in different line', (context: string) => {
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie);
const { title } = result.value;
expect(title).toBe('sample title');
});
it.each([
`pie showData title sample title`,
`pie showData title sample title
`,
])('should handle regular pie + showData + title', (context: string) => {
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie);
const { showData, title } = result.value;
expect(showData).toBeTruthy();
expect(title).toBe('sample title');
});
it.each([
`pie showData
title sample title`,
`pie showData
title sample title
`,
`pie showData
title sample title`,
`pie showData
title sample title
`,
])('should handle regular showData + title in different line', (context: string) => {
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie);
const { showData, title } = result.value;
expect(showData).toBeTruthy();
expect(title).toBe('sample title');
});
describe('sections', () => {
describe('normal', () => {
it.each([ it.each([
`pie `pie
title sample title`,
`pie
title sample title
`,
`pie
title sample title`,
`pie
title sample title
`,
])('should handle regular pie + title in different line', (context: string) => {
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie);
const { title } = result.value;
expect(title).toBe('sample title');
});
});
describe('should handle TitleAndAccessibilities with showData', () => {
it.each([
`pie showData title sample title`,
`pie showData title sample title
`,
])('should handle regular pie + showData + title', (context: string) => {
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie);
const { showData, title } = result.value;
expect(showData).toBeTruthy();
expect(title).toBe('sample title');
});
it.each([
`pie showData
title sample title`,
`pie showData
title sample title
`,
`pie showData
title sample title`,
`pie showData
title sample title
`,
])('should handle regular showData + title in different line', (context: string) => {
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie);
const { showData, title } = result.value;
expect(showData).toBeTruthy();
expect(title).toBe('sample title');
});
});
});
describe('should handle sections', () => {
it.each([
`pie
"GitHub":100 "GitHub":100
"GitLab":50`, "GitLab":50`,
`pie `pie
"GitHub" : 100 "GitHub" : 100
"GitLab" : 50`, "GitLab" : 50`,
`pie `pie
"GitHub"\t:\t100 "GitHub"\t:\t100
"GitLab"\t:\t50`, "GitLab"\t:\t50`,
`pie `pie
\t"GitHub" \t : \t 100 \t"GitHub" \t : \t 100
\t"GitLab" \t : \t 50 \t"GitLab" \t : \t 50
`, `,
])('should handle regular sections', (context: string) => { ])('should handle regular sections', (context: string) => {
const result = parse(context); const result = parse(context);
expectNoErrorsOrAlternatives(result); expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie); expect(result.value.$type).toBe(Pie);
const { sections } = result.value; const { sections } = result.value;
expect(sections[0].label).toBe('GitHub'); expect(sections[0].label).toBe('GitHub');
expect(sections[0].value).toBe(100); expect(sections[0].value).toBe(100);
expect(sections[1].label).toBe('GitLab'); expect(sections[1].label).toBe('GitLab');
expect(sections[1].value).toBe(50); expect(sections[1].value).toBe(50);
}); });
it('should handle sections with showData', () => { it('should handle sections with showData', () => {
const context = `pie showData const context = `pie showData
"GitHub": 100 "GitHub": 100
"GitLab": 50`; "GitLab": 50`;
const result = parse(context); const result = parse(context);
expectNoErrorsOrAlternatives(result); expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie); expect(result.value.$type).toBe(Pie);
const { showData, sections } = result.value; const { showData, sections } = result.value;
expect(showData).toBeTruthy(); expect(showData).toBeTruthy();
expect(sections[0].label).toBe('GitHub'); expect(sections[0].label).toBe('GitHub');
expect(sections[0].value).toBe(100); expect(sections[0].value).toBe(100);
expect(sections[1].label).toBe('GitLab'); expect(sections[1].label).toBe('GitLab');
expect(sections[1].value).toBe(50); expect(sections[1].value).toBe(50);
}); });
it('should handle sections with title', () => { it('should handle sections with title', () => {
const context = `pie title sample wow const context = `pie title sample wow
"GitHub": 100 "GitHub": 100
"GitLab": 50`; "GitLab": 50`;
const result = parse(context); const result = parse(context);
expectNoErrorsOrAlternatives(result); expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie); expect(result.value.$type).toBe(Pie);
const { title, sections } = result.value; const { title, sections } = result.value;
expect(title).toBe('sample wow'); expect(title).toBe('sample wow');
expect(sections[0].label).toBe('GitHub'); expect(sections[0].label).toBe('GitHub');
expect(sections[0].value).toBe(100); expect(sections[0].value).toBe(100);
expect(sections[1].label).toBe('GitLab'); expect(sections[1].label).toBe('GitLab');
expect(sections[1].value).toBe(50); expect(sections[1].value).toBe(50);
}); });
it('should handle sections with accTitle', () => { it('should handle value with positive decimal', () => {
const context = `pie accTitle: sample wow const context = `pie
"ash": 60.67
"bat": 40`;
const result = parse(context);
expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie);
const { sections } = result.value;
expect(sections[0].label).toBe('ash');
expect(sections[0].value).toBe(60.67);
expect(sections[1].label).toBe('bat');
expect(sections[1].value).toBe(40);
});
it('should handle sections with accTitle', () => {
const context = `pie accTitle: sample wow
"GitHub": 100 "GitHub": 100
"GitLab": 50`; "GitLab": 50`;
const result = parse(context); const result = parse(context);
expectNoErrorsOrAlternatives(result); expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie); expect(result.value.$type).toBe(Pie);
const { accTitle, sections } = result.value; const { accTitle, sections } = result.value;
expect(accTitle).toBe('sample wow'); expect(accTitle).toBe('sample wow');
expect(sections[0].label).toBe('GitHub'); expect(sections[0].label).toBe('GitHub');
expect(sections[0].value).toBe(100); expect(sections[0].value).toBe(100);
expect(sections[1].label).toBe('GitLab'); expect(sections[1].label).toBe('GitLab');
expect(sections[1].value).toBe(50); expect(sections[1].value).toBe(50);
}); });
it('should handle sections with single line accDescr', () => { it('should handle sections with single line accDescr', () => {
const context = `pie accDescr: sample wow const context = `pie accDescr: sample wow
"GitHub": 100 "GitHub": 100
"GitLab": 50`; "GitLab": 50`;
const result = parse(context); const result = parse(context);
expectNoErrorsOrAlternatives(result); expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie); expect(result.value.$type).toBe(Pie);
const { accDescr, sections } = result.value; const { accDescr, sections } = result.value;
expect(accDescr).toBe('sample wow'); expect(accDescr).toBe('sample wow');
expect(sections[0].label).toBe('GitHub'); expect(sections[0].label).toBe('GitHub');
expect(sections[0].value).toBe(100); expect(sections[0].value).toBe(100);
expect(sections[1].label).toBe('GitLab'); expect(sections[1].label).toBe('GitLab');
expect(sections[1].value).toBe(50); expect(sections[1].value).toBe(50);
}); });
it('should handle sections with multi line accDescr', () => { it('should handle sections with multi line accDescr', () => {
const context = `pie accDescr { const context = `pie accDescr {
sample wow sample wow
} }
"GitHub": 100 "GitHub": 100
"GitLab": 50`; "GitLab": 50`;
const result = parse(context); const result = parse(context);
expectNoErrorsOrAlternatives(result); expectNoErrorsOrAlternatives(result);
expect(result.value.$type).toBe(Pie); expect(result.value.$type).toBe(Pie);
const { accDescr, sections } = result.value; const { accDescr, sections } = result.value;
expect(accDescr).toBe('sample wow'); expect(accDescr).toBe('sample wow');
expect(sections[0].label).toBe('GitHub'); expect(sections[0].label).toBe('GitHub');
expect(sections[0].value).toBe(100); expect(sections[0].value).toBe(100);
expect(sections[1].label).toBe('GitLab'); expect(sections[1].label).toBe('GitLab');
expect(sections[1].value).toBe(50); expect(sections[1].value).toBe(50);
});
}); });
}); });
}); });

View File

@@ -1,6 +1,8 @@
import type { LangiumParser, ParseResult } from 'langium'; import type { LangiumParser, ParseResult } from 'langium';
import { expect, vi } from 'vitest'; import { expect, vi } from 'vitest';
import type { import type {
Architecture,
ArchitectureServices,
Info, Info,
InfoServices, InfoServices,
Pie, Pie,
@@ -13,6 +15,7 @@ import type {
GitGraphServices, GitGraphServices,
} from '../src/language/index.js'; } from '../src/language/index.js';
import { import {
createArchitectureServices,
createInfoServices, createInfoServices,
createPieServices, createPieServices,
createRadarServices, createRadarServices,
@@ -47,6 +50,17 @@ export function createInfoTestServices() {
} }
export const infoParse = createInfoTestServices().parse; export const infoParse = createInfoTestServices().parse;
const architectureServices: ArchitectureServices = createArchitectureServices().Architecture;
const architectureParser: LangiumParser = architectureServices.parser.LangiumParser;
export function createArchitectureTestServices() {
const parse = (input: string) => {
return architectureParser.parse<Architecture>(input);
};
return { services: architectureServices, parse };
}
export const architectureParse = createArchitectureTestServices().parse;
const pieServices: PieServices = createPieServices().Pie; const pieServices: PieServices = createPieServices().Pie;
const pieParser: LangiumParser = pieServices.parser.LangiumParser; const pieParser: LangiumParser = pieServices.parser.LangiumParser;
export function createPieTestServices() { export function createPieTestServices() {