UNPKG

rooibos-roku

Version:

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

212 lines 13.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TestGroup = void 0; const brighterscript_1 = require("brighterscript"); const brighterscript = require("brighterscript"); const BrsTranspileState_1 = require("brighterscript/dist/parser/BrsTranspileState"); const Diagnostics_1 = require("../utils/Diagnostics"); const TestSuite_1 = require("./TestSuite"); const Utils_1 = require("./Utils"); class TestGroup extends TestSuite_1.TestBlock { constructor(testSuite, annotation) { super(annotation); this.testCases = []; this.testSuite = testSuite; this.setupFunctionName = this.setupFunctionName || this.testSuite.setupFunctionName; this.tearDownFunctionName = this.tearDownFunctionName || this.testSuite.tearDownFunctionName; this.beforeEachFunctionName = this.beforeEachFunctionName || this.testSuite.beforeEachFunctionName; this.afterEachFunctionName = this.afterEachFunctionName || this.testSuite.afterEachFunctionName; } addTestCase(testCase) { this.testCases.push(testCase); this.hasIgnoredTests = this.hasIgnoredTests || testCase.isIgnored; this.hasSoloTests = this.hasSoloTests || testCase.isSolo; this.hasAsyncTests = this.hasAsyncTests || testCase.isAsync; } modifyAssertions(testCase, noEarlyExit, editor, namespaceLookup, scope) { //for each method //if assertion //wrap with if is not fail //add line number as last param const transpileState = new BrsTranspileState_1.BrsTranspileState(this.file); try { let func = this.testSuite.classStatement.methods.find((m) => m.name.text.toLowerCase() === testCase.funcName.toLowerCase()); func.walk(brighterscript.createVisitor({ ExpressionStatement: (expressionStatement, parent, owner, key) => { var _a; let callExpression = expressionStatement.expression; if (brighterscript.isCallExpression(callExpression) && brighterscript.isDottedGetExpression(callExpression.callee)) { let dge = callExpression.callee; let isSub = ((_a = callExpression.findAncestor(brighterscript_1.isFunctionExpression)) === null || _a === void 0 ? void 0 : _a.functionType.kind) === brighterscript_1.TokenKind.Sub; let assertRegex = /(?:fail|assert(?:[a-z0-9]*)|expect(?:[a-z0-9]*)|stubCall)/i; if (dge && assertRegex.test(dge.name.text)) { // get the path to the call expression // `m`.assert*(...) // `m.testSuite`.assert*(...) // `someMagicVar`.assert*(...) const callPath = brighterscript_1.util.getAllDottedGetParts(callExpression.callee.obj).map((part) => part.text).join('.'); if (dge.name.text === 'stubCall') { this.modifyModernRooibosExpectCallExpression(callExpression, editor, namespaceLookup, scope); return expressionStatement; } else { if (dge.name.text === 'expectCalled' || dge.name.text === 'expectNotCalled') { this.modifyModernRooibosExpectCallExpression(callExpression, editor, namespaceLookup, scope); } if (dge.name.text === 'expectCalled' || dge.name.text === 'expectNotCalled') { this.modifyModernRooibosExpectCallExpression(callExpression, editor, namespaceLookup, scope); } if (!noEarlyExit) { const trailingLine = brighterscript_1.Parser.parse(`if ${callPath}.currentResult?.isFail = true then ${callPath}.done() : return ${isSub ? '' : 'invalid'}`).ast.statements[0]; editor.arraySplice(owner, key + 1, 0, trailingLine); } const leadingLine = brighterscript_1.Parser.parse(`${callPath}.currentAssertLineNumber = ${callExpression.range.start.line + 1}`).ast.statements[0]; editor.arraySplice(owner, key, 0, leadingLine); } } } } }), { walkMode: brighterscript.WalkMode.visitStatementsRecursive }); } catch (e) { console.error(e); // eslint-disable-next-line @typescript-eslint/no-unsafe-argument (0, Diagnostics_1.diagnosticErrorProcessingFile)(this.testSuite.file, e.message); } } modifyModernRooibosExpectCallExpression(callExpression, editor, namespaceLookup, scope) { let isNotCalled = false; let isStubCall = false; //modify args let arg0 = callExpression.args[0]; let arg1 = callExpression.args[1]; if ((0, brighterscript_1.isDottedGetExpression)(callExpression.callee)) { const nameText = callExpression.callee.name.text; isNotCalled = nameText === 'expectNotCalled'; isStubCall = nameText === 'stubCall'; if (isStubCall && this.shouldNotModifyStubCall(arg0, namespaceLookup, scope)) { return; } editor.setProperty(callExpression.callee.name, 'text', `_${nameText}`); } if (brighterscript.isCallExpression(arg0) && (0, brighterscript_1.isDottedGetExpression)(arg0.callee)) { //is it a namespace? let dg = arg0.callee; let nameParts = (0, Utils_1.getAllDottedGetParts)(dg); let name = nameParts.pop(); if (name) { //is a namespace? if (nameParts[0] && namespaceLookup.has(nameParts[0].toLowerCase())) { //then this must be a namespace method let fullPathName = nameParts.join('.').toLowerCase(); let ns = namespaceLookup.get(fullPathName); if (!ns) { //TODO this is an error condition! } nameParts.push(name); let functionName = nameParts.join('_').toLowerCase(); editor.removeFromArray(callExpression.args, 0); if (!isNotCalled && !isStubCall) { const expectedArgs = new brighterscript_1.ArrayLiteralExpression(arg0.args, (0, brighterscript_1.createToken)(brighterscript_1.TokenKind.LeftSquareBracket), (0, brighterscript_1.createToken)(brighterscript_1.TokenKind.RightSquareBracket)); editor.addToArray(callExpression.args, 0, expectedArgs); } editor.addToArray(callExpression.args, 0, (0, brighterscript_1.createInvalidLiteral)()); editor.addToArray(callExpression.args, 0, (0, brighterscript_1.createInvalidLiteral)()); editor.addToArray(callExpression.args, 0, (0, brighterscript_1.createStringLiteral)(functionName)); editor.addToArray(callExpression.args, 0, brighterscript.createVariableExpression(functionName)); this.testSuite.session.globalStubbedMethods.add(functionName); } else { let functionName = arg0.callee.name.text; let fullPath = (0, Utils_1.getStringPathFromDottedGet)(arg0.callee.obj); editor.removeFromArray(callExpression.args, 0); if (!isNotCalled && !isStubCall) { const expectedArgs = new brighterscript_1.ArrayLiteralExpression(arg0.args, (0, brighterscript_1.createToken)(brighterscript_1.TokenKind.LeftSquareBracket), (0, brighterscript_1.createToken)(brighterscript_1.TokenKind.RightSquareBracket)); editor.addToArray(callExpression.args, 0, expectedArgs); } editor.addToArray(callExpression.args, 0, fullPath !== null && fullPath !== void 0 ? fullPath : (0, brighterscript_1.createInvalidLiteral)()); editor.addToArray(callExpression.args, 0, (0, Utils_1.getRootObjectFromDottedGet)(arg0.callee)); editor.addToArray(callExpression.args, 0, (0, brighterscript_1.createStringLiteral)(functionName)); editor.addToArray(callExpression.args, 0, arg0.callee.obj); } } } else if (brighterscript.isDottedGetExpression(arg0)) { let functionName = arg0.name.text; let fullPath = (0, Utils_1.getStringPathFromDottedGet)(arg0.obj); arg0 = callExpression.args[0]; editor.removeFromArray(callExpression.args, 0); if (!isNotCalled && !isStubCall) { editor.addToArray(callExpression.args, 0, (0, brighterscript_1.createInvalidLiteral)()); } editor.addToArray(callExpression.args, 0, fullPath !== null && fullPath !== void 0 ? fullPath : (0, brighterscript_1.createInvalidLiteral)()); editor.addToArray(callExpression.args, 0, (0, Utils_1.getRootObjectFromDottedGet)(arg0)); editor.addToArray(callExpression.args, 0, (0, brighterscript_1.createStringLiteral)(functionName)); editor.addToArray(callExpression.args, 0, arg0.obj); } else if (brighterscript.isCallfuncExpression(arg0)) { let functionName = arg0.methodName.text; editor.removeFromArray(callExpression.args, 0); if (isNotCalled || isStubCall) { //TODO in future we can improve is notCalled to know which callFunc function it is // const expectedArgs = new ArrayLiteralExpression([createStringLiteral(functionName)], createToken(TokenKind.LeftSquareBracket), createToken(TokenKind.RightSquareBracket)); // editor.addToArray(callExpression.args, 0, expectedArgs); } else { const expectedArgs = new brighterscript_1.ArrayLiteralExpression([(0, brighterscript_1.createStringLiteral)(functionName), ...arg0.args], (0, brighterscript_1.createToken)(brighterscript_1.TokenKind.LeftSquareBracket), (0, brighterscript_1.createToken)(brighterscript_1.TokenKind.RightSquareBracket)); editor.addToArray(callExpression.args, 0, expectedArgs); } let fullPath = (0, Utils_1.getStringPathFromDottedGet)(arg0.callee); editor.addToArray(callExpression.args, 0, fullPath !== null && fullPath !== void 0 ? fullPath : (0, brighterscript_1.createInvalidLiteral)()); editor.addToArray(callExpression.args, 0, (0, Utils_1.getRootObjectFromDottedGet)(arg0.callee)); editor.addToArray(callExpression.args, 0, (0, brighterscript_1.createStringLiteral)('callFunc')); editor.addToArray(callExpression.args, 0, arg0.callee); } else if (brighterscript.isCallExpression(arg0) && brighterscript.isVariableExpression(arg0.callee)) { let functionName = arg0.callee.getName(brighterscript.ParseMode.BrightScript); editor.removeFromArray(callExpression.args, 0); if (!isNotCalled && !isStubCall) { const expectedArgs = new brighterscript_1.ArrayLiteralExpression(arg0.args, (0, brighterscript_1.createToken)(brighterscript_1.TokenKind.LeftSquareBracket), (0, brighterscript_1.createToken)(brighterscript_1.TokenKind.RightSquareBracket)); editor.addToArray(callExpression.args, 0, expectedArgs); } editor.addToArray(callExpression.args, 0, (0, brighterscript_1.createInvalidLiteral)()); editor.addToArray(callExpression.args, 0, (0, brighterscript_1.createInvalidLiteral)()); editor.addToArray(callExpression.args, 0, (0, brighterscript_1.createStringLiteral)(functionName)); editor.addToArray(callExpression.args, 0, brighterscript.createVariableExpression(functionName)); this.testSuite.session.globalStubbedMethods.add(functionName); } } shouldNotModifyStubCall(arg0, namespaceLookup, scope) { if (brighterscript.isDottedGetExpression(arg0)) { let nameParts = (0, Utils_1.getAllDottedGetParts)(arg0); let functionName = nameParts.join('.'); return scope.getCallableByName(functionName); } else if (brighterscript.isVariableExpression(arg0)) { return (scope.symbolTable.hasSymbol(arg0.getName(brighterscript_1.ParseMode.BrightScript)) || scope.getCallableByName(arg0.getName(brighterscript_1.ParseMode.BrighterScript))); } return false; } asText() { let testCaseText = [...this.testCases].filter((tc) => tc.isIncluded).map((tc) => tc.asText()); return ` { name: ${(0, Utils_1.sanitizeBsJsonString)(this.name)} isSolo: ${this.isSolo} isIgnored: ${this.isIgnored} isAsync: ${this.isAsync} filename: "${this.pkgPath}" lineNumber: "${this.annotation.annotation.range.start.line + 1}" setupFunctionName: "${this.setupFunctionName || ''}" tearDownFunctionName: "${this.tearDownFunctionName || ''}" beforeEachFunctionName: "${this.beforeEachFunctionName || ''}" afterEachFunctionName: "${this.afterEachFunctionName || ''}" testCases: [${testCaseText.join(',\n')}] }`; } } exports.TestGroup = TestGroup; //# sourceMappingURL=TestGroup.js.map