Skip to content

Commit

Permalink
Merge pull request #265 from luis-soares-sky/fix/main-scope-issues
Browse files Browse the repository at this point in the history
Allow custom test reporter
  • Loading branch information
TwitchBronBron authored Apr 10, 2024
2 parents 3e36c50 + 4356755 commit 5d7df2c
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 89 deletions.
2 changes: 1 addition & 1 deletion bsc-plugin/src/lib/rooibos/Annotation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,4 @@ export class RooibosAnnotation {

export function getAnnotationType(text: string): AnnotationType {
return annotationLookup[text.toLowerCase()] || AnnotationType.None;
}
}
2 changes: 1 addition & 1 deletion bsc-plugin/src/lib/rooibos/MockUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export class MockUtil {
${globalAaName} = getGlobalAa()
if RBS_SM_${this.fileId}_getMocksByFunctionName()["${methodName}"] <> invalid
${resultName} = RBS_SM_${this.fileId}_getMocksByFunctionName()["${methodName}"].callback(${paramNames})
return${requiresReturnValue ? ` ${resultName}` : '' }
return${requiresReturnValue ? ` ${resultName}` : ''}
else if type(${globalAaName}?.${storageName}?.${methodName}).endsWith("Function")
__stubFunction = ${globalAaName}.${storageName}.${methodName}
${resultName} = __stubFunction(${paramNames})
Expand Down
5 changes: 5 additions & 0 deletions bsc-plugin/src/lib/rooibos/RooibosConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ export interface RooibosConfig {
catchCrashes?: boolean;
throwOnFailedAssertion?: boolean;
sendHomeOnFinish?: boolean;

/**
* @deprecated Use the `reporters` array instead
*/
reporter?: string;
reporters?: string[];
keepAppOpen?: boolean;
testSceneName?: string;

Expand Down
26 changes: 25 additions & 1 deletion bsc-plugin/src/lib/rooibos/RooibosSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export class RooibosSession {
method.func.body.statements.length,
Parser.parse(undent`
return {
"reporter": "${this.config.reporter || ''}"
"reporters": ${this.getReportersList()}
"failFast": ${this.config.failFast ? 'true' : 'false'}
"sendHomeOnFinish": ${this.config.sendHomeOnFinish ? 'true' : 'false'}
"logLevel": ${this.config.logLevel ?? 0}
Expand All @@ -156,6 +156,30 @@ export class RooibosSession {
}
}

getReportersList() {
let reporters = this.config.reporters;
if (!Array.isArray(reporters)) {
reporters = [];
}
if (this.config.reporter) {
// @todo: warn that `reporter` is deprecated and to use `reporters` instead
reporters.push(this.config.reporter);
}
if (reporters.length < 1) {
reporters.push('console');
}
return `[${reporters.map(this.sanitiseReporterName).toString()}]`;
}

sanitiseReporterName(name: string) {
switch (name.toLowerCase()) {
case 'console': return 'rooibos_ConsoleTestReporter';
case 'junit': return 'rooibos_JUnitTestReporter';
}
// @todo: check if function name is valid
return name;
}

updateVersionTextFunction(classStatement: ClassStatement, editor: AstEditor) {
let method = classStatement.methods.find((m) => m.name.text === 'getVersionText');
if (method) {
Expand Down
2 changes: 1 addition & 1 deletion bsc-plugin/src/lib/rooibos/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export function getPathValuePartAsString(expr: Expression) {

export function getScopeForSuite(testSuite: TestSuite) {
if (testSuite.isNodeTest) {
return testSuite.file.program.getScopesForFile(testSuite.file).find((scope)=> {
return testSuite.file.program.getScopesForFile(testSuite.file).find((scope) => {
return isXmlScope(scope) && scope.xmlFile.componentName.text === testSuite.generatedNodeName;
});

Expand Down
167 changes: 110 additions & 57 deletions bsc-plugin/src/plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,13 @@ describe('RooibosPlugin', () => {
let program: Program;
let builder: ProgramBuilder;
let plugin: RooibosPlugin;
let options;
beforeEach(() => {
plugin = new RooibosPlugin();
options = {
rootDir: _rootDir,
stagingFolderPath: _stagingFolderPath,
stagingDir: _stagingFolderPath,
rooibos: {
isGlobalMethodMockingEnabled: true
}
};

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

plugin = new RooibosPlugin();
builder = new ProgramBuilder();
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
builder.options = util.normalizeAndResolveConfig(options);
Expand All @@ -40,13 +32,28 @@ describe('RooibosPlugin', () => {
plugin.beforeProgramCreate(builder);
plugin.fileFactory['options'].frameworkSourcePath = path.resolve(path.join('../framework/src/source'));
plugin.afterProgramCreate(program);
});
}

afterEach(() => {
function destroyProgram() {
fsExtra.ensureDirSync(tmpPath);
fsExtra.emptyDirSync(tmpPath);
builder.dispose();
program.dispose();
}

beforeEach(() => {
setupProgram({
rootDir: _rootDir,
stagingFolderPath: _stagingFolderPath,
stagingDir: _stagingFolderPath,
rooibos: {
isGlobalMethodMockingEnabled: true
}
});
});

afterEach(() => {
destroyProgram();
});

describe('basic tests', () => {
Expand Down Expand Up @@ -594,29 +601,15 @@ describe('RooibosPlugin', () => {


it('adds launch hook with custom scene', async () => {
options = {
setupProgram({
rootDir: _rootDir,
stagingFolderPath: _stagingFolderPath,
stagingDir: _stagingFolderPath,
rooibos: {
testSceneName: 'CustomRooibosScene'
}
};
plugin = new RooibosPlugin();
fsExtra.ensureDirSync(_stagingFolderPath);
fsExtra.ensureDirSync(_rootDir);
fsExtra.ensureDirSync(tmpPath);

builder = new ProgramBuilder();
builder.options = util.normalizeAndResolveConfig(options);
builder.program = new Program(builder.options);
program = builder.program;
program.plugins.add(plugin);
program.createSourceScope(); //ensure source scope is created
plugin.beforeProgramCreate(builder);
plugin.fileFactory['options'].frameworkSourcePath = path.resolve(path.join('../framework/src/source'));
plugin.afterProgramCreate(program);
// program.validate();
});

const file = program.setFile<BrsFile>('source/main.bs', `
sub main()
print "main"
Expand Down Expand Up @@ -1908,34 +1901,14 @@ describe('RooibosPlugin', () => {
`;

beforeEach(() => {
plugin = new RooibosPlugin();
options = {
setupProgram({
rootDir: _rootDir,
stagingFolderPath: _stagingFolderPath
};
fsExtra.ensureDirSync(_stagingFolderPath);
fsExtra.ensureDirSync(_rootDir);
fsExtra.ensureDirSync(tmpPath);

builder = new ProgramBuilder();
builder.options = util.normalizeAndResolveConfig(options);
builder.program = new Program(builder.options);
program = builder.program;
builder.program = new Program(builder.options);
program = builder.program;
program.plugins.add(plugin);
program.createSourceScope(); //ensure source scope is created
plugin.beforeProgramCreate(builder);
plugin.fileFactory['options'].frameworkSourcePath = path.resolve(path.join('../framework/src/source'));
plugin.afterProgramCreate(program);
// program.validate();
});
});

afterEach(() => {
fsExtra.ensureDirSync(tmpPath);
fsExtra.emptyDirSync(tmpPath);
builder.dispose();
program.dispose();
destroyProgram();
});

it('tag one', async () => {
Expand Down Expand Up @@ -2057,9 +2030,9 @@ describe('RooibosPlugin', () => {
expect(findMethod('getIgnoredTestInfo').func.body.statements).to.be.empty;

await builder.transpile();
let testContents = getTestFunctionContents();

expect(
testContents
getTestFunctionContents()
).to.eql(undent`
item = {
id: "item"
Expand All @@ -2078,7 +2051,6 @@ describe('RooibosPlugin', () => {
end if
`);

let a = getContents('rooibos/RuntimeConfig.brs');
expect(
getContents('rooibos/RuntimeConfig.brs')
).to.eql(undent`
Expand All @@ -2091,7 +2063,9 @@ describe('RooibosPlugin', () => {
end function
instance.getRuntimeConfig = function()
return {
"reporter": ""
"reporters": [
rooibos_ConsoleTestReporter
]
"failFast": true
"sendHomeOnFinish": true
"logLevel": 0
Expand Down Expand Up @@ -2143,6 +2117,85 @@ describe('RooibosPlugin', () => {
expect(findMethod('getAllTestSuitesNames').func.body.statements).to.be.empty;
expect(findMethod('getIgnoredTestInfo').func.body.statements).to.be.empty;
});

const sep = '\n ';
const params: [string[], string][] = [
[[], 'rooibos_ConsoleTestReporter'],
[['CONSOLE'], 'rooibos_ConsoleTestReporter'],
[['MyCustomReporter'], 'MyCustomReporter'],
[['JUnit', 'MyCustomReporter'], `rooibos_JUnitTestReporter${sep}MyCustomReporter`]
];
it('adds custom test reporters', async () => {
for (const [reporters, expected] of params) {
setupProgram({
rootDir: _rootDir,
stagingFolderPath: _stagingFolderPath,
stagingDir: _stagingFolderPath,
rooibos: {
reporters: reporters
}
});

program.validate();
expect(program.getDiagnostics()).to.be.empty;

await builder.transpile();

expect(
getContents('rooibos/RuntimeConfig.brs')
).to.eql(undent`
function __rooibos_RuntimeConfig_builder()
instance = {}
instance.new = sub()
end sub
instance.getVersionText = function()
return "${version}"
end function
instance.getRuntimeConfig = function()
return {
"reporters": [
${expected}
]
"failFast": true
"sendHomeOnFinish": true
"logLevel": 0
"showOnlyFailures": true
"printTestTimes": true
"lineWidth": 60
"printLcov": false
"port": "invalid"
"catchCrashes": true
"throwOnFailedAssertion": false
"keepAppOpen": true
"isRecordingCodeCoverage": false
}
end function
instance.getTestSuiteClassWithName = function(name)
if false
? "noop"
end if
end function
instance.getAllTestSuitesNames = function()
return []
end function
instance.getIgnoredTestInfo = function()
return {
"count": 0
"items": []
}
end function
return instance
end function
function rooibos_RuntimeConfig()
instance = __rooibos_RuntimeConfig_builder()
instance.new()
return instance
end function
`);

destroyProgram();
}
});
});

describe.skip('run a local project', () => {
Expand Down
4 changes: 4 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,11 @@ Here is the information converted into a Markdown table:
| isGlobalMethodMockingEnabled | boolean | Default is false. Enables mocking and stubbing support for global and namespace functions |
| isGlobalMethodMockingEfficientMode | boolean | default to true, when set causes rooibos to modify only those functions that were mocked or stubbed |
| globalMethodMockingExcludedFiles | string[] | Files that rooibos will not modify when adding global function or namespace function mocking support |
| reporter? @deprecated <sup>1</sup> | string | The built-in reporter to use. Defaults to empty. Possible values are `console` and `junit`. |
| reporters? <sup>2</sup> | string[] | An array of factory functions/classes which implement `rooibos.BaseTestReporter`. Built-in reporters include `console` and `junit`. Defaults to `["console"]`. |

**<sup>1</sup>** This parameter is deprecated, use `reporters` instead. When specified, the reporter will be appended to the list of `reporters`.
**<sup>2</sup>** Custom reporters are not currently supported on [node-based tests](#testing-nodes), because rooibos does not know which files it should include in the generated test components. This will be addressed in a future Rooibos version (see issue [#266](https://github.com/georgejecook/rooibos/issues/266)).

## Creating test suites
<a name="organize-tests-by-suites-groups-and-cases"></a>
Expand Down
12 changes: 6 additions & 6 deletions framework/src/source/BaseTestReporter.bs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
namespace rooibos
interface ITestReporterOnEndEvent
stats as rooibos.Stats
end interface

class BaseTestReporter

public testRunner = invalid
Expand All @@ -11,15 +15,11 @@ namespace rooibos
m.allStats = runner.stats
end function

function reportResults(allStats as dynamic)
'override me
end function

function testLogInfo(text as string)
function onBegin(ev as dynamic)
'override me
end function

function testLogError(text as string)
function onEnd(ev as rooibos.ITestReporterOnEndEvent)
'override me
end function

Expand Down
12 changes: 2 additions & 10 deletions framework/src/source/ConsoleTestReporter.bs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ namespace rooibos
end if
end function

override function reportResults(allStats)
m.allStats = allStats
override function onEnd(ev as rooibos.ITestReporterOnEndEvent)
m.allStats = ev.stats
m.startReport()
for each testSuite in m.testRunner.testSuites
if not m.allStats.hasFailures or ((not m.config.showOnlyFailures) or testSuite.stats.failedCount > 0 or testSuite.stats.crashedCount > 0)
Expand Down Expand Up @@ -186,14 +186,6 @@ namespace rooibos
'++ printing
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

override function testLogInfo(text)
? "INFO " ; text
end function

override function testLogError(text)
? "ERROR " ; text
end function

function printLine(depth = 0, text = "")
? " " ; text
end function
Expand Down
6 changes: 1 addition & 5 deletions framework/src/source/JUnitTestReporter.bs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
namespace rooibos
class JUnitTestReporter extends rooibos.BaseTestReporter

function new(testRunner as dynamic)
super(testRunner)
end function

override function reportResults(allStats as dynamic)
override function onEnd(ev as rooibos.ITestReporterOnEndEvent)
root = createObject("roXMLElement")
root.SetName("testsuites")
properties = root.addElement("properties")
Expand Down
Loading

0 comments on commit 5d7df2c

Please sign in to comment.