add initial macOS support #40

This commit is contained in:
undergroundwires
2021-01-13 16:31:20 +01:00
parent 2428de23ee
commit 8a8b7319d5
99 changed files with 2663 additions and 1135 deletions

View File

@@ -3,10 +3,23 @@ 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;
}
}
describe('appendLine', () => {
it('when empty appends empty line', () => {
// arrange
const sut = new CodeBuilder();
const sut = new CodeBuilderConcrete();
// act
sut.appendLine().appendLine().appendLine();
// assert
@@ -14,7 +27,7 @@ describe('CodeBuilder', () => {
});
it('when not empty append string in new line', () => {
// arrange
const sut = new CodeBuilder();
const sut = new CodeBuilderConcrete();
const expected = 'str';
// act
sut.appendLine()
@@ -27,7 +40,7 @@ describe('CodeBuilder', () => {
});
it('appendFunction', () => {
// arrange
const sut = new CodeBuilder();
const sut = new CodeBuilderConcrete();
const functionName = 'function';
const code = 'code';
// act
@@ -39,11 +52,13 @@ describe('CodeBuilder', () => {
});
it('appendTrailingHyphensCommentLine', () => {
// arrange
const sut = new CodeBuilder();
const totalHypens = 5;
const expected = `:: ${'-'.repeat(totalHypens)}`;
const commentDelimiter = '//';
const sut = new CodeBuilderConcrete()
.withCommentDelimiter(commentDelimiter);
const totalHyphens = 5;
const expected = `${commentDelimiter} ${'-'.repeat(totalHyphens)}`;
// act
sut.appendTrailingHyphensCommentLine(totalHypens);
sut.appendTrailingHyphensCommentLine(totalHyphens);
// assert
const result = sut.toString();
const lines = getLines(result);
@@ -51,38 +66,45 @@ describe('CodeBuilder', () => {
});
it('appendCommentLine', () => {
// arrange
const sut = new CodeBuilder();
const commentDelimiter = '//';
const sut = new CodeBuilderConcrete()
.withCommentDelimiter(commentDelimiter);
const comment = 'comment';
const expected = ':: comment';
const expected = `${commentDelimiter} comment`;
// act
sut.appendCommentLine(comment);
const result = sut
.appendCommentLine(comment)
.toString();
// assert
const result = sut.toString();
const lines = getLines(result);
expect(lines[0]).to.equal(expected);
});
it('appendCommentLineWithHyphensAround', () => {
// arrange
const sut = new CodeBuilder();
const commentDelimiter = '//';
const sut = new CodeBuilderConcrete()
.withCommentDelimiter(commentDelimiter);
const sectionName = 'section';
const totalHypens = sectionName.length + 3 * 2;
const expected = ':: ---section---';
sut.appendCommentLineWithHyphensAround(sectionName, totalHypens);
const totalHyphens = sectionName.length + 3 * 2;
const expected = `${commentDelimiter} ---section---`;
// act
const result = sut
.appendCommentLineWithHyphensAround(sectionName, totalHyphens)
.toString();
// assert
const result = sut.toString();
const lines = getLines(result);
expect(lines[1]).to.equal(expected);
});
describe('currentLine', () => {
it('no lines returns zero', () => {
// arrange & act
const sut = new CodeBuilder();
const sut = new CodeBuilderConcrete();
// assert
expect(sut.currentLine).to.equal(0);
});
it('single line returns one', () => {
// arrange
const sut = new CodeBuilder();
const sut = new CodeBuilderConcrete();
// act
sut.appendLine();
// assert
@@ -90,15 +112,17 @@ describe('CodeBuilder', () => {
});
it('multiple lines returns as expected', () => {
// arrange
const sut = new CodeBuilder();
const sut = new CodeBuilderConcrete();
// act
sut.appendLine('1').appendCommentLine('2').appendLine();
sut.appendLine('1')
.appendCommentLine('2')
.appendLine();
// assert
expect(sut.currentLine).to.equal(3);
});
it('multiple lines in code', () => {
// arrange
const sut = new CodeBuilder();
const sut = new CodeBuilderConcrete();
// act
sut.appendLine('hello\ncode-here\nwith-3-lines');
// assert

View File

@@ -0,0 +1,36 @@
import 'mocha';
import { expect } from 'chai';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { ShellBuilder } from '@/application/Context/State/Code/Generation/Languages/ShellBuilder';
import { BatchBuilder } from '@/application/Context/State/Code/Generation/Languages/BatchBuilder';
import { CodeBuilderFactory } from '@/application/Context/State/Code/Generation/CodeBuilderFactory';
describe('CodeBuilderFactory', () => {
describe('create', () => {
describe('creates expected type', () => {
// arrange
const testCases: Array< { language: ScriptingLanguage, expected: any} > = [
{ language: ScriptingLanguage.shellscript, expected: ShellBuilder},
{ language: ScriptingLanguage.batchfile, expected: BatchBuilder},
];
for (const testCase of testCases) {
it(ScriptingLanguage[testCase.language], () => {
// act
const sut = new CodeBuilderFactory();
const result = sut.create(testCase.language);
// assert
expect(result).to.be.instanceOf(testCase.expected,
`Actual was: ${result.constructor.name}`);
});
}
});
it('throws on unknown scripting language', () => {
// arrange
const sut = new CodeBuilderFactory();
// act
const act = () => sut.create(3131313131);
// assert
expect(act).to.throw(`unknown language: "${ScriptingLanguage[3131313131]}"`);
});
});
});

View File

@@ -0,0 +1,37 @@
import 'mocha';
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);
}
}
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', () => {
it('prepends expected', () => {
// arrange
const text = 'test';
const expected = `echo ${text}`;
const sut = new BatchBuilderRevealer();
// act
const actual = sut.writeStandardOut(text);
// assert
expect(expected).to.equal(actual);
});
});
});

View File

@@ -0,0 +1,37 @@
import 'mocha';
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);
}
}
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', () => {
it('prepends expected', () => {
// arrange
const text = 'test';
const expected = `echo '${text}'`;
const sut = new ShellBuilderRevealer();
// act
const actual = sut.writeStandardOut(text);
// assert
expect(expected).to.equal(actual);
});
});
});

View File

@@ -2,7 +2,8 @@ import 'mocha';
import { expect } from 'chai';
import { UserScriptGenerator } from '@/application/Context/State/Code/Generation/UserScriptGenerator';
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
import { CodeBuilder } from '@/application/Context/State/Code/Generation/CodeBuilder';
import { ICodeBuilderFactory } from '@/application/Context/State/Code/Generation/ICodeBuilderFactory';
import { ICodeBuilder } from '@/application/Context/State/Code/Generation/ICodeBuilder';
import { ScriptStub } from '../../../../../stubs/ScriptStub';
import { ScriptingDefinitionStub } from '../../../../../stubs/ScriptingDefinitionStub';
@@ -28,14 +29,15 @@ describe('UserScriptGenerator', () => {
});
it('is not prepended if empty', () => {
// arrange
const sut = new UserScriptGenerator();
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 = new CodeBuilder()
const expectedStart = codeBuilderStub
.appendFunction(script.script.name, script.script.code.execute)
.toString();
// act
@@ -64,15 +66,16 @@ describe('UserScriptGenerator', () => {
});
it('is not appended if empty', () => {
// arrange
const sut = new UserScriptGenerator();
const codeBuilderStub = new CodeBuilderStub();
const sut = new UserScriptGenerator(mockCodeBuilderFactory(codeBuilderStub));
const script = new ScriptStub('id')
.withCode('code\nmulti-lined')
.toSelectedScript();
const definition = new ScriptingDefinitionStub()
.withEndCode(undefined);
const expectedEnd = new CodeBuilder()
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
@@ -199,3 +202,36 @@ describe('UserScriptGenerator', () => {
});
});
});
function mockCodeBuilderFactory(mock: ICodeBuilder): ICodeBuilderFactory {
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;
}
}