From 3e36c500efcfa9b65f3b1b013ec627d54bc3c6fb Mon Sep 17 00:00:00 2001 From: Christopher Dwyer-Perkins Date: Tue, 26 Mar 2024 17:03:36 -0300 Subject: [PATCH 01/18] Fixed logs sometimes getting cut off at the end of running tests (#279) --- framework/src/source/Rooibos.bs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/framework/src/source/Rooibos.bs b/framework/src/source/Rooibos.bs index 91c08249..2853a4a3 100644 --- a/framework/src/source/Rooibos.bs +++ b/framework/src/source/Rooibos.bs @@ -36,6 +36,9 @@ namespace rooibos ? "keepAppOpen is false; exiting Rooibos" ' End statement will also exit the caller of this function ' leading to an instant exit of the application + + ' Give the io port time to finish sending all the logs + sleep(200) end end if end if @@ -91,4 +94,4 @@ namespace rooibos return 0 end function -end namespace \ No newline at end of file +end namespace From 0c26b3345f2b2828f0e7cc74dc14121916d56b00 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 2 Feb 2024 21:25:05 +0000 Subject: [PATCH 02/18] Refactor test reporter initialisation --- framework/src/source/TestRunner.bs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/framework/src/source/TestRunner.bs b/framework/src/source/TestRunner.bs index 05f183a2..263aa04f 100644 --- a/framework/src/source/TestRunner.bs +++ b/framework/src/source/TestRunner.bs @@ -32,12 +32,7 @@ namespace rooibos m.stats = new rooibos.Stats() m.runtimeConfig = new rooibos.RuntimeConfig() m.config = m.runtimeConfig.getRuntimeConfig() - - if m.config.reporter = "JUnitTestReporter" - m.testReporter = new Rooibos.JUnitTestReporter(m) - else - m.testReporter = new Rooibos.ConsoleTestReporter(m) - end if + m.testReporter = m.getTestReporter() end function ' /** @@ -307,6 +302,13 @@ namespace rooibos ut.PostFromString("") end function + private function getTestReporter() + if m.config.reporter = "JUnitTestReporter" + return new Rooibos.JUnitTestReporter(m) + end if + return new Rooibos.ConsoleTestReporter(m) + end function + end class '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ From 56f26e4d82c589c37e7c67802dfb100ee151264e Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 2 Feb 2024 21:27:47 +0000 Subject: [PATCH 03/18] "Fix" lint error --- framework/src/source/JUnitTestReporter.bs | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/source/JUnitTestReporter.bs b/framework/src/source/JUnitTestReporter.bs index d7320c34..16a781f4 100644 --- a/framework/src/source/JUnitTestReporter.bs +++ b/framework/src/source/JUnitTestReporter.bs @@ -2,6 +2,7 @@ namespace rooibos class JUnitTestReporter extends rooibos.BaseTestReporter function new(testRunner as dynamic) + 'bs:disable-next-line super(testRunner) end function From be5ca4122a007c8bc1fb4f13ba73cb01461b60a3 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 2 Feb 2024 21:38:30 +0000 Subject: [PATCH 04/18] Add new field "reporterClass" and logic to allow custom classes --- bsc-plugin/src/lib/rooibos/RooibosConfig.ts | 1 + bsc-plugin/src/lib/rooibos/RooibosSession.ts | 1 + bsc-plugin/src/plugin.spec.ts | 1 + framework/src/source/TestRunner.bs | 9 ++++++--- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/bsc-plugin/src/lib/rooibos/RooibosConfig.ts b/bsc-plugin/src/lib/rooibos/RooibosConfig.ts index 6d5cd16b..43645e4f 100644 --- a/bsc-plugin/src/lib/rooibos/RooibosConfig.ts +++ b/bsc-plugin/src/lib/rooibos/RooibosConfig.ts @@ -25,6 +25,7 @@ export interface RooibosConfig { throwOnFailedAssertion?: boolean; sendHomeOnFinish?: boolean; reporter?: string; + reporterClass?: string; keepAppOpen?: boolean; testSceneName?: string; diff --git a/bsc-plugin/src/lib/rooibos/RooibosSession.ts b/bsc-plugin/src/lib/rooibos/RooibosSession.ts index bbbac930..30740711 100644 --- a/bsc-plugin/src/lib/rooibos/RooibosSession.ts +++ b/bsc-plugin/src/lib/rooibos/RooibosSession.ts @@ -138,6 +138,7 @@ export class RooibosSession { Parser.parse(undent` return { "reporter": "${this.config.reporter || ''}" + "reporterClass": ${this.config.reporterClass || 'invalid'} "failFast": ${this.config.failFast ? 'true' : 'false'} "sendHomeOnFinish": ${this.config.sendHomeOnFinish ? 'true' : 'false'} "logLevel": ${this.config.logLevel ?? 0} diff --git a/bsc-plugin/src/plugin.spec.ts b/bsc-plugin/src/plugin.spec.ts index c4d66044..2d99d9dc 100644 --- a/bsc-plugin/src/plugin.spec.ts +++ b/bsc-plugin/src/plugin.spec.ts @@ -2092,6 +2092,7 @@ describe('RooibosPlugin', () => { instance.getRuntimeConfig = function() return { "reporter": "" + "reporterClass": invalid "failFast": true "sendHomeOnFinish": true "logLevel": 0 diff --git a/framework/src/source/TestRunner.bs b/framework/src/source/TestRunner.bs index 263aa04f..c8ca5a18 100644 --- a/framework/src/source/TestRunner.bs +++ b/framework/src/source/TestRunner.bs @@ -303,9 +303,12 @@ namespace rooibos end function private function getTestReporter() - if m.config.reporter = "JUnitTestReporter" - return new Rooibos.JUnitTestReporter(m) - end if + if rooibos.common.isFunction(m.config.reporterClass) + return m.config.reporterClass(m) + end if + if m.config.reporter = "JUnitTestReporter" + return new Rooibos.JUnitTestReporter(m) + end if return new Rooibos.ConsoleTestReporter(m) end function From 37c9a5177452253932ebda298cbeb555fd64bac4 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Mon, 5 Feb 2024 15:47:44 +0000 Subject: [PATCH 05/18] Add reporterClass info to docs --- docs/index.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/index.md b/docs/index.md index 720df32d..4196d3b1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -172,7 +172,10 @@ 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? | string | The built-in reporter to use. Defaults to empty. Possible values are "" and "JUnitTestReporter". | +| reporterClass? 1 | string | The full name (namespace included) of a custom class that extends from `rooibos.BaseTestReporter`, to use as the test reporter. Defaults to empty. | +**1** `reporterClass` is currently not 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](#266)). ## Creating test suites From 8fe6a0fde25b9e3c48962bd33612453ccc81a7bf Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Mon, 5 Feb 2024 15:49:09 +0000 Subject: [PATCH 06/18] Tweak issue link in docs --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 4196d3b1..53ff57d4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -175,7 +175,7 @@ Here is the information converted into a Markdown table: | reporter? | string | The built-in reporter to use. Defaults to empty. Possible values are "" and "JUnitTestReporter". | | reporterClass? 1 | string | The full name (namespace included) of a custom class that extends from `rooibos.BaseTestReporter`, to use as the test reporter. Defaults to empty. | -**1** `reporterClass` is currently not 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](#266)). +**1** `reporterClass` is currently not 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 From 0bc3ec4c074321a8aafd4e74e72328e0c3cf1a92 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Sat, 10 Feb 2024 10:59:38 +0000 Subject: [PATCH 07/18] Fix lint errors post rebase --- bsc-plugin/src/lib/rooibos/Annotation.ts | 2 +- bsc-plugin/src/lib/rooibos/MockUtil.ts | 2 +- bsc-plugin/src/lib/rooibos/Utils.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bsc-plugin/src/lib/rooibos/Annotation.ts b/bsc-plugin/src/lib/rooibos/Annotation.ts index 23c9d831..dfd3821e 100644 --- a/bsc-plugin/src/lib/rooibos/Annotation.ts +++ b/bsc-plugin/src/lib/rooibos/Annotation.ts @@ -219,4 +219,4 @@ export class RooibosAnnotation { export function getAnnotationType(text: string): AnnotationType { return annotationLookup[text.toLowerCase()] || AnnotationType.None; -} \ No newline at end of file +} diff --git a/bsc-plugin/src/lib/rooibos/MockUtil.ts b/bsc-plugin/src/lib/rooibos/MockUtil.ts index fa66034a..1462d6c3 100644 --- a/bsc-plugin/src/lib/rooibos/MockUtil.ts +++ b/bsc-plugin/src/lib/rooibos/MockUtil.ts @@ -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}) diff --git a/bsc-plugin/src/lib/rooibos/Utils.ts b/bsc-plugin/src/lib/rooibos/Utils.ts index 39bd00a8..7b3d788e 100644 --- a/bsc-plugin/src/lib/rooibos/Utils.ts +++ b/bsc-plugin/src/lib/rooibos/Utils.ts @@ -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; }); From 599e6ce0e02bd16f5ca6bc06ab16bb2a7ec8d1e2 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Sat, 10 Feb 2024 18:13:26 +0000 Subject: [PATCH 08/18] Adjust implementation to fit with new proposal --- bsc-plugin/src/lib/rooibos/RooibosConfig.ts | 6 +- bsc-plugin/src/lib/rooibos/RooibosSession.ts | 27 ++- bsc-plugin/src/plugin.spec.ts | 167 ++++++++++++------- framework/src/source/TestRunner.bs | 26 +-- 4 files changed, 155 insertions(+), 71 deletions(-) diff --git a/bsc-plugin/src/lib/rooibos/RooibosConfig.ts b/bsc-plugin/src/lib/rooibos/RooibosConfig.ts index 43645e4f..af5cdc68 100644 --- a/bsc-plugin/src/lib/rooibos/RooibosConfig.ts +++ b/bsc-plugin/src/lib/rooibos/RooibosConfig.ts @@ -24,8 +24,12 @@ export interface RooibosConfig { catchCrashes?: boolean; throwOnFailedAssertion?: boolean; sendHomeOnFinish?: boolean; + + /** + * @deprecated Use the `reporters` array instead + */ reporter?: string; - reporterClass?: string; + reporters?: string[]; keepAppOpen?: boolean; testSceneName?: string; diff --git a/bsc-plugin/src/lib/rooibos/RooibosSession.ts b/bsc-plugin/src/lib/rooibos/RooibosSession.ts index 30740711..adb0d389 100644 --- a/bsc-plugin/src/lib/rooibos/RooibosSession.ts +++ b/bsc-plugin/src/lib/rooibos/RooibosSession.ts @@ -137,8 +137,7 @@ export class RooibosSession { method.func.body.statements.length, Parser.parse(undent` return { - "reporter": "${this.config.reporter || ''}" - "reporterClass": ${this.config.reporterClass || 'invalid'} + "reporters": ${this.getReportersList()} "failFast": ${this.config.failFast ? 'true' : 'false'} "sendHomeOnFinish": ${this.config.sendHomeOnFinish ? 'true' : 'false'} "logLevel": ${this.config.logLevel ?? 0} @@ -157,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) { diff --git a/bsc-plugin/src/plugin.spec.ts b/bsc-plugin/src/plugin.spec.ts index 2d99d9dc..01d887b9 100644 --- a/bsc-plugin/src/plugin.spec.ts +++ b/bsc-plugin/src/plugin.spec.ts @@ -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); @@ -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', () => { @@ -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('source/main.bs', ` sub main() print "main" @@ -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 () => { @@ -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" @@ -2078,7 +2051,6 @@ describe('RooibosPlugin', () => { end if `); - let a = getContents('rooibos/RuntimeConfig.brs'); expect( getContents('rooibos/RuntimeConfig.brs') ).to.eql(undent` @@ -2091,8 +2063,9 @@ describe('RooibosPlugin', () => { end function instance.getRuntimeConfig = function() return { - "reporter": "" - "reporterClass": invalid + "reporters": [ + rooibos_ConsoleTestReporter + ] "failFast": true "sendHomeOnFinish": true "logLevel": 0 @@ -2144,6 +2117,84 @@ 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 + } + 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', () => { diff --git a/framework/src/source/TestRunner.bs b/framework/src/source/TestRunner.bs index c8ca5a18..e0a8218a 100644 --- a/framework/src/source/TestRunner.bs +++ b/framework/src/source/TestRunner.bs @@ -11,7 +11,7 @@ namespace rooibos ' */ class TestRunner public testScene = invalid - public testReporter = invalid + public testReporters = [] public nodeContext = invalid public config = invalid public testSuites = [] @@ -32,7 +32,8 @@ namespace rooibos m.stats = new rooibos.Stats() m.runtimeConfig = new rooibos.RuntimeConfig() m.config = m.runtimeConfig.getRuntimeConfig() - m.testReporter = m.getTestReporter() + + m.testReporters = m.getTestReporters() end function ' /** @@ -98,7 +99,9 @@ namespace rooibos m.stats.time = rooibosTimer.totalMilliseconds() - m.testReporter.reportResults(m.stats) + for each reporter in m.testReporters + reporter.reportResults(m.stats) + end for rooibosResult = { stats: m.stats @@ -302,14 +305,17 @@ namespace rooibos ut.PostFromString("") end function - private function getTestReporter() - if rooibos.common.isFunction(m.config.reporterClass) - return m.config.reporterClass(m) - end if - if m.config.reporter = "JUnitTestReporter" - return new Rooibos.JUnitTestReporter(m) + private function getTestReporters() + reporters = [] + for each factory in m.config.reporters + if rooibos.common.isFunction(factory) + reporters.push(factory(m)) + end if + end for + if reporters.isEmpty() + reporters.push(new rooibos.ConsoleTestReporter(m)) end if - return new Rooibos.ConsoleTestReporter(m) + return reporters end function end class From 7ed33434c1be3f415560da2fe8e4cd35828d1fa7 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Sat, 10 Feb 2024 18:25:49 +0000 Subject: [PATCH 09/18] Tweak documentation --- docs/index.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/index.md b/docs/index.md index 53ff57d4..f158c89b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -172,10 +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? | string | The built-in reporter to use. Defaults to empty. Possible values are "" and "JUnitTestReporter". | -| reporterClass? 1 | string | The full name (namespace included) of a custom class that extends from `rooibos.BaseTestReporter`, to use as the test reporter. Defaults to empty. | +| reporter? @deprecated 1 | string | The built-in reporter to use. Defaults to empty. Possible values are `console` and `junit`. | +| reporters? 2 | string[] | An array of factory functions/classes which implement `rooibos.BaseTestReporter`. Built-in reporters include `console` and `junit`. Defaults to `["console"]`. | -**1** `reporterClass` is currently not 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)). +**1** This parameter is deprecated, use `reporters` instead. When specified, the reporter will be appended to the list of `reporters`. +**2** 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 From 54aa936382786b35823406b7d14e9d7a47f8f227 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 14 Feb 2024 15:12:13 +0000 Subject: [PATCH 10/18] Switch reporter API to conform to new spec proposal, add `onBegin` and `onEnd` --- framework/src/source/BaseTestReporter.bs | 8 ++------ framework/src/source/ConsoleTestReporter.bs | 10 +--------- framework/src/source/JUnitTestReporter.bs | 2 +- framework/src/source/TestRunner.bs | 6 +++++- 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/framework/src/source/BaseTestReporter.bs b/framework/src/source/BaseTestReporter.bs index 2f114272..390ef882 100644 --- a/framework/src/source/BaseTestReporter.bs +++ b/framework/src/source/BaseTestReporter.bs @@ -11,15 +11,11 @@ namespace rooibos m.allStats = runner.stats end function - function reportResults(allStats as dynamic) + function onBegin() 'override me end function - function testLogInfo(text as string) - 'override me - end function - - function testLogError(text as string) + function onEnd(allStats as dynamic) 'override me end function diff --git a/framework/src/source/ConsoleTestReporter.bs b/framework/src/source/ConsoleTestReporter.bs index d0e609f4..0f448959 100644 --- a/framework/src/source/ConsoleTestReporter.bs +++ b/framework/src/source/ConsoleTestReporter.bs @@ -13,7 +13,7 @@ namespace rooibos end if end function - override function reportResults(allStats) + override function onEnd(allStats) m.allStats = allStats m.startReport() for each testSuite in m.testRunner.testSuites @@ -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 diff --git a/framework/src/source/JUnitTestReporter.bs b/framework/src/source/JUnitTestReporter.bs index 16a781f4..ace166f6 100644 --- a/framework/src/source/JUnitTestReporter.bs +++ b/framework/src/source/JUnitTestReporter.bs @@ -6,7 +6,7 @@ namespace rooibos super(testRunner) end function - override function reportResults(allStats as dynamic) + override function onEnd(allStats as dynamic) root = createObject("roXMLElement") root.SetName("testsuites") properties = root.addElement("properties") diff --git a/framework/src/source/TestRunner.bs b/framework/src/source/TestRunner.bs index e0a8218a..deef3b55 100644 --- a/framework/src/source/TestRunner.bs +++ b/framework/src/source/TestRunner.bs @@ -45,6 +45,10 @@ namespace rooibos ' */ public function run() + for each reporter in m.testReporters + reporter.onBegin() + end for + rooibosTimer = createObject("roTimespan") rooibosTimer.mark() suiteNames = m.runtimeConfig.getAllTestSuitesNames() @@ -100,7 +104,7 @@ namespace rooibos m.stats.time = rooibosTimer.totalMilliseconds() for each reporter in m.testReporters - reporter.reportResults(m.stats) + reporter.onEnd(m.stats) end for rooibosResult = { From 9fec48b11044ef7afc4a83a1f184642af5da09b8 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 14 Feb 2024 15:18:53 +0000 Subject: [PATCH 11/18] Fix failing test post rebase --- bsc-plugin/src/plugin.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/bsc-plugin/src/plugin.spec.ts b/bsc-plugin/src/plugin.spec.ts index 01d887b9..3ff66c93 100644 --- a/bsc-plugin/src/plugin.spec.ts +++ b/bsc-plugin/src/plugin.spec.ts @@ -2167,6 +2167,7 @@ describe('RooibosPlugin', () => { "catchCrashes": true "throwOnFailedAssertion": false "keepAppOpen": true + "isRecordingCodeCoverage": false } end function instance.getTestSuiteClassWithName = function(name) From bb476a6543409cf793c207865e6f43d03c58907c Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 14 Feb 2024 15:22:46 +0000 Subject: [PATCH 12/18] Removed redundant constructor --- framework/src/source/JUnitTestReporter.bs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/framework/src/source/JUnitTestReporter.bs b/framework/src/source/JUnitTestReporter.bs index ace166f6..0229e248 100644 --- a/framework/src/source/JUnitTestReporter.bs +++ b/framework/src/source/JUnitTestReporter.bs @@ -1,11 +1,6 @@ namespace rooibos class JUnitTestReporter extends rooibos.BaseTestReporter - function new(testRunner as dynamic) - 'bs:disable-next-line - super(testRunner) - end function - override function onEnd(allStats as dynamic) root = createObject("roXMLElement") root.SetName("testsuites") From 8f522dd2b9f67013b17f083585d8cf7c42e35547 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 27 Feb 2024 17:28:31 +0000 Subject: [PATCH 13/18] Add guards to reflect methods being optional --- framework/src/source/TestRunner.bs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/framework/src/source/TestRunner.bs b/framework/src/source/TestRunner.bs index deef3b55..c49b83b8 100644 --- a/framework/src/source/TestRunner.bs +++ b/framework/src/source/TestRunner.bs @@ -46,7 +46,9 @@ namespace rooibos public function run() for each reporter in m.testReporters - reporter.onBegin() + if rooibos.common.isFunction(reporter.onBegin) + reporter.onBegin() + end if end for rooibosTimer = createObject("roTimespan") @@ -104,7 +106,9 @@ namespace rooibos m.stats.time = rooibosTimer.totalMilliseconds() for each reporter in m.testReporters - reporter.onEnd(m.stats) + if rooibos.common.isFunction(reporter.onEnd) + reporter.onEnd(m.stats) + end if end for rooibosResult = { From c2f0b2fb1ec0e5ebc1dcb164802542636f78499f Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 27 Feb 2024 17:29:37 +0000 Subject: [PATCH 14/18] Tweak reporter method signature to accept event AA --- framework/src/source/BaseTestReporter.bs | 8 ++++++-- framework/src/source/ConsoleTestReporter.bs | 4 ++-- framework/src/source/JUnitTestReporter.bs | 2 +- framework/src/source/TestRunner.bs | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/framework/src/source/BaseTestReporter.bs b/framework/src/source/BaseTestReporter.bs index 390ef882..e7fda9dd 100644 --- a/framework/src/source/BaseTestReporter.bs +++ b/framework/src/source/BaseTestReporter.bs @@ -1,4 +1,8 @@ namespace rooibos + interface TestReporterOnEndEvent + stats as rooibos.Stats + end interface + class BaseTestReporter public testRunner = invalid @@ -11,11 +15,11 @@ namespace rooibos m.allStats = runner.stats end function - function onBegin() + function onBegin(ev as dynamic) 'override me end function - function onEnd(allStats as dynamic) + function onEnd(ev as rooibos.TestReporterOnEndEvent) 'override me end function diff --git a/framework/src/source/ConsoleTestReporter.bs b/framework/src/source/ConsoleTestReporter.bs index 0f448959..2e0a7bde 100644 --- a/framework/src/source/ConsoleTestReporter.bs +++ b/framework/src/source/ConsoleTestReporter.bs @@ -13,8 +13,8 @@ namespace rooibos end if end function - override function onEnd(allStats) - m.allStats = allStats + override function onEnd(ev as rooibos.TestReporterOnEndEvent) + 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) diff --git a/framework/src/source/JUnitTestReporter.bs b/framework/src/source/JUnitTestReporter.bs index 0229e248..eacaff7e 100644 --- a/framework/src/source/JUnitTestReporter.bs +++ b/framework/src/source/JUnitTestReporter.bs @@ -1,7 +1,7 @@ namespace rooibos class JUnitTestReporter extends rooibos.BaseTestReporter - override function onEnd(allStats as dynamic) + override function onEnd(ev as rooibos.TestReporterOnEndEvent) root = createObject("roXMLElement") root.SetName("testsuites") properties = root.addElement("properties") diff --git a/framework/src/source/TestRunner.bs b/framework/src/source/TestRunner.bs index c49b83b8..e216b0d0 100644 --- a/framework/src/source/TestRunner.bs +++ b/framework/src/source/TestRunner.bs @@ -47,7 +47,7 @@ namespace rooibos for each reporter in m.testReporters if rooibos.common.isFunction(reporter.onBegin) - reporter.onBegin() + reporter.onBegin({}) end if end for @@ -107,7 +107,7 @@ namespace rooibos for each reporter in m.testReporters if rooibos.common.isFunction(reporter.onEnd) - reporter.onEnd(m.stats) + reporter.onEnd({ stats: m.stats }) end if end for From 435675533c5842ca4b36ee9de1db38bd506f1c37 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 27 Feb 2024 17:36:05 +0000 Subject: [PATCH 15/18] Tweak interface name --- framework/src/source/BaseTestReporter.bs | 4 ++-- framework/src/source/ConsoleTestReporter.bs | 2 +- framework/src/source/JUnitTestReporter.bs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/framework/src/source/BaseTestReporter.bs b/framework/src/source/BaseTestReporter.bs index e7fda9dd..15db20ef 100644 --- a/framework/src/source/BaseTestReporter.bs +++ b/framework/src/source/BaseTestReporter.bs @@ -1,5 +1,5 @@ namespace rooibos - interface TestReporterOnEndEvent + interface ITestReporterOnEndEvent stats as rooibos.Stats end interface @@ -19,7 +19,7 @@ namespace rooibos 'override me end function - function onEnd(ev as rooibos.TestReporterOnEndEvent) + function onEnd(ev as rooibos.ITestReporterOnEndEvent) 'override me end function diff --git a/framework/src/source/ConsoleTestReporter.bs b/framework/src/source/ConsoleTestReporter.bs index 2e0a7bde..d33abb0c 100644 --- a/framework/src/source/ConsoleTestReporter.bs +++ b/framework/src/source/ConsoleTestReporter.bs @@ -13,7 +13,7 @@ namespace rooibos end if end function - override function onEnd(ev as rooibos.TestReporterOnEndEvent) + override function onEnd(ev as rooibos.ITestReporterOnEndEvent) m.allStats = ev.stats m.startReport() for each testSuite in m.testRunner.testSuites diff --git a/framework/src/source/JUnitTestReporter.bs b/framework/src/source/JUnitTestReporter.bs index eacaff7e..4fe3346a 100644 --- a/framework/src/source/JUnitTestReporter.bs +++ b/framework/src/source/JUnitTestReporter.bs @@ -1,7 +1,7 @@ namespace rooibos class JUnitTestReporter extends rooibos.BaseTestReporter - override function onEnd(ev as rooibos.TestReporterOnEndEvent) + override function onEnd(ev as rooibos.ITestReporterOnEndEvent) root = createObject("roXMLElement") root.SetName("testsuites") properties = root.addElement("properties") From 21a0cc0a4edd59f471b117e3a97611f93dffb180 Mon Sep 17 00:00:00 2001 From: Christopher Dwyer-Perkins Date: Tue, 11 Jun 2024 10:47:40 -0300 Subject: [PATCH 16/18] Updated to node 16.20.2 --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8346eb20..7d542c8d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@master - uses: actions/setup-node@master with: - node-version: "14.18.1" + node-version: "16.20.2" # - run: npm run build - run: cd bsc-plugin && npm install - run: cd bsc-plugin && npm run preversion @@ -31,7 +31,7 @@ jobs: - uses: actions/checkout@master - uses: actions/setup-node@master with: - node-version: "10.19.0" + node-version: "16.20.2" - run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ./.npmrc - run: npm ci - run: npm run build From 9b045684f0e57a13b3e6e90ec4185dd3294301d6 Mon Sep 17 00:00:00 2001 From: George Cook Date: Sat, 15 Jun 2024 17:44:18 +0100 Subject: [PATCH 17/18] addresses regression that prevents stubCall allowing non-function return values (#283) --- bsc-plugin/src/lib/rooibos/MockUtil.spec.ts | 27 +++++++++ bsc-plugin/src/lib/rooibos/MockUtil.ts | 3 + bsc-plugin/src/plugin.spec.ts | 6 ++ bsconfig-prod.json | 14 +++++ framework/src/source/BaseTestSuite.bs | 2 +- tests/.vscode/launch.json | 4 +- tests/bsconfig.json | 2 +- tests/package-lock.json | 34 ++++++++++++ tests/src/source/Charlies-Issues.spec.bs | 61 +++++++++++++++++++++ tests/src/source/SomeModel.brs | 34 ++++++++++++ 10 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 bsconfig-prod.json create mode 100644 tests/src/source/Charlies-Issues.spec.bs create mode 100644 tests/src/source/SomeModel.brs diff --git a/bsc-plugin/src/lib/rooibos/MockUtil.spec.ts b/bsc-plugin/src/lib/rooibos/MockUtil.spec.ts index 8f963933..13ae670a 100644 --- a/bsc-plugin/src/lib/rooibos/MockUtil.spec.ts +++ b/bsc-plugin/src/lib/rooibos/MockUtil.spec.ts @@ -85,6 +85,9 @@ describe('MockUtil', () => { __stubFunction = __stubs_globalAa.__globalStubs.sayhello __stubOrMockResult = __stubFunction(a1, a2) return __stubOrMockResult + else if __stubs_globalAa?.__globalStubs <> invalid and __stubs_globalAa.__globalStubs.doesExist("sayhello") + value = __stubs_globalAa.__globalStubs.sayhello + return value end if print "hello" end function @@ -122,6 +125,9 @@ describe('MockUtil', () => { __stubFunction = __stubs_globalAa.__globalStubs.sayhello __stubOrMockResult = __stubFunction(a1, a2) return __stubOrMockResult + else if __stubs_globalAa?.__globalStubs <> invalid and __stubs_globalAa.__globalStubs.doesExist("sayhello") + value = __stubs_globalAa.__globalStubs.sayhello + return value end if print "hello" end function @@ -162,6 +168,9 @@ describe('MockUtil', () => { __stubFunction = __stubs_globalAa.__globalStubs.redlines_setrulerlines __stubOrMockResult = __stubFunction(rulerLines) return + else if __stubs_globalAa?.__globalStubs <> invalid and __stubs_globalAa.__globalStubs.doesExist("redlines_setrulerlines") + value = __stubs_globalAa.__globalStubs.redlines_setrulerlines + return end if For Each line In rulerLines.Items() RedLines_AddLine(line.key, line.value.position, line.value.coords, m.node, m.childMap) @@ -177,6 +186,9 @@ describe('MockUtil', () => { __stubFunction = __stubs_globalAa.__globalStubs.redlines_addline __stubOrMockResult = __stubFunction(id, position, coords, node, childMap) return __stubOrMockResult + else if __stubs_globalAa?.__globalStubs <> invalid and __stubs_globalAa.__globalStubs.doesExist("redlines_addline") + value = __stubs_globalAa.__globalStubs.redlines_addline + return value end if line = CreateObject("roSGNode", "Rectangle") line.setField("id", id) @@ -213,6 +225,9 @@ describe('MockUtil', () => { __stubFunction = __stubs_globalAa.__globalStubs.sayhello __stubOrMockResult = __stubFunction(a1, a2) return + else if __stubs_globalAa?.__globalStubs <> invalid and __stubs_globalAa.__globalStubs.doesExist("sayhello") + value = __stubs_globalAa.__globalStubs.sayhello + return end if print "hello" end sub @@ -250,6 +265,9 @@ describe('MockUtil', () => { __stubFunction = __stubs_globalAa.__globalStubs.person_utils_sayhello __stubOrMockResult = __stubFunction(a1, a2) return __stubOrMockResult + else if __stubs_globalAa?.__globalStubs <> invalid and __stubs_globalAa.__globalStubs.doesExist("person_utils_sayhello") + value = __stubs_globalAa.__globalStubs.person_utils_sayhello + return value end if print "hello" end function @@ -287,6 +305,9 @@ describe('MockUtil', () => { __stubFunction = __stubs_globalAa.__globalStubs.person_utils_sayhello __stubOrMockResult = __stubFunction(a1, a2) return + else if __stubs_globalAa?.__globalStubs <> invalid and __stubs_globalAa.__globalStubs.doesExist("person_utils_sayhello") + value = __stubs_globalAa.__globalStubs.person_utils_sayhello + return end if print "hello" end sub @@ -378,6 +399,9 @@ describe('MockUtil', () => { __stubFunction = __stubs_globalAa.__globalStubs.beings_sayhello __stubOrMockResult = __stubFunction() return __stubOrMockResult + else if __stubs_globalAa?.__globalStubs <> invalid and __stubs_globalAa.__globalStubs.doesExist("beings_sayhello") + value = __stubs_globalAa.__globalStubs.beings_sayhello + return value end if print "hello2" end function @@ -391,6 +415,9 @@ describe('MockUtil', () => { __stubFunction = __stubs_globalAa.__globalStubs.sayhello __stubOrMockResult = __stubFunction() return __stubOrMockResult + else if __stubs_globalAa?.__globalStubs <> invalid and __stubs_globalAa.__globalStubs.doesExist("sayhello") + value = __stubs_globalAa.__globalStubs.sayhello + return value end if print "hello3" end function diff --git a/bsc-plugin/src/lib/rooibos/MockUtil.ts b/bsc-plugin/src/lib/rooibos/MockUtil.ts index 1462d6c3..525251b7 100644 --- a/bsc-plugin/src/lib/rooibos/MockUtil.ts +++ b/bsc-plugin/src/lib/rooibos/MockUtil.ts @@ -112,6 +112,9 @@ export class MockUtil { __stubFunction = ${globalAaName}.${storageName}.${methodName} ${resultName} = __stubFunction(${paramNames}) return${requiresReturnValue ? ` ${resultName}` : ''} + else if ${globalAaName}?.${storageName} <> invalid and ${globalAaName}.${storageName}.doesExist("${methodName}") + value = ${globalAaName}.${storageName}.${methodName} + return${requiresReturnValue ? ` value` : ''} end if `; const astCodeToInject = Parser.parse(template).ast.statements; diff --git a/bsc-plugin/src/plugin.spec.ts b/bsc-plugin/src/plugin.spec.ts index 3ff66c93..bb0267c1 100644 --- a/bsc-plugin/src/plugin.spec.ts +++ b/bsc-plugin/src/plugin.spec.ts @@ -1063,6 +1063,9 @@ describe('RooibosPlugin', () => { __stubFunction = __stubs_globalAa.__globalStubs.sayhello __stubOrMockResult = __stubFunction(firstName, lastName) return __stubOrMockResult + else if __stubs_globalAa?.__globalStubs <> invalid and __stubs_globalAa.__globalStubs.doesExist("sayhello") + value = __stubs_globalAa.__globalStubs.sayhello + return value end if print firstName + " " + lastName end function @@ -1151,6 +1154,9 @@ describe('RooibosPlugin', () => { __stubFunction = __stubs_globalAa.__globalStubs.utils_sayhello __stubOrMockResult = __stubFunction(firstName, lastName) return __stubOrMockResult + else if __stubs_globalAa?.__globalStubs <> invalid and __stubs_globalAa.__globalStubs.doesExist("utils_sayhello") + value = __stubs_globalAa.__globalStubs.utils_sayhello + return value end if print firstName + " " + lastName end function diff --git a/bsconfig-prod.json b/bsconfig-prod.json new file mode 100644 index 00000000..2a748abc --- /dev/null +++ b/bsconfig-prod.json @@ -0,0 +1,14 @@ +{ + "rootDir": "framework/src", + "files": ["manifest", "source/**/*.*", "components/**/*.*"], + "autoImportComponentScript": true, + "createPackage": false, + "stagingFolderPath": "dist", + "diagnosticFilters": [ + { + "src": "**/roku_modules/**/*.*", + "codes": [1107, 1009] + } + ], + "plugins": ["@rokucommunity/bslint"] +} diff --git a/framework/src/source/BaseTestSuite.bs b/framework/src/source/BaseTestSuite.bs index 5a031091..fe73329d 100644 --- a/framework/src/source/BaseTestSuite.bs +++ b/framework/src/source/BaseTestSuite.bs @@ -1833,7 +1833,7 @@ namespace rooibos end if if not type(stubOrReturnValue).endsWith("Function") - throw "Did not provide a stub function" + ' throw "Did not provide a stub function" end if ' Store the stub on the component scope diff --git a/tests/.vscode/launch.json b/tests/.vscode/launch.json index 728cb81a..26f48708 100644 --- a/tests/.vscode/launch.json +++ b/tests/.vscode/launch.json @@ -30,7 +30,7 @@ "stopDebuggerOnAppExit": true, "enableVariablesPanel": false, "injectRaleTrackerTask": false, - "enableDebugProtocol": false + "enableDebugProtocol": true }, { "name": "watch tests", @@ -61,7 +61,7 @@ "stopDebuggerOnAppExit": true, "enableVariablesPanel": false, "injectRaleTrackerTask": false, - "enableDebugProtocol": false + "enableDebugProtocol": true, } ] } diff --git a/tests/bsconfig.json b/tests/bsconfig.json index 08ba2e32..891684c7 100644 --- a/tests/bsconfig.json +++ b/tests/bsconfig.json @@ -27,7 +27,7 @@ ], "rooibos": { "showOnlyFailures": true, - "catchCrashes": true, + "catchCrashes": false, "lineWidth": 70, "failFast": false, "sendHomeOnFinish": false, diff --git a/tests/package-lock.json b/tests/package-lock.json index 7eff43d1..b8765bdc 100644 --- a/tests/package-lock.json +++ b/tests/package-lock.json @@ -166,6 +166,16 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, + "node_modules/@types/node": { + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "dev": true, + "peer": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@xml-tools/parser": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@xml-tools/parser/-/parser-1.0.11.tgz", @@ -1658,6 +1668,13 @@ "node": ">=4.2.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "peer": true + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -2022,6 +2039,16 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, + "@types/node": { + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "dev": true, + "peer": true, + "requires": { + "undici-types": "~5.26.4" + } + }, "@xml-tools/parser": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@xml-tools/parser/-/parser-1.0.11.tgz", @@ -3183,6 +3210,13 @@ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "peer": true + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", diff --git a/tests/src/source/Charlies-Issues.spec.bs b/tests/src/source/Charlies-Issues.spec.bs new file mode 100644 index 00000000..889f2913 --- /dev/null +++ b/tests/src/source/Charlies-Issues.spec.bs @@ -0,0 +1,61 @@ +namespace tests + @suite + class MockExample extends rooibos.BaseTestSuite + + protected override function setUp() + super.setUp() + end function + + protected override function beforeEach() + m.SUT = SomeModel() + end function + + protected override function afterEach() + m.cleanMocks() + m.cleanStubs() + m.SUT = invalid + end function + + '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @describe("Example Tests on SomeModel public methods") + '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + @it("globalMockExample1_passing") + function _() + m.stubCall(getManifestValue, function(key) : return "stubCall hardcoded title" : end function) + m.SUT.globalMockExample() + m.assertEqual(m.SUT.appTitle, "stubCall hardcoded title") + end function + + @it("globalMockExample2_crashing_due_to_returnValue") + @params("stubCall dynamic title") + function _(manifestValue as string) + m.stubCall(getManifestValue, manifestValue) + m.SUT.globalMockExample() + m.assertEqual(m.SUT.appTitle, manifestValue) + end function + + @it("stubExample1_passing") + @params({ configSetVia_config: true }, { configSetViaStub: true }) + function _(config1 as object, config2 as object) + m.SUT._config = config1 + m.stub(m.SUT, "_getConfig", config2) + m.SUT.setUpdatedConfig1() + expectedKeyNameConfig2 = config2.keys()[0] + resultKeyName = m.SUT.updatedConfig.keys()[0] + m.assertEqual(expectedKeyNameConfig2, resultKeyName) + end function + + @ignore("this is not supported - we do not support mocking singleton objects between test runs") + @it("stubExample2_crashing_stub_from_stubExample1_persisting") + @params({ configSetVia_config: true }, { configSetViaStub: true }) + function _(config1 as object, config2 as object) + m.SUT._config = config1 + m.SUT.setUpdatedConfig2() + expectedKeyNameConfig1 = config1.keys()[0] + resultKeyName = m.SUT.updatedConfig.keys()[0] + m.assertEqual(expectedKeyNameConfig1, resultKeyName) + end function + + end class +end namespace \ No newline at end of file diff --git a/tests/src/source/SomeModel.brs b/tests/src/source/SomeModel.brs new file mode 100644 index 00000000..116f4b2d --- /dev/null +++ b/tests/src/source/SomeModel.brs @@ -0,0 +1,34 @@ +function SomeModel() as object + if (m._someModel = invalid) + + obj = {} + obj.appTitle = "" + obj._config = invalid + obj.updatedConfig = invalid + + obj.globalMockExample = sub() + appTitle = getManifestValue("title") + m.appTitle = appTitle + end sub + + obj.setUpdatedConfig1 = sub() + m.updatedConfig = m._getConfig() + end sub + + obj.setUpdatedConfig2 = sub() + m.updatedConfig = m._getConfig() + end sub + + obj._getConfig = function() as object + return m._config + end function + + m._someModel = obj + end if + + return m._someModel +end function + +function getManifestValue(key as string) as string + return createObject("roAppInfo").getValue(key) +end function \ No newline at end of file From ee9bf4fb39b92611026e9b281ef0282e11b0ddfb Mon Sep 17 00:00:00 2001 From: Christopher Dwyer-Perkins Date: Wed, 19 Jun 2024 07:20:03 -0300 Subject: [PATCH 18/18] Bugfix/general fixes (#284) * Fixed error log printing when it shouldn't * Fixed a bug where asyn tests that finish sync could result in problems * insure object key order when converting to string * increased sleep at the end of the run to better flush the io logs --- framework/src/source/BaseTestSuite.bs | 2 ++ framework/src/source/CommonUtils.bs | 4 +++- framework/src/source/Rooibos.bs | 2 +- framework/src/source/TestRunner.bs | 1 + 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/framework/src/source/BaseTestSuite.bs b/framework/src/source/BaseTestSuite.bs index fe73329d..da40806e 100644 --- a/framework/src/source/BaseTestSuite.bs +++ b/framework/src/source/BaseTestSuite.bs @@ -199,6 +199,8 @@ namespace rooibos m.testRunner.top.unobserveFieldScoped("rooibosGroupFinished") ' m.testGroupDone() m.onAsyncGroupComplete(group) + else if m.testRunner.top.rooibosGroupFinished + m.onAsyncGroupComplete(group) end if end if diff --git a/framework/src/source/CommonUtils.bs b/framework/src/source/CommonUtils.bs index 9b9a6f51..38451201 100755 --- a/framework/src/source/CommonUtils.bs +++ b/framework/src/source/CommonUtils.bs @@ -334,7 +334,9 @@ namespace rooibos.common 'bs:disable-next-line isFirst = false end if - for each key in input + keys = input.keys() + keys.sort() + for each key in keys if rooibos.common.canSafelyIterateAAKey(input, key) text = text + key + ":" + rooibos.common.asString(input[key], includeType) end if diff --git a/framework/src/source/Rooibos.bs b/framework/src/source/Rooibos.bs index 2853a4a3..03b1108e 100644 --- a/framework/src/source/Rooibos.bs +++ b/framework/src/source/Rooibos.bs @@ -38,7 +38,7 @@ namespace rooibos ' leading to an instant exit of the application ' Give the io port time to finish sending all the logs - sleep(200) + sleep(400) end end if end if diff --git a/framework/src/source/TestRunner.bs b/framework/src/source/TestRunner.bs index e216b0d0..ee5d6dfd 100644 --- a/framework/src/source/TestRunner.bs +++ b/framework/src/source/TestRunner.bs @@ -163,6 +163,7 @@ namespace rooibos ? "Running suite asynchronously!" m.nodeContext.top.observeFieldScoped("rooibosSuiteFinished", "Rooibos_onTestSuiteComplete") testSuite.run() + return invalid else ? "Running suite synchronously!" testSuite.run()