rooibos-roku 5.16.4 → 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,48 @@ 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
+
30
+ ## [5.16.5](https://github.com/rokucommunity/rooibos/compare/5.16.4...v5.16.5) - 2026-09-09
31
+ ### Changed
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))
33
+ - Make before-exit sleep duration configurable ([#418](https://github.com/rokucommunity/rooibos/pull/418))
34
+ - Run stubCall/expectCalled/expectNotCalled rewrites in setUp/tearDown/beforeEach/afterEach hooks ([#403](https://github.com/rokucommunity/rooibos/pull/403))
35
+ - upgrade to [brighterscript@0.73.3](https://github.com/rokucommunity/brighterscript/blob/master/CHANGELOG.md#0733---2026-09-09). Notable changes since 0.72.5:
36
+ - Security enhancements ([#1733](https://github.com/rokucommunity/brighterscript/pull/1733), [#1763](https://github.com/rokucommunity/brighterscript/pull/1763), [#1764](https://github.com/rokucommunity/brighterscript/pull/1764), [#1766](https://github.com/rokucommunity/brighterscript/pull/1766), [#1773](https://github.com/rokucommunity/brighterscript/pull/1773), [#1774](https://github.com/rokucommunity/brighterscript/pull/1774), [#1775](https://github.com/rokucommunity/brighterscript/pull/1775), [#1782](https://github.com/rokucommunity/brighterscript/pull/1782), [#1796](https://github.com/rokucommunity/brighterscript/pull/1796))
37
+ - upgrade to [roku-debug@0.24.3](https://github.com/rokucommunity/roku-debug/blob/master/CHANGELOG.md#0243---2026-09-09). Notable changes since 0.23.11:
38
+ - Security enhancements ([#369](https://github.com/rokucommunity/roku-debug/pull/369), [#372](https://github.com/rokucommunity/roku-debug/pull/372), [#387](https://github.com/rokucommunity/roku-debug/pull/387), [#402](https://github.com/rokucommunity/roku-debug/pull/402), [#403](https://github.com/rokucommunity/roku-debug/pull/403), [#407](https://github.com/rokucommunity/roku-debug/pull/407), [#412](https://github.com/rokucommunity/roku-debug/pull/412), [#414](https://github.com/rokucommunity/roku-debug/pull/414), [#417](https://github.com/rokucommunity/roku-debug/pull/417))
39
+ - upgrade to [roku-deploy@3.18.4](https://github.com/rokucommunity/roku-deploy/blob/master/CHANGELOG.md#3184---2026-09-02). Notable changes since 3.17.6:
40
+ - Security enhancements ([#293](https://github.com/rokucommunity/roku-deploy/pull/293), [#345](https://github.com/rokucommunity/roku-deploy/pull/345))
41
+ - upgrade to [@rokucommunity/bslint@0.8.46](https://github.com/rokucommunity/bslint/blob/master/CHANGELOG.md#0846---2026-09-09). Notable changes since 0.8.43:
42
+ - Security enhancements ([#186](https://github.com/rokucommunity/bslint/pull/186), [#196](https://github.com/rokucommunity/bslint/pull/196), [#198](https://github.com/rokucommunity/bslint/pull/198), [#203](https://github.com/rokucommunity/bslint/pull/203))
43
+ - upgrade to [ropm@0.11.11](https://github.com/rokucommunity/ropm/blob/master/CHANGELOG.md#01111---2026-09-09). Notable changes since 0.11.8:
44
+ - Security enhancements ([#147](https://github.com/rokucommunity/ropm/pull/147), [#152](https://github.com/rokucommunity/ropm/pull/152), [#154](https://github.com/rokucommunity/ropm/pull/154), [#156](https://github.com/rokucommunity/ropm/pull/156), [#159](https://github.com/rokucommunity/ropm/pull/159))
45
+ ### Fixed
46
+ - Fix coverage instrumentation changing constructor execution order ([#355](https://github.com/rokucommunity/rooibos/pull/355))
47
+ - fix: skip assertion tracking injection for namespace function calls ([#385](https://github.com/rokucommunity/rooibos/pull/385))
48
+
49
+
50
+
9
51
  ## [5.16.4](https://github.com/rokucommunity/rooibos/compare/5.16.3...v5.16.4) - 2026-06-10
10
52
  ### Changed
11
53
  - Make tests less brittle - removes full transpile string checks ([#396](https://github.com/rokucommunity/rooibos/pull/396))
package/README.md CHANGED
@@ -30,6 +30,16 @@ Rooibos is an independent open-source project maintained exclusively by voluntee
30
30
 
31
31
  You might want to help! Get in touch via the [slack group](https://join.slack.com/t/rokudevelopers/shared_invite/zt-4vw7rg6v-NH46oY7hTktpRIBM_zGvwA) or [raise issues](https://github.com/rokucommunity/rooibos/issues/new).
32
32
 
33
+ To work on Rooibos locally:
34
+
35
+ ```bash
36
+ npm install
37
+ npx ropm copy # copies the framework's ropm dependencies into framework/src
38
+ npm test
39
+ ```
40
+
41
+ `npx ropm copy` is required because `npm install` alone doesn't copy the ropm modules the framework depends on. `npm run build` also runs it for you, and the test/device scripts will tell you if you've forgotten it.
42
+
33
43
  ## Sample project
34
44
 
35
45
  https://github.com/rokucommunity/rooibos-roku-sample
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
  }
package/dist/cli.js CHANGED
@@ -6,6 +6,33 @@ const brighterscript_1 = require("brighterscript");
6
6
  const yargs = require("yargs");
7
7
  const roku_deploy_1 = require("roku-deploy");
8
8
  const fs = require("fs");
9
+ const path = require("path");
10
+ /**
11
+ * Load simple `KEY=value` pairs from a .env file into process.env, without
12
+ * overwriting variables that are already set in the real environment.
13
+ */
14
+ function loadDotEnv(envPath = '.env') {
15
+ var _a;
16
+ var _b, _c;
17
+ if (!fs.existsSync(envPath)) {
18
+ return;
19
+ }
20
+ const contents = fs.readFileSync(envPath, 'utf8');
21
+ for (const line of contents.split(/\r?\n/)) {
22
+ const match = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(line);
23
+ if (!match) {
24
+ //skip blanks and comments
25
+ continue;
26
+ }
27
+ let value = match[2].trim();
28
+ //strip matching surrounding quotes
29
+ if (/^"(.*)"$/.test(value) || /^'(.*)'$/.test(value)) {
30
+ value = value.slice(1, -1);
31
+ }
32
+ (_a = (_b = process.env)[_c = match[1]]) !== null && _a !== void 0 ? _a : (_b[_c] = value);
33
+ }
34
+ }
35
+ loadDotEnv();
9
36
  let options = yargs
10
37
  .usage('$0', 'Rooibos: a simple, flexible, fun Brightscript test framework for Roku Scenegraph apps')
11
38
  .help('help', 'View help information about this tool.')
@@ -15,11 +42,11 @@ let options = yargs
15
42
  .option('log-level', { type: 'string', defaultDescription: '"log"', description: 'The log level. Value can be "error", "warn", "log", "info", "debug".' })
16
43
  .check((argv) => {
17
44
  var _a;
18
- if (!argv.host) {
19
- return new Error('You must provide a host. (--host)');
45
+ if (!argv.host && !process.env.ROKU_HOST) {
46
+ return new Error('You must provide a host. (--host, or ROKU_HOST in .env)');
20
47
  }
21
- if (!argv.password) {
22
- return new Error('You must provide a password. (--password)');
48
+ if (!argv.password && !process.env.ROKU_PASSWORD) {
49
+ return new Error('You must provide a password. (--password, or ROKU_PASSWORD in .env)');
23
50
  }
24
51
  if (!argv.project) {
25
52
  console.log('No project file specified. Using "./bsconfig.json"');
@@ -32,22 +59,23 @@ let options = yargs
32
59
  })
33
60
  .argv;
34
61
  async function main() {
35
- var _a, _b, _c, _d;
62
+ var _a, _b, _c, _d, _e, _f;
36
63
  let currentErrorCode = 0;
37
64
  let bsconfigPath = (_a = options.project) !== null && _a !== void 0 ? _a : 'bsconfig.json';
38
65
  console.log(`Using bsconfig: ${bsconfigPath}`);
39
66
  const rawConfig = brighterscript_1.util.loadConfigFile(bsconfigPath);
40
67
  const bsConfig = brighterscript_1.util.normalizeConfig(rawConfig);
41
- const host = (_b = options.host) !== null && _b !== void 0 ? _b : bsConfig.host;
42
- const password = (_c = options.password) !== null && _c !== void 0 ? _c : bsConfig.password;
43
- const logLevel = (_d = brighterscript_1.LogLevel[options['log-level']]) !== null && _d !== void 0 ? _d : bsConfig.logLevel;
68
+ const host = (_c = (_b = options.host) !== null && _b !== void 0 ? _b : bsConfig.host) !== null && _c !== void 0 ? _c : process.env.ROKU_HOST;
69
+ const password = (_e = (_d = options.password) !== null && _d !== void 0 ? _d : bsConfig.password) !== null && _e !== void 0 ? _e : process.env.ROKU_PASSWORD;
70
+ const logLevel = (_f = brighterscript_1.LogLevel[options['log-level']]) !== null && _f !== void 0 ? _f : bsConfig.logLevel;
44
71
  const builder = new brighterscript_1.ProgramBuilder();
45
72
  builder.logger.logLevel = logLevel;
46
73
  await builder.run(Object.assign(Object.assign({}, options), { retainStagingDir: true, createPackage: true }));
74
+ const device = { host: host };
47
75
  const rokuDeploy = new roku_deploy_1.RokuDeploy();
48
- const deviceInfo = await rokuDeploy.getDeviceInfo({ host: host });
49
- const rendezvousTracker = new roku_debug_1.RendezvousTracker({ softwareVersion: deviceInfo['software-version'] }, { host: host, remotePort: 8085 });
50
- const telnet = new roku_debug_1.TelnetAdapter({ host: options.host }, rendezvousTracker);
76
+ const deviceInfo = await rokuDeploy.getDeviceInfo({ device: device });
77
+ const rendezvousTracker = new roku_debug_1.RendezvousTracker({ softwareVersion: deviceInfo['software-version'] }, { device: device, remotePort: 8085 });
78
+ const telnet = new roku_debug_1.TelnetAdapter({ device: device }, rendezvousTracker);
51
79
  telnet.logger.logLevel = logLevel;
52
80
  await telnet.activate();
53
81
  await telnet.connect();
@@ -57,7 +85,7 @@ async function main() {
57
85
  if (emitAppExit) {
58
86
  telnet.beginAppExit();
59
87
  }
60
- await rokuDeploy.pressHomeButton(host); // roku-deploy v4: keyPress({ host: options.host, key: 'home' });
88
+ await rokuDeploy.keyPress({ device: device, key: 'Home' });
61
89
  process.exit(currentErrorCode);
62
90
  }
63
91
  telnet.on('console-output', (output) => {
@@ -96,11 +124,10 @@ async function main() {
96
124
  async function deployBuiltFiles() {
97
125
  const outFile = bsConfig.outFile;
98
126
  console.log(`Deploying ${outFile} to ${host}`);
99
- await rokuDeploy.publish({
127
+ await rokuDeploy.sideload({
100
128
  password: password,
101
- host: host,
102
- outFile: outFile,
103
- outDir: process.cwd()
129
+ device: device,
130
+ zip: path.resolve(process.cwd(), outFile)
104
131
  });
105
132
  }
106
133
  await deployBuiltFiles();
@@ -685,7 +685,7 @@ sub rooibos_promises_internal_delay(callback as Function, context as dynamic, du
685
685
  end sub
686
686
 
687
687
  ' Observes a node field using observeFieldScoped
688
- ' @param {roSGNode} node - The node to apply the observer
688
+ ' @param {rooibos.promises.roSGNode} node - The node to apply the observer
689
689
  ' @param {String} field - The name of the field to be monitored.
690
690
  ' @param {Dynamic} callback - The name or message port to be executed when the value of the field changes.
691
691
  ' @return true if field could be observed, false if not
@@ -704,7 +704,7 @@ function rooibos_promises_internal_observeFieldScoped(node as object, field as s
704
704
  end function
705
705
 
706
706
  ' Unobserve a node field using unobserveFieldScoped
707
- ' @param {roSGNode} node - The node to remove the observer from
707
+ ' @param {rooibos.promises.roSGNode} node - The node to remove the observer from
708
708
  ' @param {String} field - The name of the field to no longer be monitored.
709
709
  ' @return true if field could be unobserved, false if not
710
710
  function rooibos_promises_internal_unobserveFieldScoped(node as object, field as string)
@@ -1,49 +1,49 @@
1
+ namespace rooibos.promises
1
2
  ' @rokucommunity/promises v0.5.0
2
3
  ' Create a new promise
3
- namespace rooibos.promises
4
- function create() as dynamic
4
+ function create() as dynamic
5
5
  end function
6
6
  end namespace
7
- ' TODO rename this to `then` once BrighterScript supports using keywords as namespaced function names
8
7
  namespace rooibos.promises
9
- function onThen(promise as dynamic, callback as function, context = "__INVALID__" as object) as dynamic
8
+ ' TODO rename this to `then` once BrighterScript supports using keywords as namespaced function names
9
+ function onThen(promise as dynamic, callback as function, context = "__INVALID__" as object) as dynamic
10
10
  end function
11
11
  end namespace
12
- ' TODO rename this to `catch` once BrighterScript supports using keywords as namespaced function names
13
12
  namespace rooibos.promises
14
- function onCatch(promise as dynamic, callback as function, context = "__INVALID__" as object) as dynamic
13
+ ' TODO rename this to `catch` once BrighterScript supports using keywords as namespaced function names
14
+ function onCatch(promise as dynamic, callback as function, context = "__INVALID__" as object) as dynamic
15
15
  end function
16
16
  end namespace
17
- ' TODO rename this to `finally` once BrighterScript supports using keywords as namespaced function names
18
17
  namespace rooibos.promises
19
- function onFinally(promise as dynamic, callback as function, context = "__INVALID__" as object) as dynamic
18
+ ' TODO rename this to `finally` once BrighterScript supports using keywords as namespaced function names
19
+ function onFinally(promise as dynamic, callback as function, context = "__INVALID__" as object) as dynamic
20
20
  end function
21
21
  end namespace
22
- ' Takes an array of promises as input and returns a single Promise.
22
+ namespace rooibos.promises
23
+ ' Takes an array of promises as input and returns a single Promise.
23
24
  ' This returned promise fulfills when all of the input's promises fulfill (including when an empty array is passed), with an array of the fulfillment values.
24
25
  ' It rejects when any of the input's promises rejects, with this first rejection reason.
25
- namespace rooibos.promises
26
- function all(promiseArray as dynamic) as dynamic
26
+ function all(promiseArray as dynamic) as dynamic
27
27
  end function
28
28
  end namespace
29
- ' Takes an array of promises as input and returns a single Promise.
29
+ namespace rooibos.promises
30
+ ' Takes an array of promises as input and returns a single Promise.
30
31
  ' This returned promise fulfills when all of the input's promises settle (including when an empty array is passed),
31
32
  ' with an array of objects that describe the outcome of each promise.
32
- namespace rooibos.promises
33
- function allSettled(promiseArray as dynamic) as dynamic
33
+ function allSettled(promiseArray as dynamic) as dynamic
34
34
  end function
35
35
  end namespace
36
- ' Takes an array of promises as input and returns a single Promise.
36
+ namespace rooibos.promises
37
+ ' Takes an array of promises as input and returns a single Promise.
37
38
  ' This returned promise fulfills when any of the input's promises fulfills, with this first fulfillment value.
38
39
  ' It rejects when all of the input's promises reject (including when an empty array is passed), with an AggregateError containing an array of rejection reasons.
39
- namespace rooibos.promises
40
- function any(promiseArray as dynamic) as dynamic
40
+ function any(promiseArray as dynamic) as dynamic
41
41
  end function
42
42
  end namespace
43
- ' Takes an array of promises as input and returns a single Promise.
44
- ' This returned promise settles with the eventual state of the first promise that settles.
45
43
  namespace rooibos.promises
46
- function race(promiseArray as dynamic) as dynamic
44
+ ' Takes an array of promises as input and returns a single Promise.
45
+ ' This returned promise settles with the eventual state of the first promise that settles.
46
+ function race(promiseArray as dynamic) as dynamic
47
47
  end function
48
48
  end namespace
49
49
  namespace rooibos.promises
@@ -58,29 +58,29 @@ end namespace
58
58
  function isComplete(promise as object) as boolean
59
59
  end function
60
60
  end namespace
61
- ' Determines if the given item is a promise.
61
+ namespace rooibos.promises
62
+ ' Determines if the given item is a promise.
62
63
  '
63
64
  ' Will return true if at least one of the following conditions are true:
64
65
  ' - the SubType exactly equals "Promise"
65
66
  ' - the subtype ends with "_promise" case insensitive
66
67
  ' - the node has a field called "promiseState"
67
- namespace rooibos.promises
68
- function isPromise(promise as dynamic) as boolean
68
+ function isPromise(promise as dynamic) as boolean
69
69
  end function
70
70
  end namespace
71
- ' Remove all promise storage from the current m
72
71
  namespace rooibos.promises
73
- sub clean()
72
+ ' Remove all promise storage from the current m
73
+ sub clean()
74
74
  end sub
75
75
  end namespace
76
- 'Allows chaining multiple promise operations in a row in a clean syntax
77
76
  namespace rooibos.promises
78
- function chain(initialPromise as object, context = "__INVALID__" as object) as object
77
+ 'Allows chaining multiple promise operations in a row in a clean syntax
78
+ function chain(initialPromise as object, context = "__INVALID__" as object) as object
79
79
  end function
80
80
  end namespace
81
- ' Makes sure the value supplied is a promise
82
81
  namespace rooibos.promises
83
- function ensurePromise(value as object) as object
82
+ ' Makes sure the value supplied is a promise
83
+ function ensurePromise(value as object) as object
84
84
  end function
85
85
  end namespace
86
86
  namespace rooibos.promises
@@ -151,14 +151,14 @@ namespace rooibos.promises.internal
151
151
  sub delay(callback as function, context as dynamic, duration = 0.0001 as float)
152
152
  end sub
153
153
  ' Observes a node field using observeFieldScoped
154
- ' @param {roSGNode} node - The node to apply the observer
154
+ ' @parrooibos.promises.internal.roSGNodeNode} node - The node to apply the observer
155
155
  ' @param {String} field - The name of the field to be monitored.
156
156
  ' @param {Dynamic} callback - The name or message port to be executed when the value of the field changes.
157
157
  ' @return true if field could be observed, false if not
158
158
  function observeFieldScoped(node as object, field as string, callback as dynamic, infoFields = [] as object)
159
159
  end function
160
160
  ' Unobserve a node field using unobserveFieldScoped
161
- ' @param {roSGNode} node - The node to remove the observer from
161
+ ' @parrooibos.promises.internal.roSGNodeNode} node - The node to remove the observer from
162
162
  ' @param {String} field - The name of the field to no longer be monitored.
163
163
  ' @return true if field could be unobserved, false if not
164
164
  function unobserveFieldScoped(node as object, field as string)
@@ -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)
@@ -40,7 +40,7 @@ namespace rooibos
40
40
  ' leading to an instant exit of the application
41
41
 
42
42
  ' Give the io port time to finish sending all the logs
43
- sleep(400)
43
+ sleep(runner.config.shutdownDelay)
44
44
  end
45
45
  end if
46
46
  end if
@@ -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;
@@ -121,7 +121,11 @@ class CodeCoverageProcessor {
121
121
  },
122
122
  ExpressionStatement: (ds, parent, owner, key) => {
123
123
  this.addStatement(ds);
124
- this.convertStatementToCoverageStatement(ds, CodeCoverageLineType.code, owner, key);
124
+ //bsc's class transpiler assumes a `super()` call sits at index 0 of the constructor body, and
125
+ //injects field initializers immediately after it. Inserting our coverage statement *before*
126
+ //`super()` would shift it off index 0, causing field initializers to be emitted before the
127
+ //`super()` call. So for `super()` we insert coverage *after* the call instead.
128
+ this.convertStatementToCoverageStatement(ds, CodeCoverageLineType.code, owner, key, this.isSuperCall(ds));
125
129
  }
126
130
  }), { walkMode: brighterscript_1.WalkMode.visitAllRecursive });
127
131
  const coverageMapObject = {};
@@ -132,14 +136,27 @@ class CodeCoverageProcessor {
132
136
  this.filePathMap[this.fileId] = file.pkgPath;
133
137
  this.addBrsAPIText(file, astEditor);
134
138
  }
135
- convertStatementToCoverageStatement(statement, coverageType, owner, key) {
139
+ /**
140
+ * Is this statement a call to `super()`? (i.e. the parent-constructor call in a derived class constructor)
141
+ */
142
+ isSuperCall(statement) {
143
+ var _a, _b, _c;
144
+ return (0, brighterscript_1.isExpressionStatement)(statement) &&
145
+ (0, brighterscript_1.isCallExpression)(statement.expression) &&
146
+ ((_c = (_b = (_a = brighterscript_1.util.findBeginningVariableExpression(statement.expression.callee)) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.text) === null || _c === void 0 ? void 0 : _c.toLowerCase()) === 'super';
147
+ }
148
+ /**
149
+ * Insert a coverage-tracking statement adjacent to the given statement.
150
+ * When `insertAfter` is true, the coverage statement is inserted *after* the given statement rather than before it.
151
+ */
152
+ convertStatementToCoverageStatement(statement, coverageType, owner, key, insertAfter = false) {
136
153
  if (this.processedStatements.has(statement) || this.addedStatements.has(statement)) {
137
154
  return;
138
155
  }
139
156
  const lineNumber = statement.range.start.line;
140
157
  this.coverageMap.set(lineNumber, coverageType);
141
158
  const parsed = brighterscript_1.Parser.parse(this.getFuncCallText(lineNumber, coverageType)).ast.statements[0];
142
- this.astEditor.arraySplice(owner, key, 0, parsed);
159
+ this.astEditor.arraySplice(owner, insertAfter ? key + 1 : key, 0, parsed);
143
160
  this.addedStatements.add(parsed);
144
161
  // store the statement in a set to avoid handling again after inserting statement above
145
162
  this.processedStatements.add(statement);
@@ -101,15 +101,35 @@ class MockUtil {
101
101
  }
102
102
  gatherGlobalMethodMocks(testSuite) {
103
103
  // console.log('gathering global method mocks for testSuite', testSuite.name);
104
+ const processedFuncs = new Set();
104
105
  for (let group of [...testSuite.testGroups.values()].filter((tg) => tg.isIncluded)) {
106
+ for (const hookName of [group.setupFunctionName, group.tearDownFunctionName, group.beforeEachFunctionName, group.afterEachFunctionName]) {
107
+ if (hookName) {
108
+ const key = hookName.toLowerCase();
109
+ if (!processedFuncs.has(key)) {
110
+ this.gatherMockedFunctionByName(testSuite, hookName);
111
+ processedFuncs.add(key);
112
+ }
113
+ }
114
+ }
105
115
  for (let testCase of [...group.testCases].filter((tc) => tc.isIncluded)) {
106
- this.gatherMockedGlobalMethods(testSuite, testCase);
116
+ const key = testCase.funcName.toLowerCase();
117
+ if (!processedFuncs.has(key)) {
118
+ this.gatherMockedGlobalMethods(testSuite, testCase);
119
+ processedFuncs.add(key);
120
+ }
107
121
  }
108
122
  }
109
123
  }
110
124
  gatherMockedGlobalMethods(testSuite, testCase) {
125
+ this.gatherMockedFunctionByName(testSuite, testCase.funcName);
126
+ }
127
+ gatherMockedFunctionByName(testSuite, funcName) {
111
128
  try {
112
- let func = testSuite.classStatement.methods.find((m) => m.name.text.toLowerCase() === testCase.funcName.toLowerCase());
129
+ let func = testSuite.classStatement.methods.find((m) => m.name.text.toLowerCase() === funcName.toLowerCase());
130
+ if (!func) {
131
+ return;
132
+ }
113
133
  func.walk((0, brighterscript_1.createVisitor)({
114
134
  ExpressionStatement: (expressionStatement, parent, owner) => {
115
135
  let callExpression = expressionStatement.expression;
@@ -112,7 +112,7 @@ class RooibosSession {
112
112
  }
113
113
  }
114
114
  updateRunTimeConfigFunction(classStatement, editor) {
115
- var _a, _b, _c;
115
+ var _a, _b, _c, _d;
116
116
  let method = classStatement.methods.find((m) => m.name.text === 'getRuntimeConfig');
117
117
  if (method) {
118
118
  editor.addToArray(method.func.body.statements, method.func.body.statements.length, brighterscript_1.Parser.parse((0, undent_1.default) `
@@ -130,6 +130,7 @@ class RooibosSession {
130
130
  "colorizeOutput": ${this.config.colorizeOutput ? 'true' : 'false'}
131
131
  "throwOnFailedAssertion": ${this.config.throwOnFailedAssertion ? 'true' : 'false'}
132
132
  "keepAppOpen": ${this.config.keepAppOpen === undefined || this.config.keepAppOpen ? 'true' : 'false'}
133
+ "shutdownDelay": ${(_d = this.config.shutdownDelay) !== null && _d !== void 0 ? _d : 400}
133
134
  "isRecordingCodeCoverage": ${this.config.isRecordingCodeCoverage ? 'true' : 'false'}
134
135
  }
135
136
  `).ast.statements[0]);
@@ -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
@@ -23,15 +23,28 @@ class TestGroup extends TestSuite_1.TestBlock {
23
23
  this.hasAsyncTests || (this.hasAsyncTests = testCase.isAsync);
24
24
  }
25
25
  modifyAssertions(testCase, noEarlyExit, editor, namespaceLookup, scope) {
26
+ let func = this.testSuite.classStatement.methods.find((m) => m.name.text.toLowerCase() === testCase.funcName.toLowerCase());
27
+ this.modifyAssertionsInFunction(func, noEarlyExit, editor, namespaceLookup, scope);
28
+ }
29
+ modifyAssertionsForHook(hookFuncName, noEarlyExit, editor, namespaceLookup, scope) {
30
+ if (!hookFuncName) {
31
+ return;
32
+ }
33
+ let func = this.testSuite.classStatement.methods.find((m) => m.name.text.toLowerCase() === hookFuncName.toLowerCase());
34
+ if (!func) {
35
+ return;
36
+ }
37
+ this.modifyAssertionsInFunction(func, noEarlyExit, editor, namespaceLookup, scope);
38
+ }
39
+ modifyAssertionsInFunction(func, noEarlyExit, editor, namespaceLookup, scope) {
26
40
  //for each method
27
41
  //if assertion
28
42
  //wrap with if is not fail
29
43
  //add line number as last param
30
44
  try {
31
- let func = this.testSuite.classStatement.methods.find((m) => m.name.text.toLowerCase() === testCase.funcName.toLowerCase());
32
45
  func.walk((0, brighterscript_1.createVisitor)({
33
46
  ExpressionStatement: (expressionStatement, parent, owner, key) => {
34
- var _a, _b;
47
+ var _a, _b, _c;
35
48
  let callExpression = expressionStatement.expression;
36
49
  if ((0, brighterscript_1.isCallExpression)(callExpression) && (0, brighterscript_1.isDottedGetExpression)(callExpression.callee)) {
37
50
  let dge = callExpression.callee;
@@ -44,6 +57,14 @@ class TestGroup extends TestSuite_1.TestBlock {
44
57
  // `someMagicVar`.assert*(...)
45
58
  const callPath = (_b = brighterscript_1.util.getAllDottedGetParts(callExpression.callee.obj)) === null || _b === void 0 ? void 0 : _b.map((part) => part.text).join('.');
46
59
  if (callPath) {
60
+ // Skip if callPath starts with a namespace name — this is a namespace
61
+ // function call (e.g. some.space.assertEqual()), not a method call on
62
+ // an object like m. Injecting assertion tracking on a namespace prefix
63
+ // produces invalid output (e.g. some_space.currentAssertLineNumber).
64
+ const callPathFirstPart = callPath.split('.')[0].toLowerCase();
65
+ if (namespaceLookup.has(callPathFirstPart) || ((_c = scope === null || scope === void 0 ? void 0 : scope.namespaceLookup) === null || _c === void 0 ? void 0 : _c.has(callPathFirstPart))) {
66
+ return;
67
+ }
47
68
  if (dge.name.text === 'stubCall') {
48
69
  this.modifyModernRooibosExpectCallExpression(callExpression, editor, namespaceLookup, scope);
49
70
  return expressionStatement;
@@ -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,22 +130,35 @@ 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) {
144
148
  console.warn(`WARNING: testSuite "${testSuite.name}" is marked as noEarlyExit`);
145
149
  }
146
150
  const modifiedTestCases = new Set();
147
- testSuite.addDataFunctions(event.editor);
151
+ const modifiedHookFunctions = new Set();
148
152
  for (let group of [...testSuite.testGroups.values()].filter((tg) => tg.isIncluded)) {
153
+ for (const hookName of [group.setupFunctionName, group.tearDownFunctionName, group.beforeEachFunctionName, group.afterEachFunctionName]) {
154
+ if (hookName) {
155
+ const hookKey = group.testSuite.generatedNodeName + group.file.pkgPath + hookName.toLowerCase();
156
+ if (!modifiedHookFunctions.has(hookKey)) {
157
+ group.modifyAssertionsForHook(hookName, noEarlyExit, event.editor, this.session.namespaceLookup, scope);
158
+ modifiedHookFunctions.add(hookKey);
159
+ }
160
+ }
161
+ }
149
162
  for (let testCase of [...group.testCases].filter((tc) => tc.isIncluded)) {
150
163
  let caseName = group.testSuite.generatedNodeName + group.file.pkgPath + testCase.funcName;
151
164
  if (!modifiedTestCases.has(caseName)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rooibos-roku",
3
- "version": "5.16.4",
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",
@@ -16,15 +16,16 @@
16
16
  "test:nocover": "mocha",
17
17
  "audit": "npm audit || audit-ci --config ./audit-ci.jsonc",
18
18
  "cli": "ts-node src/cli.ts",
19
+ "cli:device": "ts-node src/cli.ts --project test-project/bsconfig.device.json",
19
20
  "package": "npm run build && npm pack"
20
21
  },
21
22
  "dependencies": {
22
- "brighterscript": "^0.72.5",
23
+ "brighterscript": "^0.73.5",
23
24
  "fast-glob": "^3.2.12",
24
25
  "fs-extra": "^10.1.0",
25
26
  "minimatch": "^3.0.4",
26
- "roku-debug": "^0.23.11",
27
- "roku-deploy": "^3.17.6",
27
+ "roku-debug": "^0.24.6",
28
+ "roku-deploy": "^4.0.0-alpha.9",
28
29
  "rooibos_promises": "npm:@rokucommunity/promises@^0.5.0",
29
30
  "source-map": "^0.7.3",
30
31
  "undent": "^1.0.1",
@@ -33,7 +34,7 @@
33
34
  "yargs": "^16.2.0"
34
35
  },
35
36
  "devDependencies": {
36
- "@rokucommunity/bslint": "^0.8.43",
37
+ "@rokucommunity/bslint": "^0.8.46",
37
38
  "@types/chai": "^4.1.2",
38
39
  "@types/events": "^3.0.0",
39
40
  "@types/fs-extra": "^5.0.1",
@@ -55,13 +56,19 @@
55
56
  "jsdoc": "^4.0.5",
56
57
  "mocha": "^10.8.2",
57
58
  "nyc": "^15.1.0",
58
- "ropm": "^0.11.8",
59
+ "ropm": "^0.11.11",
59
60
  "source-map-support": "^0.5.13",
60
61
  "ts-node": "^10.7.0",
61
62
  "typescript": "^4.7.2"
62
63
  },
63
64
  "overrides": {
64
- "serialize-javascript": "^7.0.5"
65
+ "serialize-javascript": "^7",
66
+ "js-yaml@^3": "^3.15.2",
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"
65
72
  },
66
73
  "main": "dist/plugin.js",
67
74
  "bin": {
@@ -109,17 +116,6 @@
109
116
  "functions": 5,
110
117
  "branches": 5
111
118
  },
112
- "mocha": {
113
- "spec": "src/**/*.spec.ts",
114
- "fullTrace": true,
115
- "require": [
116
- "source-map-support/register",
117
- "ts-node/register"
118
- ],
119
- "watchExtensions": [
120
- "ts"
121
- ]
122
- },
123
119
  "ropm": {
124
120
  "rootDir": "./framework/src"
125
121
  }