Skip to content

Commit

Permalink
Fixed a bug where scope validations where incomplete for node tests (#…
Browse files Browse the repository at this point in the history
…280)

* Fixed a bug where scope validations where incomplete for node tests

* Update bsc-plugin/src/plugin.spec.ts

* Fix lint issues.

---------

Co-authored-by: Bronley Plumb <[email protected]>
  • Loading branch information
chrisdp and TwitchBronBron authored Jul 2, 2024
1 parent 728124b commit d81fc64
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 22 deletions.
10 changes: 8 additions & 2 deletions bsc-plugin/src/lib/rooibos/FileFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { standardizePath as s } from 'brighterscript';
import * as path from 'path';
import * as fs from 'fs';
import * as fse from 'fs-extra';
import type { TestSuite } from './TestSuite';

export class FileFactory {
private coverageComponentXmlTemplate;
Expand Down Expand Up @@ -71,10 +72,15 @@ export class FileFactory {
);
}

public createTestXML(name: string, baseName: string, useBs = true): string {
public createTestXML(name: string, baseName: string, suite?: TestSuite): string {
let scriptImports = [];
for (let fileName of this.frameworkFileNames) {
scriptImports.push(`<script type="text/bright${useBs ? 'er' : ''}script" uri="pkg:/${this.targetPath}${fileName}.${useBs ? 'bs' : 'brs'}" />`);
scriptImports.push(`<script type="text/brighterscript" uri="pkg:/${this.targetPath}${fileName}.bs" />`);
}

// Add the test spec file rather then relying on auto imports
if (suite) {
scriptImports.push(`<script type="text/brighterscript" uri="pkg:/${suite.file.pkgPath.replace(/\\/g, '/')}" />`);
}

let contents = `<?xml version="1.0" encoding="UTF-8" ?>
Expand Down
14 changes: 5 additions & 9 deletions bsc-plugin/src/lib/rooibos/RooibosSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,18 +208,14 @@ export class RooibosSession {
}

createNodeFile(program: Program, suite: TestSuite) {
let p = path.join('components', 'rooibos', 'generated');

let xmlText = this.getNodeTestXmlText(suite);
let bsPath = path.join(p, `${suite.generatedNodeName}.bs`);
this.fileFactory.addFile(program, path.join(p, `${suite.generatedNodeName}.xml`), xmlText);
let bsFile = program.getFile(bsPath);
this.fileFactory.addFile(program, suite.xmlPkgPath, xmlText);
let bsFile = program.getFile(suite.bsPkgPath);
if (bsFile) {
(bsFile as BrsFile).parser.statements.push();
bsFile.needsTranspiled = true;
}
let brsFile = this.fileFactory.addFile(program, bsPath, undent`
import "pkg:/${suite.file.pkgPath}"
let brsFile = this.fileFactory.addFile(program, suite.bsPkgPath, undent`
function init()
nodeRunner = Rooibos_TestRunner(m.top.getScene(), m)
m.top.rooibosTestResult = nodeRunner.runInNodeMode("${suite.name}")
Expand All @@ -228,8 +224,8 @@ export class RooibosSession {
brsFile.parser.invalidateReferences();
}

private getNodeTestXmlText(suite: TestSuite) {
return this.fileFactory.createTestXML(suite.generatedNodeName, suite.nodeName);
public getNodeTestXmlText(suite: TestSuite) {
return this.fileFactory.createTestXML(suite.generatedNodeName, suite.nodeName, suite);
}

private getNamespaceLookup(scope: Scope): Map<string, NamespaceContainer> {
Expand Down
7 changes: 6 additions & 1 deletion bsc-plugin/src/lib/rooibos/TestSuite.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as path from 'path';
import type { AstEditor, BrsFile, ClassStatement } from 'brighterscript';

import { diagnosticNodeTestIllegalNode, diagnosticNodeTestRequiresNode } from '../utils/Diagnostics';
Expand Down Expand Up @@ -58,6 +59,8 @@ export class TestBlock {
public tearDownFunctionName: string;
public beforeEachFunctionName: string;
public afterEachFunctionName: string;
public xmlPkgPath: string;
public bsPkgPath: string;

}

Expand All @@ -71,7 +74,9 @@ export class TestSuite extends TestBlock {
this.annotation.name = classStatement.name.text;
}
this.generatedNodeName = (this.name || 'ERROR').replace(/[^a-zA-Z0-9]/g, '_');

let pathBase = path.join('components', 'rooibos', 'generated');
this.xmlPkgPath = path.join(pathBase, this.generatedNodeName + '.xml');
this.bsPkgPath = path.join(pathBase, this.generatedNodeName + '.bs');
}

//state
Expand Down
34 changes: 32 additions & 2 deletions bsc-plugin/src/plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ describe('RooibosPlugin', () => {
let plugin: RooibosPlugin;

function setupProgram(options) {
fsExtra.emptyDirSync(tmpPath);
fsExtra.ensureDirSync(_stagingFolderPath);
fsExtra.ensureDirSync(_rootDir);
fsExtra.ensureDirSync(tmpPath);

plugin = new RooibosPlugin();
builder = new ProgramBuilder();
Expand Down Expand Up @@ -1992,6 +1992,37 @@ describe('RooibosPlugin', () => {
});
});

describe('does not prevent component scope validation of node tests', () => {
it('does not prevent valid scope based diagnostics for node tests', () => {
program.setFile('components/customComponent.xml', `
<component name="CustomComponent" extends="Group" />
`);
program.setFile('source/baseTestClass.spec.bs', `
class BaseTestClass extends rooibos.BaseTestSuite
public function customHelperFunction() as boolean
return true
end function
end class
`);
program.setFile('components/test2.spec.bs', `
@suite
@SGNode("CustomComponent")
class ATest2 extends BaseTestClass
@describe("groupA")
@it("test1")
function _()
item = {id: "item"}
m.expectNotCalled(item.getFunction())
m.expectNotCalled(item.getFunction())
end function
end class
`);
program.validate();
let files = [...Object.values(program.files)].map(x => ({ src: x.srcPath, dest: x.pkgPath }));
expect(program.getDiagnostics().map(x => x.message)).to.eql([`Cannot find name 'BaseTestClass'`]);
});
});

describe('addTestRunnerMetadata', () => {
it('does not permanently modify the AST', async () => {
program.setFile('source/test.spec.bs', `
Expand Down Expand Up @@ -2335,4 +2366,3 @@ function getTestSubContents() {
);
return result;
}

31 changes: 23 additions & 8 deletions bsc-plugin/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ import type {
TranspileObj,
AstEditor,
BeforeFileTranspileEvent,
PluginHandler,
ClassStatement,
FunctionStatement,
Statement,
Scope,
BrsFile
XmlFile
} from 'brighterscript';
import {
isBrsFile
Expand All @@ -21,6 +16,7 @@ import { CodeCoverageProcessor } from './lib/rooibos/CodeCoverageProcessor';
import { FileFactory } from './lib/rooibos/FileFactory';
import type { RooibosConfig } from './lib/rooibos/RooibosConfig';
import * as minimatch from 'minimatch';
import * as path from 'path';
import { MockUtil } from './lib/rooibos/MockUtil';
import { getScopeForSuite } from './lib/rooibos/Utils';

Expand Down Expand Up @@ -119,6 +115,15 @@ export class RooibosPlugin implements CompilerPlugin {
this.fileFactory.addFrameworkFiles(program);
}

afterFileDispose(file: BscFile) {
// eslint-disable-next-line @typescript-eslint/dot-notation
const xmlFile = file['rooibosXmlFile'] as XmlFile;
if (xmlFile) {
// Remove the old generated xml files
this._builder.program.removeFile(xmlFile.srcPath);
}
}

afterFileParse(file: BscFile): void {
// console.log('afp', file.pkgPath);
if (file.pathAbsolute.includes('/rooibos/bsc-plugin/dist/framework')) {
Expand All @@ -129,10 +134,20 @@ export class RooibosPlugin implements CompilerPlugin {
if (this.fileFactory.isIgnoredFile(file) || !this.shouldSearchInFileForTests(file)) {
return;
}

// console.log('processing ', file.pkgPath);

if (isBrsFile(file)) {
this.session.processFile(file);
// Add the node test component so brighter script can validate the test files
let suites = this.session.processFile(file);
let nodeSuites = suites.filter((ts) => ts.isNodeTest);
for (const suite of nodeSuites) {
const xmlFile = this._builder.program.setFile({
src: path.resolve(suite.xmlPkgPath),
dest: suite.xmlPkgPath
}, this.session.getNodeTestXmlText(suite));
// eslint-disable-next-line @typescript-eslint/dot-notation
file['rooibosXmlFile'] = xmlFile;
}
}
}

Expand Down

0 comments on commit d81fc64

Please sign in to comment.