Skip to content

Commit

Permalink
Implemented testing for new language
Browse files Browse the repository at this point in the history
  • Loading branch information
ozcanxbreeze committed Aug 17, 2023
1 parent 62ae32c commit a40b2b8
Show file tree
Hide file tree
Showing 33 changed files with 3,829 additions and 5 deletions.
5 changes: 5 additions & 0 deletions configs/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node'
};
5 changes: 5 additions & 0 deletions extensions/crossmodel-lang/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const baseConfig = require('../../configs/jest.config');

module.exports = {
...baseConfig
};
1 change: 1 addition & 0 deletions extensions/crossmodel-lang/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"symlink": "yarn symlink:browser && yarn symlink:electron",
"symlink:browser": "symlink-dir . ../../applications/browser-app/plugins/crossmodel-lang",
"symlink:electron": "symlink-dir . ../../applications/electron-app/plugins/crossmodel-lang",
"test": "jest",
"vscode:prepublish": "yarn lint",
"watch": "yarn watch:webpack",
"watch:tsc": "tsc -b tsconfig.json --watch",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Entity:
EntityFields infers Entity:
(
'id' ':' name=STRING |
'name' ':' name_val=STRING |
'description' ':' description=STRING |
'attributes' ':' EntityAttributes
)
Expand Down Expand Up @@ -80,7 +81,8 @@ SystemDiagramFields infers SystemDiagram:
'nodes' ':' SystemDiagramNodes |
'edges' ':' SystemDiagramEdge |
'id' ':' name=STRING |
'description' ':' description=STRING
'description' ':' description=STRING |
'name' ':' name_val=STRING
)
;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export interface Entity extends AstNode {
attributes: Array<EntityAttribute>
description?: string
name?: string
name_val?: string
}

export const Entity = 'Entity';
Expand Down Expand Up @@ -107,6 +108,7 @@ export interface SystemDiagram extends AstNode {
description?: string
edges: Array<DiagramEdge>
name?: string
name_val?: string
nodes: Array<DiagramNode>
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,31 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load
}
]
},
{
"$type": "Group",
"elements": [
{
"$type": "Keyword",
"value": "name"
},
{
"$type": "Keyword",
"value": ":"
},
{
"$type": "Assignment",
"feature": "name_val",
"operator": "=",
"terminal": {
"$type": "RuleCall",
"rule": {
"$ref": "#/rules@18"
},
"arguments": []
}
}
]
},
{
"$type": "Group",
"elements": [
Expand Down Expand Up @@ -811,6 +836,31 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load
}
}
]
},
{
"$type": "Group",
"elements": [
{
"$type": "Keyword",
"value": "name"
},
{
"$type": "Keyword",
"value": ":"
},
{
"$type": "Assignment",
"feature": "name_val",
"operator": "=",
"terminal": {
"$type": "RuleCall",
"rule": {
"$ref": "#/rules@18"
},
"arguments": []
}
}
]
}
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/********************************************************************************
* Copyright (c) 2023 CrossBreeze.
********************************************************************************/
import { describe, expect, test } from '@jest/globals';
import { EmptyFileSystem, isReference } from 'langium';

import { parseDocument } from './utils/utils';
import { diagram1, diagram2, diagram3, diagram4, diagram5, diagram6 } from './utils/test-documents/diagram/index';

import { CrossModelRoot } from '../../src/language-server/generated/ast';
import { createCrossModelServices } from '../../src/language-server/cross-model-module';

const services = createCrossModelServices({ ...EmptyFileSystem }).CrossModel;

describe('CrossModel language Diagram', () => {
describe('Diagram without nodes and edges', () => {
test('Simple file for diagram', async () => {
const document = diagram1;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;

expect(model).toHaveProperty('diagram');
expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(0);

expect(model.diagram?.name).toBe('Systemdiagram1');
});

test('Diagram with indentation error', async () => {
const document = diagram4;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;

expect(model).toHaveProperty('diagram');
expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(1);
});
});

describe('Diagram with nodes', () => {
test('Simple file for diagram and nodes', async () => {
const document = diagram2;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;
const node1 = model.diagram?.nodes[0];

expect(model).toHaveProperty('diagram');
expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(0);

expect(model.diagram?.nodes.length).toBe(1);

expect(node1?.name).toBe('CustomerNode');
expect(isReference(node1?.for)).toBe(true);
expect(node1?.for?.$refText).toBe('Customer');
expect(node1?.x).toBe(100);
});
});

describe('Diagram with edges', () => {
test('Simple file for diagram and edges', async () => {
const document = diagram3;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;
const edge1 = model.diagram?.edges[0];

expect(model).toHaveProperty('diagram');
expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(0);

expect(model.diagram?.edges.length).toBe(1);

expect(edge1?.name).toBe('OrderCustomerEdge');
expect(isReference(edge1?.for)).toBe(true);
expect(edge1?.for?.$refText).toBe('Order_Customer');
});
});

describe('Diagram with nodes and edges', () => {
test('Simple file for diagram and edges', async () => {
const document = diagram5;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;
const node1 = model.diagram?.nodes[0];
const edge1 = model.diagram?.edges[0];

expect(model).toHaveProperty('diagram');

expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(0);

expect(model.diagram?.name_val).toBe('System diagram 1');
expect(model.diagram?.description).toBe('This is a basic diagram with nodes and edges');
expect(model.diagram?.nodes.length).toBe(1);
expect(model.diagram?.edges.length).toBe(1);

expect(node1?.name).toBe('CustomerNode');
expect(isReference(node1?.for)).toBe(true);
expect(node1?.for?.$refText).toBe('Customer');
expect(node1?.x).toBe(100);

expect(edge1?.name).toBe('OrderCustomerEdge');
expect(isReference(edge1?.for)).toBe(true);
expect(edge1?.for?.$refText).toBe('Order_Customer');
});

test('Simple file for diagram and edges, but descirption and name coming last', async () => {
const document = diagram6;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;
const node1 = model.diagram?.nodes[0];
const edge1 = model.diagram?.edges[0];

expect(model).toHaveProperty('diagram');
expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(0);

expect(model.diagram?.name_val).toBe('System diagram 1');
expect(model.diagram?.description).toBe('This is a basic diagram with nodes and edges');
expect(model.diagram?.nodes.length).toBe(1);
expect(model.diagram?.edges.length).toBe(1);

expect(node1?.name).toBe('CustomerNode');
expect(isReference(node1?.for)).toBe(true);
expect(node1?.for?.$refText).toBe('Customer');
expect(node1?.x).toBe(100);

expect(edge1?.name).toBe('OrderCustomerEdge');
expect(isReference(edge1?.for)).toBe(true);
expect(edge1?.for?.$refText).toBe('Order_Customer');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/********************************************************************************
* Copyright (c) 2023 CrossBreeze.
********************************************************************************/

import { describe, expect, test } from '@jest/globals';
import { EmptyFileSystem } from 'langium';

import { parseDocument } from './utils/utils';
import { entity1, entity2, entity3, entity4 } from './utils/test-documents/entity/index';

import { CrossModelRoot } from '../../src/language-server/generated/ast';
import { createCrossModelServices } from '../../src/language-server/cross-model-module';

const services = createCrossModelServices({ ...EmptyFileSystem }).CrossModel;

describe('CrossModel language Entity', () => {
describe('Without attributes', () => {
test('Simple file for entity', async () => {
const document = entity1;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;

expect(model).toHaveProperty('entity');
expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(0);

expect(model.entity?.name).toBe('Customer');
expect(model.entity?.name_val).toBe('Customer');
expect(model.entity?.description).toBe('A customer with whom a transaction has been made.');
});
});

describe('With attributes', () => {
test('entity with attributes', async () => {
const document = entity2;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;

expect(model).toHaveProperty('entity');

expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(0);

expect(model.entity?.attributes.length).toBe(6);
expect(model.entity?.attributes[0].name).toBe('Id');
expect(model.entity?.attributes[0].name_val).toBe('Id');
expect(model.entity?.attributes[0].datatype).toBe('int');
});

test('entity with attributes coming before the description and name', async () => {
const document = entity4;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;

expect(model).toHaveProperty('entity');
expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(0);

expect(model.entity?.name).toBe('Customer');
expect(model.entity?.name_val).toBe('Customer');
expect(model.entity?.description).toBe('A customer with whom a transaction has been made.');

expect(model.entity?.attributes.length).toBe(6);
expect(model.entity?.attributes[0].name).toBe('Id');
expect(model.entity?.attributes[0].name_val).toBe('Id');
expect(model.entity?.attributes[0].datatype).toBe('int');
});

test('entity with indentation error', async () => {
const document = entity3;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;

expect(model).toHaveProperty('entity');
expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(1);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/********************************************************************************
* Copyright (c) 2023 CrossBreeze.
********************************************************************************/

import { describe, expect, test } from '@jest/globals';
import { EmptyFileSystem, isReference } from 'langium';

import { parseDocument } from './utils/utils';
import { relationship1, relationship2 } from './utils/test-documents/relationship/index';

import { CrossModelRoot } from '../../src/language-server/generated/ast';
import { createCrossModelServices } from '../../src/language-server/cross-model-module';

const services = createCrossModelServices({ ...EmptyFileSystem }).CrossModel;

describe('CrossModel language Relationship', () => {
test('Simple file for relationship', async () => {
const document = relationship1;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;

expect(model).toHaveProperty('relationship');
expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(0);

expect(model.relationship?.name).toBe('Order_Customer');
expect(model.relationship?.name_val).toBe('Customer Order relationship');
expect(model.relationship?.type).toBe('1:1');
expect(model.relationship?.description).toBe('A relationship between a customer and an order.');

expect(isReference(model.relationship?.parent)).toBe(true);
expect(isReference(model.relationship?.child)).toBe(true);
expect(model.relationship?.parent?.$refText).toBe('Customer');
expect(model.relationship?.child?.$refText).toBe('Order');
});

test('relationship with indentation error', async () => {
const document = relationship2;
const parsedDocument = await parseDocument(services, document);
const model = parsedDocument.parseResult.value as CrossModelRoot;

expect(model).toHaveProperty('relationship');
expect(parsedDocument.parseResult.lexerErrors.length).toBe(0);
expect(parsedDocument.parseResult.parserErrors.length).toBe(1);
});
});

0 comments on commit a40b2b8

Please sign in to comment.