Files
privacy.sexy/tests/unit/domain/ScriptCode.spec.ts

192 lines
7.1 KiB
TypeScript

import 'mocha';
import { expect } from 'chai';
import { ScriptCode } from '@/domain/ScriptCode';
import { IScriptCode } from '@/domain/IScriptCode';
import { ILanguageSyntax } from '@/domain/ScriptCode';
import { LanguageSyntaxStub } from '../stubs/LanguageSyntaxStub';
describe('ScriptCode', () => {
describe('code', () => {
describe('throws with invalid code', () => {
// arrange
const testCases = [
{
name: 'throws when "execute" and "revert" are same',
code: {
execute: 'same',
revert: 'same',
},
expectedError: `(revert): Code itself and its reverting code cannot be the same`,
},
{
name: 'cannot construct with undefined "execute"',
code: {
execute: undefined,
revert: 'code',
},
expectedError: `code is empty or undefined`,
},
{
name: 'cannot construct with empty "execute"',
code: {
execute: '',
revert: 'code',
},
expectedError: `code is empty or undefined`,
},
];
for (const testCase of testCases) {
it(testCase.name, () => {
// act
const act = () => new ScriptCodeBuilder()
.withExecute( testCase.code.execute)
.withRevert(testCase.code.revert)
.build();
// assert
expect(act).to.throw(testCase.expectedError);
});
}
});
describe('throws with invalid code in both "execute" or "revert"', () => {
// arrange
const testCases = [
{
testName: 'cannot construct with duplicate lines',
code: 'duplicate\nduplicate\ntest\nduplicate',
expectedMessage: 'Duplicates detected in script:\n(0) - duplicate\n(1) - duplicate',
},
{
testName: 'cannot construct with empty lines',
code: 'line1\n\n\nline2',
expectedMessage: 'script has empty lines',
},
];
// act
const actions = [];
for (const testCase of testCases) {
actions.push(...[
{
act: () => new ScriptCodeBuilder()
.withExecute(testCase.code)
.build(),
testName: `execute: ${testCase.testName}`,
expectedMessage: testCase.expectedMessage,
},
{
act: () => new ScriptCodeBuilder()
.withRevert(testCase.code)
.build(),
testName: `revert: ${testCase.testName}`,
expectedMessage: `(revert): ${testCase.expectedMessage}`,
},
]);
}
// assert
for (const action of actions) {
it(action.testName, () => {
expect(action.act).to.throw(action.expectedMessage,
`Code used: ${action.code}`);
});
}
});
describe('sets as expected with valid "execute" or "revert"', () => {
// arrange
const syntax = new LanguageSyntaxStub()
.withCommonCodeParts(')', 'else', '(')
.withCommentDelimiters('#', '//');
const testCases = [
{
testName: 'code is a valid string',
code: 'valid code',
},
{
testName: 'code consists of common code parts',
code: syntax.commonCodeParts.join(' '),
},
{
testName: 'code is a common code part',
code: syntax.commonCodeParts[0],
},
{
testName: `code with duplicated comment lines (${syntax.commentDelimiters[0]})`,
code: `${syntax.commentDelimiters[0]} comment\n${syntax.commentDelimiters[0]} comment`,
},
{
testName: `code with duplicated comment lines (${syntax.commentDelimiters[1]})`,
code: `${syntax.commentDelimiters[1]} comment\n${syntax.commentDelimiters[1]} comment`,
},
];
// act
const actions = [];
for (const testCase of testCases) {
actions.push(...[
{
testName: `execute: ${testCase.testName}`,
act: () =>
new ScriptCodeBuilder()
.withSyntax(syntax)
.withExecute(testCase.code)
.build(),
expect: (sut: IScriptCode) => sut.execute === testCase.code,
},
{
testName: `revert: ${testCase.testName}`,
act: () =>
new ScriptCodeBuilder()
.withSyntax(syntax)
.withRevert(testCase.code)
.build(),
expect: (sut: IScriptCode) => sut.revert === testCase.code,
},
]);
}
// assert
for (const action of actions) {
it(action.testName, () => {
const sut = action.act();
expect(action.expect(sut));
});
}
});
});
describe('syntax', () => {
it('throws if undefined', () => {
// arrange
const expectedError = 'undefined syntax';
const syntax = undefined;
// act
const act = () => new ScriptCodeBuilder()
.withSyntax(syntax)
.build();
// assert
expect(act).to.throw(expectedError);
});
});
});
class ScriptCodeBuilder {
public execute = 'default-execute-code';
public revert = '';
public syntax: ILanguageSyntax = new LanguageSyntaxStub();
public withExecute(execute: string) {
this.execute = execute;
return this;
}
public withRevert(revert: string) {
this.revert = revert;
return this;
}
public withSyntax(syntax: ILanguageSyntax) {
this.syntax = syntax;
return this;
}
public build(): ScriptCode {
return new ScriptCode(
this.execute,
this.revert,
this.syntax);
}
}