rooibos-roku 5.16.5 → 5.16.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.mocharc.cjs ADDED
@@ -0,0 +1,15 @@
1
+ const nodeVersion = +process.versions.node.split('.')[0];
2
+ const config = {
3
+ spec: 'src/**/*.spec.ts',
4
+ require: [
5
+ 'source-map-support/register',
6
+ 'ts-node/register'
7
+ ],
8
+ fullTrace: true,
9
+ timeout: 2000,
10
+ watchExtensions: ['ts']
11
+ };
12
+ if (nodeVersion >= 22) {
13
+ config['node-option'] = ['no-experimental-strip-types'];
14
+ }
15
+ module.exports = config;
package/CHANGELOG.md CHANGED
@@ -6,6 +6,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
 
8
8
 
9
+ ## [5.16.6](https://github.com/rokucommunity/rooibos/compare/5.16.5...v5.16.6) - 2026-10-01
10
+ ### Changed
11
+ - Process every test suite in a file, not just the first ([#441](https://github.com/rokucommunity/rooibos/pull/441))
12
+ - Support enums and constants in @params annotations ([#438](https://github.com/rokucommunity/rooibos/pull/438))
13
+ - Security enhancements ([#426](https://github.com/rokucommunity/rooibos/pull/426), [#429](https://github.com/rokucommunity/rooibos/pull/429), [#439](https://github.com/rokucommunity/rooibos/pull/439))
14
+ - upgrade to [brighterscript@0.73.5](https://github.com/rokucommunity/brighterscript/blob/v0.73.5/CHANGELOG.md#0735---2026-09-15). Notable changes since 0.73.3:
15
+ - Fix crash stripping sourceMappingURL comment from non-transpiled files ([#1821](https://github.com/rokucommunity/brighterscript/pull/1821))
16
+ - Tolerate older BrsTranspileState in continue back-transpile ([#1812](https://github.com/rokucommunity/brighterscript/pull/1812))
17
+ - Security enhancements ([#1804](https://github.com/rokucommunity/brighterscript/pull/1804), [#1805](https://github.com/rokucommunity/brighterscript/pull/1805))
18
+ - Locate the super() call when injecting field initializers ([#1803](https://github.com/rokucommunity/brighterscript/pull/1803))
19
+ - upgrade to [roku-debug@0.24.6](https://github.com/rokucommunity/roku-debug/blob/v0.24.6/CHANGELOG.md#0246---2026-10-01). Notable changes since 0.24.3:
20
+ - Security enhancements ([#419](https://github.com/rokucommunity/roku-debug/pull/419), [#427](https://github.com/rokucommunity/roku-debug/pull/427))
21
+ - upgrade to [roku-deploy@4.0.0-alpha.9](https://github.com/rokucommunity/roku-deploy/blob/v4.0.0-alpha.9/CHANGELOG.md#400-alpha9---2026-09-28). Notable changes since 4.0.0-alpha.5:
22
+ - Security enhancements ([#422](https://github.com/rokucommunity/roku-deploy/pull/422))
23
+ - upgrade to [@rokucommunity/logger@0.4.2](https://github.com/rokucommunity/logger/blob/master/CHANGELOG.md#042---2026-09-02). Notable changes since 0.4.1:
24
+ - Security enhancements ([#38](https://github.com/rokucommunity/logger/pull/38), [#39](https://github.com/rokucommunity/logger/pull/39))
25
+ ### Fixed
26
+ - Fixed ignored tests count reporting in the summary output ([#435](https://github.com/rokucommunity/rooibos/pull/435))
27
+
28
+
29
+
9
30
  ## [5.16.5](https://github.com/rokucommunity/rooibos/compare/5.16.4...v5.16.5) - 2026-09-09
10
31
  ### Changed
11
32
  - Security enhancements ([#405](https://github.com/rokucommunity/rooibos/pull/405), [#406](https://github.com/rokucommunity/rooibos/pull/406), [#407](https://github.com/rokucommunity/rooibos/pull/407), [#409](https://github.com/rokucommunity/rooibos/pull/409), [#410](https://github.com/rokucommunity/rooibos/pull/410), [#411](https://github.com/rokucommunity/rooibos/pull/411), [#412](https://github.com/rokucommunity/rooibos/pull/412), [#414](https://github.com/rokucommunity/rooibos/pull/414), [#421](https://github.com/rokucommunity/rooibos/pull/421))
package/audit-ci.jsonc CHANGED
@@ -3,13 +3,5 @@
3
3
  // why each allowlisted entry is safe to defer.
4
4
  "$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
5
5
  "high": true,
6
- "allowlist": [
7
- {
8
- "GHSA-w5hq-g745-h8pq": {
9
- // Added: 2026-05-22
10
- "active": true,
11
- "notes": "`uuid` <11.1.1 (via `postman-request` and dev-only `nyc>istanbul-lib-processinfo`): vulnerable code path is `v3()`/`v5()`/`v6()` when a caller-provided buffer is passed. All consumers in this dep graph call only `v4()` (no buffer arg), so the vulnerable path is unreachable."
12
- }
13
- }
14
- ]
6
+ "allowlist": []
15
7
  }
@@ -72,12 +72,12 @@ namespace rooibos
72
72
  m.printLine(0, " Passed: " + rooibos.common.AsString(m.allStats.passedCount))
73
73
  m.printLine(0, " Crashed: " + rooibos.common.AsString(m.allStats.crashedCount))
74
74
  m.printLine(0, " Failed: " + rooibos.common.AsString(m.allStats.failedCount))
75
- m.printLine(0, " Ignored: " + rooibos.common.AsString(ignoredInfo.count))
75
+ m.printLine(0, " Ignored: " + rooibos.common.AsString(m.allStats.ignoredCount))
76
76
  m.printLine(0, " Time: " + rooibos.common.AsString(m.allStats.time) + "ms")
77
77
  m.printLine()
78
78
  m.printLine()
79
79
 
80
- if ignoredInfo.count > 0 then
80
+ if m.allStats.ignoredCount > 0 then
81
81
  m.printLine(0, "IGNORED TESTS:")
82
82
  for each ignoredItemName in ignoredInfo.items
83
83
  m.printLine(1, ignoredItemName)
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getAnnotationType = exports.RooibosAnnotation = exports.AnnotationParams = exports.AnnotationType = void 0;
4
4
  const Diagnostics_1 = require("../utils/Diagnostics");
5
+ const Utils_1 = require("./Utils");
5
6
  var AnnotationType;
6
7
  (function (AnnotationType) {
7
8
  AnnotationType["None"] = "none";
@@ -46,9 +47,12 @@ let annotationLookup = {
46
47
  };
47
48
  const defaultSlowDuration = 75;
48
49
  class AnnotationParams {
49
- constructor(annotation, text, lineNumber, params, isIgnore = false, isSolo = false, noCatch = false, noEarlyexit = false) {
50
+ constructor(annotation, lineNumber,
51
+ /**
52
+ * The argument expressions of the annotation. These are cloned into the generated test suite data so they get transpiled like any other code
53
+ */
54
+ params, isIgnore = false, isSolo = false, noCatch = false, noEarlyexit = false) {
50
55
  this.annotation = annotation;
51
- this.text = text;
52
56
  this.lineNumber = lineNumber;
53
57
  this.params = params;
54
58
  this.isIgnore = isIgnore;
@@ -167,6 +171,7 @@ class RooibosAnnotation {
167
171
  asyncTimeout = -1;
168
172
  }
169
173
  for (const annotation of getAnnotationsOfType(AnnotationType.Params, AnnotationType.SoloParams, AnnotationType.IgnoreParams)) {
174
+ (0, Utils_1.linkAnnotationToStatement)(annotation, statement);
170
175
  if (testAnnotation) {
171
176
  testAnnotation.parseParams(file, annotation, getAnnotationType(annotation.name), noCatch);
172
177
  }
@@ -194,23 +199,13 @@ class RooibosAnnotation {
194
199
  return { blockAnnotation: blockAnnotation, testAnnotation: testAnnotation };
195
200
  }
196
201
  parseParams(file, annotation, annotationType, noCatch) {
197
- let rawParams = JSON.stringify(annotation.getArguments());
202
+ var _a, _b;
198
203
  let isSolo = annotationType === AnnotationType.SoloParams;
199
204
  let isIgnore = annotationType === AnnotationType.IgnoreParams;
200
205
  if (isSolo) {
201
206
  this.hasSoloParams = true;
202
207
  }
203
- try {
204
- if (rawParams) {
205
- this.params.push(new AnnotationParams(annotation, rawParams, annotation.range.start.line, annotation.getArguments(), isIgnore, isSolo, noCatch));
206
- }
207
- else {
208
- (0, Diagnostics_1.diagnosticIllegalParams)(file, annotation);
209
- }
210
- }
211
- catch (e) {
212
- (0, Diagnostics_1.diagnosticIllegalParams)(file, annotation);
213
- }
208
+ this.params.push(new AnnotationParams(annotation, annotation.range.start.line, (_b = (_a = annotation.call) === null || _a === void 0 ? void 0 : _a.args) !== null && _b !== void 0 ? _b : [], isIgnore, isSolo, noCatch));
214
209
  }
215
210
  }
216
211
  exports.RooibosAnnotation = RooibosAnnotation;
@@ -21,7 +21,6 @@ class TestCase {
21
21
  this.isParamTest = this.expectedNumberOfParams > 0;
22
22
  }
23
23
  asText() {
24
- let rawParamsText = this.fixBadJson(this.rawParams).replace(/null/g, 'invalid');
25
24
  return `
26
25
  {
27
26
  isSolo: ${this.isSolo}
@@ -36,28 +35,12 @@ class TestCase {
36
35
  lineNumber: ${this.lineNumber + 1}
37
36
  paramLineNumber: ${this.isParamTest ? this.paramLineNumber + 1 : 0}
38
37
  assertIndex: ${this.assertIndex}
39
- rawParams: ${rawParamsText}
38
+ rawParams: ${this.rawParams ? '[]' /* filled with the actual param expressions by `addParamsToTestSuiteData` */ : 'invalid'}
40
39
  paramTestIndex: ${this.paramTestIndex}
41
40
  expectedNumberOfParams: ${this.expectedNumberOfParams}
42
41
  isParamsValid: ${(this.rawParams || []).length === this.expectedNumberOfParams}
43
42
  }`;
44
43
  }
45
- fixBadJson(o) {
46
- // In case of an array we'll stringify all objects.
47
- if (Array.isArray(o)) {
48
- return `[${o.map(obj => `${this.fixBadJson(obj)}`).join(',')}]`;
49
- }
50
- // not an object, stringify using native function
51
- if (typeof o !== 'object' || o === null) {
52
- return JSON.stringify(o);
53
- }
54
- return `{${Object
55
- .keys(o)
56
- .map(key => {
57
- return `"${key.replace(/"/g, '')}":${this.fixBadJson(o[key])}`;
58
- })
59
- .join(',')}}`;
60
- }
61
44
  }
62
45
  exports.TestCase = TestCase;
63
46
  //# sourceMappingURL=TestCase.js.map
@@ -78,7 +78,17 @@ class TestSuite extends TestBlock {
78
78
  }
79
79
  addDataFunctions(editor) {
80
80
  if (this.isIncluded) {
81
- (0, Utils_1.addOverriddenMethod)(this.file, this.annotation.annotation, this.classStatement, 'getTestSuiteData', `return ${this.asText()}`, editor);
81
+ const method = (0, Utils_1.addOverriddenMethod)(this.file, this.annotation.annotation, this.classStatement, 'getTestSuiteData', `return ${this.asText()}`, editor);
82
+ if (method) {
83
+ //same order as the `rawParams` placeholders in `asText()`
84
+ const paramExpressionsList = [];
85
+ for (const testGroup of [...this.testGroups.values()].filter((tg) => tg.isIncluded)) {
86
+ for (const testCase of [...testGroup.testCases].filter((tc) => tc.isIncluded && tc.rawParams)) {
87
+ paramExpressionsList.push(testCase.rawParams);
88
+ }
89
+ }
90
+ (0, Utils_1.addParamsToTestSuiteData)(this.file, method, paramExpressionsList, editor);
91
+ }
82
92
  }
83
93
  }
84
94
  getTestGroups() {
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getScopeForSuite = exports.getPathValuePartAsString = exports.getStringPathFromDottedGet = exports.getRootObjectFromDottedGet = exports.getAllDottedGetParts = exports.functionRequiresReturnValue = exports.sanitizeBsJsonString = exports.addOverriddenMethod = void 0;
3
+ exports.getScopeForSuite = exports.addParamsToTestSuiteData = exports.linkAnnotationToStatement = exports.getPathValuePartAsString = exports.getStringPathFromDottedGet = exports.getRootObjectFromDottedGet = exports.getAllDottedGetParts = exports.functionRequiresReturnValue = exports.sanitizeBsJsonString = exports.addOverriddenMethod = void 0;
4
4
  const brighterscript_1 = require("brighterscript");
5
5
  const Diagnostics_1 = require("../utils/Diagnostics");
6
+ /**
7
+ * Add a generated method to the class.
8
+ * @returns the added method, or undefined if the source could not be parsed
9
+ */
6
10
  function addOverriddenMethod(file, annotation, target, name, source, editor) {
7
11
  var _a, _b;
8
12
  let { method, diagnostics, text } = createMethod(file, name, source);
@@ -11,11 +15,12 @@ function addOverriddenMethod(file, annotation, target, name, source, editor) {
11
15
  //trigger that functionality BEFORE performing AstEditor operations. TODO remove this whenever bsc stops doing this.
12
16
  (_b = (_a = target).ensureConstructorFunctionExists) === null || _b === void 0 ? void 0 : _b.call(_a);
13
17
  editor.addToArray(target.body, target.body.length, method);
14
- return true;
18
+ method.parent = target;
19
+ return method;
15
20
  }
16
21
  const error = (diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.length) > 0 ? diagnostics[0].message : 'unknown error';
17
22
  (0, Diagnostics_1.diagnosticCorruptTestProduced)(file, annotation, error, text);
18
- return false;
23
+ return undefined;
19
24
  }
20
25
  exports.addOverriddenMethod = addOverriddenMethod;
21
26
  /**
@@ -130,6 +135,73 @@ function getPathValuePartAsString(expr) {
130
135
  }
131
136
  }
132
137
  exports.getPathValuePartAsString = getPathValuePartAsString;
138
+ /**
139
+ * bsc does not link annotations into the AST, so the expressions in their arguments have no parent (and therefore no symbol table or namespace).
140
+ * That makes the bsc validator flag references like `@params(SomeEnum.value)` as unknown names. Link the annotation (and its arguments) to
141
+ * the statement it decorates so those references are validated and resolved like any other expression in that statement's scope.
142
+ */
143
+ function linkAnnotationToStatement(annotation, statement) {
144
+ if (!(annotation === null || annotation === void 0 ? void 0 : annotation.call)) {
145
+ return;
146
+ }
147
+ (0, brighterscript_1.walkArray)(annotation.call.args, () => { }, { walkMode: brighterscript_1.WalkMode.visitAllRecursive }, annotation.call);
148
+ annotation.call.parent = annotation;
149
+ annotation.parent = statement;
150
+ }
151
+ exports.linkAnnotationToStatement = linkAnnotationToStatement;
152
+ /**
153
+ * Fill the `rawParams: []` placeholders in a generated `getTestSuiteData` method with clones of each test case's actual `@params` argument expressions.
154
+ * The clones are registered in the file's references, so bsc's own pre-transpile processing (i.e. inlining enums and constants) applies to them
155
+ * exactly like it does for handwritten code. This must run before bsc's `beforeFileTranspile` (i.e. during `beforeProgramTranspile`).
156
+ * @param file the file containing the test suite
157
+ * @param method the generated `getTestSuiteData` method
158
+ * @param paramExpressionsList the `@params` argument expressions for each placeholder, in the order they appear in the method
159
+ * @param editor the editor used to make (and later undo) the changes
160
+ */
161
+ function addParamsToTestSuiteData(file, method, paramExpressionsList, editor) {
162
+ const placeholders = [];
163
+ method.walk((node) => {
164
+ if ((0, brighterscript_1.isAAMemberExpression)(node) && node.keyToken.text === 'rawParams' && (0, brighterscript_1.isArrayLiteralExpression)(node.value)) {
165
+ placeholders.push(node.value);
166
+ }
167
+ }, { walkMode: brighterscript_1.WalkMode.visitExpressionsRecursive });
168
+ const references = new Set();
169
+ const addReferences = (expression) => {
170
+ references.add(expression);
171
+ if ((0, brighterscript_1.isArrayLiteralExpression)(expression)) {
172
+ for (const element of expression.elements) {
173
+ if (!(0, brighterscript_1.isCommentStatement)(element)) {
174
+ addReferences(element);
175
+ }
176
+ }
177
+ }
178
+ else if ((0, brighterscript_1.isAALiteralExpression)(expression)) {
179
+ for (const member of expression.elements) {
180
+ if ((0, brighterscript_1.isAAMemberExpression)(member)) {
181
+ addReferences(member.value);
182
+ }
183
+ }
184
+ }
185
+ };
186
+ for (let i = 0; i < placeholders.length && i < paramExpressionsList.length; i++) {
187
+ const clones = paramExpressionsList[i].map(x => x.clone());
188
+ editor.arrayPush(placeholders[i].elements, ...clones);
189
+ //link the clones into the AST
190
+ (0, brighterscript_1.walkArray)(placeholders[i].elements, () => { }, { walkMode: brighterscript_1.WalkMode.visitAllRecursive }, placeholders[i]);
191
+ clones.forEach(addReferences);
192
+ }
193
+ const fileReferences = file.parser.references.expressions;
194
+ editor.edit(() => {
195
+ for (const expression of references) {
196
+ fileReferences.add(expression);
197
+ }
198
+ }, () => {
199
+ for (const expression of references) {
200
+ fileReferences.delete(expression);
201
+ }
202
+ });
203
+ }
204
+ exports.addParamsToTestSuiteData = addParamsToTestSuiteData;
133
205
  function getScopeForSuite(testSuite) {
134
206
  if (testSuite.isNodeTest) {
135
207
  return testSuite.file.program.getScopesForFile(testSuite.file).find((scope) => {
package/dist/plugin.js CHANGED
@@ -130,14 +130,18 @@ class RooibosPlugin {
130
130
  }
131
131
  beforeProgramTranspile(program, entries, editor) {
132
132
  this.session.prepareForTranspile(editor, program, this.mockUtil);
133
+ //this must happen before bsc's `beforeFileTranspile` (which runs before ours), so bsc will inline any enums/constants used in the `@params`
134
+ for (const testSuite of this.session.sessionInfo.testSuitesToRun) {
135
+ testSuite.addDataFunctions(editor);
136
+ }
133
137
  }
134
138
  afterProgramTranspile(program, entries, editor) {
135
139
  this.session.addLaunchHookFileIfNotPresent();
136
140
  this.codeCoverageProcessor.generateMetadata(this.config.isRecordingCodeCoverage, program);
137
141
  }
138
142
  beforeFileTranspile(event) {
139
- let testSuite = this.session.sessionInfo.testSuitesToRun.find((ts) => ts.file.pkgPath === event.file.pkgPath);
140
- if (testSuite) {
143
+ const testSuites = this.session.sessionInfo.testSuitesToRun.filter((ts) => ts.file.pkgPath === event.file.pkgPath);
144
+ for (const testSuite of testSuites) {
141
145
  const scope = (0, Utils_1.getScopeForSuite)(testSuite);
142
146
  let noEarlyExit = testSuite.annotation.noEarlyExit;
143
147
  if (noEarlyExit) {
@@ -145,7 +149,6 @@ class RooibosPlugin {
145
149
  }
146
150
  const modifiedTestCases = new Set();
147
151
  const modifiedHookFunctions = new Set();
148
- testSuite.addDataFunctions(event.editor);
149
152
  for (let group of [...testSuite.testGroups.values()].filter((tg) => tg.isIncluded)) {
150
153
  for (const hookName of [group.setupFunctionName, group.tearDownFunctionName, group.beforeEachFunctionName, group.afterEachFunctionName]) {
151
154
  if (hookName) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rooibos-roku",
3
- "version": "5.16.5",
3
+ "version": "5.16.6",
4
4
  "description": "simple, flexible, fun brightscript test framework for roku scenegraph apps - roku brighterscript plugin",
5
5
  "scripts": {
6
6
  "preversion": "npm run build && npm run lint && npm run test",
@@ -20,12 +20,12 @@
20
20
  "package": "npm run build && npm pack"
21
21
  },
22
22
  "dependencies": {
23
- "brighterscript": "^0.73.3",
23
+ "brighterscript": "^0.73.5",
24
24
  "fast-glob": "^3.2.12",
25
25
  "fs-extra": "^10.1.0",
26
26
  "minimatch": "^3.0.4",
27
- "roku-debug": "^0.24.3",
28
- "roku-deploy": "^4.0.0-alpha.5",
27
+ "roku-debug": "^0.24.6",
28
+ "roku-deploy": "^4.0.0-alpha.9",
29
29
  "rooibos_promises": "npm:@rokucommunity/promises@^0.5.0",
30
30
  "source-map": "^0.7.3",
31
31
  "undent": "^1.0.1",
@@ -62,10 +62,13 @@
62
62
  "typescript": "^4.7.2"
63
63
  },
64
64
  "overrides": {
65
- "serialize-javascript": "^7.0.5",
65
+ "serialize-javascript": "^7",
66
66
  "js-yaml@^3": "^3.15.2",
67
- "js-yaml@^4": "^4.3.2",
68
- "browserslist": "^4.28.8"
67
+ "js-yaml@^4": "^4",
68
+ "browserslist": "^4.28.8",
69
+ "istanbul-lib-processinfo": "^3.0.1",
70
+ "uuid": "^11.1.1",
71
+ "@babel/core": "^7.29.7"
69
72
  },
70
73
  "main": "dist/plugin.js",
71
74
  "bin": {
@@ -113,17 +116,6 @@
113
116
  "functions": 5,
114
117
  "branches": 5
115
118
  },
116
- "mocha": {
117
- "spec": "src/**/*.spec.ts",
118
- "fullTrace": true,
119
- "require": [
120
- "source-map-support/register",
121
- "ts-node/register"
122
- ],
123
- "watchExtensions": [
124
- "ts"
125
- ]
126
- },
127
119
  "ropm": {
128
120
  "rootDir": "./framework/src"
129
121
  }