UNPKG

rooibos-roku

Version:

simple, flexible, fun brightscript test framework for roku scenegraph apps - roku brighterscript plugin

245 lines (244 loc) 12.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RooibosSession = void 0; const path = require("path"); const brighterscript_1 = require("brighterscript"); const RooibosSessionInfo_1 = require("./RooibosSessionInfo"); const TestSuiteBuilder_1 = require("./TestSuiteBuilder"); const Diagnostics_1 = require("../utils/Diagnostics"); const undent_1 = require("undent"); const fsExtra = require("fs-extra"); // eslint-disable-next-line const pkg = require('../../../package.json'); class RooibosSession { constructor(builder, fileFactory) { this.globalStubbedMethods = new Set(); this.fileFactory = fileFactory; this.config = builder.options ? builder.options.rooibos || {} : {}; this._builder = builder; this._suiteBuilder = new TestSuiteBuilder_1.TestSuiteBuilder(this); this.reset(); } reset() { this.sessionInfo = new RooibosSessionInfo_1.SessionInfo(this.config); } prepareForTranspile(editor, program, mockUtil) { this.addTestRunnerMetadata(editor); this.addLaunchHookToExistingMain(editor); // Make sure to create the node files before running the global mock logic // We realy on them in order to check the component scope for the global functions for (let testSuite of this.sessionInfo.testSuitesToRun) { if (testSuite.isNodeTest) { this.createNodeFile(program, testSuite); } } if (this.config.isGlobalMethodMockingEnabled && this.config.isGlobalMethodMockingEfficientMode) { console.log('Efficient global stubbing is enabled'); this.namespaceLookup = this.getNamespaces(program); for (let testSuite of this.sessionInfo.testSuitesToRun) { mockUtil.gatherGlobalMethodMocks(testSuite); } } else { this.namespaceLookup = new Map(); } } updateSessionStats() { this.sessionInfo.updateInfo(); } processFile(file) { let testSuites = this._suiteBuilder.processFile(file); return testSuites; } addLaunchHookToExistingMain(editor) { var _a, _b; let mainFunction; const files = this._builder.program.getScopeByName('source').getOwnFiles(); for (let file of files) { if ((0, brighterscript_1.isBrsFile)(file)) { const mainFunc = file.parser.references.functionStatements.find((f) => f.name.text.toLowerCase() === 'main'); if (mainFunc) { mainFunction = mainFunc; break; } } } if (mainFunction) { const initCall = mainFunction.func.body.findChild(f => (0, brighterscript_1.isCallExpression)(f) && (0, brighterscript_1.isVariableExpression)(f.callee) && f.callee.name.text.toLowerCase() === 'rooibos_init', { walkMode: brighterscript_1.WalkMode.visitAllRecursive }); if (!initCall) { editor.addToArray(mainFunction.func.body.statements, 0, brighterscript_1.Parser.parse(`Rooibos_init("${(_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.testSceneName) !== null && _b !== void 0 ? _b : 'RooibosScene'}")`).ast.statements[0]); } } } addLaunchHookFileIfNotPresent() { var _a, _b, _c; let mainFunction; const files = this._builder.program.getScopeByName('source').getOwnFiles(); for (let file of files) { if ((0, brighterscript_1.isBrsFile)(file)) { const mainFunc = file.parser.references.functionStatements.find((f) => f.name.text.toLowerCase() === 'main'); if (mainFunc) { mainFunction = mainFunc; break; } } } if (!mainFunction) { (0, Diagnostics_1.diagnosticErrorNoMainFound)(files[0]); if (!this._builder.options.stagingDir && !this._builder.options.stagingFolderPath) { console.error('this plugin requires that stagingDir or the deprecated stagingFolderPath bsconfig option is set'); (0, Diagnostics_1.diagnosticNoStagingDir)(files[0]); } else { const filePath = path.join((_a = this._builder.options.stagingDir) !== null && _a !== void 0 ? _a : this._builder.options.stagingFolderPath, 'source/rooibosMain.brs'); fsExtra.writeFileSync(filePath, `function main()\n Rooibos_init("${(_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.testSceneName) !== null && _c !== void 0 ? _c : 'RooibosScene'}")\nend function`); } } } addTestRunnerMetadata(editor) { var _a; let runtimeConfig = this._builder.program.getFile('source/rooibos/RuntimeConfig.bs'); const classStatement = (_a = runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.ast) === null || _a === void 0 ? void 0 : _a.findChild((node) => { var _a, _b; return (0, brighterscript_1.isClassStatement)(node) && ((_b = (_a = node.name) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === 'runtimeconfig'; }); if (classStatement) { this.updateRunTimeConfigFunction(classStatement, editor); this.updateVersionTextFunction(classStatement, editor); this.updateClassMapFunction(classStatement, editor); this.createIgnoredTestsInfoFunction(classStatement, editor); } } updateRunTimeConfigFunction(classStatement, editor) { var _a; let method = classStatement.methods.find((m) => m.name.text === 'getRuntimeConfig'); if (method) { editor.addToArray(method.func.body.statements, method.func.body.statements.length, brighterscript_1.Parser.parse((0, undent_1.default) ` return { "reporters": ${this.getReportersList()} "failFast": ${this.config.failFast ? 'true' : 'false'} "sendHomeOnFinish": ${this.config.sendHomeOnFinish ? 'true' : 'false'} "logLevel": ${(_a = this.config.logLevel) !== null && _a !== void 0 ? _a : 0} "showOnlyFailures": ${this.config.showOnlyFailures ? 'true' : 'false'} "printTestTimes": ${this.config.printTestTimes ? 'true' : 'false'} "lineWidth": ${this.config.lineWidth || 60} "printLcov": ${this.config.printLcov ? 'true' : 'false'} "port": "${this.config.port || 'invalid'}" "catchCrashes": ${this.config.catchCrashes ? 'true' : 'false'} "colorizeOutput": ${this.config.colorizeOutput ? 'true' : 'false'} "throwOnFailedAssertion": ${this.config.throwOnFailedAssertion ? 'true' : 'false'} "keepAppOpen": ${this.config.keepAppOpen === undefined || this.config.keepAppOpen ? 'true' : 'false'} "isRecordingCodeCoverage": ${this.config.isRecordingCodeCoverage ? 'true' : 'false'} } `).ast.statements[0]); } } 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) { switch (name.toLowerCase()) { case 'console': return 'rooibos_ConsoleTestReporter'; case 'junit': return 'rooibos_JUnitTestReporter'; case 'mocha': return 'rooibos_MochaTestReporter'; } // @todo: check if function name is valid return name; } updateVersionTextFunction(classStatement, editor) { let method = classStatement.methods.find((m) => m.name.text === 'getVersionText'); if (method) { editor.addToArray(method.func.body.statements, method.func.body.statements.length, brighterscript_1.Parser.parse(`return "${pkg.version}"`).ast.statements[0]); } } updateClassMapFunction(classStatement, editor) { let method = classStatement.methods.find((m) => m.name.text === 'getTestSuiteClassMap'); if (method) { editor.arrayPush(method.func.body.statements, ...brighterscript_1.Parser.parse((0, undent_1.default) ` return {${this.sessionInfo.testSuitesToRun.map(suite => ` "${suite.name}": ${suite.classStatement.getName(brighterscript_1.ParseMode.BrightScript)}`).join('')} } `).ast.statements); } } createNodeFiles(program) { for (let suite of this.sessionInfo.testSuitesToRun.filter((s) => s.isNodeTest)) { this.createNodeFile(program, suite); } } createNodeFile(program, suite) { let xmlText = this.getNodeTestXmlText(suite); this.fileFactory.addFile(program, suite.xmlPkgPath, xmlText); let bsFile = program.getFile(suite.bsPkgPath); if (bsFile) { bsFile.parser.statements.push(); bsFile.needsTranspiled = true; } let brsFile = this.fileFactory.addFile(program, suite.bsPkgPath, (0, undent_1.default) ` function init() m.top.addField("rooibosRunSuite", "boolean", false) m.top.observeFieldScoped("rooibosRunSuite", "rooibosRunSuite") end function function rooibosRunSuite() m.top.unobserveFieldScoped("rooibosRunSuite") nodeRunner = Rooibos_TestRunner(m.top.getScene(), m) m.top.rooibosTestResult = nodeRunner.runInNodeMode("${suite.name}") end function `); brsFile.parser.invalidateReferences(); } getNodeTestXmlText(suite) { return this.fileFactory.createTestXML(suite.generatedNodeName, suite.nodeName, suite); } getNamespaceLookup(scope) { // eslint-disable-next-line @typescript-eslint/dot-notation return scope['cache'].getOrAdd('namespaceLookup', () => scope.buildNamespaceLookup()); } getNamespaces(program) { let scopeNamespaces = new Map(); let processedScopes = new Set(); for (const file of Object.values(program.files)) { for (let scope of program.getScopesForFile(file)) { if (processedScopes.has(scope.dependencyGraphKey)) { // Skip this scope if it has already been processed continue; } let scopeMap = this.getNamespaceLookup(scope); // scopeNamespaces = new Map<string, NamespaceContainer>([...Array.from(scopeMap.entries())]); for (let [key, value] of scopeMap.entries()) { scopeNamespaces.set(key, value); } processedScopes.add(scope.dependencyGraphKey); } } return scopeNamespaces; } createIgnoredTestsInfoFunction(cs, editor) { let method = cs.methods.find((m) => m.name.text === 'getIgnoredTestInfo'); if (method) { editor.arrayPush(method.func.body.statements, ...brighterscript_1.Parser.parse([ 'return {', ` "count": ${this.sessionInfo.ignoredCount}`, ` "items": [`, ...this.sessionInfo.ignoredTestNames.map((name) => `"${name}"`), ` ]`, `}` ].join('\n')).ast.statements); } } } exports.RooibosSession = RooibosSession; //# sourceMappingURL=RooibosSession.js.map