Skip to content

test: run the TestRunner suite on jasmine-core 7 from npm - #547

Draft
edusperoni wants to merge 2 commits into
mainfrom
test/jasmine-7
Draft

edusperoni wants to merge 2 commits into
mainfrom
test/jasmine-7

Conversation

@edusperoni

Copy link
Copy Markdown
Collaborator

Moves the TestRunner suite from a vendored Jasmine 2.0.1 (2014) to jasmine-core 7.0.2, installed from npm instead of committed.

jasmine-core comes from npm

  • jasmine-core is a pinned root devDependency (7.0.2).
  • A new Stage Test Runner Dependencies phase on the TestRunner target runs tools/stage-test-runner-deps.mjs before Copy Bundle Resources. It copies the package's single-file build and its license into TestRunner/app/Infrastructure/Jasmine/vendor/ (gitignored), which the app-folder reference then bundles.
  • The phase finds node through .xcode.env / .xcode.env.local, like the js2c phase. CI already runs npm install at the repo root (scripts/install-ci-deps.sh), so no workflow changes are needed. Locally, run npm install once (README updated).

Harness

  • New Infrastructure/Jasmine/boot.js. It keeps declaration order (random: false; the shared Workers suite carries state between specs), the quarantine specFilter and the suite progress beacon. The async-function and fail() shims are dropped because Jasmine now handles both.
  • A custom object formatter works around Jasmine's pretty-printer throwing on null-prototype tagged objects such as module namespaces. toBe() builds its message even when it passes, so expect(ns).toBe(ns) threw value.toString is not a function. This is worth reporting upstream.
  • Reporters:
    • excluded and notApplicable specs count as skipped.
    • Suite-level errors (afterAll, errors raised between specs) and run-level errors are written as failing JUnit testcases, so verify-junit-xml fails the build on them.
    • XML escaping no longer double-escapes entities, and a ]]> in a stack no longer breaks the CDATA block.

Spec changes

  • Global errors. Jasmine 7 fails the running spec when a global error/unhandledrejection event fires; 2.0.1 never saw those events.

    • 15 specs that raise them on purpose (error events, unhandled rejections, escapeException boundaries, worker error forwarding, event-loop drain) run under raisesGlobalErrors (Infrastructure/Jasmine/globalErrorSpy.js). It wraps jasmine.spyOnGlobalErrorsAsync and doesn't cancel the events, so listeners, preventDefault() and the __onUncaughtError fallback still behave as in production.
    • Two worker specs whose error used to be re-reported on the global scope after they had finished now cancel it on the parent.
    • The malformed-URL HTTP loader spec left import("http://") unhandled, and its rejection landed in a later RemoteModuleSecurity spec. It now waits for the import.
  • Duplicate names are now a declaration error.

    • MethodCallsTests: 28 instance/static property pairs shared a name; they now use the file's …_Instance…/…_Static… scheme.
    • MethodCallsTests: a spec that had been pasted into another spec's body is split back out.
    • Timers.js: a copied spec is removed.
  • Shared tests. The submodule is bumped to common-runtime-tests-app test/jasmine-7-compat. That branch makes the shared specs version-agnostic:

    • worker errors raised on purpose are cancelled on the parent;
    • the Performance observer spec uses the global error spy when it exists;
    • done(reason) failure branches fail on 2.0.1 too.

    The branch is not on master yet. Merge it there first, then point this submodule at master before merging.

Testing

./run_tests.sh --keep-sim, iPhone 16 Pro / iOS 26.3:

Run Specs Failures Skipped
main (Jasmine 2.0.1, shared a2ccd8c) 1836 0 11
main harness + shared test/jasmine-7-compat (backwards-compat check) 1836 0 11
This branch 1836 0 11
This branch, rebuilt after deleting vendor/ (the phase restages it) 1836 0 11

The reporters were also checked in Node against jasmine-core 7 with a fake suite (failing, xit, filtered, pending, afterAll error, done(reason), async); the XML output parses.

Not covered here: Android still runs Jasmine 2.0.1. Only the backwards-compatible shared changes affect it, and I did not run its suite.

jasmine-core becomes a pinned root devDependency instead of a vendored copy.
A new "Stage Test Runner Dependencies" phase on the TestRunner target runs
tools/stage-test-runner-deps.mjs before Copy Bundle Resources, copying the
package's single-file build and license into the gitignored
TestRunner/app/Infrastructure/Jasmine/vendor/ so the app-folder reference
bundles it. The phase finds node the same way the js2c phase does
(.xcode.env / .xcode.env.local), and CI already runs `npm install` at the
repo root through scripts/install-ci-deps.sh.

The script rewrites a file only when its content changed, so incremental
builds do not recopy the app folder.
Replaces the vendored Jasmine 2.0.1 (and its 2.0 typings) with jasmine-core
7.0.2 from the staging step.

Harness:
- New Infrastructure/Jasmine/boot.js: installGlobals, declaration-order runs
  (random: false), the quarantine specFilter and the progress beacon carry
  over; the async-function and fail() shims are gone because Jasmine handles
  both natively.
- A custom object formatter keeps Jasmine's pretty-printer from throwing on
  null-prototype tagged objects such as module namespaces. toBe() formats
  its message even when it passes, so expect(ns).toBe(ns) threw.
- Reporters count excluded/notApplicable specs as skipped and write
  suite-level (afterAll, between-spec) and run-level errors as failing
  JUnit testcases, so CI's verify-junit-xml sees them. The JUnit escaping
  no longer double-escapes entities, and stacks containing "]]>" stay
  inside their CDATA.

Specs:
- Jasmine 7 routes global `error`/`unhandledrejection` events to the
  running spec. Specs that raise them on purpose run under
  raisesGlobalErrors (Infrastructure/Jasmine/globalErrorSpy.js), a wrapper
  over jasmine.spyOnGlobalErrorsAsync that leaves the events uncancelled.
  Worker specs whose error used to be re-reported on the global scope
  after they finished now cancel it on the parent, and the malformed-URL
  HTTP loader spec waits for the import it starts.
- Duplicate spec names are now a declaration error: MethodCallsTests'
  instance/static property pairs get the file's Instance/Static naming, a
  spec pasted into another spec's body is split back out, and a copied
  Timers spec is removed.
- Bumps the shared tests to common-runtime-tests-app test/jasmine-7-compat,
  which makes the shared specs work on both Jasmine 2.0.1 and 7.
@coderabbitai

coderabbitai Bot commented Nov 6, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant