add initial macOS support #40
This commit is contained in:
@@ -22,7 +22,7 @@ describe('ApplicationContext', () => {
|
||||
.construct();
|
||||
sut.changeContext(OperatingSystem.macOS);
|
||||
// assert
|
||||
expect(sut.collection).to.equal(expectedCollection);
|
||||
expect(sut.state.collection).to.equal(expectedCollection);
|
||||
});
|
||||
it('currentOs is changed as expected', () => {
|
||||
// arrange
|
||||
@@ -35,9 +35,9 @@ describe('ApplicationContext', () => {
|
||||
.construct();
|
||||
sut.changeContext(expectedOs);
|
||||
// assert
|
||||
expect(sut.currentOs).to.equal(expectedOs);
|
||||
expect(sut.state.os).to.equal(expectedOs);
|
||||
});
|
||||
it('state is changed as expected', () => {
|
||||
it('new state is empty', () => {
|
||||
// arrange
|
||||
const testContext = new ObservableApplicationContextFactory()
|
||||
.withAppContainingCollections(OperatingSystem.Windows, OperatingSystem.macOS);
|
||||
@@ -45,6 +45,7 @@ describe('ApplicationContext', () => {
|
||||
const sut = testContext
|
||||
.withInitialOs(OperatingSystem.Windows)
|
||||
.construct();
|
||||
sut.state.filter.setFilter('filtered');
|
||||
sut.changeContext(OperatingSystem.macOS);
|
||||
// assert
|
||||
expectEmptyState(sut.state);
|
||||
@@ -82,12 +83,13 @@ describe('ApplicationContext', () => {
|
||||
const sut = testContext
|
||||
.withInitialOs(OperatingSystem.Windows)
|
||||
.construct();
|
||||
const oldState = sut.state;
|
||||
sut.changeContext(nextOs);
|
||||
// assert
|
||||
expect(testContext.firedEvents.length).to.equal(1);
|
||||
expect(testContext.firedEvents[0].newCollection).to.equal(expectedCollection);
|
||||
expect(testContext.firedEvents[0].newState).to.equal(sut.state);
|
||||
expect(testContext.firedEvents[0].newOs).to.equal(nextOs);
|
||||
expect(testContext.firedEvents[0].newState.collection).to.equal(expectedCollection);
|
||||
expect(testContext.firedEvents[0].oldState).to.equal(oldState);
|
||||
});
|
||||
it('is not fired when initial os is changed to same one', () => {
|
||||
// arrange
|
||||
@@ -148,7 +150,7 @@ describe('ApplicationContext', () => {
|
||||
.withInitialOs(os)
|
||||
.construct();
|
||||
// assert
|
||||
const actual = sut.collection;
|
||||
const actual = sut.state.collection;
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
@@ -174,7 +176,7 @@ describe('ApplicationContext', () => {
|
||||
.withInitialOs(expected)
|
||||
.construct();
|
||||
// assert
|
||||
const actual = sut.currentOs;
|
||||
const actual = sut.state.os;
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
describe('throws when OS is invalid', () => {
|
||||
|
||||
@@ -17,7 +17,7 @@ describe('ApplicationContextProvider', () => {
|
||||
// act
|
||||
const context = buildContext(parserMock);
|
||||
// assert
|
||||
// TODO: expect(expected).to.equal(context.app);
|
||||
expect(expected).to.equal(context.app);
|
||||
});
|
||||
describe('sets initial OS as expected', () => {
|
||||
it('returns currentOs if it is supported', () => {
|
||||
@@ -28,7 +28,8 @@ describe('ApplicationContextProvider', () => {
|
||||
// act
|
||||
const context = buildContext(parser, environment);
|
||||
// assert
|
||||
expect(expected).to.equal(context.currentOs);
|
||||
const actual = context.state.os;
|
||||
expect(expected).to.equal(actual);
|
||||
});
|
||||
it('fallbacks to other os if OS in environment is not supported', () => {
|
||||
// arrange
|
||||
@@ -39,11 +40,25 @@ describe('ApplicationContextProvider', () => {
|
||||
// act
|
||||
const context = buildContext(parser, environment);
|
||||
// assert
|
||||
const actual = context.currentOs;
|
||||
const actual = context.state.os;
|
||||
expect(expected).to.equal(actual);
|
||||
});
|
||||
it('fallbacks to most supported os if current os is not supported', () => {
|
||||
// TODO: After more than single collection can be parsed
|
||||
// arrange
|
||||
const expectedOs = OperatingSystem.Android;
|
||||
const allCollections = [
|
||||
new CategoryCollectionStub().withOs(OperatingSystem.Linux).withTotalScripts(3),
|
||||
new CategoryCollectionStub().withOs(expectedOs).withTotalScripts(5),
|
||||
new CategoryCollectionStub().withOs(OperatingSystem.Windows).withTotalScripts(4),
|
||||
];
|
||||
const environment = new EnvironmentStub().withOs(OperatingSystem.macOS);
|
||||
const app = new ApplicationStub().withCollections(...allCollections);
|
||||
const parser: ApplicationParserType = () => app;
|
||||
// act
|
||||
const context = buildContext(parser, environment);
|
||||
// assert
|
||||
const actual = context.state.os;
|
||||
expect(expectedOs).to.equal(actual, `Expected: ${OperatingSystem[expectedOs]}, actual: ${OperatingSystem[actual]}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ import { expect } from 'chai';
|
||||
import { UserSelection } from '@/application/Context/State/Selection/UserSelection';
|
||||
import { ApplicationCode } from '@/application/Context/State/Code/ApplicationCode';
|
||||
import { CategoryCollectionState } from '@/application/Context/State/CategoryCollectionState';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { IScript } from '@/domain/IScript';
|
||||
import { ScriptStub } from '../../../stubs/ScriptStub';
|
||||
import { CategoryStub } from '../../../stubs/CategoryStub';
|
||||
@@ -21,7 +22,8 @@ describe('CategoryCollectionState', () => {
|
||||
});
|
||||
it('reacts to selection changes as expected', () => {
|
||||
// arrange
|
||||
const collection = new CategoryCollectionStub().withAction(new CategoryStub(0).withScriptIds('scriptId'));
|
||||
const collection = new CategoryCollectionStub()
|
||||
.withAction(new CategoryStub(0).withScriptIds('scriptId'));
|
||||
const selectionStub = new UserSelection(collection, []);
|
||||
const expectedCodeGenerator = new ApplicationCode(selectionStub, collection.scripting);
|
||||
selectionStub.selectAll();
|
||||
@@ -34,6 +36,19 @@ describe('CategoryCollectionState', () => {
|
||||
expect(actualCode).to.equal(expectedCode);
|
||||
});
|
||||
});
|
||||
describe('os', () => {
|
||||
it('same as its collection', () => {
|
||||
// arrange
|
||||
const expected = OperatingSystem.macOS;
|
||||
const collection = new CategoryCollectionStub()
|
||||
.withOs(expected);
|
||||
// act
|
||||
const sut = new CategoryCollectionState(collection);
|
||||
// assert
|
||||
const actual = sut.os;
|
||||
expect(expected).to.equal(actual);
|
||||
});
|
||||
});
|
||||
describe('selection', () => {
|
||||
it('initialized with no selection', () => {
|
||||
// arrange
|
||||
@@ -70,7 +85,8 @@ describe('CategoryCollectionState', () => {
|
||||
it('can match a script from current collection', () => {
|
||||
// arrange
|
||||
const scriptNameFilter = 'scriptName';
|
||||
const expectedScript = new ScriptStub('scriptId').withName(scriptNameFilter);
|
||||
const expectedScript = new ScriptStub('scriptId')
|
||||
.withName(scriptNameFilter);
|
||||
const collection = new CategoryCollectionStub()
|
||||
.withAction(new CategoryStub(0).withScript(expectedScript));
|
||||
const sut = new CategoryCollectionState(collection);
|
||||
@@ -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
|
||||
|
||||
@@ -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]}"`);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user