import 'mocha'; import { expect } from 'chai'; import { parseProjectInformation } from '@/application/Parser/ProjectInformationParser'; import { CategoryCollectionParserType, parseApplication } from '@/application/Parser/ApplicationParser'; import WindowsData from 'js-yaml-loader!@/application/collections/windows.yaml'; import MacOsData from 'js-yaml-loader!@/application/collections/macos.yaml'; import { CollectionData } from 'js-yaml-loader!@/*'; import { IProjectInformation } from '@/domain/IProjectInformation'; import { ProjectInformation } from '@/domain/ProjectInformation'; import { ICategoryCollection } from '@/domain/ICategoryCollection'; import { OperatingSystem } from '@/domain/OperatingSystem'; import { getEnumValues } from '@/application/Common/Enum'; import { CategoryCollectionStub } from '../../stubs/CategoryCollectionStub'; import { getProcessEnvironmentStub } from '../../stubs/ProcessEnvironmentStub'; import { CollectionDataStub } from '../../stubs/CollectionDataStub'; describe('ApplicationParser', () => { describe('parseApplication', () => { it('can parse current application', () => { // Integration test // act const act = () => parseApplication(); // assert expect(act).to.not.throw(); }); describe('parser', () => { it('returns result from the parser', () => { // arrange const os = OperatingSystem.macOS; const data = new CollectionDataStub(); const expected = new CategoryCollectionStub() .withOs(os); const parser = new CategoryCollectionParserSpy() .setUpReturnValue(data, expected) .mockParser(); const env = getProcessEnvironmentStub(); const collections = [ data ]; // act const app = parseApplication(parser, env, collections); // assert const actual = app.getCollection(os); expect(expected).to.equal(actual); }); }); describe('processEnv', () => { it('used to parse expected project information', () => { // arrange const env = getProcessEnvironmentStub(); const expected = parseProjectInformation(env); const parserSpy = new CategoryCollectionParserSpy(); const parserMock = parserSpy.mockParser(); // act const app = parseApplication(parserMock, env); // assert expect(expected).to.deep.equal(app.info); expect(parserSpy.arguments.map((arg) => arg.info).every((info) => info === expected)); }); it('defaults to process.env', () => { // arrange const env = process.env; const expected = parseProjectInformation(env); const parserSpy = new CategoryCollectionParserSpy(); const parserMock = parserSpy.mockParser(); // act const app = parseApplication(parserMock); // assert expect(expected).to.deep.equal(app.info); expect(parserSpy.arguments.map((arg) => arg.info).every((info) => info === expected)); }); }); describe('collectionsData', () => { describe('set as expected', () => { // arrange const testCases = [ { name: 'single collection', input: [ new CollectionDataStub() ], output: [ new CategoryCollectionStub().withOs(OperatingSystem.macOS) ], }, { name: 'multiple collections', input: [ new CollectionDataStub().withOs('windows'), new CollectionDataStub().withOs('macos'), ], output: [ new CategoryCollectionStub().withOs(OperatingSystem.macOS), new CategoryCollectionStub().withOs(OperatingSystem.Windows), ], }, ]; // act for (const testCase of testCases) { it(testCase.name, () => { const env = getProcessEnvironmentStub(); let parserSpy = new CategoryCollectionParserSpy(); for (let i = 0; i < testCase.input.length; i++) { parserSpy = parserSpy.setUpReturnValue(testCase.input[i], testCase.output[i]); } const parserMock = parserSpy.mockParser(); // act const app = parseApplication(parserMock, env, testCase.input); // assert expect(app.collections).to.deep.equal(testCase.output); }); } }); it('defaults to expected data', () => { // arrange const expected = [ WindowsData, MacOsData ]; const parserSpy = new CategoryCollectionParserSpy(); const parserMock = parserSpy.mockParser(); // act parseApplication(parserMock); // assert const actual = parserSpy.arguments.map((args) => args.data); expect(actual).to.deep.equal(expected); }); describe('throws when data is invalid', () => { // arrange const testCases = [ { expectedError: 'no collection provided', data: [], }, { expectedError: 'undefined collection provided', data: [ new CollectionDataStub(), undefined ], }, ]; for (const testCase of testCases) { it(testCase.expectedError, () => { const parserMock = new CategoryCollectionParserSpy().mockParser(); const env = getProcessEnvironmentStub(); // act const act = () => parseApplication(parserMock, env, testCase.data); // assert expect(act).to.throw(testCase.expectedError); }); } }); }); }); }); class CategoryCollectionParserSpy { public arguments = new Array<{ data: CollectionData, info: ProjectInformation, }>(); private returnValues = new Map(); public setUpReturnValue(data: CollectionData, collection: ICategoryCollection): CategoryCollectionParserSpy { this.returnValues.set(data, collection); return this; } public mockParser(): CategoryCollectionParserType { return (data: CollectionData, info: IProjectInformation) => { this.arguments.push({ data, info }); if (this.returnValues.has(data)) { return this.returnValues.get(data); } else { // Get next OS with a unique OS so mock does not result in invalid app (with duplicate OS collections) const currentRun = this.arguments.length - 1; const nextOs = getEnumValues(OperatingSystem)[currentRun]; return new CategoryCollectionStub().withOs(nextOs); } }; } }