Refactor code to comply with ESLint rules
Major refactoring using ESLint with rules from AirBnb and Vue. Enable most of the ESLint rules and do necessary linting in the code. Also add more information for rules that are disabled to describe what they are and why they are disabled. Allow logging (`console.log`) in test files, and in development mode (e.g. when working with `npm run serve`), but disable it when environment is production (as pre-configured by Vue). Also add flag (`--mode production`) in `lint:eslint` command so production linting is executed earlier in lifecycle. Disable rules that requires a separate work. Such as ESLint rules that are broken in TypeScript: no-useless-constructor (eslint/eslint#14118) and no-shadow (eslint/eslint#13014).
This commit is contained in:
@@ -3,134 +3,137 @@ import { expect } from 'chai';
|
||||
import { CodeBuilder } from '@/application/Context/State/Code/Generation/CodeBuilder';
|
||||
|
||||
describe('CodeBuilder', () => {
|
||||
class CodeBuilderConcrete extends CodeBuilder {
|
||||
private commentDelimiter = '//';
|
||||
public withCommentDelimiter(delimiter: string): CodeBuilderConcrete {
|
||||
this.commentDelimiter = delimiter;
|
||||
return this;
|
||||
}
|
||||
protected getCommentDelimiter(): string {
|
||||
return this.commentDelimiter;
|
||||
}
|
||||
protected writeStandardOut(text: string): string {
|
||||
return text;
|
||||
}
|
||||
class CodeBuilderConcrete extends CodeBuilder {
|
||||
private commentDelimiter = '//';
|
||||
|
||||
public withCommentDelimiter(delimiter: string): CodeBuilderConcrete {
|
||||
this.commentDelimiter = delimiter;
|
||||
return this;
|
||||
}
|
||||
describe('appendLine', () => {
|
||||
it('when empty appends empty line', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
// act
|
||||
sut.appendLine().appendLine().appendLine();
|
||||
// assert
|
||||
expect(sut.toString()).to.equal('\n\n');
|
||||
});
|
||||
it('when not empty append string in new line', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
const expected = 'str';
|
||||
// act
|
||||
sut.appendLine()
|
||||
.appendLine(expected);
|
||||
// assert
|
||||
const result = sut.toString();
|
||||
const lines = getLines(result);
|
||||
expect(lines[1]).to.equal('str');
|
||||
});
|
||||
|
||||
protected getCommentDelimiter(): string {
|
||||
return this.commentDelimiter;
|
||||
}
|
||||
|
||||
protected writeStandardOut(text: string): string {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
describe('appendLine', () => {
|
||||
it('when empty appends empty line', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
// act
|
||||
sut.appendLine().appendLine().appendLine();
|
||||
// assert
|
||||
expect(sut.toString()).to.equal('\n\n');
|
||||
});
|
||||
it('appendFunction', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
const functionName = 'function';
|
||||
const code = 'code';
|
||||
// act
|
||||
sut.appendFunction(functionName, code);
|
||||
// assert
|
||||
const result = sut.toString();
|
||||
expect(result).to.include(functionName);
|
||||
expect(result).to.include(code);
|
||||
it('when not empty append string in new line', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
const expected = 'str';
|
||||
// act
|
||||
sut.appendLine()
|
||||
.appendLine(expected);
|
||||
// assert
|
||||
const result = sut.toString();
|
||||
const lines = getLines(result);
|
||||
expect(lines[1]).to.equal('str');
|
||||
});
|
||||
it('appendTrailingHyphensCommentLine', () => {
|
||||
// arrange
|
||||
const commentDelimiter = '//';
|
||||
const sut = new CodeBuilderConcrete()
|
||||
.withCommentDelimiter(commentDelimiter);
|
||||
const totalHyphens = 5;
|
||||
const expected = `${commentDelimiter} ${'-'.repeat(totalHyphens)}`;
|
||||
// act
|
||||
sut.appendTrailingHyphensCommentLine(totalHyphens);
|
||||
// assert
|
||||
const result = sut.toString();
|
||||
const lines = getLines(result);
|
||||
expect(lines[0]).to.equal(expected);
|
||||
});
|
||||
it('appendFunction', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
const functionName = 'function';
|
||||
const code = 'code';
|
||||
// act
|
||||
sut.appendFunction(functionName, code);
|
||||
// assert
|
||||
const result = sut.toString();
|
||||
expect(result).to.include(functionName);
|
||||
expect(result).to.include(code);
|
||||
});
|
||||
it('appendTrailingHyphensCommentLine', () => {
|
||||
// arrange
|
||||
const commentDelimiter = '//';
|
||||
const sut = new CodeBuilderConcrete()
|
||||
.withCommentDelimiter(commentDelimiter);
|
||||
const totalHyphens = 5;
|
||||
const expected = `${commentDelimiter} ${'-'.repeat(totalHyphens)}`;
|
||||
// act
|
||||
sut.appendTrailingHyphensCommentLine(totalHyphens);
|
||||
// assert
|
||||
const result = sut.toString();
|
||||
const lines = getLines(result);
|
||||
expect(lines[0]).to.equal(expected);
|
||||
});
|
||||
it('appendCommentLine', () => {
|
||||
// arrange
|
||||
const commentDelimiter = '//';
|
||||
const sut = new CodeBuilderConcrete()
|
||||
.withCommentDelimiter(commentDelimiter);
|
||||
const comment = 'comment';
|
||||
const expected = `${commentDelimiter} comment`;
|
||||
// act
|
||||
const result = sut
|
||||
.appendCommentLine(comment)
|
||||
.toString();
|
||||
// assert
|
||||
const lines = getLines(result);
|
||||
expect(lines[0]).to.equal(expected);
|
||||
});
|
||||
it('appendCommentLineWithHyphensAround', () => {
|
||||
// arrange
|
||||
const commentDelimiter = '//';
|
||||
const sut = new CodeBuilderConcrete()
|
||||
.withCommentDelimiter(commentDelimiter);
|
||||
const sectionName = 'section';
|
||||
const totalHyphens = sectionName.length + 3 * 2;
|
||||
const expected = `${commentDelimiter} ---section---`;
|
||||
// act
|
||||
const result = sut
|
||||
.appendCommentLineWithHyphensAround(sectionName, totalHyphens)
|
||||
.toString();
|
||||
// assert
|
||||
const lines = getLines(result);
|
||||
expect(lines[1]).to.equal(expected);
|
||||
});
|
||||
describe('currentLine', () => {
|
||||
it('no lines returns zero', () => {
|
||||
// arrange & act
|
||||
const sut = new CodeBuilderConcrete();
|
||||
// assert
|
||||
expect(sut.currentLine).to.equal(0);
|
||||
});
|
||||
it('appendCommentLine', () => {
|
||||
// arrange
|
||||
const commentDelimiter = '//';
|
||||
const sut = new CodeBuilderConcrete()
|
||||
.withCommentDelimiter(commentDelimiter);
|
||||
const comment = 'comment';
|
||||
const expected = `${commentDelimiter} comment`;
|
||||
// act
|
||||
const result = sut
|
||||
.appendCommentLine(comment)
|
||||
.toString();
|
||||
// assert
|
||||
const lines = getLines(result);
|
||||
expect(lines[0]).to.equal(expected);
|
||||
it('single line returns one', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
// act
|
||||
sut.appendLine();
|
||||
// assert
|
||||
expect(sut.currentLine).to.equal(1);
|
||||
});
|
||||
it('appendCommentLineWithHyphensAround', () => {
|
||||
// arrange
|
||||
const commentDelimiter = '//';
|
||||
const sut = new CodeBuilderConcrete()
|
||||
.withCommentDelimiter(commentDelimiter);
|
||||
const sectionName = 'section';
|
||||
const totalHyphens = sectionName.length + 3 * 2;
|
||||
const expected = `${commentDelimiter} ---section---`;
|
||||
// act
|
||||
const result = sut
|
||||
.appendCommentLineWithHyphensAround(sectionName, totalHyphens)
|
||||
.toString();
|
||||
// assert
|
||||
const lines = getLines(result);
|
||||
expect(lines[1]).to.equal(expected);
|
||||
it('multiple lines returns as expected', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
// act
|
||||
sut.appendLine('1')
|
||||
.appendCommentLine('2')
|
||||
.appendLine();
|
||||
// assert
|
||||
expect(sut.currentLine).to.equal(3);
|
||||
});
|
||||
describe('currentLine', () => {
|
||||
it('no lines returns zero', () => {
|
||||
// arrange & act
|
||||
const sut = new CodeBuilderConcrete();
|
||||
// assert
|
||||
expect(sut.currentLine).to.equal(0);
|
||||
});
|
||||
it('single line returns one', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
// act
|
||||
sut.appendLine();
|
||||
// assert
|
||||
expect(sut.currentLine).to.equal(1);
|
||||
});
|
||||
it('multiple lines returns as expected', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
// act
|
||||
sut.appendLine('1')
|
||||
.appendCommentLine('2')
|
||||
.appendLine();
|
||||
// assert
|
||||
expect(sut.currentLine).to.equal(3);
|
||||
});
|
||||
it('multiple lines in code', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
// act
|
||||
sut.appendLine('hello\ncode-here\nwith-3-lines');
|
||||
// assert
|
||||
expect(sut.currentLine).to.equal(3);
|
||||
});
|
||||
it('multiple lines in code', () => {
|
||||
// arrange
|
||||
const sut = new CodeBuilderConcrete();
|
||||
// act
|
||||
sut.appendLine('hello\ncode-here\nwith-3-lines');
|
||||
// assert
|
||||
expect(sut.currentLine).to.equal(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getLines(text: string): string[] {
|
||||
return text.split(/\r\n|\r|\n/);
|
||||
return text.split(/\r\n|\r|\n/);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import { CodeBuilderFactory } from '@/application/Context/State/Code/Generation/
|
||||
import { ScriptingLanguageFactoryTestRunner } from '@tests/unit/application/Common/ScriptingLanguage/ScriptingLanguageFactoryTestRunner';
|
||||
|
||||
describe('CodeBuilderFactory', () => {
|
||||
const sut = new CodeBuilderFactory();
|
||||
const runner = new ScriptingLanguageFactoryTestRunner()
|
||||
.expect(ScriptingLanguage.shellscript, ShellBuilder)
|
||||
.expect(ScriptingLanguage.batchfile, BatchBuilder);
|
||||
runner.testCreateMethod(sut);
|
||||
const sut = new CodeBuilderFactory();
|
||||
const runner = new ScriptingLanguageFactoryTestRunner()
|
||||
.expect(ScriptingLanguage.shellscript, ShellBuilder)
|
||||
.expect(ScriptingLanguage.batchfile, BatchBuilder);
|
||||
runner.testCreateMethod(sut);
|
||||
});
|
||||
|
||||
@@ -3,57 +3,58 @@ import { expect } from 'chai';
|
||||
import { BatchBuilder } from '@/application/Context/State/Code/Generation/Languages/BatchBuilder';
|
||||
|
||||
describe('BatchBuilder', () => {
|
||||
class BatchBuilderRevealer extends BatchBuilder {
|
||||
public getCommentDelimiter(): string {
|
||||
return super.getCommentDelimiter();
|
||||
}
|
||||
public writeStandardOut(text: string): string {
|
||||
return super.writeStandardOut(text);
|
||||
}
|
||||
class BatchBuilderRevealer extends BatchBuilder {
|
||||
public getCommentDelimiter(): string {
|
||||
return super.getCommentDelimiter();
|
||||
}
|
||||
describe('getCommentDelimiter', () => {
|
||||
it('returns expected', () => {
|
||||
// arrange
|
||||
const expected = '::';
|
||||
const sut = new BatchBuilderRevealer();
|
||||
// act
|
||||
const actual = sut.getCommentDelimiter();
|
||||
// assert
|
||||
expect(expected).to.equal(actual);
|
||||
});
|
||||
});
|
||||
describe('writeStandardOut', () => {
|
||||
const testData = [
|
||||
{
|
||||
name: 'plain text',
|
||||
text: 'test',
|
||||
expected: 'echo test',
|
||||
},
|
||||
{
|
||||
name: 'text with ampersand',
|
||||
text: 'a & b',
|
||||
expected: 'echo a ^& b',
|
||||
},
|
||||
{
|
||||
name: 'text with percent sign',
|
||||
text: '90%',
|
||||
expected: 'echo 90%%',
|
||||
},
|
||||
{
|
||||
name: 'text with multiple ampersands and percent signs',
|
||||
text: 'Me&you in % ? You & me = 0%',
|
||||
expected: 'echo Me^&you in %% ? You ^& me = 0%%',
|
||||
},
|
||||
];
|
||||
for (const test of testData) {
|
||||
it(test.name, () => {
|
||||
// arrange
|
||||
const sut = new BatchBuilderRevealer();
|
||||
// act
|
||||
const actual = sut.writeStandardOut(test.text);
|
||||
// assert
|
||||
expect(test.expected).to.equal(actual);
|
||||
});
|
||||
}
|
||||
|
||||
public writeStandardOut(text: string): string {
|
||||
return super.writeStandardOut(text);
|
||||
}
|
||||
}
|
||||
describe('getCommentDelimiter', () => {
|
||||
it('returns expected', () => {
|
||||
// arrange
|
||||
const expected = '::';
|
||||
const sut = new BatchBuilderRevealer();
|
||||
// act
|
||||
const actual = sut.getCommentDelimiter();
|
||||
// assert
|
||||
expect(expected).to.equal(actual);
|
||||
});
|
||||
});
|
||||
describe('writeStandardOut', () => {
|
||||
const testData = [
|
||||
{
|
||||
name: 'plain text',
|
||||
text: 'test',
|
||||
expected: 'echo test',
|
||||
},
|
||||
{
|
||||
name: 'text with ampersand',
|
||||
text: 'a & b',
|
||||
expected: 'echo a ^& b',
|
||||
},
|
||||
{
|
||||
name: 'text with percent sign',
|
||||
text: '90%',
|
||||
expected: 'echo 90%%',
|
||||
},
|
||||
{
|
||||
name: 'text with multiple ampersands and percent signs',
|
||||
text: 'Me&you in % ? You & me = 0%',
|
||||
expected: 'echo Me^&you in %% ? You ^& me = 0%%',
|
||||
},
|
||||
];
|
||||
for (const test of testData) {
|
||||
it(test.name, () => {
|
||||
// arrange
|
||||
const sut = new BatchBuilderRevealer();
|
||||
// act
|
||||
const actual = sut.writeStandardOut(test.text);
|
||||
// assert
|
||||
expect(test.expected).to.equal(actual);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,52 +3,53 @@ import { expect } from 'chai';
|
||||
import { ShellBuilder } from '@/application/Context/State/Code/Generation/Languages/ShellBuilder';
|
||||
|
||||
describe('ShellBuilder', () => {
|
||||
class ShellBuilderRevealer extends ShellBuilder {
|
||||
public getCommentDelimiter(): string {
|
||||
return super.getCommentDelimiter();
|
||||
}
|
||||
public writeStandardOut(text: string): string {
|
||||
return super.writeStandardOut(text);
|
||||
}
|
||||
class ShellBuilderRevealer extends ShellBuilder {
|
||||
public getCommentDelimiter(): string {
|
||||
return super.getCommentDelimiter();
|
||||
}
|
||||
describe('getCommentDelimiter', () => {
|
||||
it('returns expected', () => {
|
||||
// arrange
|
||||
const expected = '#';
|
||||
const sut = new ShellBuilderRevealer();
|
||||
// act
|
||||
const actual = sut.getCommentDelimiter();
|
||||
// assert
|
||||
expect(expected).to.equal(actual);
|
||||
});
|
||||
});
|
||||
describe('writeStandardOut', () => {
|
||||
const testData = [
|
||||
{
|
||||
name: 'plain text',
|
||||
text: 'test',
|
||||
expected: 'echo \'test\'',
|
||||
},
|
||||
{
|
||||
name: 'text with single quote',
|
||||
text: 'I\'m not who you think I am',
|
||||
expected: 'echo \'I\'\\\'\'m not who you think I am\'',
|
||||
},
|
||||
{
|
||||
name: 'text with multiple single quotes',
|
||||
text: 'I\'m what you\'re',
|
||||
expected: 'echo \'I\'\\\'\'m what you\'\\\'\'re\'',
|
||||
},
|
||||
];
|
||||
for (const test of testData) {
|
||||
it(test.name, () => {
|
||||
// arrange
|
||||
const sut = new ShellBuilderRevealer();
|
||||
// act
|
||||
const actual = sut.writeStandardOut(test.text);
|
||||
// assert
|
||||
expect(test.expected).to.equal(actual);
|
||||
});
|
||||
}
|
||||
|
||||
public writeStandardOut(text: string): string {
|
||||
return super.writeStandardOut(text);
|
||||
}
|
||||
}
|
||||
describe('getCommentDelimiter', () => {
|
||||
it('returns expected', () => {
|
||||
// arrange
|
||||
const expected = '#';
|
||||
const sut = new ShellBuilderRevealer();
|
||||
// act
|
||||
const actual = sut.getCommentDelimiter();
|
||||
// assert
|
||||
expect(expected).to.equal(actual);
|
||||
});
|
||||
});
|
||||
describe('writeStandardOut', () => {
|
||||
const testData = [
|
||||
{
|
||||
name: 'plain text',
|
||||
text: 'test',
|
||||
expected: 'echo \'test\'',
|
||||
},
|
||||
{
|
||||
name: 'text with single quote',
|
||||
text: 'I\'m not who you think I am',
|
||||
expected: 'echo \'I\'\\\'\'m not who you think I am\'',
|
||||
},
|
||||
{
|
||||
name: 'text with multiple single quotes',
|
||||
text: 'I\'m what you\'re',
|
||||
expected: 'echo \'I\'\\\'\'m what you\'\\\'\'re\'',
|
||||
},
|
||||
];
|
||||
for (const test of testData) {
|
||||
it(test.name, () => {
|
||||
// arrange
|
||||
const sut = new ShellBuilderRevealer();
|
||||
// act
|
||||
const actual = sut.writeStandardOut(test.text);
|
||||
// assert
|
||||
expect(test.expected).to.equal(actual);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,230 +8,239 @@ import { ScriptStub } from '@tests/unit/stubs/ScriptStub';
|
||||
import { ScriptingDefinitionStub } from '@tests/unit/stubs/ScriptingDefinitionStub';
|
||||
|
||||
describe('UserScriptGenerator', () => {
|
||||
describe('scriptingDefinition', () => {
|
||||
describe('startCode', () => {
|
||||
it('is prepended if not empty', () => {
|
||||
// arrange
|
||||
const sut = new UserScriptGenerator();
|
||||
const startCode = 'Start\nCode';
|
||||
const script = new ScriptStub('id')
|
||||
.withCode('code\nmulti-lined')
|
||||
.toSelectedScript();
|
||||
const definition = new ScriptingDefinitionStub()
|
||||
.withStartCode(startCode)
|
||||
.withEndCode(undefined);
|
||||
const expectedStart = `${startCode}\n`;
|
||||
// act
|
||||
const code = sut.buildCode([script], definition);
|
||||
// assert
|
||||
const actual = code.code;
|
||||
expect(actual.startsWith(expectedStart));
|
||||
});
|
||||
it('is not prepended if empty', () => {
|
||||
// arrange
|
||||
const codeBuilderStub = new CodeBuilderStub();
|
||||
const sut = new UserScriptGenerator(mockCodeBuilderFactory(codeBuilderStub));
|
||||
const script = new ScriptStub('id')
|
||||
.withCode('code\nmulti-lined')
|
||||
.toSelectedScript();
|
||||
const definition = new ScriptingDefinitionStub()
|
||||
.withStartCode(undefined)
|
||||
.withEndCode(undefined);
|
||||
const expectedStart = codeBuilderStub
|
||||
.appendFunction(script.script.name, script.script.code.execute)
|
||||
.toString();
|
||||
// act
|
||||
const code = sut.buildCode([script], definition);
|
||||
// assert
|
||||
const actual = code.code;
|
||||
expect(actual.startsWith(expectedStart));
|
||||
});
|
||||
});
|
||||
describe('endCode', () => {
|
||||
it('is appended if not empty', () => {
|
||||
// arrange
|
||||
const sut = new UserScriptGenerator();
|
||||
const endCode = 'End\nCode';
|
||||
const script = new ScriptStub('id')
|
||||
.withCode('code\nmulti-lined')
|
||||
.toSelectedScript();
|
||||
const definition = new ScriptingDefinitionStub()
|
||||
.withEndCode(endCode);
|
||||
const expectedEnd = `${endCode}\n`;
|
||||
// act
|
||||
const code = sut.buildCode([script], definition);
|
||||
// assert
|
||||
const actual = code.code;
|
||||
expect(actual.endsWith(expectedEnd));
|
||||
});
|
||||
it('is not appended if empty', () => {
|
||||
// arrange
|
||||
const codeBuilderStub = new CodeBuilderStub();
|
||||
const sut = new UserScriptGenerator(mockCodeBuilderFactory(codeBuilderStub));
|
||||
const script = new ScriptStub('id')
|
||||
.withCode('code\nmulti-lined')
|
||||
.toSelectedScript();
|
||||
const expectedEnd = codeBuilderStub
|
||||
.appendFunction(script.script.name, script.script.code.execute)
|
||||
.toString();
|
||||
const definition = new ScriptingDefinitionStub()
|
||||
.withEndCode(undefined);
|
||||
// act
|
||||
const code = sut.buildCode([script], definition);
|
||||
// assert
|
||||
const actual = code.code;
|
||||
expect(actual.endsWith(expectedEnd));
|
||||
});
|
||||
});
|
||||
});
|
||||
it('appends revert script', () => {
|
||||
describe('scriptingDefinition', () => {
|
||||
describe('startCode', () => {
|
||||
it('is prepended if not empty', () => {
|
||||
// arrange
|
||||
const sut = new UserScriptGenerator();
|
||||
const scriptName = 'test non-revert script';
|
||||
const scriptCode = 'REM nop';
|
||||
const startCode = 'Start\nCode';
|
||||
const script = new ScriptStub('id')
|
||||
.withName(scriptName)
|
||||
.withRevertCode(scriptCode)
|
||||
.toSelectedScript(true);
|
||||
const definition = new ScriptingDefinitionStub();
|
||||
.withCode('code\nmulti-lined')
|
||||
.toSelectedScript();
|
||||
const definition = new ScriptingDefinitionStub()
|
||||
.withStartCode(startCode)
|
||||
.withEndCode(undefined);
|
||||
const expectedStart = `${startCode}\n`;
|
||||
// act
|
||||
const actual = sut.buildCode([ script ], definition);
|
||||
const code = sut.buildCode([script], definition);
|
||||
// assert
|
||||
expect(actual.code).to.include(`${scriptName} (revert)`);
|
||||
expect(actual.code).to.include(scriptCode);
|
||||
});
|
||||
it('appends non-revert script', () => {
|
||||
const sut = new UserScriptGenerator();
|
||||
const actual = code.code;
|
||||
expect(actual.startsWith(expectedStart));
|
||||
});
|
||||
it('is not prepended if empty', () => {
|
||||
// arrange
|
||||
const scriptName = 'test non-revert script';
|
||||
const scriptCode = 'REM nop';
|
||||
const script = new ScriptStub('id').withName(scriptName).withCode(scriptCode);
|
||||
const selectedScripts = [ new SelectedScript(script, false)];
|
||||
const definition = new ScriptingDefinitionStub();
|
||||
const codeBuilderStub = new CodeBuilderStub();
|
||||
const sut = new UserScriptGenerator(mockCodeBuilderFactory(codeBuilderStub));
|
||||
const script = new ScriptStub('id')
|
||||
.withCode('code\nmulti-lined')
|
||||
.toSelectedScript();
|
||||
const definition = new ScriptingDefinitionStub()
|
||||
.withStartCode(undefined)
|
||||
.withEndCode(undefined);
|
||||
const expectedStart = codeBuilderStub
|
||||
.appendFunction(script.script.name, script.script.code.execute)
|
||||
.toString();
|
||||
// act
|
||||
const code = sut.buildCode([script], definition);
|
||||
// assert
|
||||
const actual = code.code;
|
||||
expect(actual.startsWith(expectedStart));
|
||||
});
|
||||
});
|
||||
describe('endCode', () => {
|
||||
it('is appended if not empty', () => {
|
||||
// arrange
|
||||
const sut = new UserScriptGenerator();
|
||||
const endCode = 'End\nCode';
|
||||
const script = new ScriptStub('id')
|
||||
.withCode('code\nmulti-lined')
|
||||
.toSelectedScript();
|
||||
const definition = new ScriptingDefinitionStub()
|
||||
.withEndCode(endCode);
|
||||
const expectedEnd = `${endCode}\n`;
|
||||
// act
|
||||
const code = sut.buildCode([script], definition);
|
||||
// assert
|
||||
const actual = code.code;
|
||||
expect(actual.endsWith(expectedEnd));
|
||||
});
|
||||
it('is not appended if empty', () => {
|
||||
// arrange
|
||||
const codeBuilderStub = new CodeBuilderStub();
|
||||
const sut = new UserScriptGenerator(mockCodeBuilderFactory(codeBuilderStub));
|
||||
const script = new ScriptStub('id')
|
||||
.withCode('code\nmulti-lined')
|
||||
.toSelectedScript();
|
||||
const expectedEnd = codeBuilderStub
|
||||
.appendFunction(script.script.name, script.script.code.execute)
|
||||
.toString();
|
||||
const definition = new ScriptingDefinitionStub()
|
||||
.withEndCode(undefined);
|
||||
// act
|
||||
const code = sut.buildCode([script], definition);
|
||||
// assert
|
||||
const actual = code.code;
|
||||
expect(actual.endsWith(expectedEnd));
|
||||
});
|
||||
});
|
||||
});
|
||||
it('appends revert script', () => {
|
||||
// arrange
|
||||
const sut = new UserScriptGenerator();
|
||||
const scriptName = 'test non-revert script';
|
||||
const scriptCode = 'REM nop';
|
||||
const script = new ScriptStub('id')
|
||||
.withName(scriptName)
|
||||
.withRevertCode(scriptCode)
|
||||
.toSelectedScript(true);
|
||||
const definition = new ScriptingDefinitionStub();
|
||||
// act
|
||||
const actual = sut.buildCode([script], definition);
|
||||
// assert
|
||||
expect(actual.code).to.include(`${scriptName} (revert)`);
|
||||
expect(actual.code).to.include(scriptCode);
|
||||
});
|
||||
it('appends non-revert script', () => {
|
||||
const sut = new UserScriptGenerator();
|
||||
// arrange
|
||||
const scriptName = 'test non-revert script';
|
||||
const scriptCode = 'REM nop';
|
||||
const script = new ScriptStub('id').withName(scriptName).withCode(scriptCode);
|
||||
const selectedScripts = [new SelectedScript(script, false)];
|
||||
const definition = new ScriptingDefinitionStub();
|
||||
// act
|
||||
const actual = sut.buildCode(selectedScripts, definition);
|
||||
// assert
|
||||
expect(actual.code).to.include(scriptName);
|
||||
expect(actual.code).to.not.include(`${scriptName} (revert)`);
|
||||
expect(actual.code).to.include(scriptCode);
|
||||
});
|
||||
describe('scriptPositions', () => {
|
||||
it('without script; returns empty', () => {
|
||||
// arrange
|
||||
const sut = new UserScriptGenerator();
|
||||
const selectedScripts = [];
|
||||
const definition = new ScriptingDefinitionStub();
|
||||
// act
|
||||
const actual = sut.buildCode(selectedScripts, definition);
|
||||
// assert
|
||||
expect(actual.scriptPositions.size).to.equal(0);
|
||||
});
|
||||
describe('with scripts', () => {
|
||||
// arrange
|
||||
const totalStartCodeLines = 2;
|
||||
const totalFunctionNameLines = 4;
|
||||
const definition = new ScriptingDefinitionStub()
|
||||
.withStartCode('First line\nSecond line');
|
||||
describe('single script', () => {
|
||||
const testCases = [
|
||||
{
|
||||
name: 'single-lined',
|
||||
scriptCode: 'only line',
|
||||
codeLines: 1,
|
||||
},
|
||||
{
|
||||
name: 'multi-lined',
|
||||
scriptCode: 'first line\nsecond line',
|
||||
codeLines: 2,
|
||||
},
|
||||
];
|
||||
const sut = new UserScriptGenerator();
|
||||
for (const testCase of testCases) {
|
||||
it(testCase.name, () => {
|
||||
const expectedStartLine = totalStartCodeLines
|
||||
+ 1 // empty line code begin
|
||||
+ 1; // code begin
|
||||
const expectedEndLine = expectedStartLine
|
||||
+ totalFunctionNameLines
|
||||
+ testCase.codeLines;
|
||||
const selectedScript = new ScriptStub('script-id')
|
||||
.withName('script')
|
||||
.withCode(testCase.scriptCode)
|
||||
.toSelectedScript(false);
|
||||
// act
|
||||
const actual = sut.buildCode([selectedScript], definition);
|
||||
// expect
|
||||
expect(1).to.equal(actual.scriptPositions.size);
|
||||
const position = actual.scriptPositions.get(selectedScript);
|
||||
expect(expectedStartLine).to.equal(position.startLine, 'Unexpected start line position');
|
||||
expect(expectedEndLine).to.equal(position.endLine, 'Unexpected end line position');
|
||||
});
|
||||
}
|
||||
});
|
||||
it('multiple scripts', () => {
|
||||
const sut = new UserScriptGenerator();
|
||||
const selectedScripts = [
|
||||
new ScriptStub('1').withCode('only line'),
|
||||
new ScriptStub('2').withCode('first line\nsecond line'),
|
||||
].map((s) => s.toSelectedScript());
|
||||
const expectedFirstScriptStart = totalStartCodeLines
|
||||
+ 1 // empty line code begin
|
||||
+ 1; // code begin
|
||||
const expectedFirstScriptEnd = expectedFirstScriptStart
|
||||
+ totalFunctionNameLines
|
||||
+ 1; // total code lines
|
||||
const expectedSecondScriptStart = expectedFirstScriptEnd
|
||||
+ 1 // code end hyphens
|
||||
+ 1 // new line
|
||||
+ 1; // code begin
|
||||
const expectedSecondScriptEnd = expectedSecondScriptStart
|
||||
+ totalFunctionNameLines
|
||||
+ 2; // total lines of second script
|
||||
// act
|
||||
const actual = sut.buildCode(selectedScripts, definition);
|
||||
// assert
|
||||
expect(actual.code).to.include(scriptName);
|
||||
expect(actual.code).to.not.include(`${scriptName} (revert)`);
|
||||
expect(actual.code).to.include(scriptCode);
|
||||
});
|
||||
describe('scriptPositions', () => {
|
||||
it('without script; returns empty', () => {
|
||||
// arrange
|
||||
const sut = new UserScriptGenerator();
|
||||
const selectedScripts = [ ];
|
||||
const definition = new ScriptingDefinitionStub();
|
||||
// act
|
||||
const actual = sut.buildCode(selectedScripts, definition);
|
||||
// assert
|
||||
expect(actual.scriptPositions.size).to.equal(0);
|
||||
});
|
||||
describe('with scripts', () => {
|
||||
// arrange
|
||||
const totalStartCodeLines = 2;
|
||||
const totalFunctionNameLines = 4;
|
||||
const definition = new ScriptingDefinitionStub()
|
||||
.withStartCode('First line\nSecond line');
|
||||
describe('single script', () => {
|
||||
const testCases = [
|
||||
{
|
||||
name: 'single-lined',
|
||||
scriptCode: 'only line',
|
||||
codeLines: 1,
|
||||
},
|
||||
{
|
||||
name: 'multi-lined',
|
||||
scriptCode: 'first line\nsecond line',
|
||||
codeLines: 2,
|
||||
},
|
||||
];
|
||||
const sut = new UserScriptGenerator();
|
||||
for (const testCase of testCases) {
|
||||
it(testCase.name, () => {
|
||||
const expectedStartLine = totalStartCodeLines
|
||||
+ 1 // empty line code begin
|
||||
+ 1; // code begin
|
||||
const expectedEndLine = expectedStartLine
|
||||
+ totalFunctionNameLines
|
||||
+ testCase.codeLines;
|
||||
const selectedScript = new ScriptStub(`script-id`)
|
||||
.withName(`script`)
|
||||
.withCode(testCase.scriptCode)
|
||||
.toSelectedScript(false);
|
||||
// act
|
||||
const actual = sut.buildCode([ selectedScript ], definition);
|
||||
// expect
|
||||
expect(1).to.equal(actual.scriptPositions.size);
|
||||
const position = actual.scriptPositions.get(selectedScript);
|
||||
expect(expectedStartLine).to.equal(position.startLine, 'Unexpected start line position');
|
||||
expect(expectedEndLine).to.equal(position.endLine, 'Unexpected end line position');
|
||||
});
|
||||
}
|
||||
});
|
||||
it('multiple scripts', () => {
|
||||
const sut = new UserScriptGenerator();
|
||||
const selectedScripts = [
|
||||
new ScriptStub('1').withCode('only line'),
|
||||
new ScriptStub('2').withCode('first line\nsecond line'),
|
||||
].map((s) => s.toSelectedScript());
|
||||
const expectedFirstScriptStart = totalStartCodeLines
|
||||
+ 1 // empty line code begin
|
||||
+ 1; // code begin
|
||||
const expectedFirstScriptEnd = expectedFirstScriptStart
|
||||
+ totalFunctionNameLines
|
||||
+ 1; // total code lines
|
||||
const expectedSecondScriptStart = expectedFirstScriptEnd
|
||||
+ 1 // code end hyphens
|
||||
+ 1 // new line
|
||||
+ 1; // code begin
|
||||
const expectedSecondScriptEnd =
|
||||
expectedSecondScriptStart
|
||||
+ totalFunctionNameLines
|
||||
+ 2; // total lines of second script
|
||||
// act
|
||||
const actual = sut.buildCode(selectedScripts, definition);
|
||||
// assert
|
||||
const firstPosition = actual.scriptPositions.get(selectedScripts[0]);
|
||||
const secondPosition = actual.scriptPositions.get(selectedScripts[1]);
|
||||
expect(actual.scriptPositions.size).to.equal(2);
|
||||
expect(expectedFirstScriptStart).to.equal(firstPosition.startLine, 'Unexpected start line position (first script)');
|
||||
expect(expectedFirstScriptEnd).to.equal(firstPosition.endLine, 'Unexpected end line position (first script)');
|
||||
expect(expectedSecondScriptStart).to.equal(secondPosition.startLine, 'Unexpected start line position (second script)');
|
||||
expect(expectedSecondScriptEnd).to.equal(secondPosition.endLine, 'Unexpected end line position (second script)');
|
||||
});
|
||||
});
|
||||
const firstPosition = actual.scriptPositions.get(selectedScripts[0]);
|
||||
const secondPosition = actual.scriptPositions.get(selectedScripts[1]);
|
||||
expect(actual.scriptPositions.size).to.equal(2);
|
||||
expect(expectedFirstScriptStart).to.equal(firstPosition.startLine, 'Unexpected start line position (first script)');
|
||||
expect(expectedFirstScriptEnd).to.equal(firstPosition.endLine, 'Unexpected end line position (first script)');
|
||||
expect(expectedSecondScriptStart).to.equal(secondPosition.startLine, 'Unexpected start line position (second script)');
|
||||
expect(expectedSecondScriptEnd).to.equal(secondPosition.endLine, 'Unexpected end line position (second script)');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function mockCodeBuilderFactory(mock: ICodeBuilder): ICodeBuilderFactory {
|
||||
return {
|
||||
create: () => mock,
|
||||
};
|
||||
return {
|
||||
create: () => mock,
|
||||
};
|
||||
}
|
||||
|
||||
class CodeBuilderStub implements ICodeBuilder {
|
||||
public currentLine = 0;
|
||||
private text = '';
|
||||
public appendLine(code?: string): ICodeBuilder {
|
||||
this.text += this.text ? `${code}\n` : code;
|
||||
this.currentLine++;
|
||||
return this;
|
||||
}
|
||||
public appendTrailingHyphensCommentLine(totalRepeatHyphens: number): ICodeBuilder {
|
||||
return this.appendLine(`trailing-hyphens-${totalRepeatHyphens}`);
|
||||
}
|
||||
public appendCommentLine(commentLine?: string): ICodeBuilder {
|
||||
return this.appendLine(`Comment | ${commentLine}`);
|
||||
}
|
||||
public appendCommentLineWithHyphensAround(sectionName: string, totalRepeatHyphens: number): ICodeBuilder {
|
||||
return this.appendLine(`hyphens-around-${totalRepeatHyphens} | Section name: ${sectionName} | hyphens-around-${totalRepeatHyphens}`);
|
||||
}
|
||||
public appendFunction(name: string, code: string): ICodeBuilder {
|
||||
return this
|
||||
.appendLine(`Function | Name: ${name}`)
|
||||
.appendLine(`Function | Code: ${code}`);
|
||||
}
|
||||
public toString(): string {
|
||||
return this.text;
|
||||
}
|
||||
public currentLine = 0;
|
||||
|
||||
private text = '';
|
||||
|
||||
public appendLine(code?: string): ICodeBuilder {
|
||||
this.text += this.text ? `${code}\n` : code;
|
||||
this.currentLine++;
|
||||
return this;
|
||||
}
|
||||
|
||||
public appendTrailingHyphensCommentLine(totalRepeatHyphens: number): ICodeBuilder {
|
||||
return this.appendLine(`trailing-hyphens-${totalRepeatHyphens}`);
|
||||
}
|
||||
|
||||
public appendCommentLine(commentLine?: string): ICodeBuilder {
|
||||
return this.appendLine(`Comment | ${commentLine}`);
|
||||
}
|
||||
|
||||
public appendCommentLineWithHyphensAround(
|
||||
sectionName: string,
|
||||
totalRepeatHyphens: number,
|
||||
): ICodeBuilder {
|
||||
return this.appendLine(`hyphens-around-${totalRepeatHyphens} | Section name: ${sectionName} | hyphens-around-${totalRepeatHyphens}`);
|
||||
}
|
||||
|
||||
public appendFunction(name: string, code: string): ICodeBuilder {
|
||||
return this
|
||||
.appendLine(`Function | Name: ${name}`)
|
||||
.appendLine(`Function | Code: ${code}`);
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
return this.text;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user