refactor application.yaml to become an os definition #40
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
import { IEntity } from '@/infrastructure/Entity/IEntity';
|
||||
import applicationFile, { YamlCategory, YamlScript, ApplicationYaml } from 'js-yaml-loader!@/application/application.yaml';
|
||||
import applicationFile, { YamlCategory, YamlScript, YamlApplication, YamlScriptingDefinition } from 'js-yaml-loader!@/application/application.yaml';
|
||||
import { parseApplication } from '@/application/Parser/ApplicationParser';
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { parseCategory } from '@/application/Parser/CategoryParser';
|
||||
import { RecommendationLevel } from '@/domain/RecommendationLevel';
|
||||
import { ScriptCompilerStub } from '../../stubs/ScriptCompilerStub';
|
||||
import { parseProjectInformation } from '@/application/Parser/ProjectInformationParser';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { parseScriptingDefinition } from '@/application/Parser/ScriptingDefinitionParser';
|
||||
import { mockEnumParser } from '../../stubs/EnumParserStub';
|
||||
|
||||
describe('ApplicationParser', () => {
|
||||
describe('parseApplication', () => {
|
||||
@@ -23,33 +28,50 @@ describe('ApplicationParser', () => {
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
});
|
||||
it('throws when undefined actions', () => {
|
||||
// arrange
|
||||
const sut: ApplicationYaml = { actions: undefined, functions: undefined };
|
||||
const expectedError = 'application does not define any action';
|
||||
// act
|
||||
const act = () => parseApplication(sut);
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
describe('actions', () => {
|
||||
it('throws when undefined actions', () => {
|
||||
// arrange
|
||||
const app = new YamlApplicationBuilder().withActions(undefined).build();
|
||||
// act
|
||||
const act = () => parseApplication(app);
|
||||
// assert
|
||||
expect(act).to.throw('application does not define any action');
|
||||
});
|
||||
it('throws when has no actions', () => {
|
||||
// arrange
|
||||
const app = new YamlApplicationBuilder().withActions([]).build();
|
||||
// act
|
||||
const act = () => parseApplication(app);
|
||||
// assert
|
||||
expect(act).to.throw('application does not define any action');
|
||||
});
|
||||
it('parses actions', () => {
|
||||
// arrange
|
||||
const actions = [ getTestCategory('test1'), getTestCategory('test2') ];
|
||||
const compiler = new ScriptCompilerStub();
|
||||
const expected = [ parseCategory(actions[0], compiler), parseCategory(actions[1], compiler) ];
|
||||
const app = new YamlApplicationBuilder().withActions(actions).build();
|
||||
// act
|
||||
const actual = parseApplication(app).actions;
|
||||
// assert
|
||||
expect(excludingId(actual)).to.be.deep.equal(excludingId(expected));
|
||||
function excludingId<TId>(array: ReadonlyArray<IEntity<TId>>) {
|
||||
return array.map((obj) => {
|
||||
const { ['id']: omitted, ...rest } = obj;
|
||||
return rest;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
it('throws when has no actions', () => {
|
||||
// arrange
|
||||
const sut: ApplicationYaml = { actions: [], functions: undefined };
|
||||
const expectedError = 'application does not define any action';
|
||||
// act
|
||||
const act = () => parseApplication(sut);
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
});
|
||||
describe('information', () => {
|
||||
describe('info', () => {
|
||||
it('returns expected repository version', () => {
|
||||
// arrange
|
||||
const expected = 'expected-version';
|
||||
const env = getProcessEnvironmentStub();
|
||||
env.VUE_APP_VERSION = expected;
|
||||
const sut: ApplicationYaml = { actions: [ getTestCategory() ], functions: undefined };
|
||||
const app = new YamlApplicationBuilder().build();
|
||||
// act
|
||||
const actual = parseApplication(sut, env).info.version;
|
||||
const actual = parseApplication(app, env).info.version;
|
||||
// assert
|
||||
expect(actual).to.be.equal(expected);
|
||||
});
|
||||
@@ -58,9 +80,9 @@ describe('ApplicationParser', () => {
|
||||
const expected = 'https://expected-repository.url';
|
||||
const env = getProcessEnvironmentStub();
|
||||
env.VUE_APP_REPOSITORY_URL = expected;
|
||||
const sut: ApplicationYaml = { actions: [ getTestCategory() ], functions: undefined };
|
||||
const app = new YamlApplicationBuilder().build();
|
||||
// act
|
||||
const actual = parseApplication(sut, env).info.repositoryUrl;
|
||||
const actual = parseApplication(app, env).info.repositoryUrl;
|
||||
// assert
|
||||
expect(actual).to.be.equal(expected);
|
||||
});
|
||||
@@ -69,9 +91,9 @@ describe('ApplicationParser', () => {
|
||||
const expected = 'expected-app-name';
|
||||
const env = getProcessEnvironmentStub();
|
||||
env.VUE_APP_NAME = expected;
|
||||
const sut: ApplicationYaml = { actions: [ getTestCategory() ], functions: undefined };
|
||||
const app = new YamlApplicationBuilder().build();
|
||||
// act
|
||||
const actual = parseApplication(sut, env).info.name;
|
||||
const actual = parseApplication(app, env).info.name;
|
||||
// assert
|
||||
expect(actual).to.be.equal(expected);
|
||||
});
|
||||
@@ -80,33 +102,79 @@ describe('ApplicationParser', () => {
|
||||
const expected = 'https://expected.sexy';
|
||||
const env = getProcessEnvironmentStub();
|
||||
env.VUE_APP_HOMEPAGE_URL = expected;
|
||||
const sut: ApplicationYaml = { actions: [ getTestCategory() ], functions: undefined };
|
||||
const app = new YamlApplicationBuilder().build();
|
||||
// act
|
||||
const actual = parseApplication(sut, env).info.homepage;
|
||||
const actual = parseApplication(app, env).info.homepage;
|
||||
// assert
|
||||
expect(actual).to.be.equal(expected);
|
||||
});
|
||||
});
|
||||
it('parses actions', () => {
|
||||
// arrange
|
||||
const actions = [ getTestCategory('test1'), getTestCategory('test2') ];
|
||||
const compiler = new ScriptCompilerStub();
|
||||
const expected = [ parseCategory(actions[0], compiler), parseCategory(actions[1], compiler) ];
|
||||
const sut: ApplicationYaml = { actions, functions: undefined };
|
||||
// act
|
||||
const actual = parseApplication(sut).actions;
|
||||
// assert
|
||||
expect(excludingId(actual)).to.be.deep.equal(excludingId(expected));
|
||||
function excludingId<TId>(array: ReadonlyArray<IEntity<TId>>) {
|
||||
return array.map((obj) => {
|
||||
const { ['id']: omitted, ...rest } = obj;
|
||||
return rest;
|
||||
});
|
||||
}
|
||||
describe('scripting definition', () => {
|
||||
it('parses scripting definition as expected', () => {
|
||||
// arrange
|
||||
const app = new YamlApplicationBuilder().build();
|
||||
const information = parseProjectInformation(process.env);
|
||||
const expected = parseScriptingDefinition(app.scripting, information);
|
||||
// act
|
||||
const actual = parseApplication(app).scripting;
|
||||
// assert
|
||||
expect(expected).to.deep.equal(actual);
|
||||
});
|
||||
});
|
||||
describe('os', () => {
|
||||
it('parses as expected', () => {
|
||||
// arrange
|
||||
const expectedOs = OperatingSystem.macOS;
|
||||
const osText = 'macos';
|
||||
const expectedName = 'os';
|
||||
const app = new YamlApplicationBuilder()
|
||||
.withOs(osText)
|
||||
.build();
|
||||
const parserMock = mockEnumParser(expectedName, osText, expectedOs);
|
||||
const env = getProcessEnvironmentStub();
|
||||
// act
|
||||
const actual = parseApplication(app, env, parserMock);
|
||||
// assert
|
||||
expect(actual.os).to.equal(expectedOs);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
class YamlApplicationBuilder {
|
||||
private os = 'windows';
|
||||
private actions: readonly YamlCategory[] = [ getTestCategory() ];
|
||||
private scripting: YamlScriptingDefinition = getTestDefinition();
|
||||
|
||||
public withActions(actions: readonly YamlCategory[]): YamlApplicationBuilder {
|
||||
this.actions = actions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withOs(os: string): YamlApplicationBuilder {
|
||||
this.os = os;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withScripting(scripting: YamlScriptingDefinition): YamlApplicationBuilder {
|
||||
this.scripting = scripting;
|
||||
return this;
|
||||
}
|
||||
|
||||
public build(): YamlApplication {
|
||||
return { os: this.os, scripting: this.scripting, actions: this.actions };
|
||||
}
|
||||
}
|
||||
|
||||
function getTestDefinition(): YamlScriptingDefinition {
|
||||
return {
|
||||
fileExtension: '.bat',
|
||||
language: ScriptingLanguage[ScriptingLanguage.batchfile],
|
||||
startCode: 'start',
|
||||
endCode: 'end',
|
||||
};
|
||||
}
|
||||
|
||||
function getTestCategory(scriptPrefix = 'testScript'): YamlCategory {
|
||||
return {
|
||||
category: 'category name',
|
||||
|
||||
141
tests/unit/application/Parser/Compiler/ILCode.spec.ts
Normal file
141
tests/unit/application/Parser/Compiler/ILCode.spec.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { generateIlCode } from '@/application/Parser/Compiler/ILCode';
|
||||
|
||||
describe('ILCode', () => {
|
||||
describe('getUniqueParameterNames', () => {
|
||||
// arrange
|
||||
const testCases = [
|
||||
{
|
||||
name: 'empty parameters: returns an empty array',
|
||||
code: 'no expressions',
|
||||
expected: [ ],
|
||||
},
|
||||
{
|
||||
name: 'single parameter: returns expected for single usage',
|
||||
code: '{{ $single }}',
|
||||
expected: [ 'single' ],
|
||||
},
|
||||
{
|
||||
name: 'single parameter: returns distinct values for repeating parameters',
|
||||
code: '{{ $singleRepeating }}, {{ $singleRepeating }}',
|
||||
expected: [ 'singleRepeating' ],
|
||||
},
|
||||
{
|
||||
name: 'multiple parameters: returns expected for single usage of each',
|
||||
code: '{{ $firstParameter }}, {{ $secondParameter }}',
|
||||
expected: [ 'firstParameter', 'secondParameter' ],
|
||||
},
|
||||
{
|
||||
name: 'multiple parameters: returns distinct values for repeating parameters',
|
||||
code: '{{ $firstParameter }}, {{ $firstParameter }}, {{ $firstParameter }} {{ $secondParameter }}, {{ $secondParameter }}',
|
||||
expected: [ 'firstParameter', 'secondParameter' ],
|
||||
},
|
||||
];
|
||||
for (const testCase of testCases) {
|
||||
it(testCase.name, () => {
|
||||
// act
|
||||
const sut = generateIlCode(testCase.code);
|
||||
const actual = sut.getUniqueParameterNames();
|
||||
// assert
|
||||
expect(actual).to.deep.equal(testCase.expected);
|
||||
});
|
||||
}
|
||||
});
|
||||
describe('substituteParameter', () => {
|
||||
describe('substitutes by ignoring white spaces inside mustaches', () => {
|
||||
// arrange
|
||||
const mustacheVariations = [
|
||||
'Hello {{ $test }}!',
|
||||
'Hello {{$test }}!',
|
||||
'Hello {{ $test}}!',
|
||||
'Hello {{$test}}!'];
|
||||
mustacheVariations.forEach((variation) => {
|
||||
it(variation, () => {
|
||||
// arrange
|
||||
const ilCode = generateIlCode(variation);
|
||||
const expected = 'Hello world!';
|
||||
// act
|
||||
const actual = ilCode
|
||||
.substituteParameter('test', 'world')
|
||||
.compile();
|
||||
// assert
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('substitutes as expected', () => {
|
||||
// arrange
|
||||
const testCases = [
|
||||
{
|
||||
name: 'single parameter',
|
||||
code: 'Hello {{ $firstParameter }}!',
|
||||
expected: 'Hello world!',
|
||||
parameters: {
|
||||
firstParameter: 'world',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'single parameter repeated',
|
||||
code: '{{ $firstParameter }} {{ $firstParameter }}!',
|
||||
expected: 'hello hello!',
|
||||
parameters: {
|
||||
firstParameter: 'hello',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'multiple parameters',
|
||||
code: 'He{{ $firstParameter }} {{ $secondParameter }}!',
|
||||
expected: 'Hello world!',
|
||||
parameters: {
|
||||
firstParameter: 'llo',
|
||||
secondParameter: 'world',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'multiple parameters repeated',
|
||||
code: 'He{{ $firstParameter }} {{ $secondParameter }} and He{{ $firstParameter }} {{ $secondParameter }}!',
|
||||
expected: 'Hello world and Hello world!',
|
||||
parameters: {
|
||||
firstParameter: 'llo',
|
||||
secondParameter: 'world',
|
||||
},
|
||||
},
|
||||
];
|
||||
for (const testCase of testCases) {
|
||||
it(testCase.name, () => {
|
||||
// act
|
||||
let ilCode = generateIlCode(testCase.code);
|
||||
for (const parameterName of Object.keys(testCase.parameters)) {
|
||||
const value = testCase.parameters[parameterName];
|
||||
ilCode = ilCode.substituteParameter(parameterName, value);
|
||||
}
|
||||
const actual = ilCode.compile();
|
||||
// assert
|
||||
expect(actual).to.deep.equal(testCase.expected);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('compile', () => {
|
||||
it('throws if there are expressions left', () => {
|
||||
// arrange
|
||||
const expectedError = 'unknown expression: "each"';
|
||||
const code = '{{ each }}';
|
||||
// act
|
||||
const ilCode = generateIlCode(code);
|
||||
const act = () => ilCode.compile();
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
});
|
||||
it('returns code as it is if there are no expressions', () => {
|
||||
// arrange
|
||||
const expected = 'I should be the same!';
|
||||
const ilCode = generateIlCode(expected);
|
||||
// act
|
||||
const actual = ilCode.compile();
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -215,30 +215,6 @@ describe('ScriptCompiler', () => {
|
||||
});
|
||||
});
|
||||
describe('parameter substitution', () => {
|
||||
describe('substitutes by ignoring whitespaces inside mustaches', () => {
|
||||
// arrange
|
||||
const mustacheVariations = [
|
||||
'Hello {{ $test }}!',
|
||||
'Hello {{$test }}!',
|
||||
'Hello {{ $test}}!',
|
||||
'Hello {{$test}}!'];
|
||||
mustacheVariations.forEach((variation) => {
|
||||
it(variation, () => {
|
||||
// arrange
|
||||
const env = new TestEnvironment({
|
||||
code: variation,
|
||||
parameters: {
|
||||
test: 'world',
|
||||
},
|
||||
});
|
||||
const expected = env.expect('Hello world!');
|
||||
// act
|
||||
const actual = env.sut.compile(env.script);
|
||||
// assert
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('substitutes as expected', () => {
|
||||
it('with different parameters', () => {
|
||||
// arrange
|
||||
@@ -255,15 +231,15 @@ describe('ScriptCompiler', () => {
|
||||
// assert
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
it('with same parameter repeated', () => {
|
||||
it('with single parameter', () => {
|
||||
// arrange
|
||||
const env = new TestEnvironment({
|
||||
code: '{{ $parameter }} {{ $parameter }}!',
|
||||
code: '{{ $parameter }}!',
|
||||
parameters: {
|
||||
parameter: 'Hodor',
|
||||
},
|
||||
});
|
||||
const expected = env.expect('Hodor Hodor!');
|
||||
const expected = env.expect('Hodor!');
|
||||
// act
|
||||
const actual = env.sut.compile(env.script);
|
||||
// assert
|
||||
@@ -295,20 +271,6 @@ describe('ScriptCompiler', () => {
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
});
|
||||
it('throws on unknown expressions', () => {
|
||||
// arrange
|
||||
const env = new TestEnvironment({
|
||||
code: '{{ each }}',
|
||||
parameters: {
|
||||
parameter: undefined,
|
||||
},
|
||||
});
|
||||
const expectedError = 'unknown expression: "each"';
|
||||
// act
|
||||
const act = () => env.sut.compile(env.script);
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { parseProjectInformation } from '@/application/Parser/ProjectInformationParser';
|
||||
|
||||
describe('ProjectInformationParser', () => {
|
||||
describe('parseProjectInformation', () => {
|
||||
it('parses expected repository version', () => {
|
||||
// arrange
|
||||
const expected = 'expected-version';
|
||||
const env = getProcessEnvironmentStub();
|
||||
env.VUE_APP_VERSION = expected;
|
||||
// act
|
||||
const info = parseProjectInformation(env);
|
||||
// assert
|
||||
expect(info.version).to.be.equal(expected);
|
||||
});
|
||||
it('parses expected repository url', () => {
|
||||
// arrange
|
||||
const expected = 'https://expected-repository.url';
|
||||
const env = getProcessEnvironmentStub();
|
||||
env.VUE_APP_REPOSITORY_URL = expected;
|
||||
// act
|
||||
const info = parseProjectInformation(env);
|
||||
// assert
|
||||
expect(info.repositoryUrl).to.be.equal(expected);
|
||||
});
|
||||
it('parses expected name', () => {
|
||||
// arrange
|
||||
const expected = 'expected-app-name';
|
||||
const env = getProcessEnvironmentStub();
|
||||
env.VUE_APP_NAME = expected;
|
||||
// act
|
||||
const info = parseProjectInformation(env);
|
||||
// assert
|
||||
expect(info.name).to.be.equal(expected);
|
||||
});
|
||||
it('parses expected homepage url', () => {
|
||||
// arrange
|
||||
const expected = 'https://expected.sexy';
|
||||
const env = getProcessEnvironmentStub();
|
||||
env.VUE_APP_HOMEPAGE_URL = expected;
|
||||
// act
|
||||
const info = parseProjectInformation(env);
|
||||
// assert
|
||||
expect(info.homepage).to.be.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function getProcessEnvironmentStub(): NodeJS.ProcessEnv {
|
||||
return {
|
||||
VUE_APP_VERSION: 'stub-version',
|
||||
VUE_APP_NAME: 'stub-name',
|
||||
VUE_APP_REPOSITORY_URL: 'stub-repository-url',
|
||||
VUE_APP_HOMEPAGE_URL: 'stub-homepage-url',
|
||||
};
|
||||
}
|
||||
@@ -2,10 +2,11 @@ import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { parseScript } from '@/application/Parser/ScriptParser';
|
||||
import { parseDocUrls } from '@/application/Parser/DocumentationParser';
|
||||
import { RecommendationLevelNames, RecommendationLevel } from '@/domain/RecommendationLevel';
|
||||
import { RecommendationLevel } from '@/domain/RecommendationLevel';
|
||||
import { ScriptCode } from '@/domain/ScriptCode';
|
||||
import { ScriptCompilerStub } from '../../stubs/ScriptCompilerStub';
|
||||
import { YamlScriptStub } from '../../stubs/YamlScriptStub';
|
||||
import { mockEnumParser } from '../../stubs/EnumParserStub';
|
||||
|
||||
describe('ScriptParser', () => {
|
||||
describe('parseScript', () => {
|
||||
@@ -84,63 +85,27 @@ describe('ScriptParser', () => {
|
||||
undefinedLevels.forEach((undefinedLevel) => {
|
||||
// arrange
|
||||
const compiler = new ScriptCompilerStub();
|
||||
const script = YamlScriptStub.createWithCode();
|
||||
script.recommend = undefinedLevel;
|
||||
const script = YamlScriptStub.createWithCode()
|
||||
.withRecommend(undefinedLevel);
|
||||
// act
|
||||
const actual = parseScript(script, compiler);
|
||||
// assert
|
||||
expect(actual.level).to.equal(undefined);
|
||||
});
|
||||
});
|
||||
it('throws on unknown level', () => {
|
||||
// arrange
|
||||
const unknownLevel = 'boi';
|
||||
const compiler = new ScriptCompilerStub();
|
||||
const script = YamlScriptStub.createWithCode();
|
||||
script.recommend = unknownLevel;
|
||||
// act
|
||||
const act = () => parseScript(script, compiler);
|
||||
// assert
|
||||
expect(act).to.throw(`unknown level: "${unknownLevel}"`);
|
||||
});
|
||||
it('throws on non-string type', () => {
|
||||
const nonStringTypes: any[] = [ 5, true ];
|
||||
nonStringTypes.forEach((nonStringType) => {
|
||||
// arrange
|
||||
const script = YamlScriptStub.createWithCode();
|
||||
const compiler = new ScriptCompilerStub();
|
||||
script.recommend = nonStringType;
|
||||
// act
|
||||
const act = () => parseScript(script, compiler);
|
||||
// assert
|
||||
expect(act).to.throw(`level must be a string but it was ${typeof nonStringType}`);
|
||||
});
|
||||
});
|
||||
describe('parses level as expected', () => {
|
||||
for (const levelText of RecommendationLevelNames) {
|
||||
it(levelText, () => {
|
||||
// arrange
|
||||
const expectedLevel = RecommendationLevel[levelText];
|
||||
const script = YamlScriptStub.createWithCode();
|
||||
const compiler = new ScriptCompilerStub();
|
||||
script.recommend = levelText;
|
||||
// act
|
||||
const actual = parseScript(script, compiler);
|
||||
// assert
|
||||
expect(actual.level).to.equal(expectedLevel);
|
||||
});
|
||||
}
|
||||
});
|
||||
it('parses level case insensitive', () => {
|
||||
// arrange
|
||||
const script = YamlScriptStub.createWithCode();
|
||||
const expectedLevel = RecommendationLevel.Standard;
|
||||
const expectedName = 'level';
|
||||
const levelText = 'standard';
|
||||
const script = YamlScriptStub.createWithCode()
|
||||
.withRecommend(levelText);
|
||||
const compiler = new ScriptCompilerStub();
|
||||
const expected = RecommendationLevel.Standard;
|
||||
script.recommend = RecommendationLevel[expected].toUpperCase();
|
||||
const parserMock = mockEnumParser(expectedName, levelText, expectedLevel);
|
||||
// act
|
||||
const actual = parseScript(script, compiler);
|
||||
const actual = parseScript(script, compiler, parserMock);
|
||||
// assert
|
||||
expect(actual.level).to.equal(expected);
|
||||
expect(actual.level).to.equal(expectedLevel);
|
||||
});
|
||||
});
|
||||
describe('code', () => {
|
||||
@@ -196,3 +161,4 @@ describe('ScriptParser', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
150
tests/unit/application/Parser/ScriptingDefinitionParser.spec.ts
Normal file
150
tests/unit/application/Parser/ScriptingDefinitionParser.spec.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { YamlScriptingDefinition } from 'js-yaml-loader!./application.yaml';
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { parseScriptingDefinition } from '@/application/Parser/ScriptingDefinitionParser';
|
||||
import { ProjectInformationStub } from './../../stubs/ProjectInformationStub';
|
||||
import { mockEnumParser } from '../../stubs/EnumParserStub';
|
||||
|
||||
describe('ScriptingDefinitionParser', () => {
|
||||
describe('parseScriptingDefinition', () => {
|
||||
it('throws when info is undefined', () => {
|
||||
// arrange
|
||||
const info = undefined;
|
||||
const definition = new ScriptingDefinitionBuilder().construct();
|
||||
// act
|
||||
const act = () => parseScriptingDefinition(definition, info);
|
||||
// assert
|
||||
expect(act).to.throw('undefined info');
|
||||
});
|
||||
it('throws when definition is undefined', () => {
|
||||
// arrange
|
||||
const info = new ProjectInformationStub();
|
||||
const definition = undefined;
|
||||
// act
|
||||
const act = () => parseScriptingDefinition(definition, info);
|
||||
// assert
|
||||
expect(act).to.throw('undefined definition');
|
||||
});
|
||||
describe('language', () => {
|
||||
it('parses as expected', () => {
|
||||
// arrange
|
||||
const expectedLanguage = ScriptingLanguage.batchfile;
|
||||
const languageText = 'batchfile';
|
||||
const expectedName = 'language';
|
||||
const info = new ProjectInformationStub();
|
||||
const definition = new ScriptingDefinitionBuilder()
|
||||
.withLanguage(languageText).construct();
|
||||
const parserMock = mockEnumParser(expectedName, languageText, expectedLanguage);
|
||||
// act
|
||||
const actual = parseScriptingDefinition(definition, info, new Date(), parserMock);
|
||||
// assert
|
||||
expect(actual.language).to.equal(expectedLanguage);
|
||||
});
|
||||
});
|
||||
describe('fileExtension', () => {
|
||||
it('parses as expected', () => {
|
||||
// arrange
|
||||
const expected = 'bat';
|
||||
const info = new ProjectInformationStub();
|
||||
const file = new ScriptingDefinitionBuilder()
|
||||
.withExtension(expected).construct();
|
||||
// act
|
||||
const definition = parseScriptingDefinition(file, info);
|
||||
// assert
|
||||
const actual = definition.fileExtension;
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
});
|
||||
describe('startCode', () => {
|
||||
it('sets as it is', () => {
|
||||
// arrange
|
||||
const expected = 'expected-start-code';
|
||||
const info = new ProjectInformationStub();
|
||||
const file = new ScriptingDefinitionBuilder().withStartCode(expected).construct();
|
||||
// act
|
||||
const definition = parseScriptingDefinition(file, info);
|
||||
// assert
|
||||
expect(definition.startCode).to.equal(expected);
|
||||
});
|
||||
it('substitutes as expected', () => {
|
||||
// arrange
|
||||
const code = 'homepage: {{ $homepage }}, version: {{ $version }}, date: {{ $date }}';
|
||||
const homepage = 'https://cloudarchitecture.io';
|
||||
const version = '1.0.2';
|
||||
const date = new Date();
|
||||
const expected = `homepage: ${homepage}, version: ${version}, date: ${date.toUTCString()}`;
|
||||
const info = new ProjectInformationStub().withHomepageUrl(homepage).withVersion(version);
|
||||
const file = new ScriptingDefinitionBuilder().withStartCode(code).construct();
|
||||
// act
|
||||
const definition = parseScriptingDefinition(file, info, date);
|
||||
// assert
|
||||
const actual = definition.startCode;
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
});
|
||||
describe('endCode', () => {
|
||||
it('sets as it is', () => {
|
||||
// arrange
|
||||
const expected = 'expected-end-code';
|
||||
const info = new ProjectInformationStub();
|
||||
const file = new ScriptingDefinitionBuilder().withEndCode(expected).construct();
|
||||
// act
|
||||
const definition = parseScriptingDefinition(file, info);
|
||||
// assert
|
||||
expect(definition.endCode).to.equal(expected);
|
||||
});
|
||||
it('substitutes as expected', () => {
|
||||
// arrange
|
||||
const code = 'homepage: {{ $homepage }}, version: {{ $version }}, date: {{ $date }}';
|
||||
const homepage = 'https://cloudarchitecture.io';
|
||||
const version = '1.0.2';
|
||||
const date = new Date();
|
||||
const expected = `homepage: ${homepage}, version: ${version}, date: ${date.toUTCString()}`;
|
||||
const info = new ProjectInformationStub().withHomepageUrl(homepage).withVersion(version);
|
||||
const file = new ScriptingDefinitionBuilder().withEndCode(code).construct();
|
||||
// act
|
||||
const definition = parseScriptingDefinition(file, info, date);
|
||||
// assert
|
||||
const actual = definition.endCode;
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
class ScriptingDefinitionBuilder {
|
||||
private language = ScriptingLanguage[ScriptingLanguage.batchfile];
|
||||
private fileExtension = 'bat';
|
||||
private startCode = 'startCode';
|
||||
private endCode = 'endCode';
|
||||
|
||||
public withLanguage(language: string): ScriptingDefinitionBuilder {
|
||||
this.language = language;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withStartCode(startCode: string): ScriptingDefinitionBuilder {
|
||||
this.startCode = startCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withEndCode(endCode: string): ScriptingDefinitionBuilder {
|
||||
this.endCode = endCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withExtension(extension: string): ScriptingDefinitionBuilder {
|
||||
this.fileExtension = extension;
|
||||
return this;
|
||||
}
|
||||
|
||||
public construct(): YamlScriptingDefinition {
|
||||
return {
|
||||
language: this.language,
|
||||
fileExtension: this.fileExtension,
|
||||
startCode: this.startCode,
|
||||
endCode: this.endCode,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user