Skip to content

Commit

Permalink
bunch of fixes for solo test and solo param filtering, introduces mor…
Browse files Browse the repository at this point in the history
…e stub test data to work with (mainly just looking at output right now - needs more asserts) and also better handling of params (deals with bright scripts loose json parser and invalid type, by having direct control of the suite, group and test via asText, as opposed to simply doing asJson and stringily)
  • Loading branch information
George Cook committed Feb 6, 2019
1 parent fea54bb commit 26e1f09
Show file tree
Hide file tree
Showing 173 changed files with 29,323 additions and 85 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
},
"devDependencies": {
"del": "^3.0.0",
"docdash": "^0.4.0",
"gulp-concat": "^2.6.1",
"gulp-copy": "^4.0.1",
"gulp-rm-lines": "0.0.9",
"gulpclass": "^0.2.0",
"minami": "^1.2.3",
"typescript": "^3.3.1",
"vinyl-paths": "^2.1.0",
"docdash": "^0.4.0",
"minami": "^1.2.3"
"vinyl-paths": "^2.1.0"
},
"scripts": {
"test": "test"
Expand Down
2 changes: 1 addition & 1 deletion rooibosPreprocessor/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rooibos-preprocessor",
"version": "1.0.4",
"version": "1.0.5",
"description": "preprocessor for roku brightscript and scenegraph projects, using rooibos",
"main": "dist/index.ts",
"directories": {
Expand Down
39 changes: 34 additions & 5 deletions rooibosPreprocessor/src/lib/ItGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ export class ItGroup {
constructor(name: string, isSolo: boolean, isIgnore: boolean, filename: string) {
this.name = name;
this.isSolo = isSolo;
this.hasSoloTests = false;
this.isIncluded = false;
this.isIgnored = isIgnore;
this.filename = filename;
this.testCases = [];
this.ignoredTestCases = [];
this.soloTestCases = [];
}

public isIncluded: boolean;
public isSolo: boolean;
public isIgnored: boolean;
public filename: string;
Expand All @@ -19,7 +22,6 @@ export class ItGroup {
public testCases: TestCase[];
public ignoredTestCases: TestCase[];
public soloTestCases: TestCase[];
public testCaseLookup: boolean;
public setupFunctionName: string;
public tearDownFunctionName: string;
public beforeEachFunctionName: string;
Expand All @@ -28,11 +30,13 @@ export class ItGroup {

public asJson(): object {
return {
testCases: this.testCases.map((testCase) => testCase.asJson()),
ignoredTestCases: this.ignoredTestCases.map((testCase) => testCase.asJson()),
soloTestCases: this.soloTestCases.map((testCase) => testCase.asJson()),
testCases: this.testCases.filter( (testCase) => testCase.isIncluded)
.map((testCase) => testCase.asJson()),
ignoredTestCases: this.ignoredTestCases.filter( (testCase) => testCase.isIncluded)
.map((testCase) => testCase.asJson()),
soloTestCases: this.soloTestCases.filter( (testCase) => testCase.isIncluded)
.map((testCase) => testCase.asJson()),
filename: this.filename,
testCaseLookup: this.testCaseLookup,
setupFunctionName: this.setupFunctionName,
tearDownFunctionName: this.tearDownFunctionName,
beforeEachFunctionName: this.beforeEachFunctionName,
Expand All @@ -43,6 +47,31 @@ export class ItGroup {
name: this.name
};
}

public asText(): string {
let testCases = this.testCases.filter( (testCase) => testCase.isIncluded)
.map((testCase) => testCase.asText());
let ignoredTestCases = this.ignoredTestCases.filter( (testCase) => testCase.isIncluded)
.map((testCase) => testCase.asText());
let soloTestCases = this.soloTestCases.filter( (testCase) => testCase.isIncluded)
.map((testCase) => testCase.asText());
return `
{
testCases: [${testCases}]
ignoredTestCases: [${ignoredTestCases}]
soloTestCases: [${soloTestCases}]
filename: "${this.filename}"
setupFunctionName: "${this.setupFunctionName || ''}"
tearDownFunctionName: "${this.tearDownFunctionName || ''}"
beforeEachFunctionName: "${this.beforeEachFunctionName || ''}"
afterEachFunctionName: "${this.afterEachFunctionName || ''}"
isSolo: ${this.isSolo}
isIgnored: ${this.isIgnored}
hasSoloTests: ${this.hasSoloTests}
name: "${this.name || ''}"
}`;
}

public addTestCase(testCase: TestCase) {
if (testCase.isSolo) {
this.soloTestCases.push(testCase);
Expand Down
88 changes: 88 additions & 0 deletions rooibosPreprocessor/src/lib/RuntimeConfig.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import * as chai from 'chai';
import * as fs from 'fs-extra';
import * as path from 'path';

import { expect } from 'chai';

import FunctionMap from './FunctionMap';
import { RuntimeConfig } from './RuntimeConfig';

const chaiSubset = require('chai-subset');

chai.use(chaiSubset);
let runtimeConfig: RuntimeConfig;
let sourcePathBunchOfFiles = 'src/test/stubProject';
let sourcePathOneFile = 'src/test/stubProjectOnlyTests_oneFile';
let sourcePathSoloTests = 'src/test/stubProjectOnlyTests';
let sourcePathSoloGroup = 'src/test/stubProjectOnlyItGroup';
let sourcePathSoloSuites = 'src/test/stubProjectOnlySuite';
let sourcePathNoSolos = 'src/test/stubProjectNoSolos';
let targetPath = 'build';

function clearFiles() {
fs.removeSync(targetPath);
}

function copyFiles(sourcePath) {
try {
fs.copySync(sourcePath, targetPath);
} catch (err) {
console.error(err);
}
}

describe('RuntimeConfig tests ', function() {
beforeEach(() => {
let functionMap = new FunctionMap();
runtimeConfig = new RuntimeConfig(functionMap);
});

describe('oneFile', function() {
beforeEach(() => {
clearFiles();
});

it('processes valid test file', () => {
copyFiles(sourcePathOneFile);
runtimeConfig.processPath(path.join(targetPath, 'source/tests'), targetPath);
let suites = runtimeConfig.testSuites;
expect(suites).to.not.be.null;
});

it('processes bunch of files', () => {
copyFiles(sourcePathBunchOfFiles);
runtimeConfig.processPath(path.join(targetPath, 'source/tests'), targetPath);
let suites = runtimeConfig.testSuites;
expect(suites).to.not.be.null;
});

it('processes files with solo suite', () => {
copyFiles(sourcePathSoloSuites);
runtimeConfig.processPath(path.join(targetPath, 'source/tests'), targetPath);
let suites = runtimeConfig.testSuites;
expect(suites).to.not.be.null;
});

it('processes files with solo group', () => {
copyFiles(sourcePathSoloGroup);
runtimeConfig.processPath(path.join(targetPath, 'source/tests'), targetPath);
let suites = runtimeConfig.testSuites;
expect(suites).to.not.be.null;
});

it('processes files with solo tests', () => {
copyFiles(sourcePathSoloTests);
runtimeConfig.processPath(path.join(targetPath, 'source/tests'), targetPath);
let suites = runtimeConfig.testSuites;
expect(suites).to.not.be.null;
});

it('processes files with no solo tests', () => {
copyFiles(sourcePathNoSolos);
runtimeConfig.processPath(path.join(targetPath, 'source/tests'), targetPath);
let suites = runtimeConfig.testSuites;
expect(suites).to.not.be.null;
let json = runtimeConfig.asJson(); //TODO test these return values
});
});
});
85 changes: 80 additions & 5 deletions rooibosPreprocessor/src/lib/RuntimeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@ export class RuntimeConfig {
this._testSuites = [];
this._warnings = [];
this._errors = [];
this.ignoredTestNames = [];
this._functionMap = functionMap;
this._excludeMatcher = new Minimatch(`rooibos.cat.brs`);
}

private ignoredCount: number = 0;
private ignoredTestNames: string[];
private readonly _warnings: string[];
private readonly _errors: string[];
private _excludeMatcher: M.IMinimatch;
private _testSuites: TestSuite[];
private _hasSoloSuites: boolean;
private _hasSoloGroups: boolean;
private _hasSoloTests: boolean;
private _hasSoloSuites: boolean = false;
private _hasSoloGroups: boolean = false;
private _hasSoloTests: boolean = false;
private _functionMap: FunctionMap;

get testSuites(): TestSuite[] {
Expand Down Expand Up @@ -84,6 +87,9 @@ export class RuntimeConfig {
}
}
});

this.updateIncludedFlags();

this.errors.concat(testSuiteBuilder.errors);
this.warnings.concat(testSuiteBuilder.warnings);
}
Expand All @@ -93,13 +99,82 @@ export class RuntimeConfig {
function RBSFM_getTestSuitesForProject()
return [
`;

this.testSuites.forEach((testSuite) => {
text += `\n${JSON.stringify(testSuite.asJson(), null, 2)},\n`;
if (testSuite.isIncluded) {
text += `\n${testSuite.asText()},\n`;
}
});
text += `
]
end function\n`;
return text;
}

/**
* Once we know what's ignored/solo/etc, we can ascertain if we're going
* to include it in the final json payload
*/
private updateIncludedFlags() {
this.testSuites.forEach( (testSuite) => {
if (this._hasSoloTests && !testSuite.hasSoloTests) {
testSuite.isIncluded = false;
} else if (this._hasSoloSuites && !testSuite.isSolo) {
testSuite.isIncluded = false;
} else if (testSuite.isIgnored) {
testSuite.isIncluded = false;
this.ignoredTestNames.push('|-' + testSuite.name + ' [WHOLE SUITE]');
this.ignoredCount++;
} else {
testSuite.isIncluded = true;
}
// console.log('testSuite ' + testSuite.name);
testSuite.itGroups.forEach( (itGroup) => {
// console.log('GROUP ' + itGroup.name);
if (itGroup.isIgnored) {
this.ignoredCount += itGroup.testCases.length;
this.ignoredTestNames.push(' |-' + itGroup.name + ' [WHOLE GROUP]');
} else {
if (itGroup.ignoredTestCases.length > 0) {
this.ignoredTestNames.push(' |-' + itGroup.name);
this.ignoredCount += itGroup.ignoredTestCases.length;
itGroup.ignoredTestCases.forEach((ignoredTestCase) => {
if (!ignoredTestCase.isParamTest) {
this.ignoredTestNames.push(' | |--' + ignoredTestCase.name);
} else if (ignoredTestCase.paramTestIndex === 0) {
let testCaseName = ignoredTestCase.name;
if (testCaseName.length > 1 && testCaseName.substr(testCaseName.length - 1) === '0') {
testCaseName = testCaseName.substr(0, testCaseName.length - 1);
}
this.ignoredTestNames.push(' | |--' + testCaseName);
}
});
}
if (this._hasSoloTests && !itGroup.hasSoloTests && !itGroup.isSolo) {
itGroup.isIncluded = false;
} else if (itGroup.testCases.length === 0 && itGroup.soloTestCases.length === 0) {
itGroup.isIncluded = false;
} else {
itGroup.isIncluded = testSuite.isIncluded;
}
itGroup.testCases.forEach( (testCase) => {
// console.log(testCase.name + ' this._hasSoloTests ' + this._hasSoloTests + ' testCase.isSolo ' + testCase.isSolo);
if (this._hasSoloTests && !testCase.isSolo) {
testCase.isIncluded = false;
} else {
testCase.isIncluded = itGroup.isIncluded || testCase.isSolo;
}
});
itGroup.soloTestCases.forEach( (testCase) => {
// console.log(testCase.name + ' this._hasSoloTests ' + this._hasSoloTests + ' testCase.isSolo ' + testCase.isSolo);
testCase.isIncluded = true;
});
}
});
});
}

public asJson(): object[] {
return this.testSuites.filter( (testSuite) => testSuite.isIncluded)
.map((testSuite) => testSuite.asJson());
}
}
22 changes: 21 additions & 1 deletion rooibosPreprocessor/src/lib/TestCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class TestCase {
}
}

public isIncluded: boolean;
public isSolo: boolean;
public funcName: string;
public isIgnored: boolean;
Expand All @@ -44,13 +45,32 @@ export class TestCase {
paramLineNumber: this.paramLineNumber,
assertIndex: this.assertIndex,
assertLineNumberMap: this.assertLineNumberMap,
rawParams: this.rawParams || [],
rawParams: this.rawParams ? JSON.stringify(this.rawParams).replace(/null/g, 'invalid') : [],
paramTestIndex: this.paramTestIndex,
expectedNumberOfParams: this.expectedNumberOfParams,
isParamsValid: (this.rawParams || []).length === this.expectedNumberOfParams
};
}

public asText(): string {
return `
{
isSolo: ${this.isSolo}
funcName: "${this.funcName || ''}"
isIgnored: ${this.isIgnored}
isParamTest: ${this.isParamTest}
name: "${this.name || ''}"
lineNumber: ${this.lineNumber}
paramLineNumber: ${this.paramLineNumber}
assertIndex: ${this.assertIndex}
assertLineNumberMap: ${JSON.stringify(this.assertLineNumberMap)}
rawParams: ${this.rawParams ? JSON.stringify(this.rawParams).replace(/null/g, 'invalid') : '[]'}
paramTestIndex: ${this.paramTestIndex}
expectedNumberOfParams: ${this.expectedNumberOfParams}
isParamsValid: ${(this.rawParams || []).length === this.expectedNumberOfParams}
}`;
}

public addAssertLine(lineNumber: number) {
this.assertLineNumberMap[this.assertIndex.toString().trim()] = lineNumber;
this.assertIndex++;
Expand Down
27 changes: 26 additions & 1 deletion rooibosPreprocessor/src/lib/TestSuite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export class TestSuite {
public isSolo: boolean;
public isIgnored: boolean;
public isValid: boolean;
public isIncluded: boolean;

public itGroups: ItGroup[];
public hasFailures: boolean;
Expand All @@ -49,7 +50,8 @@ export class TestSuite {
hasSoloGroups: this.hasSoloGroups,
isSolo: this.isSolo,
isIgnored: this.isIgnored,
itGroups: this.itGroups.map((itGroup) => itGroup.asJson()),
itGroups: this.itGroups.filter( (itGroup) => itGroup.isIncluded)
.map((itGroup) => itGroup.asJson()),
setupFunctionName: this.setupFunctionName,
tearDownFunctionName: this.tearDownFunctionName,
isNodeTest: this.isNodeTest,
Expand All @@ -58,4 +60,27 @@ export class TestSuite {
afterEachFunctionName: this.afterEachFunctionName,
};
}

public asText(): string {
let itGroups = this.itGroups.filter( (itGroup) => itGroup.isIncluded)
.map((itGroup) => itGroup.asText());
return `{
name: "${this.name}"
filePath: "${this.filePath}"
valid: ${this.isValid}
hasFailures: ${this.hasFailures}
hasSoloTests: ${this.hasSoloTests}
hasIgnoredTests: ${this.hasIgnoredTests}
hasSoloGroups: ${this.hasSoloGroups}
isSolo: ${this.isSolo}
isIgnored: ${this.isIgnored}
itGroups: [${itGroups}]
setupFunctionName: "${this.setupFunctionName || ''}"
tearDownFunctionName: "${this.tearDownFunctionName || ''}"
isNodeTest: ${this.isNodeTest}
nodeTestFileName: "${this.nodeTestFileName || ''}"
beforeEachFunctionName: "${this.beforeEachFunctionName || ''}"
afterEachFunctionName: "${this.afterEachFunctionName || ''}"
}`;
}
}
Loading

0 comments on commit 26e1f09

Please sign in to comment.