123 lines
4.5 KiB
TypeScript
123 lines
4.5 KiB
TypeScript
import 'mocha';
|
|
import { expect } from 'chai';
|
|
import { ExpressionEvaluator } from '@/application/Parser/Script/Compiler/Expressions/Expression/Expression';
|
|
import { IPrimitiveExpression, RegexParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/RegexParser';
|
|
import { ExpressionPosition } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPosition';
|
|
|
|
describe('RegexParser', () => {
|
|
describe('findExpressions', () => {
|
|
describe('matches regex as expected', () => {
|
|
// arrange
|
|
const testCases = [
|
|
{
|
|
name: 'returns no result when regex does not match',
|
|
regex: /hello/g,
|
|
code: 'world',
|
|
},
|
|
{
|
|
name: 'returns expected when regex matches single',
|
|
regex: /hello/g,
|
|
code: 'hello world',
|
|
},
|
|
{
|
|
name: 'returns expected when regex matches multiple',
|
|
regex: /l/g,
|
|
code: 'hello world',
|
|
},
|
|
];
|
|
for (const testCase of testCases) {
|
|
it(testCase.name, () => {
|
|
const expected = Array.from(testCase.code.matchAll(testCase.regex));
|
|
const matches = new Array<RegExpMatchArray>();
|
|
const builder = (m: RegExpMatchArray): IPrimitiveExpression => {
|
|
matches.push(m);
|
|
return mockPrimitiveExpression();
|
|
};
|
|
const sut = new RegexParserConcrete(testCase.regex, builder);
|
|
// act
|
|
const expressions = sut.findExpressions(testCase.code);
|
|
// assert
|
|
expect(expressions).to.have.lengthOf(matches.length);
|
|
expect(matches).to.deep.equal(expected);
|
|
});
|
|
}
|
|
});
|
|
it('sets evaluator as expected', () => {
|
|
// arrange
|
|
const expected = getEvaluatorStub();
|
|
const regex = /hello/g;
|
|
const code = 'hello';
|
|
const builder = (): IPrimitiveExpression => ({
|
|
evaluator: expected,
|
|
});
|
|
const sut = new RegexParserConcrete(regex, builder);
|
|
// act
|
|
const expressions = sut.findExpressions(code);
|
|
// assert
|
|
expect(expressions).to.have.lengthOf(1);
|
|
expect(expressions[0].evaluate === expected);
|
|
});
|
|
it('sets parameters as expected', () => {
|
|
// arrange
|
|
const expected = [ 'parameter1', 'parameter2' ];
|
|
const regex = /hello/g;
|
|
const code = 'hello';
|
|
const builder = (): IPrimitiveExpression => ({
|
|
evaluator: getEvaluatorStub(),
|
|
parameters: expected,
|
|
});
|
|
const sut = new RegexParserConcrete(regex, builder);
|
|
// act
|
|
const expressions = sut.findExpressions(code);
|
|
// assert
|
|
expect(expressions).to.have.lengthOf(1);
|
|
expect(expressions[0].parameters).to.equal(expected);
|
|
});
|
|
it('sets expected position', () => {
|
|
// arrange
|
|
const code = 'mate date in state is fate';
|
|
const regex = /ate/g;
|
|
const expected = [
|
|
new ExpressionPosition(1, 4),
|
|
new ExpressionPosition(6, 9),
|
|
new ExpressionPosition(15, 18),
|
|
new ExpressionPosition(23, 26),
|
|
];
|
|
const sut = new RegexParserConcrete(regex);
|
|
// act
|
|
const expressions = sut.findExpressions(code);
|
|
// assert
|
|
const actual = expressions.map((e) => e.position);
|
|
expect(actual).to.deep.equal(expected);
|
|
});
|
|
});
|
|
});
|
|
|
|
function mockBuilder(): (match: RegExpMatchArray) => IPrimitiveExpression {
|
|
return () => ({
|
|
evaluator: getEvaluatorStub(),
|
|
});
|
|
}
|
|
function getEvaluatorStub(): ExpressionEvaluator {
|
|
return () => undefined;
|
|
}
|
|
|
|
function mockPrimitiveExpression(): IPrimitiveExpression {
|
|
return {
|
|
evaluator: getEvaluatorStub(),
|
|
};
|
|
}
|
|
|
|
class RegexParserConcrete extends RegexParser {
|
|
protected regex: RegExp;
|
|
public constructor(
|
|
regex: RegExp,
|
|
private readonly builder = mockBuilder()) {
|
|
super();
|
|
this.regex = regex;
|
|
}
|
|
protected buildExpression(match: RegExpMatchArray): IPrimitiveExpression {
|
|
return this.builder(match);
|
|
}
|
|
}
|