Skip to content

Commit

Permalink
Implemented model tests
Browse files Browse the repository at this point in the history
  • Loading branch information
arminzavada committed Nov 4, 2024
1 parent 2d00f88 commit 2e7b512
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 158 deletions.
9 changes: 9 additions & 0 deletions test/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
declare global {
namespace jest {
interface Matchers<R> {
toBeValid(): R;
}
}
}

export {};
53 changes: 0 additions & 53 deletions test/linking/linking.test.ts

This file was deleted.

180 changes: 141 additions & 39 deletions test/parsing/parsing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,160 @@ import { EmptyFileSystem, type LangiumDocument } from "langium";
import { expandToString as s } from "langium/generate";
import { parseHelper } from "langium/test";
import { createHw2Services } from "../../src/language/hw-2-module.js";
import { Model, isModel } from "../../src/language/generated/ast.js";
import {CPSModel, isCPSModel } from "../../src/language/generated/ast.js";

let services: ReturnType<typeof createHw2Services>;
let parse: ReturnType<typeof parseHelper<Model>>;
let document: LangiumDocument<Model> | undefined;
let parse: ReturnType<typeof parseHelper<CPSModel>>;
let document: LangiumDocument<CPSModel> | undefined;

beforeAll(async () => {
services = createHw2Services(EmptyFileSystem);
parse = parseHelper<Model>(services.Hw2);
parse = parseHelper<CPSModel>(services.Hw2);
});

expect.extend({
toBeValid(received: LangiumDocument) {
if (received.parseResult.lexerErrors.length != 0) {
return {
message: () => s`
Lexer errors:
${received.parseResult.lexerErrors.map(e => e.message).join('\n ')}
`,
pass: false
};
}

if (received.parseResult.parserErrors.length != 0) {
return {
message: () => s`
Parser errors:
${received.parseResult.parserErrors.map(e => e.message).join('\n ')}
`,
pass: false
};
}

if (received.parseResult.value === undefined) {
return {
message: () => `ParseResult is 'undefined'.`,
pass: false
}
}

if (!isCPSModel(received.parseResult.value)) {
return {
message: () => `ParseResult is not a CPSModel instance.`,
pass: false
}
}

// activate the following if your linking test requires elements from a built-in library, for example
// await services.shared.workspace.WorkspaceManager.initializeWorkspace([]);
return {
message: () => `Model successfully parsed!`,
pass: true
}
}
});

describe('Parsing tests', () => {

test('parse simple model', async () => {
test('Test model 1: Empty sections with comments', async () => {
document = await parse(`
person Langium
Hello Langium!
repository {
// there will be a section for different softwares
}
market {
// there will be a section for different computers
}
cps SmartHome {
// This will be a simplified specification for our smart home
}
`);

// check for absensce of parser errors the classic way:
// deacivated, find a much more human readable way below!
// expect(document.parseResult.parserErrors).toHaveLength(0);

expect(
// here we use a (tagged) template expression to create a human readable representation
// of the AST part we are interested in and that is to be compared to our expectation;
// prior to the tagged template expression we check for validity of the parsed document object
// by means of the reusable function 'checkDocumentValid()' to sort out (critical) typos first;
checkDocumentValid(document) || s`
Persons:
${document.parseResult.value?.persons?.map(p => p.name)?.join('\n ')}
Greetings to:
${document.parseResult.value?.greetings?.map(g => g.person.$refText)?.join('\n ')}
`
).toBe(s`
Persons:
Langium
Greetings to:
Langium
expect(document).toBeValid();
});

test('Test model 2: Computers specified in the market', async () => {
document = await parse(`
repository { }
market {
computer RaspBerr5M2G processor 2.4 GHz 4 cores memory 2 GB;
computer RaspBerr5M4G processor 2.4 GHz 4 cores memory 4 GB;
computer RaspBerr5M8G processor 2.4 GHz 4 cores memory 8 GB;
computer PersonalComputer processor 3.6 GHz memory 32 GB;
}
cps SmartHome { }
`);

expect(document).toBeValid();
});
});

function checkDocumentValid(document: LangiumDocument): string | undefined {
return document.parseResult.parserErrors.length && s`
Parser errors:
${document.parseResult.parserErrors.map(e => e.message).join('\n ')}
`
|| document.parseResult.value === undefined && `ParseResult is 'undefined'.`
|| !isModel(document.parseResult.value) && `Root AST object is a ${document.parseResult.value.$type}, expected a '${Model}'.`
|| undefined;
}
test('Test model 3: Software in repository and computers in market', async () => {
document = await parse(`
repository {
software RaspberryOS requires memory 1 GB;
software BasicSensorDriverPack depends on RaspberryOS;
software RabbitMQApp depends on BasicSensorDriverPack RaspberryOS;
software FedoraWorkstation requires memory 4 GB;
software OpenControlPanel depends on FedoraWorkstation;
}
market {
computer RaspBerr5M2G processor 2.4 GHz 4 cores memory 2 GB;
computer RaspBerr5M4G processor 2.4 GHz 4 cores memory 4 GB;
computer RaspBerr5M8G processor 2.4 GHz 4 cores memory 8 GB;
computer PersonalComputer processor 3.6 GHz memory 32 GB;
}
cps SmartHome { }
`);

expect(document).toBeValid();
});

test('Test model 4: Full CPS specification with computers and connections', async () => {
document = await parse(`
repository {
software RaspberryOS requires memory 1 GB;
software BasicSensorDriverPack depends on RaspberryOS;
software RabbitMQApp depends on BasicSensorDriverPack RaspberryOS;
software FedoraWorkstation requires memory 4 GB;
software OpenControlPanel depends on FedoraWorkstation;
}
market {
computer RaspBerr5M2G processor 2.4 GHz 4 cores memory 2 GB;
computer RaspBerr5M4G processor 2.4 GHz 4 cores memory 4 GB;
computer RaspBerr5M8G processor 2.4 GHz 4 cores memory 8 GB;
computer PersonalComputer processor 3.6 GHz memory 32 GB;
}
cps SmartHome {
computer RaspBerr5M2G termometer1 {
add Thermometer
install RaspberryOS
install BasicSensorDriverPack
}
computer RaspBerr5M2G termometer2 {
add Thermometer
install RaspberryOS
install BasicSensorDriverPack
}
computer RaspBerr5M2G heatController {
install RaspberryOS
install BasicSensorDriverPack
add HeatController
}
termometer1 -o)- heatController
termometer2 -o)- heatController
computer RaspBerr5M2G smokeDetector {
add SmokeDetector
add FireAlarm
install RaspberryOS
install BasicSensorDriverPack
}
smokeDetector -o)- smokeDetector
}
`);

expect(document).toBeValid();
});
});
66 changes: 0 additions & 66 deletions test/validating/validating.test.ts

This file was deleted.

0 comments on commit 2e7b512

Please sign in to comment.