add support for shared functions #41

This commit is contained in:
undergroundwires
2020-09-17 21:46:20 +01:00
parent 1a9db31c77
commit 8ce06facbd
27 changed files with 1533 additions and 354 deletions

View File

@@ -1,58 +1,93 @@
import { YamlScript } from 'js-yaml-loader!./application.yaml';
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 { ScriptCode } from '@/domain/ScriptCode';
import { ScriptCompilerStub } from '../../stubs/ScriptCompilerStub';
import { YamlScriptStub } from '../../stubs/YamlScriptStub';
describe('ScriptParser', () => {
describe('parseScript', () => {
it('parses name as expected', () => {
// arrange
const script = getValidScript();
script.name = 'expected-name';
const expected = 'test-expected-name';
const script = YamlScriptStub.createWithCode()
.withName(expected);
const compiler = new ScriptCompilerStub();
// act
const actual = parseScript(script);
const actual = parseScript(script, compiler);
// assert
expect(actual.name).to.equal(script.name);
});
it('parses code as expected', () => {
// arrange
const script = getValidScript();
script.code = 'expected-code';
// act
const actual = parseScript(script);
// assert
expect(actual.code).to.equal(script.code);
});
it('parses revertCode as expected', () => {
// arrange
const script = getValidScript();
script.code = 'expected-code';
// act
const actual = parseScript(script);
// assert
expect(actual.revertCode).to.equal(script.revertCode);
expect(actual.name).to.equal(expected);
});
it('parses docs as expected', () => {
// arrange
const script = getValidScript();
script.docs = [ 'https://expected-doc1.com', 'https://expected-doc2.com' ];
const docs = [ 'https://expected-doc1.com', 'https://expected-doc2.com' ];
const script = YamlScriptStub.createWithCode()
.withDocs(docs);
const compiler = new ScriptCompilerStub();
const expected = parseDocUrls(script);
// act
const actual = parseScript(script);
const actual = parseScript(script, compiler);
// assert
expect(actual.documentationUrls).to.deep.equal(expected);
});
describe('invalid script', () => {
it('throws when script is undefined', () => {
// arrange
const expectedError = 'undefined script';
const compiler = new ScriptCompilerStub();
const script = undefined;
// act
const act = () => parseScript(script, compiler);
// assert
expect(act).to.throw(expectedError);
});
it('throws when both function call and code are defined', () => {
// arrange
const expectedError = 'cannot define both "call" and "code"';
const compiler = new ScriptCompilerStub();
const script = YamlScriptStub
.createWithCall()
.withCode('code');
// act
const act = () => parseScript(script, compiler);
// assert
expect(act).to.throw(expectedError);
});
it('throws when both function call and revertCode are defined', () => {
// arrange
const expectedError = 'cannot define "revertCode" if "call" is defined';
const compiler = new ScriptCompilerStub();
const script = YamlScriptStub
.createWithCall()
.withRevertCode('revert-code');
// act
const act = () => parseScript(script, compiler);
// assert
expect(act).to.throw(expectedError);
});
it('throws when neither call or revertCode are defined', () => {
// arrange
const expectedError = 'must define either "call" or "code"';
const compiler = new ScriptCompilerStub();
const script = YamlScriptStub.createWithoutCallOrCodes();
// act
const act = () => parseScript(script, compiler);
// assert
expect(act).to.throw(expectedError);
});
});
describe('level', () => {
it('accepts undefined level', () => {
const undefinedLevels: string[] = [ '', undefined ];
undefinedLevels.forEach((undefinedLevel) => {
// arrange
const script = getValidScript();
const compiler = new ScriptCompilerStub();
const script = YamlScriptStub.createWithCode();
script.recommend = undefinedLevel;
// act
const actual = parseScript(script);
const actual = parseScript(script, compiler);
// assert
expect(actual.level).to.equal(undefined);
});
@@ -60,10 +95,11 @@ describe('ScriptParser', () => {
it('throws on unknown level', () => {
// arrange
const unknownLevel = 'boi';
const script = getValidScript();
const compiler = new ScriptCompilerStub();
const script = YamlScriptStub.createWithCode();
script.recommend = unknownLevel;
// act
const act = () => parseScript(script);
const act = () => parseScript(script, compiler);
// assert
expect(act).to.throw(`unknown level: "${unknownLevel}"`);
});
@@ -71,10 +107,11 @@ describe('ScriptParser', () => {
const nonStringTypes: any[] = [ 5, true ];
nonStringTypes.forEach((nonStringType) => {
// arrange
const script = getValidScript();
const script = YamlScriptStub.createWithCode();
const compiler = new ScriptCompilerStub();
script.recommend = nonStringType;
// act
const act = () => parseScript(script);
const act = () => parseScript(script, compiler);
// assert
expect(act).to.throw(`level must be a string but it was ${typeof nonStringType}`);
});
@@ -84,10 +121,11 @@ describe('ScriptParser', () => {
it(levelText, () => {
// arrange
const expectedLevel = RecommendationLevel[levelText];
const script = getValidScript();
const script = YamlScriptStub.createWithCode();
const compiler = new ScriptCompilerStub();
script.recommend = levelText;
// act
const actual = parseScript(script);
const actual = parseScript(script, compiler);
// assert
expect(actual.level).to.equal(expectedLevel);
});
@@ -95,24 +133,66 @@ describe('ScriptParser', () => {
});
it('parses level case insensitive', () => {
// arrange
const script = getValidScript();
const script = YamlScriptStub.createWithCode();
const compiler = new ScriptCompilerStub();
const expected = RecommendationLevel.Standard;
script.recommend = RecommendationLevel[expected].toUpperCase();
// act
const actual = parseScript(script);
const actual = parseScript(script, compiler);
// assert
expect(actual.level).to.equal(expected);
});
});
describe('code', () => {
it('parses code as expected', () => {
// arrange
const expected = 'expected-code';
const script = YamlScriptStub
.createWithCode()
.withCode(expected);
const compiler = new ScriptCompilerStub();
// act
const parsed = parseScript(script, compiler);
// assert
const actual = parsed.code.execute;
expect(actual).to.equal(expected);
});
it('parses revertCode as expected', () => {
// arrange
const expected = 'expected-revert-code';
const script = YamlScriptStub
.createWithCode()
.withRevertCode(expected);
const compiler = new ScriptCompilerStub();
// act
const parsed = parseScript(script, compiler);
// assert
const actual = parsed.code.revert;
expect(actual).to.equal(expected);
});
describe('compiler', () => {
it('throws when compiler is not defined', () => {
// arrange
const script = YamlScriptStub.createWithCode();
const compiler = undefined;
// act
const act = () => parseScript(script, compiler);
// assert
expect(act).to.throw('undefined compiler');
});
it('gets code from compiler', () => {
// arrange
const expected = new ScriptCode('test-script', 'code', 'revert-code');
const script = YamlScriptStub.createWithCode();
const compiler = new ScriptCompilerStub()
.withCompileAbility(script, expected);
// act
const parsed = parseScript(script, compiler);
// assert
const actual = parsed.code;
expect(actual).to.equal(expected);
});
});
});
});
});
function getValidScript(): YamlScript {
return {
name: 'valid-name',
code: 'valid-code',
revertCode: 'expected revert code',
docs: ['hello.com'],
recommend: RecommendationLevel[RecommendationLevel.Standard].toLowerCase(),
};
}