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:
@@ -6,113 +6,113 @@ import { CategoryCollectionStub } from '@tests/unit/stubs/CategoryCollectionStub
|
||||
import { ProjectInformationStub } from '@tests/unit/stubs/ProjectInformationStub';
|
||||
|
||||
describe('Application', () => {
|
||||
describe('getCollection', () => {
|
||||
it('returns undefined if not found', () => {
|
||||
// arrange
|
||||
const expected = undefined;
|
||||
const info = new ProjectInformationStub();
|
||||
const collections = [ new CategoryCollectionStub().withOs(OperatingSystem.Windows) ];
|
||||
// act
|
||||
const sut = new Application(info, collections);
|
||||
const actual = sut.getCollection(OperatingSystem.Android);
|
||||
// assert
|
||||
expect(actual).to.equals(expected);
|
||||
});
|
||||
it('returns expected when multiple collections exist', () => {
|
||||
// arrange
|
||||
const os = OperatingSystem.Windows;
|
||||
const expected = new CategoryCollectionStub().withOs(os);
|
||||
const info = new ProjectInformationStub();
|
||||
const collections = [ expected, new CategoryCollectionStub().withOs(OperatingSystem.Android) ];
|
||||
// act
|
||||
const sut = new Application(info, collections);
|
||||
const actual = sut.getCollection(os);
|
||||
// assert
|
||||
expect(actual).to.equals(expected);
|
||||
});
|
||||
describe('getCollection', () => {
|
||||
it('returns undefined if not found', () => {
|
||||
// arrange
|
||||
const expected = undefined;
|
||||
const info = new ProjectInformationStub();
|
||||
const collections = [new CategoryCollectionStub().withOs(OperatingSystem.Windows)];
|
||||
// act
|
||||
const sut = new Application(info, collections);
|
||||
const actual = sut.getCollection(OperatingSystem.Android);
|
||||
// assert
|
||||
expect(actual).to.equals(expected);
|
||||
});
|
||||
describe('ctor', () => {
|
||||
describe('info', () => {
|
||||
it('throws if undefined', () => {
|
||||
// arrange
|
||||
const expectedError = 'undefined project information';
|
||||
const info = undefined;
|
||||
const collections = [new CategoryCollectionStub()];
|
||||
// act
|
||||
const act = () => new Application(info, collections);
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
});
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const expected = new ProjectInformationStub();
|
||||
const collections = [new CategoryCollectionStub()];
|
||||
// act
|
||||
const sut = new Application(expected, collections);
|
||||
// assert
|
||||
expect(sut.info).to.equal(expected);
|
||||
});
|
||||
});
|
||||
describe('collections', () => {
|
||||
describe('throws on invalid value', () => {
|
||||
// arrange
|
||||
const testCases = [
|
||||
{
|
||||
name: 'undefined',
|
||||
expectedError: 'undefined collections',
|
||||
value: undefined,
|
||||
},
|
||||
{
|
||||
name: 'empty',
|
||||
expectedError: 'no collection in the list',
|
||||
value: [],
|
||||
},
|
||||
{
|
||||
name: 'undefined value in list',
|
||||
expectedError: 'undefined collection in the list',
|
||||
value: [ new CategoryCollectionStub(), undefined ],
|
||||
},
|
||||
{
|
||||
name: 'two collections with same OS',
|
||||
expectedError: 'multiple collections with same os: windows',
|
||||
value: [
|
||||
new CategoryCollectionStub().withOs(OperatingSystem.Windows),
|
||||
new CategoryCollectionStub().withOs(OperatingSystem.Windows),
|
||||
new CategoryCollectionStub().withOs(OperatingSystem.BlackBerry),
|
||||
],
|
||||
},
|
||||
];
|
||||
for (const testCase of testCases) {
|
||||
const info = new ProjectInformationStub();
|
||||
const collections = testCase.value;
|
||||
// act
|
||||
const act = () => new Application(info, collections);
|
||||
// assert
|
||||
expect(act).to.throw(testCase.expectedError);
|
||||
}
|
||||
});
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const info = new ProjectInformationStub();
|
||||
const expected = [new CategoryCollectionStub()];
|
||||
// act
|
||||
const sut = new Application(info, expected);
|
||||
// assert
|
||||
expect(sut.collections).to.equal(expected);
|
||||
});
|
||||
});
|
||||
it('returns expected when multiple collections exist', () => {
|
||||
// arrange
|
||||
const os = OperatingSystem.Windows;
|
||||
const expected = new CategoryCollectionStub().withOs(os);
|
||||
const info = new ProjectInformationStub();
|
||||
const collections = [expected, new CategoryCollectionStub().withOs(OperatingSystem.Android)];
|
||||
// act
|
||||
const sut = new Application(info, collections);
|
||||
const actual = sut.getCollection(os);
|
||||
// assert
|
||||
expect(actual).to.equals(expected);
|
||||
});
|
||||
describe('getSupportedOsList', () => {
|
||||
it('returns expected', () => {
|
||||
// arrange
|
||||
const expected = [ OperatingSystem.Windows, OperatingSystem.macOS ];
|
||||
const info = new ProjectInformationStub();
|
||||
const collections = expected.map((os) => new CategoryCollectionStub().withOs(os));
|
||||
// act
|
||||
const sut = new Application(info, collections);
|
||||
const actual = sut.getSupportedOsList();
|
||||
// assert
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
describe('ctor', () => {
|
||||
describe('info', () => {
|
||||
it('throws if undefined', () => {
|
||||
// arrange
|
||||
const expectedError = 'undefined project information';
|
||||
const info = undefined;
|
||||
const collections = [new CategoryCollectionStub()];
|
||||
// act
|
||||
const act = () => new Application(info, collections);
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
});
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const expected = new ProjectInformationStub();
|
||||
const collections = [new CategoryCollectionStub()];
|
||||
// act
|
||||
const sut = new Application(expected, collections);
|
||||
// assert
|
||||
expect(sut.info).to.equal(expected);
|
||||
});
|
||||
});
|
||||
describe('collections', () => {
|
||||
describe('throws on invalid value', () => {
|
||||
// arrange
|
||||
const testCases = [
|
||||
{
|
||||
name: 'undefined',
|
||||
expectedError: 'undefined collections',
|
||||
value: undefined,
|
||||
},
|
||||
{
|
||||
name: 'empty',
|
||||
expectedError: 'no collection in the list',
|
||||
value: [],
|
||||
},
|
||||
{
|
||||
name: 'undefined value in list',
|
||||
expectedError: 'undefined collection in the list',
|
||||
value: [new CategoryCollectionStub(), undefined],
|
||||
},
|
||||
{
|
||||
name: 'two collections with same OS',
|
||||
expectedError: 'multiple collections with same os: windows',
|
||||
value: [
|
||||
new CategoryCollectionStub().withOs(OperatingSystem.Windows),
|
||||
new CategoryCollectionStub().withOs(OperatingSystem.Windows),
|
||||
new CategoryCollectionStub().withOs(OperatingSystem.BlackBerry),
|
||||
],
|
||||
},
|
||||
];
|
||||
for (const testCase of testCases) {
|
||||
const info = new ProjectInformationStub();
|
||||
const collections = testCase.value;
|
||||
// act
|
||||
const act = () => new Application(info, collections);
|
||||
// assert
|
||||
expect(act).to.throw(testCase.expectedError);
|
||||
}
|
||||
});
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const info = new ProjectInformationStub();
|
||||
const expected = [new CategoryCollectionStub()];
|
||||
// act
|
||||
const sut = new Application(info, expected);
|
||||
// assert
|
||||
expect(sut.collections).to.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('getSupportedOsList', () => {
|
||||
it('returns expected', () => {
|
||||
// arrange
|
||||
const expected = [OperatingSystem.Windows, OperatingSystem.macOS];
|
||||
const info = new ProjectInformationStub();
|
||||
const collections = expected.map((os) => new CategoryCollectionStub().withOs(os));
|
||||
// act
|
||||
const sut = new Application(info, collections);
|
||||
const actual = sut.getSupportedOsList();
|
||||
// assert
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,122 +5,117 @@ import { CategoryStub } from '@tests/unit/stubs/CategoryStub';
|
||||
import { ScriptStub } from '@tests/unit/stubs/ScriptStub';
|
||||
|
||||
describe('Category', () => {
|
||||
describe('ctor', () => {
|
||||
it('throws when name is empty', () => {
|
||||
const expectedError = 'undefined or empty name';
|
||||
const construct = () => new Category(5, '', [], [new CategoryStub(5)], []);
|
||||
expect(construct).to.throw(expectedError);
|
||||
});
|
||||
it('throws when has no children', () => {
|
||||
const expectedError = 'A category must have at least one sub-category or script';
|
||||
const construct = () => new Category(5, 'category', [], [], []);
|
||||
expect(construct).to.throw(expectedError);
|
||||
});
|
||||
describe('ctor', () => {
|
||||
it('throws when name is empty', () => {
|
||||
const expectedError = 'undefined or empty name';
|
||||
const construct = () => new Category(5, '', [], [new CategoryStub(5)], []);
|
||||
expect(construct).to.throw(expectedError);
|
||||
});
|
||||
describe('getAllScriptsRecursively', () => {
|
||||
it('gets child scripts', () => {
|
||||
// arrange
|
||||
const expected = [ new ScriptStub('1'), new ScriptStub('2') ];
|
||||
const sut = new Category(0, 'category', [], [], expected);
|
||||
// act
|
||||
const actual = sut.getAllScriptsRecursively();
|
||||
// assert
|
||||
expect(actual).to.have.deep.members(expected);
|
||||
});
|
||||
it('gets child categories', () => {
|
||||
// arrange
|
||||
const expectedScriptIds = ['1', '2', '3', '4'];
|
||||
const categories = [
|
||||
new CategoryStub(31).withScriptIds('1', '2'),
|
||||
new CategoryStub(32).withScriptIds('3', '4'),
|
||||
];
|
||||
const sut = new Category(0, 'category', [], categories, []);
|
||||
// act
|
||||
const actualIds = sut.getAllScriptsRecursively().map((s) => s.id);
|
||||
// assert
|
||||
expect(actualIds).to.have.deep.members(expectedScriptIds);
|
||||
|
||||
});
|
||||
it('gets child scripts and categories', () => {
|
||||
// arrange
|
||||
const expectedScriptIds = ['1', '2', '3', '4', '5' , '6'];
|
||||
const categories = [
|
||||
new CategoryStub(31).withScriptIds('1', '2'),
|
||||
new CategoryStub(32).withScriptIds('3', '4'),
|
||||
];
|
||||
const scripts = [ new ScriptStub('5'), new ScriptStub('6') ];
|
||||
const sut = new Category(0, 'category', [], categories, scripts);
|
||||
// act
|
||||
const actualIds = sut.getAllScriptsRecursively().map((s) => s.id);
|
||||
// assert
|
||||
expect(actualIds).to.have.deep.members(expectedScriptIds);
|
||||
|
||||
});
|
||||
it('gets child categories recursively', () => {
|
||||
// arrange
|
||||
const expectedScriptIds = ['1', '2', '3', '4', '5', '6'];
|
||||
const categories = [
|
||||
new CategoryStub(31)
|
||||
.withScriptIds('1', '2')
|
||||
.withCategory(
|
||||
new CategoryStub(32)
|
||||
.withScriptIds('3', '4'),
|
||||
),
|
||||
new CategoryStub(33)
|
||||
.withCategories(
|
||||
new CategoryStub(34)
|
||||
.withScriptIds('5')
|
||||
.withCategory(
|
||||
new CategoryStub(35)
|
||||
.withCategory(
|
||||
new CategoryStub(35).withScriptIds('6'),
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
// assert
|
||||
const sut = new Category(0, 'category', [], categories, []);
|
||||
// act
|
||||
const actualIds = sut.getAllScriptsRecursively().map((s) => s.id);
|
||||
// assert
|
||||
expect(actualIds).to.have.deep.members(expectedScriptIds);
|
||||
});
|
||||
it('throws when has no children', () => {
|
||||
const expectedError = 'A category must have at least one sub-category or script';
|
||||
const construct = () => new Category(5, 'category', [], [], []);
|
||||
expect(construct).to.throw(expectedError);
|
||||
});
|
||||
describe('includes', () => {
|
||||
it('return false when does not include', () => {
|
||||
// assert
|
||||
const script = new ScriptStub('3');
|
||||
const sut = new Category(0, 'category', [], [new CategoryStub(33).withScriptIds('1', '2')], []);
|
||||
// act
|
||||
const actual = sut.includes(script);
|
||||
// assert
|
||||
expect(actual).to.equal(false);
|
||||
});
|
||||
it('return true when includes as subscript', () => {
|
||||
// assert
|
||||
const script = new ScriptStub('3');
|
||||
const sut = new Category(0, 'category', [], [
|
||||
new CategoryStub(33).withScript(script).withScriptIds('non-related'),
|
||||
], []);
|
||||
// act
|
||||
const actual = sut.includes(script);
|
||||
// assert
|
||||
expect(actual).to.equal(true);
|
||||
});
|
||||
it('return true when includes as nested category script', () => {
|
||||
// assert
|
||||
const script = new ScriptStub('3');
|
||||
const sut = new Category(11, 'category', [],
|
||||
[
|
||||
new CategoryStub(22)
|
||||
.withScriptIds('non-relatedd')
|
||||
.withCategory(new CategoryStub(33).withScript(script)),
|
||||
],
|
||||
[]);
|
||||
// act
|
||||
const actual = sut.includes(script);
|
||||
// assert
|
||||
expect(actual).to.equal(true);
|
||||
});
|
||||
});
|
||||
describe('getAllScriptsRecursively', () => {
|
||||
it('gets child scripts', () => {
|
||||
// arrange
|
||||
const expected = [new ScriptStub('1'), new ScriptStub('2')];
|
||||
const sut = new Category(0, 'category', [], [], expected);
|
||||
// act
|
||||
const actual = sut.getAllScriptsRecursively();
|
||||
// assert
|
||||
expect(actual).to.have.deep.members(expected);
|
||||
});
|
||||
it('gets child categories', () => {
|
||||
// arrange
|
||||
const expectedScriptIds = ['1', '2', '3', '4'];
|
||||
const categories = [
|
||||
new CategoryStub(31).withScriptIds('1', '2'),
|
||||
new CategoryStub(32).withScriptIds('3', '4'),
|
||||
];
|
||||
const sut = new Category(0, 'category', [], categories, []);
|
||||
// act
|
||||
const actualIds = sut.getAllScriptsRecursively().map((s) => s.id);
|
||||
// assert
|
||||
expect(actualIds).to.have.deep.members(expectedScriptIds);
|
||||
});
|
||||
it('gets child scripts and categories', () => {
|
||||
// arrange
|
||||
const expectedScriptIds = ['1', '2', '3', '4', '5', '6'];
|
||||
const categories = [
|
||||
new CategoryStub(31).withScriptIds('1', '2'),
|
||||
new CategoryStub(32).withScriptIds('3', '4'),
|
||||
];
|
||||
const scripts = [new ScriptStub('5'), new ScriptStub('6')];
|
||||
const sut = new Category(0, 'category', [], categories, scripts);
|
||||
// act
|
||||
const actualIds = sut.getAllScriptsRecursively().map((s) => s.id);
|
||||
// assert
|
||||
expect(actualIds).to.have.deep.members(expectedScriptIds);
|
||||
});
|
||||
it('gets child categories recursively', () => {
|
||||
// arrange
|
||||
const expectedScriptIds = ['1', '2', '3', '4', '5', '6'];
|
||||
const categories = [
|
||||
new CategoryStub(31)
|
||||
.withScriptIds('1', '2')
|
||||
.withCategory(
|
||||
new CategoryStub(32)
|
||||
.withScriptIds('3', '4'),
|
||||
),
|
||||
new CategoryStub(33)
|
||||
.withCategories(
|
||||
new CategoryStub(34)
|
||||
.withScriptIds('5')
|
||||
.withCategory(
|
||||
new CategoryStub(35)
|
||||
.withCategory(
|
||||
new CategoryStub(35).withScriptIds('6'),
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
// assert
|
||||
const sut = new Category(0, 'category', [], categories, []);
|
||||
// act
|
||||
const actualIds = sut.getAllScriptsRecursively().map((s) => s.id);
|
||||
// assert
|
||||
expect(actualIds).to.have.deep.members(expectedScriptIds);
|
||||
});
|
||||
});
|
||||
describe('includes', () => {
|
||||
it('return false when does not include', () => {
|
||||
// assert
|
||||
const script = new ScriptStub('3');
|
||||
const sut = new Category(0, 'category', [], [new CategoryStub(33).withScriptIds('1', '2')], []);
|
||||
// act
|
||||
const actual = sut.includes(script);
|
||||
// assert
|
||||
expect(actual).to.equal(false);
|
||||
});
|
||||
it('return true when includes as subscript', () => {
|
||||
// assert
|
||||
const script = new ScriptStub('3');
|
||||
const sut = new Category(0, 'category', [], [
|
||||
new CategoryStub(33).withScript(script).withScriptIds('non-related'),
|
||||
], []);
|
||||
// act
|
||||
const actual = sut.includes(script);
|
||||
// assert
|
||||
expect(actual).to.equal(true);
|
||||
});
|
||||
it('return true when includes as nested category script', () => {
|
||||
// assert
|
||||
const script = new ScriptStub('3');
|
||||
const innerCategory = new CategoryStub(22)
|
||||
.withScriptIds('non-related')
|
||||
.withCategory(new CategoryStub(33).withScript(script));
|
||||
const sut = new Category(11, 'category', [], [innerCategory], []);
|
||||
// act
|
||||
const actual = sut.includes(script);
|
||||
// assert
|
||||
expect(actual).to.equal(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,248 +12,260 @@ import { CategoryStub } from '@tests/unit/stubs/CategoryStub';
|
||||
import { EnumRangeTestRunner } from '@tests/unit/application/Common/EnumRangeTestRunner';
|
||||
|
||||
describe('CategoryCollection', () => {
|
||||
describe('getScriptsByLevel', () => {
|
||||
it('filters out scripts without levels', () => {
|
||||
// arrange
|
||||
const recommendationLevels = getEnumValues(RecommendationLevel);
|
||||
const scriptsWithLevels = recommendationLevels.map((level, index) =>
|
||||
new ScriptStub(`Script${index}`).withLevel(level),
|
||||
);
|
||||
const toIgnore = new ScriptStub('script-to-ignore').withLevel(undefined);
|
||||
for (const currentLevel of recommendationLevels) {
|
||||
const category = new CategoryStub(0)
|
||||
.withScripts(...scriptsWithLevels)
|
||||
.withScript(toIgnore);
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withActions([category])
|
||||
.construct();
|
||||
// act
|
||||
const actual = sut.getScriptsByLevel(currentLevel);
|
||||
// assert
|
||||
expect(actual).to.not.include(toIgnore);
|
||||
}
|
||||
});
|
||||
it(`${RecommendationLevel[RecommendationLevel.Standard]} filters ${RecommendationLevel[RecommendationLevel.Strict]}`, () => {
|
||||
// arrange
|
||||
const level = RecommendationLevel.Standard;
|
||||
const expected = [
|
||||
new ScriptStub('S1').withLevel(level),
|
||||
new ScriptStub('S2').withLevel(level),
|
||||
];
|
||||
const actions = [
|
||||
new CategoryStub(3).withScripts(...expected,
|
||||
new ScriptStub('S3').withLevel(RecommendationLevel.Strict)),
|
||||
];
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withActions(actions)
|
||||
.construct();
|
||||
// act
|
||||
const actual = sut.getScriptsByLevel(level);
|
||||
// assert
|
||||
expect(expected).to.deep.equal(actual);
|
||||
});
|
||||
it(`${RecommendationLevel[RecommendationLevel.Strict]} includes ${RecommendationLevel[RecommendationLevel.Standard]}`, () => {
|
||||
// arrange
|
||||
const level = RecommendationLevel.Strict;
|
||||
const expected = [
|
||||
new ScriptStub('S1').withLevel(RecommendationLevel.Standard),
|
||||
new ScriptStub('S2').withLevel(RecommendationLevel.Strict),
|
||||
];
|
||||
const actions = [
|
||||
new CategoryStub(3).withScripts(...expected),
|
||||
];
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withActions(actions)
|
||||
.construct();
|
||||
// act
|
||||
const actual = sut.getScriptsByLevel(level);
|
||||
// assert
|
||||
expect(expected).to.deep.equal(actual);
|
||||
});
|
||||
it('throws when level is undefined', () => {
|
||||
// arrange
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.construct();
|
||||
// act
|
||||
const act = () => sut.getScriptsByLevel(undefined);
|
||||
// assert
|
||||
expect(act).to.throw('undefined level');
|
||||
});
|
||||
it('throws when level is out of range', () => {
|
||||
// arrange
|
||||
const invalidValue = 66;
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.construct();
|
||||
// act
|
||||
const act = () => sut.getScriptsByLevel(invalidValue);
|
||||
// assert
|
||||
expect(act).to.throw(`invalid level: ${invalidValue}`);
|
||||
});
|
||||
describe('getScriptsByLevel', () => {
|
||||
it('filters out scripts without levels', () => {
|
||||
// arrange
|
||||
const recommendationLevels = getEnumValues(RecommendationLevel);
|
||||
const scriptsWithLevels = recommendationLevels.map(
|
||||
(level, index) => new ScriptStub(`Script${index}`).withLevel(level),
|
||||
);
|
||||
const toIgnore = new ScriptStub('script-to-ignore').withLevel(undefined);
|
||||
for (const currentLevel of recommendationLevels) {
|
||||
const category = new CategoryStub(0)
|
||||
.withScripts(...scriptsWithLevels)
|
||||
.withScript(toIgnore);
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withActions([category])
|
||||
.construct();
|
||||
// act
|
||||
const actual = sut.getScriptsByLevel(currentLevel);
|
||||
// assert
|
||||
expect(actual).to.not.include(toIgnore);
|
||||
}
|
||||
});
|
||||
describe('actions', () => {
|
||||
it('cannot construct without actions', () => {
|
||||
// arrange
|
||||
const categories = [];
|
||||
// act
|
||||
function construct() {
|
||||
new CategoryCollectionBuilder()
|
||||
.withActions(categories)
|
||||
.construct();
|
||||
}
|
||||
// assert
|
||||
expect(construct).to.throw('must consist of at least one category');
|
||||
});
|
||||
it('cannot construct without scripts', () => {
|
||||
// arrange
|
||||
const categories = [
|
||||
new CategoryStub(3),
|
||||
new CategoryStub(2),
|
||||
];
|
||||
// act
|
||||
function construct() {
|
||||
new CategoryCollectionBuilder()
|
||||
.withActions(categories)
|
||||
.construct();
|
||||
}
|
||||
// assert
|
||||
expect(construct).to.throw('must consist of at least one script');
|
||||
});
|
||||
describe('cannot construct without any recommended scripts', () => {
|
||||
// arrange
|
||||
const recommendationLevels = getEnumValues(RecommendationLevel);
|
||||
for (const missingLevel of recommendationLevels) {
|
||||
it(`when "${RecommendationLevel[missingLevel]}" is missing`, () => {
|
||||
const expectedError = `none of the scripts are recommended as ${RecommendationLevel[missingLevel]}`;
|
||||
const otherLevels = recommendationLevels.filter((level) => level !== missingLevel);
|
||||
const categories = otherLevels.map((level, index) =>
|
||||
new CategoryStub(index).withScript(
|
||||
new ScriptStub(`Script${index}`).withLevel(level),
|
||||
));
|
||||
// act
|
||||
const construct = () => new CategoryCollectionBuilder()
|
||||
.withActions(categories)
|
||||
.construct();
|
||||
// assert
|
||||
expect(construct).to.throw(expectedError);
|
||||
});
|
||||
}
|
||||
});
|
||||
it(`${RecommendationLevel[RecommendationLevel.Standard]} filters ${RecommendationLevel[RecommendationLevel.Strict]}`, () => {
|
||||
// arrange
|
||||
const level = RecommendationLevel.Standard;
|
||||
const expected = [
|
||||
new ScriptStub('S1').withLevel(level),
|
||||
new ScriptStub('S2').withLevel(level),
|
||||
];
|
||||
const actions = [
|
||||
new CategoryStub(3).withScripts(
|
||||
...expected,
|
||||
new ScriptStub('S3').withLevel(RecommendationLevel.Strict),
|
||||
),
|
||||
];
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withActions(actions)
|
||||
.construct();
|
||||
// act
|
||||
const actual = sut.getScriptsByLevel(level);
|
||||
// assert
|
||||
expect(expected).to.deep.equal(actual);
|
||||
});
|
||||
describe('totalScripts', () => {
|
||||
it('returns total of initial scripts', () => {
|
||||
// arrange
|
||||
const categories = [
|
||||
new CategoryStub(1).withScripts(
|
||||
new ScriptStub('S1').withLevel(RecommendationLevel.Standard)),
|
||||
new CategoryStub(2).withScripts(
|
||||
new ScriptStub('S2'),
|
||||
new ScriptStub('S3').withLevel(RecommendationLevel.Strict)),
|
||||
new CategoryStub(3).withCategories(
|
||||
new CategoryStub(4).withScripts(new ScriptStub('S4'))),
|
||||
];
|
||||
// act
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withActions(categories)
|
||||
.construct();
|
||||
// assert
|
||||
expect(sut.totalScripts).to.equal(4);
|
||||
});
|
||||
it(`${RecommendationLevel[RecommendationLevel.Strict]} includes ${RecommendationLevel[RecommendationLevel.Standard]}`, () => {
|
||||
// arrange
|
||||
const level = RecommendationLevel.Strict;
|
||||
const expected = [
|
||||
new ScriptStub('S1').withLevel(RecommendationLevel.Standard),
|
||||
new ScriptStub('S2').withLevel(RecommendationLevel.Strict),
|
||||
];
|
||||
const actions = [
|
||||
new CategoryStub(3).withScripts(...expected),
|
||||
];
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withActions(actions)
|
||||
.construct();
|
||||
// act
|
||||
const actual = sut.getScriptsByLevel(level);
|
||||
// assert
|
||||
expect(expected).to.deep.equal(actual);
|
||||
});
|
||||
describe('totalCategories', () => {
|
||||
it('returns total of initial categories', () => {
|
||||
// arrange
|
||||
const expected = 4;
|
||||
const categories = [
|
||||
new CategoryStub(1).withScripts(new ScriptStub('S1').withLevel(RecommendationLevel.Strict)),
|
||||
new CategoryStub(2).withScripts(new ScriptStub('S2'), new ScriptStub('S3')),
|
||||
new CategoryStub(3).withCategories(new CategoryStub(4).withScripts(new ScriptStub('S4'))),
|
||||
];
|
||||
// act
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withActions(categories)
|
||||
.construct();
|
||||
// assert
|
||||
expect(sut.totalCategories).to.equal(expected);
|
||||
});
|
||||
it('throws when level is undefined', () => {
|
||||
// arrange
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.construct();
|
||||
// act
|
||||
const act = () => sut.getScriptsByLevel(undefined);
|
||||
// assert
|
||||
expect(act).to.throw('undefined level');
|
||||
});
|
||||
describe('os', () => {
|
||||
it('sets os as expected', () => {
|
||||
// arrange
|
||||
const expected = OperatingSystem.macOS;
|
||||
// act
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withOs(expected)
|
||||
.construct();
|
||||
// assert
|
||||
expect(sut.os).to.deep.equal(expected);
|
||||
});
|
||||
describe('throws when invalid', () => {
|
||||
// act
|
||||
const act = (os: OperatingSystem) => new CategoryCollectionBuilder()
|
||||
.withOs(os)
|
||||
.construct();
|
||||
// assert
|
||||
new EnumRangeTestRunner(act)
|
||||
.testOutOfRangeThrows()
|
||||
.testUndefinedValueThrows();
|
||||
});
|
||||
it('throws when level is out of range', () => {
|
||||
// arrange
|
||||
const invalidValue = 66;
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.construct();
|
||||
// act
|
||||
const act = () => sut.getScriptsByLevel(invalidValue);
|
||||
// assert
|
||||
expect(act).to.throw(`invalid level: ${invalidValue}`);
|
||||
});
|
||||
describe('scriptingDefinition', () => {
|
||||
it('sets scriptingDefinition as expected', () => {
|
||||
// arrange
|
||||
const expected = getValidScriptingDefinition();
|
||||
// act
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withScripting(expected)
|
||||
.construct();
|
||||
// assert
|
||||
expect(sut.scripting).to.deep.equal(expected);
|
||||
});
|
||||
it('cannot construct without initial script', () => {
|
||||
// arrange
|
||||
const scriptingDefinition = undefined;
|
||||
// act
|
||||
function construct() {
|
||||
return new CategoryCollectionBuilder()
|
||||
.withScripting(scriptingDefinition)
|
||||
.construct();
|
||||
}
|
||||
// assert
|
||||
expect(construct).to.throw('undefined scripting definition');
|
||||
});
|
||||
});
|
||||
describe('actions', () => {
|
||||
it('cannot construct without actions', () => {
|
||||
// arrange
|
||||
const categories = [];
|
||||
// act
|
||||
function construct() {
|
||||
new CategoryCollectionBuilder()
|
||||
.withActions(categories)
|
||||
.construct();
|
||||
}
|
||||
// assert
|
||||
expect(construct).to.throw('must consist of at least one category');
|
||||
});
|
||||
it('cannot construct without scripts', () => {
|
||||
// arrange
|
||||
const categories = [
|
||||
new CategoryStub(3),
|
||||
new CategoryStub(2),
|
||||
];
|
||||
// act
|
||||
function construct() {
|
||||
new CategoryCollectionBuilder()
|
||||
.withActions(categories)
|
||||
.construct();
|
||||
}
|
||||
// assert
|
||||
expect(construct).to.throw('must consist of at least one script');
|
||||
});
|
||||
describe('cannot construct without any recommended scripts', () => {
|
||||
// arrange
|
||||
const recommendationLevels = getEnumValues(RecommendationLevel);
|
||||
for (const missingLevel of recommendationLevels) {
|
||||
it(`when "${RecommendationLevel[missingLevel]}" is missing`, () => {
|
||||
const expectedError = `none of the scripts are recommended as ${RecommendationLevel[missingLevel]}`;
|
||||
const otherLevels = recommendationLevels.filter((level) => level !== missingLevel);
|
||||
const categories = otherLevels.map(
|
||||
(level, index) => new CategoryStub(index)
|
||||
.withScript(new ScriptStub(`Script${index}`).withLevel(level)),
|
||||
);
|
||||
// act
|
||||
const construct = () => new CategoryCollectionBuilder()
|
||||
.withActions(categories)
|
||||
.construct();
|
||||
// assert
|
||||
expect(construct).to.throw(expectedError);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('totalScripts', () => {
|
||||
it('returns total of initial scripts', () => {
|
||||
// arrange
|
||||
const categories = [
|
||||
new CategoryStub(1).withScripts(
|
||||
new ScriptStub('S1').withLevel(RecommendationLevel.Standard),
|
||||
),
|
||||
new CategoryStub(2).withScripts(
|
||||
new ScriptStub('S2'),
|
||||
new ScriptStub('S3').withLevel(RecommendationLevel.Strict),
|
||||
),
|
||||
new CategoryStub(3).withCategories(
|
||||
new CategoryStub(4).withScripts(new ScriptStub('S4')),
|
||||
),
|
||||
];
|
||||
// act
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withActions(categories)
|
||||
.construct();
|
||||
// assert
|
||||
expect(sut.totalScripts).to.equal(4);
|
||||
});
|
||||
});
|
||||
describe('totalCategories', () => {
|
||||
it('returns total of initial categories', () => {
|
||||
// arrange
|
||||
const expected = 4;
|
||||
const categories = [
|
||||
new CategoryStub(1).withScripts(new ScriptStub('S1').withLevel(RecommendationLevel.Strict)),
|
||||
new CategoryStub(2).withScripts(new ScriptStub('S2'), new ScriptStub('S3')),
|
||||
new CategoryStub(3).withCategories(new CategoryStub(4).withScripts(new ScriptStub('S4'))),
|
||||
];
|
||||
// act
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withActions(categories)
|
||||
.construct();
|
||||
// assert
|
||||
expect(sut.totalCategories).to.equal(expected);
|
||||
});
|
||||
});
|
||||
describe('os', () => {
|
||||
it('sets os as expected', () => {
|
||||
// arrange
|
||||
const expected = OperatingSystem.macOS;
|
||||
// act
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withOs(expected)
|
||||
.construct();
|
||||
// assert
|
||||
expect(sut.os).to.deep.equal(expected);
|
||||
});
|
||||
describe('throws when invalid', () => {
|
||||
// act
|
||||
const act = (os: OperatingSystem) => new CategoryCollectionBuilder()
|
||||
.withOs(os)
|
||||
.construct();
|
||||
// assert
|
||||
new EnumRangeTestRunner(act)
|
||||
.testOutOfRangeThrows()
|
||||
.testUndefinedValueThrows();
|
||||
});
|
||||
});
|
||||
describe('scriptingDefinition', () => {
|
||||
it('sets scriptingDefinition as expected', () => {
|
||||
// arrange
|
||||
const expected = getValidScriptingDefinition();
|
||||
// act
|
||||
const sut = new CategoryCollectionBuilder()
|
||||
.withScripting(expected)
|
||||
.construct();
|
||||
// assert
|
||||
expect(sut.scripting).to.deep.equal(expected);
|
||||
});
|
||||
it('cannot construct without initial script', () => {
|
||||
// arrange
|
||||
const scriptingDefinition = undefined;
|
||||
// act
|
||||
function construct() {
|
||||
return new CategoryCollectionBuilder()
|
||||
.withScripting(scriptingDefinition)
|
||||
.construct();
|
||||
}
|
||||
// assert
|
||||
expect(construct).to.throw('undefined scripting definition');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getValidScriptingDefinition(): IScriptingDefinition {
|
||||
return {
|
||||
fileExtension: '.bat',
|
||||
language: ScriptingLanguage.batchfile,
|
||||
startCode: 'start',
|
||||
endCode: 'end',
|
||||
};
|
||||
return {
|
||||
fileExtension: '.bat',
|
||||
language: ScriptingLanguage.batchfile,
|
||||
startCode: 'start',
|
||||
endCode: 'end',
|
||||
};
|
||||
}
|
||||
|
||||
class CategoryCollectionBuilder {
|
||||
private os = OperatingSystem.Windows;
|
||||
private actions: readonly ICategory[] = [
|
||||
new CategoryStub(1).withScripts(
|
||||
new ScriptStub('S1').withLevel(RecommendationLevel.Standard),
|
||||
new ScriptStub('S2').withLevel(RecommendationLevel.Strict)),
|
||||
];
|
||||
private script: IScriptingDefinition = getValidScriptingDefinition();
|
||||
public withOs(os: OperatingSystem): CategoryCollectionBuilder {
|
||||
this.os = os;
|
||||
return this;
|
||||
}
|
||||
public withActions(actions: readonly ICategory[]): CategoryCollectionBuilder {
|
||||
this.actions = actions;
|
||||
return this;
|
||||
}
|
||||
public withScripting(script: IScriptingDefinition): CategoryCollectionBuilder {
|
||||
this.script = script;
|
||||
return this;
|
||||
}
|
||||
public construct(): CategoryCollection {
|
||||
return new CategoryCollection(this.os, this.actions, this.script);
|
||||
}
|
||||
private os = OperatingSystem.Windows;
|
||||
|
||||
private actions: readonly ICategory[] = [
|
||||
new CategoryStub(1).withScripts(
|
||||
new ScriptStub('S1').withLevel(RecommendationLevel.Standard),
|
||||
new ScriptStub('S2').withLevel(RecommendationLevel.Strict),
|
||||
),
|
||||
];
|
||||
|
||||
private script: IScriptingDefinition = getValidScriptingDefinition();
|
||||
|
||||
public withOs(os: OperatingSystem): CategoryCollectionBuilder {
|
||||
this.os = os;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withActions(actions: readonly ICategory[]): CategoryCollectionBuilder {
|
||||
this.actions = actions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withScripting(script: IScriptingDefinition): CategoryCollectionBuilder {
|
||||
this.script = script;
|
||||
return this;
|
||||
}
|
||||
|
||||
public construct(): CategoryCollection {
|
||||
return new CategoryCollection(this.os, this.actions, this.script);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,127 +5,127 @@ import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { EnumRangeTestRunner } from '@tests/unit/application/Common/EnumRangeTestRunner';
|
||||
|
||||
describe('ProjectInformation', () => {
|
||||
it('sets name as expected', () => {
|
||||
// arrange
|
||||
const expected = 'expected-name';
|
||||
const sut = new ProjectInformation(expected, 'version', 'repositoryUrl', 'homepage');
|
||||
// act
|
||||
const actual = sut.name;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
it('sets name as expected', () => {
|
||||
// arrange
|
||||
const expected = 'expected-name';
|
||||
const sut = new ProjectInformation(expected, 'version', 'repositoryUrl', 'homepage');
|
||||
// act
|
||||
const actual = sut.name;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('sets version as expected', () => {
|
||||
// arrange
|
||||
const expected = 'expected-version';
|
||||
const sut = new ProjectInformation('name', expected, 'repositoryUrl', 'homepage');
|
||||
// act
|
||||
const actual = sut.version;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('sets repositoryUrl as expected', () => {
|
||||
// arrange
|
||||
const expected = 'expected-repository-url';
|
||||
const sut = new ProjectInformation('name', 'version', expected, 'homepage');
|
||||
// act
|
||||
const actual = sut.repositoryUrl;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
describe('sets repositoryWebUrl as expected', () => {
|
||||
it('sets repositoryUrl when it does not end with .git', () => {
|
||||
// arrange
|
||||
const expected = 'expected-repository-url';
|
||||
const sut = new ProjectInformation('name', 'version', expected, 'homepage');
|
||||
// act
|
||||
const actual = sut.repositoryWebUrl;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('sets version as expected', () => {
|
||||
// arrange
|
||||
const expected = 'expected-version';
|
||||
const sut = new ProjectInformation('name', expected, 'repositoryUrl', 'homepage');
|
||||
// act
|
||||
const actual = sut.version;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
it('removes ".git" from the end when it ends with ".git"', () => {
|
||||
// arrange
|
||||
const expected = 'expected-repository-url';
|
||||
const sut = new ProjectInformation('name', 'version', `${expected}.git`, 'homepage');
|
||||
// act
|
||||
const actual = sut.repositoryWebUrl;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('sets repositoryUrl as expected', () => {
|
||||
// arrange
|
||||
const expected = 'expected-repository-url';
|
||||
const sut = new ProjectInformation('name', 'version', expected, 'homepage');
|
||||
// act
|
||||
const actual = sut.repositoryUrl;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('sets homepage as expected', () => {
|
||||
// arrange
|
||||
const expected = 'expected-homepage';
|
||||
const sut = new ProjectInformation('name', 'version', 'repositoryUrl', expected);
|
||||
// act
|
||||
const actual = sut.homepage;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('sets feedbackUrl to github issues page', () => {
|
||||
// arrange
|
||||
const repositoryUrl = 'https://github.com/undergroundwires/privacy.sexy.git';
|
||||
const expected = 'https://github.com/undergroundwires/privacy.sexy/issues';
|
||||
const sut = new ProjectInformation('name', 'version', repositoryUrl, 'homepage');
|
||||
// act
|
||||
const actual = sut.feedbackUrl;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('sets releaseUrl to github releases page', () => {
|
||||
// arrange
|
||||
const repositoryUrl = 'https://github.com/undergroundwires/privacy.sexy.git';
|
||||
const version = '0.7.2';
|
||||
const expected = 'https://github.com/undergroundwires/privacy.sexy/releases/tag/0.7.2';
|
||||
const sut = new ProjectInformation('name', version, repositoryUrl, 'homepage');
|
||||
// act
|
||||
const actual = sut.releaseUrl;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
describe('getDownloadUrl', () => {
|
||||
it('gets expected url for macOS', () => {
|
||||
// arrange
|
||||
const expected = 'https://github.com/undergroundwires/privacy.sexy/releases/download/0.7.2/privacy.sexy-0.7.2.dmg';
|
||||
const repositoryUrl = 'https://github.com/undergroundwires/privacy.sexy.git';
|
||||
const version = '0.7.2';
|
||||
const sut = new ProjectInformation('name', version, repositoryUrl, 'homepage');
|
||||
// act
|
||||
const actual = sut.getDownloadUrl(OperatingSystem.macOS);
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
describe('sets repositoryWebUrl as expected', () => {
|
||||
it('sets repositoryUrl when it does not end with .git', () => {
|
||||
// arrange
|
||||
const expected = 'expected-repository-url';
|
||||
const sut = new ProjectInformation('name', 'version', expected, 'homepage');
|
||||
// act
|
||||
const actual = sut.repositoryWebUrl;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('removes ".git" from the end when it ends with ".git"', () => {
|
||||
// arrange
|
||||
const expected = 'expected-repository-url';
|
||||
const sut = new ProjectInformation('name', 'version', `${expected}.git`, 'homepage');
|
||||
// act
|
||||
const actual = sut.repositoryWebUrl;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('gets expected url for Linux', () => {
|
||||
// arrange
|
||||
const expected = 'https://github.com/undergroundwires/privacy.sexy/releases/download/0.7.2/privacy.sexy-0.7.2.AppImage';
|
||||
const repositoryUrl = 'https://github.com/undergroundwires/privacy.sexy.git';
|
||||
const version = '0.7.2';
|
||||
const sut = new ProjectInformation('name', version, repositoryUrl, 'homepage');
|
||||
// act
|
||||
const actual = sut.getDownloadUrl(OperatingSystem.Linux);
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('sets homepage as expected', () => {
|
||||
// arrange
|
||||
const expected = 'expected-homepage';
|
||||
const sut = new ProjectInformation('name', 'version', 'repositoryUrl', expected);
|
||||
// act
|
||||
const actual = sut.homepage;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
it('gets expected url for Windows', () => {
|
||||
// arrange
|
||||
const expected = 'https://github.com/undergroundwires/privacy.sexy/releases/download/0.7.2/privacy.sexy-Setup-0.7.2.exe';
|
||||
const repositoryUrl = 'https://github.com/undergroundwires/privacy.sexy.git';
|
||||
const version = '0.7.2';
|
||||
const sut = new ProjectInformation('name', version, repositoryUrl, 'homepage');
|
||||
// act
|
||||
const actual = sut.getDownloadUrl(OperatingSystem.Windows);
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('sets feedbackUrl to github issues page', () => {
|
||||
// arrange
|
||||
const repositoryUrl = 'https://github.com/undergroundwires/privacy.sexy.git';
|
||||
const expected = 'https://github.com/undergroundwires/privacy.sexy/issues';
|
||||
const sut = new ProjectInformation('name', 'version', repositoryUrl, 'homepage');
|
||||
// act
|
||||
const actual = sut.feedbackUrl;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('sets releaseUrl to github releases page', () => {
|
||||
// arrange
|
||||
const repositoryUrl = 'https://github.com/undergroundwires/privacy.sexy.git';
|
||||
const version = '0.7.2';
|
||||
const expected = 'https://github.com/undergroundwires/privacy.sexy/releases/tag/0.7.2';
|
||||
const sut = new ProjectInformation('name', version, repositoryUrl, 'homepage');
|
||||
// act
|
||||
const actual = sut.releaseUrl;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
describe('getDownloadUrl', () => {
|
||||
it('gets expected url for macOS', () => {
|
||||
// arrange
|
||||
const expected = 'https://github.com/undergroundwires/privacy.sexy/releases/download/0.7.2/privacy.sexy-0.7.2.dmg';
|
||||
const repositoryUrl = 'https://github.com/undergroundwires/privacy.sexy.git';
|
||||
const version = '0.7.2';
|
||||
const sut = new ProjectInformation('name', version, repositoryUrl, 'homepage');
|
||||
// act
|
||||
const actual = sut.getDownloadUrl(OperatingSystem.macOS);
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('gets expected url for Linux', () => {
|
||||
// arrange
|
||||
const expected = 'https://github.com/undergroundwires/privacy.sexy/releases/download/0.7.2/privacy.sexy-0.7.2.AppImage';
|
||||
const repositoryUrl = 'https://github.com/undergroundwires/privacy.sexy.git';
|
||||
const version = '0.7.2';
|
||||
const sut = new ProjectInformation('name', version, repositoryUrl, 'homepage');
|
||||
// act
|
||||
const actual = sut.getDownloadUrl(OperatingSystem.Linux);
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
it('gets expected url for Windows', () => {
|
||||
// arrange
|
||||
const expected = 'https://github.com/undergroundwires/privacy.sexy/releases/download/0.7.2/privacy.sexy-Setup-0.7.2.exe';
|
||||
const repositoryUrl = 'https://github.com/undergroundwires/privacy.sexy.git';
|
||||
const version = '0.7.2';
|
||||
const sut = new ProjectInformation('name', version, repositoryUrl, 'homepage');
|
||||
// act
|
||||
const actual = sut.getDownloadUrl(OperatingSystem.Windows);
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
describe('throws when os is invalid', () => {
|
||||
// arrange
|
||||
const sut = new ProjectInformation('name', 'version', 'repositoryUrl', 'homepage');
|
||||
// act
|
||||
const act = (os: OperatingSystem) => sut.getDownloadUrl(os);
|
||||
// assert
|
||||
new EnumRangeTestRunner(act)
|
||||
.testOutOfRangeThrows()
|
||||
.testUndefinedValueThrows()
|
||||
.testInvalidValueThrows(OperatingSystem.KaiOS, `Unsupported os: ${OperatingSystem[OperatingSystem.KaiOS]}`);
|
||||
});
|
||||
describe('throws when os is invalid', () => {
|
||||
// arrange
|
||||
const sut = new ProjectInformation('name', 'version', 'repositoryUrl', 'homepage');
|
||||
// act
|
||||
const act = (os: OperatingSystem) => sut.getDownloadUrl(os);
|
||||
// assert
|
||||
new EnumRangeTestRunner(act)
|
||||
.testOutOfRangeThrows()
|
||||
.testUndefinedValueThrows()
|
||||
.testInvalidValueThrows(OperatingSystem.KaiOS, `Unsupported os: ${OperatingSystem[OperatingSystem.KaiOS]}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,145 +7,148 @@ import { IScriptCode } from '@/domain/IScriptCode';
|
||||
import { ScriptCodeStub } from '@tests/unit/stubs/ScriptCodeStub';
|
||||
|
||||
describe('Script', () => {
|
||||
describe('ctor', () => {
|
||||
describe('scriptCode', () => {
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const expected = new ScriptCodeStub();
|
||||
const sut = new ScriptBuilder()
|
||||
.withCode(expected)
|
||||
.build();
|
||||
// act
|
||||
const actual = sut.code;
|
||||
// assert
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
it('throws if undefined', () => {
|
||||
// arrange
|
||||
const name = 'script-name';
|
||||
const expectedError = `undefined code (script: ${name})`;
|
||||
const code: IScriptCode = undefined;
|
||||
// act
|
||||
const construct = () => new ScriptBuilder()
|
||||
.withName(name)
|
||||
.withCode(code)
|
||||
.build();
|
||||
// assert
|
||||
expect(construct).to.throw(expectedError);
|
||||
});
|
||||
});
|
||||
describe('canRevert', () => {
|
||||
it('returns false without revert code', () => {
|
||||
// arrange
|
||||
const sut = new ScriptBuilder()
|
||||
.withCodes('code')
|
||||
.build();
|
||||
// act
|
||||
const actual = sut.canRevert();
|
||||
// assert
|
||||
expect(actual).to.equal(false);
|
||||
});
|
||||
it('returns true with revert code', () => {
|
||||
// arrange
|
||||
const sut = new ScriptBuilder()
|
||||
.withCodes('code', 'non empty revert code')
|
||||
.build();
|
||||
// act
|
||||
const actual = sut.canRevert();
|
||||
// assert
|
||||
expect(actual).to.equal(true);
|
||||
});
|
||||
});
|
||||
describe('level', () => {
|
||||
it('cannot construct with invalid wrong value', () => {
|
||||
// arrange
|
||||
const invalidValue: RecommendationLevel = 55;
|
||||
const expectedError = 'invalid level';
|
||||
// act
|
||||
const construct = () => new ScriptBuilder()
|
||||
.withRecommendationLevel(invalidValue)
|
||||
.build();
|
||||
// assert
|
||||
expect(construct).to.throw(expectedError);
|
||||
});
|
||||
it('sets undefined as expected', () => {
|
||||
// arrange
|
||||
const expected = undefined;
|
||||
// act
|
||||
const sut = new ScriptBuilder()
|
||||
.withRecommendationLevel(expected)
|
||||
.build();
|
||||
// assert
|
||||
expect(sut.level).to.equal(expected);
|
||||
});
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
for (const expected of getEnumValues(RecommendationLevel)) {
|
||||
// act
|
||||
const sut = new ScriptBuilder()
|
||||
.withRecommendationLevel(expected)
|
||||
.build();
|
||||
// assert
|
||||
const actual = sut.level;
|
||||
expect(actual).to.equal(expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('documentationUrls', () => {
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const expected = [ 'doc1', 'doc2 '];
|
||||
// act
|
||||
const sut = new ScriptBuilder()
|
||||
.withDocumentationUrls(expected)
|
||||
.build();
|
||||
const actual = sut.documentationUrls;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
});
|
||||
describe('ctor', () => {
|
||||
describe('scriptCode', () => {
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const expected = new ScriptCodeStub();
|
||||
const sut = new ScriptBuilder()
|
||||
.withCode(expected)
|
||||
.build();
|
||||
// act
|
||||
const actual = sut.code;
|
||||
// assert
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
it('throws if undefined', () => {
|
||||
// arrange
|
||||
const name = 'script-name';
|
||||
const expectedError = `undefined code (script: ${name})`;
|
||||
const code: IScriptCode = undefined;
|
||||
// act
|
||||
const construct = () => new ScriptBuilder()
|
||||
.withName(name)
|
||||
.withCode(code)
|
||||
.build();
|
||||
// assert
|
||||
expect(construct).to.throw(expectedError);
|
||||
});
|
||||
});
|
||||
describe('canRevert', () => {
|
||||
it('returns false without revert code', () => {
|
||||
// arrange
|
||||
const sut = new ScriptBuilder()
|
||||
.withCodes('code')
|
||||
.build();
|
||||
// act
|
||||
const actual = sut.canRevert();
|
||||
// assert
|
||||
expect(actual).to.equal(false);
|
||||
});
|
||||
it('returns true with revert code', () => {
|
||||
// arrange
|
||||
const sut = new ScriptBuilder()
|
||||
.withCodes('code', 'non empty revert code')
|
||||
.build();
|
||||
// act
|
||||
const actual = sut.canRevert();
|
||||
// assert
|
||||
expect(actual).to.equal(true);
|
||||
});
|
||||
});
|
||||
describe('level', () => {
|
||||
it('cannot construct with invalid wrong value', () => {
|
||||
// arrange
|
||||
const invalidValue: RecommendationLevel = 55;
|
||||
const expectedError = 'invalid level';
|
||||
// act
|
||||
const construct = () => new ScriptBuilder()
|
||||
.withRecommendationLevel(invalidValue)
|
||||
.build();
|
||||
// assert
|
||||
expect(construct).to.throw(expectedError);
|
||||
});
|
||||
it('sets undefined as expected', () => {
|
||||
// arrange
|
||||
const expected = undefined;
|
||||
// act
|
||||
const sut = new ScriptBuilder()
|
||||
.withRecommendationLevel(expected)
|
||||
.build();
|
||||
// assert
|
||||
expect(sut.level).to.equal(expected);
|
||||
});
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
for (const expected of getEnumValues(RecommendationLevel)) {
|
||||
// act
|
||||
const sut = new ScriptBuilder()
|
||||
.withRecommendationLevel(expected)
|
||||
.build();
|
||||
// assert
|
||||
const actual = sut.level;
|
||||
expect(actual).to.equal(expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('documentationUrls', () => {
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const expected = ['doc1', 'doc2'];
|
||||
// act
|
||||
const sut = new ScriptBuilder()
|
||||
.withDocumentationUrls(expected)
|
||||
.build();
|
||||
const actual = sut.documentationUrls;
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
class ScriptBuilder {
|
||||
private name = 'test-script';
|
||||
private code: IScriptCode = new ScriptCodeStub();
|
||||
private level = RecommendationLevel.Standard;
|
||||
private documentationUrls: readonly string[] = undefined;
|
||||
private name = 'test-script';
|
||||
|
||||
public withCodes(code: string, revertCode = ''): ScriptBuilder {
|
||||
this.code = new ScriptCodeStub()
|
||||
.withExecute(code)
|
||||
.withRevert(revertCode);
|
||||
return this;
|
||||
}
|
||||
private code: IScriptCode = new ScriptCodeStub();
|
||||
|
||||
public withCode(code: IScriptCode): ScriptBuilder {
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
private level = RecommendationLevel.Standard;
|
||||
|
||||
public withName(name: string): ScriptBuilder {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
private documentationUrls: readonly string[] = undefined;
|
||||
|
||||
public withRecommendationLevel(level: RecommendationLevel): ScriptBuilder {
|
||||
this.level = level;
|
||||
return this;
|
||||
}
|
||||
public withCodes(code: string, revertCode = ''): ScriptBuilder {
|
||||
this.code = new ScriptCodeStub()
|
||||
.withExecute(code)
|
||||
.withRevert(revertCode);
|
||||
return this;
|
||||
}
|
||||
|
||||
public withDocumentationUrls(urls: readonly string[]): ScriptBuilder {
|
||||
this.documentationUrls = urls;
|
||||
return this;
|
||||
}
|
||||
public withCode(code: IScriptCode): ScriptBuilder {
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public build(): Script {
|
||||
return new Script(
|
||||
this.name,
|
||||
this.code,
|
||||
this.documentationUrls,
|
||||
this.level,
|
||||
);
|
||||
}
|
||||
public withName(name: string): ScriptBuilder {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRecommendationLevel(level: RecommendationLevel): ScriptBuilder {
|
||||
this.level = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withDocumentationUrls(urls: readonly string[]): ScriptBuilder {
|
||||
this.documentationUrls = urls;
|
||||
return this;
|
||||
}
|
||||
|
||||
public build(): Script {
|
||||
return new Script(
|
||||
this.name,
|
||||
this.code,
|
||||
this.documentationUrls,
|
||||
this.level,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,191 +1,192 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { ScriptCode } from '@/domain/ScriptCode';
|
||||
import { ScriptCode, ILanguageSyntax } from '@/domain/ScriptCode';
|
||||
import { IScriptCode } from '@/domain/IScriptCode';
|
||||
import { ILanguageSyntax } from '@/domain/ScriptCode';
|
||||
import { LanguageSyntaxStub } from '@tests/unit/stubs/LanguageSyntaxStub';
|
||||
|
||||
describe('ScriptCode', () => {
|
||||
describe('code', () => {
|
||||
describe('throws with invalid code', () => {
|
||||
// arrange
|
||||
const testCases = [
|
||||
{
|
||||
name: 'throws when "execute" and "revert" are same',
|
||||
code: {
|
||||
execute: 'same',
|
||||
revert: 'same',
|
||||
},
|
||||
expectedError: `(revert): Code itself and its reverting code cannot be the same`,
|
||||
},
|
||||
{
|
||||
name: 'cannot construct with undefined "execute"',
|
||||
code: {
|
||||
execute: undefined,
|
||||
revert: 'code',
|
||||
},
|
||||
expectedError: `code is empty or undefined`,
|
||||
},
|
||||
{
|
||||
name: 'cannot construct with empty "execute"',
|
||||
code: {
|
||||
execute: '',
|
||||
revert: 'code',
|
||||
},
|
||||
expectedError: `code is empty or undefined`,
|
||||
},
|
||||
];
|
||||
for (const testCase of testCases) {
|
||||
it(testCase.name, () => {
|
||||
// act
|
||||
const act = () => new ScriptCodeBuilder()
|
||||
.withExecute( testCase.code.execute)
|
||||
.withRevert(testCase.code.revert)
|
||||
.build();
|
||||
// assert
|
||||
expect(act).to.throw(testCase.expectedError);
|
||||
});
|
||||
}
|
||||
});
|
||||
describe('throws with invalid code in both "execute" or "revert"', () => {
|
||||
// arrange
|
||||
const testCases = [
|
||||
{
|
||||
testName: 'cannot construct with duplicate lines',
|
||||
code: 'duplicate\nduplicate\nunique\nduplicate',
|
||||
expectedMessage: 'Duplicates detected in script:\n❌ (0,1,3)\t[0] duplicate\n❌ (0,1,3)\t[1] duplicate\n✅ [2] unique\n❌ (0,1,3)\t[3] duplicate',
|
||||
},
|
||||
{
|
||||
testName: 'cannot construct with empty lines',
|
||||
code: 'line1\n\n\nline2',
|
||||
expectedMessage: 'Script has empty lines:\n\n (0) line1\n (1) ❌\n (2) ❌\n (3) line2',
|
||||
},
|
||||
];
|
||||
// act
|
||||
const actions = [];
|
||||
for (const testCase of testCases) {
|
||||
actions.push(...[
|
||||
{
|
||||
act: () => new ScriptCodeBuilder()
|
||||
.withExecute(testCase.code)
|
||||
.build(),
|
||||
testName: `execute: ${testCase.testName}`,
|
||||
expectedMessage: testCase.expectedMessage,
|
||||
},
|
||||
{
|
||||
act: () => new ScriptCodeBuilder()
|
||||
.withRevert(testCase.code)
|
||||
.build(),
|
||||
testName: `revert: ${testCase.testName}`,
|
||||
expectedMessage: `(revert): ${testCase.expectedMessage}`,
|
||||
},
|
||||
]);
|
||||
}
|
||||
// assert
|
||||
for (const action of actions) {
|
||||
it(action.testName, () => {
|
||||
expect(action.act).to.throw(action.expectedMessage,
|
||||
`Code used: ${action.code}`);
|
||||
});
|
||||
}
|
||||
});
|
||||
describe('sets as expected with valid "execute" or "revert"', () => {
|
||||
// arrange
|
||||
const syntax = new LanguageSyntaxStub()
|
||||
.withCommonCodeParts(')', 'else', '(')
|
||||
.withCommentDelimiters('#', '//');
|
||||
const testCases = [
|
||||
{
|
||||
testName: 'code is a valid string',
|
||||
code: 'valid code',
|
||||
},
|
||||
{
|
||||
testName: 'code consists of common code parts',
|
||||
code: syntax.commonCodeParts.join(' '),
|
||||
},
|
||||
{
|
||||
testName: 'code is a common code part',
|
||||
code: syntax.commonCodeParts[0],
|
||||
},
|
||||
{
|
||||
testName: `code with duplicated comment lines (${syntax.commentDelimiters[0]})`,
|
||||
code: `${syntax.commentDelimiters[0]} comment\n${syntax.commentDelimiters[0]} comment`,
|
||||
},
|
||||
{
|
||||
testName: `code with duplicated comment lines (${syntax.commentDelimiters[1]})`,
|
||||
code: `${syntax.commentDelimiters[1]} comment\n${syntax.commentDelimiters[1]} comment`,
|
||||
},
|
||||
];
|
||||
// act
|
||||
const actions = [];
|
||||
for (const testCase of testCases) {
|
||||
actions.push(...[
|
||||
{
|
||||
testName: `execute: ${testCase.testName}`,
|
||||
act: () =>
|
||||
new ScriptCodeBuilder()
|
||||
.withSyntax(syntax)
|
||||
.withExecute(testCase.code)
|
||||
.build(),
|
||||
expect: (sut: IScriptCode) => sut.execute === testCase.code,
|
||||
},
|
||||
{
|
||||
testName: `revert: ${testCase.testName}`,
|
||||
act: () =>
|
||||
new ScriptCodeBuilder()
|
||||
.withSyntax(syntax)
|
||||
.withRevert(testCase.code)
|
||||
.build(),
|
||||
expect: (sut: IScriptCode) => sut.revert === testCase.code,
|
||||
},
|
||||
]);
|
||||
}
|
||||
// assert
|
||||
for (const action of actions) {
|
||||
it(action.testName, () => {
|
||||
const sut = action.act();
|
||||
expect(action.expect(sut));
|
||||
});
|
||||
}
|
||||
describe('code', () => {
|
||||
describe('throws with invalid code', () => {
|
||||
// arrange
|
||||
const testCases = [
|
||||
{
|
||||
name: 'throws when "execute" and "revert" are same',
|
||||
code: {
|
||||
execute: 'same',
|
||||
revert: 'same',
|
||||
},
|
||||
expectedError: '(revert): Code itself and its reverting code cannot be the same',
|
||||
},
|
||||
{
|
||||
name: 'cannot construct with undefined "execute"',
|
||||
code: {
|
||||
execute: undefined,
|
||||
revert: 'code',
|
||||
},
|
||||
expectedError: 'code is empty or undefined',
|
||||
},
|
||||
{
|
||||
name: 'cannot construct with empty "execute"',
|
||||
code: {
|
||||
execute: '',
|
||||
revert: 'code',
|
||||
},
|
||||
expectedError: 'code is empty or undefined',
|
||||
},
|
||||
];
|
||||
for (const testCase of testCases) {
|
||||
it(testCase.name, () => {
|
||||
// act
|
||||
const act = () => new ScriptCodeBuilder()
|
||||
.withExecute(testCase.code.execute)
|
||||
.withRevert(testCase.code.revert)
|
||||
.build();
|
||||
// assert
|
||||
expect(act).to.throw(testCase.expectedError);
|
||||
});
|
||||
}
|
||||
});
|
||||
describe('syntax', () => {
|
||||
it('throws if undefined', () => {
|
||||
// arrange
|
||||
const expectedError = 'undefined syntax';
|
||||
const syntax = undefined;
|
||||
// act
|
||||
const act = () => new ScriptCodeBuilder()
|
||||
.withSyntax(syntax)
|
||||
.build();
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
describe('throws with invalid code in both "execute" or "revert"', () => {
|
||||
// arrange
|
||||
const testCases = [
|
||||
{
|
||||
testName: 'cannot construct with duplicate lines',
|
||||
code: 'duplicate\nduplicate\nunique\nduplicate',
|
||||
expectedMessage: 'Duplicates detected in script:\n❌ (0,1,3)\t[0] duplicate\n❌ (0,1,3)\t[1] duplicate\n✅ [2] unique\n❌ (0,1,3)\t[3] duplicate',
|
||||
},
|
||||
{
|
||||
testName: 'cannot construct with empty lines',
|
||||
code: 'line1\n\n\nline2',
|
||||
expectedMessage: 'Script has empty lines:\n\n (0) line1\n (1) ❌\n (2) ❌\n (3) line2',
|
||||
},
|
||||
];
|
||||
// act
|
||||
const actions = [];
|
||||
for (const testCase of testCases) {
|
||||
actions.push(...[
|
||||
{
|
||||
act: () => new ScriptCodeBuilder()
|
||||
.withExecute(testCase.code)
|
||||
.build(),
|
||||
testName: `execute: ${testCase.testName}`,
|
||||
expectedMessage: testCase.expectedMessage,
|
||||
},
|
||||
{
|
||||
act: () => new ScriptCodeBuilder()
|
||||
.withRevert(testCase.code)
|
||||
.build(),
|
||||
testName: `revert: ${testCase.testName}`,
|
||||
expectedMessage: `(revert): ${testCase.expectedMessage}`,
|
||||
},
|
||||
]);
|
||||
}
|
||||
// assert
|
||||
for (const action of actions) {
|
||||
it(action.testName, () => {
|
||||
expect(action.act).to.throw(action.expectedMessage, `Code used: ${action.code}`);
|
||||
});
|
||||
}
|
||||
});
|
||||
describe('sets as expected with valid "execute" or "revert"', () => {
|
||||
// arrange
|
||||
const syntax = new LanguageSyntaxStub()
|
||||
.withCommonCodeParts(')', 'else', '(')
|
||||
.withCommentDelimiters('#', '//');
|
||||
const testCases = [
|
||||
{
|
||||
testName: 'code is a valid string',
|
||||
code: 'valid code',
|
||||
},
|
||||
{
|
||||
testName: 'code consists of common code parts',
|
||||
code: syntax.commonCodeParts.join(' '),
|
||||
},
|
||||
{
|
||||
testName: 'code is a common code part',
|
||||
code: syntax.commonCodeParts[0],
|
||||
},
|
||||
{
|
||||
testName: `code with duplicated comment lines (${syntax.commentDelimiters[0]})`,
|
||||
code: `${syntax.commentDelimiters[0]} comment\n${syntax.commentDelimiters[0]} comment`,
|
||||
},
|
||||
{
|
||||
testName: `code with duplicated comment lines (${syntax.commentDelimiters[1]})`,
|
||||
code: `${syntax.commentDelimiters[1]} comment\n${syntax.commentDelimiters[1]} comment`,
|
||||
},
|
||||
];
|
||||
// act
|
||||
const actions = [];
|
||||
for (const testCase of testCases) {
|
||||
actions.push(...[
|
||||
{
|
||||
testName: `execute: ${testCase.testName}`,
|
||||
act: () => new ScriptCodeBuilder()
|
||||
.withSyntax(syntax)
|
||||
.withExecute(testCase.code)
|
||||
.build(),
|
||||
expect: (sut: IScriptCode) => sut.execute === testCase.code,
|
||||
},
|
||||
{
|
||||
testName: `revert: ${testCase.testName}`,
|
||||
act: () => new ScriptCodeBuilder()
|
||||
.withSyntax(syntax)
|
||||
.withRevert(testCase.code)
|
||||
.build(),
|
||||
expect: (sut: IScriptCode) => sut.revert === testCase.code,
|
||||
},
|
||||
]);
|
||||
}
|
||||
// assert
|
||||
for (const action of actions) {
|
||||
it(action.testName, () => {
|
||||
const sut = action.act();
|
||||
expect(action.expect(sut));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('syntax', () => {
|
||||
it('throws if undefined', () => {
|
||||
// arrange
|
||||
const expectedError = 'undefined syntax';
|
||||
const syntax = undefined;
|
||||
// act
|
||||
const act = () => new ScriptCodeBuilder()
|
||||
.withSyntax(syntax)
|
||||
.build();
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
class ScriptCodeBuilder {
|
||||
public execute = 'default-execute-code';
|
||||
public revert = '';
|
||||
public syntax: ILanguageSyntax = new LanguageSyntaxStub();
|
||||
public execute = 'default-execute-code';
|
||||
|
||||
public withExecute(execute: string) {
|
||||
this.execute = execute;
|
||||
return this;
|
||||
}
|
||||
public withRevert(revert: string) {
|
||||
this.revert = revert;
|
||||
return this;
|
||||
}
|
||||
public withSyntax(syntax: ILanguageSyntax) {
|
||||
this.syntax = syntax;
|
||||
return this;
|
||||
}
|
||||
public revert = '';
|
||||
|
||||
public build(): ScriptCode {
|
||||
return new ScriptCode(
|
||||
this.execute,
|
||||
this.revert,
|
||||
this.syntax);
|
||||
}
|
||||
public syntax: ILanguageSyntax = new LanguageSyntaxStub();
|
||||
|
||||
public withExecute(execute: string) {
|
||||
this.execute = execute;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRevert(revert: string) {
|
||||
this.revert = revert;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withSyntax(syntax: ILanguageSyntax) {
|
||||
this.syntax = syntax;
|
||||
return this;
|
||||
}
|
||||
|
||||
public build(): ScriptCode {
|
||||
return new ScriptCode(
|
||||
this.execute,
|
||||
this.revert,
|
||||
this.syntax,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,129 +5,129 @@ import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { getEnumValues } from '@/application/Common/Enum';
|
||||
|
||||
describe('ScriptingDefinition', () => {
|
||||
describe('language', () => {
|
||||
describe('sets as expected', () => {
|
||||
// arrange
|
||||
const expectedValues = getEnumValues(ScriptingLanguage);
|
||||
expectedValues.forEach((expected) => {
|
||||
it(ScriptingLanguage[expected], () => {
|
||||
// act
|
||||
const sut = new ScriptingDefinitionBuilder()
|
||||
.withLanguage(expected)
|
||||
.build();
|
||||
// assert
|
||||
expect(sut.language).to.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
it('throws if unknown', () => {
|
||||
// arrange
|
||||
const unknownValue: ScriptingLanguage = 666;
|
||||
const errorMessage = `unsupported language: ${unknownValue}`;
|
||||
// act
|
||||
const act = () => new ScriptingDefinitionBuilder()
|
||||
.withLanguage(unknownValue)
|
||||
.build();
|
||||
// assert
|
||||
expect(act).to.throw(errorMessage);
|
||||
describe('language', () => {
|
||||
describe('sets as expected', () => {
|
||||
// arrange
|
||||
const expectedValues = getEnumValues(ScriptingLanguage);
|
||||
expectedValues.forEach((expected) => {
|
||||
it(ScriptingLanguage[expected], () => {
|
||||
// act
|
||||
const sut = new ScriptingDefinitionBuilder()
|
||||
.withLanguage(expected)
|
||||
.build();
|
||||
// assert
|
||||
expect(sut.language).to.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('fileExtension', () => {
|
||||
describe('returns expected for each language', () => {
|
||||
// arrange
|
||||
const testCases = new Map<ScriptingLanguage, string>([
|
||||
[ScriptingLanguage.batchfile, 'bat'],
|
||||
[ScriptingLanguage.shellscript, 'sh'],
|
||||
]);
|
||||
Array.from(testCases.entries()).forEach((test) => {
|
||||
const language = test[0];
|
||||
const expectedExtension = test[1];
|
||||
it(`${ScriptingLanguage[language]} has ${expectedExtension}`, () => {
|
||||
// act
|
||||
const sut = new ScriptingDefinitionBuilder()
|
||||
.withLanguage(language)
|
||||
.build();
|
||||
// assert
|
||||
expect(sut.fileExtension, expectedExtension);
|
||||
});
|
||||
});
|
||||
});
|
||||
it('throws if unknown', () => {
|
||||
// arrange
|
||||
const unknownValue: ScriptingLanguage = 666;
|
||||
const errorMessage = `unsupported language: ${unknownValue}`;
|
||||
// act
|
||||
const act = () => new ScriptingDefinitionBuilder()
|
||||
.withLanguage(unknownValue)
|
||||
.build();
|
||||
// assert
|
||||
expect(act).to.throw(errorMessage);
|
||||
});
|
||||
describe('startCode', () => {
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const expected = 'REM start-code';
|
||||
// act
|
||||
const sut = new ScriptingDefinitionBuilder()
|
||||
.withStartCode(expected)
|
||||
.build();
|
||||
// assert
|
||||
expect(sut.startCode).to.equal(expected);
|
||||
});
|
||||
it('throws when undefined', () => {
|
||||
// arrange
|
||||
const expectedError = 'undefined start code';
|
||||
const undefinedValues = [ '', undefined ];
|
||||
for (const undefinedValue of undefinedValues) {
|
||||
// act
|
||||
const act = () => new ScriptingDefinitionBuilder()
|
||||
.withStartCode(undefinedValue)
|
||||
.build();
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
}
|
||||
});
|
||||
describe('fileExtension', () => {
|
||||
describe('returns expected for each language', () => {
|
||||
// arrange
|
||||
const testCases = new Map<ScriptingLanguage, string>([
|
||||
[ScriptingLanguage.batchfile, 'bat'],
|
||||
[ScriptingLanguage.shellscript, 'sh'],
|
||||
]);
|
||||
Array.from(testCases.entries()).forEach((test) => {
|
||||
const language = test[0];
|
||||
const expectedExtension = test[1];
|
||||
it(`${ScriptingLanguage[language]} has ${expectedExtension}`, () => {
|
||||
// act
|
||||
const sut = new ScriptingDefinitionBuilder()
|
||||
.withLanguage(language)
|
||||
.build();
|
||||
// assert
|
||||
expect(sut.fileExtension, expectedExtension);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('endCode', () => {
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const expected = 'REM end-code';
|
||||
// act
|
||||
const sut = new ScriptingDefinitionBuilder()
|
||||
.withEndCode(expected)
|
||||
.build();
|
||||
// assert
|
||||
expect(sut.endCode).to.equal(expected);
|
||||
|
||||
});
|
||||
it('throws when undefined', () => {
|
||||
// arrange
|
||||
const expectedError = 'undefined end code';
|
||||
const undefinedValues = [ '', undefined ];
|
||||
for (const undefinedValue of undefinedValues) {
|
||||
// act
|
||||
const act = () => new ScriptingDefinitionBuilder()
|
||||
.withEndCode(undefinedValue)
|
||||
.build();
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('startCode', () => {
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const expected = 'REM start-code';
|
||||
// act
|
||||
const sut = new ScriptingDefinitionBuilder()
|
||||
.withStartCode(expected)
|
||||
.build();
|
||||
// assert
|
||||
expect(sut.startCode).to.equal(expected);
|
||||
});
|
||||
it('throws when undefined', () => {
|
||||
// arrange
|
||||
const expectedError = 'undefined start code';
|
||||
const undefinedValues = ['', undefined];
|
||||
for (const undefinedValue of undefinedValues) {
|
||||
// act
|
||||
const act = () => new ScriptingDefinitionBuilder()
|
||||
.withStartCode(undefinedValue)
|
||||
.build();
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('endCode', () => {
|
||||
it('sets as expected', () => {
|
||||
// arrange
|
||||
const expected = 'REM end-code';
|
||||
// act
|
||||
const sut = new ScriptingDefinitionBuilder()
|
||||
.withEndCode(expected)
|
||||
.build();
|
||||
// assert
|
||||
expect(sut.endCode).to.equal(expected);
|
||||
});
|
||||
it('throws when undefined', () => {
|
||||
// arrange
|
||||
const expectedError = 'undefined end code';
|
||||
const undefinedValues = ['', undefined];
|
||||
for (const undefinedValue of undefinedValues) {
|
||||
// act
|
||||
const act = () => new ScriptingDefinitionBuilder()
|
||||
.withEndCode(undefinedValue)
|
||||
.build();
|
||||
// assert
|
||||
expect(act).to.throw(expectedError);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
class ScriptingDefinitionBuilder {
|
||||
private language = ScriptingLanguage.shellscript;
|
||||
private startCode = 'REM start-code';
|
||||
private endCode = 'REM end-code';
|
||||
private language = ScriptingLanguage.shellscript;
|
||||
|
||||
public withLanguage(language: ScriptingLanguage): ScriptingDefinitionBuilder {
|
||||
this.language = language;
|
||||
return this;
|
||||
}
|
||||
private startCode = 'REM start-code';
|
||||
|
||||
public withStartCode(startCode: string): ScriptingDefinitionBuilder {
|
||||
this.startCode = startCode;
|
||||
return this;
|
||||
}
|
||||
private endCode = 'REM end-code';
|
||||
|
||||
public withEndCode(endCode: string): ScriptingDefinitionBuilder {
|
||||
this.endCode = endCode;
|
||||
return this;
|
||||
}
|
||||
public withLanguage(language: ScriptingLanguage): ScriptingDefinitionBuilder {
|
||||
this.language = language;
|
||||
return this;
|
||||
}
|
||||
|
||||
public build(): ScriptingDefinition {
|
||||
return new ScriptingDefinition(
|
||||
this.language, this.startCode, this.endCode);
|
||||
}
|
||||
public withStartCode(startCode: string): ScriptingDefinitionBuilder {
|
||||
this.startCode = startCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withEndCode(endCode: string): ScriptingDefinitionBuilder {
|
||||
this.endCode = endCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public build(): ScriptingDefinition {
|
||||
return new ScriptingDefinition(this.language, this.startCode, this.endCode);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user