Merge branch 'master' into top-level-equals
diff --git a/.github/ISSUE_TEMPLATE/01_test_runner_bug.md b/.github/ISSUE_TEMPLATE/01_test_runner_bug.md
new file mode 100644
index 0000000..e49d277
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/01_test_runner_bug.md
@@ -0,0 +1,14 @@
+---
+name: I found a bug in the test runner
+about: >-
+ Report a bug in running tests, integration with a specific platform, or
+ any behavior of 'package:test'.
+title: ''
+labels: bug
+---
+Describe the bug in detail.
+Include the specific command you ran and any relevant details about the
+environment, including operating system, Dart SDK version, and the version of
+`package:test` you are using.
+Whenever possible, include a full reproduction example that we can run to
+observe the problem.
diff --git a/.github/ISSUE_TEMPLATE/02_test_runner_feature.md b/.github/ISSUE_TEMPLATE/02_test_runner_feature.md
new file mode 100644
index 0000000..56170ba
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/02_test_runner_feature.md
@@ -0,0 +1,10 @@
+---
+name: I'd like a new feature in the test runner
+about: >-
+ Propose a feature for 'package:test' that would make testing easier or more
+ powerful.
+title: ''
+labels: enhancement
+---
+Describe the feature and include specific description of the use case, or use
+cases, you have in mind.
diff --git a/.github/ISSUE_TEMPLATE/03_checks_feedback.md b/.github/ISSUE_TEMPLATE/03_checks_feedback.md
new file mode 100644
index 0000000..5eb0039
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/03_checks_feedback.md
@@ -0,0 +1,8 @@
+---
+name: I have feedback for the package:checks preview
+about: Suggest a change, new feature, or bug, for 'package:checks'.
+title: ''
+labels: package:checks
+---
+Add any feedback about `package:checks`.
+Include a description of a specific use case for any feature requests.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 9523511..99e98e3 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -2,8 +2,28 @@
# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates
version: 2
-updates:
- - package-ecosystem: github-actions
- directory: /
+
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
schedule:
- interval: monthly
+ interval: "monthly"
+ labels:
+ - "autosubmit"
+
+ # Check daily for major version dependency updates for packages which depend
+ # on package:analyzer.
+ - package-ecosystem: "pub"
+ directory: "pkgs/test"
+ schedule:
+ interval: "daily"
+ versioning-strategy: increase-if-necessary
+ reviewers:
+ - "natebosch"
+ - package-ecosystem: "pub"
+ directory: "pkgs/test_core"
+ schedule:
+ interval: "daily"
+ versioning-strategy: increase-if-necessary
+ reviewers:
+ - "natebosch"
diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml
index c411012..098eab1 100644
--- a/.github/workflows/dart.yml
+++ b/.github/workflows/dart.yml
@@ -1,4 +1,4 @@
-# Created with package:mono_repo v6.5.0
+# Created with package:mono_repo v6.5.7
name: Dart CI
on:
push:
@@ -21,7 +21,7 @@
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:stable"
@@ -29,71 +29,37 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: stable
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- name: mono_repo self validate
- run: dart pub global activate mono_repo 6.5.0
+ run: dart pub global activate mono_repo 6.5.7
- name: mono_repo self validate
run: dart pub global run mono_repo generate --validate
job_002:
- name: "analyze_and_format; linux; Dart 2.18.0; PKG: legacy_tests/nnbd_opted_in_with_optout; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos`"
+ name: "analyze_and_format; linux; Dart 3.0.0; PKGS: pkgs/checks, pkgs/test_core; `dart analyze`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:legacy_tests/nnbd_opted_in_with_optout;commands:format-analyze_0"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/checks-pkgs/test_core;commands:analyze_1"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:legacy_tests/nnbd_opted_in_with_optout
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/checks-pkgs/test_core
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- - id: legacy_tests_nnbd_opted_in_with_optout_pub_upgrade
- name: legacy_tests/nnbd_opted_in_with_optout; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in_with_optout
- - name: "legacy_tests/nnbd_opted_in_with_optout; dart format --output=none --set-exit-if-changed ."
- run: "dart format --output=none --set-exit-if-changed ."
- if: "always() && steps.legacy_tests_nnbd_opted_in_with_optout_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in_with_optout
- - name: "legacy_tests/nnbd_opted_in_with_optout; dart analyze --fatal-infos"
- run: dart analyze --fatal-infos
- if: "always() && steps.legacy_tests_nnbd_opted_in_with_optout_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in_with_optout
- job_003:
- name: "analyze_and_format; linux; Dart 2.18.0; PKGS: pkgs/checks, pkgs/test_core; `dart analyze`"
- runs-on: ubuntu-latest
- steps:
- - name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
- with:
- path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/checks-pkgs/test_core;commands:analyze_1"
- restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/checks-pkgs/test_core
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
- os:ubuntu-latest;pub-cache-hosted
- os:ubuntu-latest
- - name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- with:
- sdk: "2.18.0"
- - id: checkout
- name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_checks_pub_upgrade
name: pkgs/checks; dart pub upgrade
run: dart pub upgrade
@@ -112,27 +78,27 @@
run: dart analyze
if: "always() && steps.pkgs_test_core_pub_upgrade.conclusion == 'success'"
working-directory: pkgs/test_core
- job_004:
- name: "analyze_and_format; linux; Dart dev; PKGS: integration_tests/spawn_hybrid, legacy_tests/nnbd_opted_in, pkgs/checks, pkgs/test, pkgs/test_api, pkgs/test_core; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos`"
+ job_003:
+ name: "analyze_and_format; linux; Dart dev; PKGS: integration_tests/spawn_hybrid, pkgs/checks, pkgs/test, pkgs/test_api, pkgs/test_core; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:integration_tests/spawn_hybrid-legacy_tests/nnbd_opted_in-pkgs/checks-pkgs/test-pkgs/test_api-pkgs/test_core;commands:format-analyze_0"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:integration_tests/spawn_hybrid-pkgs/checks-pkgs/test-pkgs/test_api-pkgs/test_core;commands:format-analyze_0"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:integration_tests/spawn_hybrid-legacy_tests/nnbd_opted_in-pkgs/checks-pkgs/test-pkgs/test_api-pkgs/test_core
+ os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:integration_tests/spawn_hybrid-pkgs/checks-pkgs/test-pkgs/test_api-pkgs/test_core
os:ubuntu-latest;pub-cache-hosted;sdk:dev
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: integration_tests_spawn_hybrid_pub_upgrade
name: integration_tests/spawn_hybrid; dart pub upgrade
run: dart pub upgrade
@@ -146,19 +112,6 @@
run: dart analyze --fatal-infos
if: "always() && steps.integration_tests_spawn_hybrid_pub_upgrade.conclusion == 'success'"
working-directory: integration_tests/spawn_hybrid
- - id: legacy_tests_nnbd_opted_in_pub_upgrade
- name: legacy_tests/nnbd_opted_in; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in
- - name: "legacy_tests/nnbd_opted_in; dart format --output=none --set-exit-if-changed ."
- run: "dart format --output=none --set-exit-if-changed ."
- if: "always() && steps.legacy_tests_nnbd_opted_in_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in
- - name: "legacy_tests/nnbd_opted_in; dart analyze --fatal-infos"
- run: dart analyze --fatal-infos
- if: "always() && steps.legacy_tests_nnbd_opted_in_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in
- id: pkgs_checks_pub_upgrade
name: pkgs/checks; dart pub upgrade
run: dart pub upgrade
@@ -211,12 +164,12 @@
run: dart analyze --fatal-infos
if: "always() && steps.pkgs_test_core_pub_upgrade.conclusion == 'success'"
working-directory: pkgs/test_core
- job_005:
+ job_004:
name: "analyze_and_format; linux; Dart main; PKG: integration_tests/wasm; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:integration_tests/wasm;commands:format-analyze_0"
@@ -226,12 +179,12 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: main
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: integration_tests_wasm_pub_upgrade
name: integration_tests/wasm; dart pub upgrade
run: dart pub upgrade
@@ -245,74 +198,27 @@
run: dart analyze --fatal-infos
if: "always() && steps.integration_tests_wasm_pub_upgrade.conclusion == 'success'"
working-directory: integration_tests/wasm
- job_006:
- name: "analyze_and_format; linux; Dart stable; PKGS: legacy_tests/nnbd_opted_out, legacy_tests/spawn_hybrid_with_optout; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos`"
+ job_005:
+ name: "unit_test; linux; Dart 3.0.0; PKG: integration_tests/spawn_hybrid; `dart test -p chrome,vm,node`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:stable;packages:legacy_tests/nnbd_opted_out-legacy_tests/spawn_hybrid_with_optout;commands:format-analyze_0"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:integration_tests/spawn_hybrid;commands:test_0"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:stable;packages:legacy_tests/nnbd_opted_out-legacy_tests/spawn_hybrid_with_optout
- os:ubuntu-latest;pub-cache-hosted;sdk:stable
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:integration_tests/spawn_hybrid
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: stable
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- - id: legacy_tests_nnbd_opted_out_pub_upgrade
- name: legacy_tests/nnbd_opted_out; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_out
- - name: "legacy_tests/nnbd_opted_out; dart format --output=none --set-exit-if-changed ."
- run: "dart format --output=none --set-exit-if-changed ."
- if: "always() && steps.legacy_tests_nnbd_opted_out_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_out
- - name: "legacy_tests/nnbd_opted_out; dart analyze --fatal-infos"
- run: dart analyze --fatal-infos
- if: "always() && steps.legacy_tests_nnbd_opted_out_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_out
- - id: legacy_tests_spawn_hybrid_with_optout_pub_upgrade
- name: legacy_tests/spawn_hybrid_with_optout; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/spawn_hybrid_with_optout
- - name: "legacy_tests/spawn_hybrid_with_optout; dart format --output=none --set-exit-if-changed ."
- run: "dart format --output=none --set-exit-if-changed ."
- if: "always() && steps.legacy_tests_spawn_hybrid_with_optout_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/spawn_hybrid_with_optout
- - name: "legacy_tests/spawn_hybrid_with_optout; dart analyze --fatal-infos"
- run: dart analyze --fatal-infos
- if: "always() && steps.legacy_tests_spawn_hybrid_with_optout_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/spawn_hybrid_with_optout
- job_007:
- name: "unit_test; linux; Dart 2.18.0; PKG: integration_tests/spawn_hybrid; `dart test -p chrome,vm,node`"
- runs-on: ubuntu-latest
- steps:
- - name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
- with:
- path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:integration_tests/spawn_hybrid;commands:test"
- restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:integration_tests/spawn_hybrid
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
- os:ubuntu-latest;pub-cache-hosted
- os:ubuntu-latest
- - name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- with:
- sdk: "2.18.0"
- - id: checkout
- name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: integration_tests_spawn_hybrid_pub_upgrade
name: integration_tests/spawn_hybrid; dart pub upgrade
run: dart pub upgrade
@@ -327,177 +233,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_008:
- name: "unit_test; linux; Dart 2.18.0; PKG: legacy_tests/nnbd_opted_in; `dart test -p chrome,vm,node`"
+ job_006:
+ name: "unit_test; linux; Dart 3.0.0; PKG: pkgs/checks; `dart test`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:legacy_tests/nnbd_opted_in;commands:test"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/checks;commands:command_01"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:legacy_tests/nnbd_opted_in
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/checks
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- - id: legacy_tests_nnbd_opted_in_pub_upgrade
- name: legacy_tests/nnbd_opted_in; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in
- - name: "legacy_tests/nnbd_opted_in; dart test -p chrome,vm,node"
- run: "dart test -p chrome,vm,node"
- if: "always() && steps.legacy_tests_nnbd_opted_in_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in
- needs:
- - job_001
- - job_002
- - job_003
- - job_004
- - job_005
- - job_006
- job_009:
- name: "unit_test; linux; Dart 2.18.0; PKG: legacy_tests/nnbd_opted_in_with_optout; `dart test -p chrome,vm,node`"
- runs-on: ubuntu-latest
- steps:
- - name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
- with:
- path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:legacy_tests/nnbd_opted_in_with_optout;commands:test"
- restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:legacy_tests/nnbd_opted_in_with_optout
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
- os:ubuntu-latest;pub-cache-hosted
- os:ubuntu-latest
- - name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- with:
- sdk: "2.18.0"
- - id: checkout
- name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- - id: legacy_tests_nnbd_opted_in_with_optout_pub_upgrade
- name: legacy_tests/nnbd_opted_in_with_optout; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in_with_optout
- - name: "legacy_tests/nnbd_opted_in_with_optout; dart test -p chrome,vm,node"
- run: "dart test -p chrome,vm,node"
- if: "always() && steps.legacy_tests_nnbd_opted_in_with_optout_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in_with_optout
- needs:
- - job_001
- - job_002
- - job_003
- - job_004
- - job_005
- - job_006
- job_010:
- name: "unit_test; linux; Dart 2.18.0; PKG: legacy_tests/nnbd_opted_out; `dart test -p chrome,vm,node`"
- runs-on: ubuntu-latest
- steps:
- - name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
- with:
- path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:legacy_tests/nnbd_opted_out;commands:test"
- restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:legacy_tests/nnbd_opted_out
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
- os:ubuntu-latest;pub-cache-hosted
- os:ubuntu-latest
- - name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- with:
- sdk: "2.18.0"
- - id: checkout
- name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- - id: legacy_tests_nnbd_opted_out_pub_upgrade
- name: legacy_tests/nnbd_opted_out; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_out
- - name: "legacy_tests/nnbd_opted_out; dart test -p chrome,vm,node"
- run: "dart test -p chrome,vm,node"
- if: "always() && steps.legacy_tests_nnbd_opted_out_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_out
- needs:
- - job_001
- - job_002
- - job_003
- - job_004
- - job_005
- - job_006
- job_011:
- name: "unit_test; linux; Dart 2.18.0; PKG: legacy_tests/spawn_hybrid_with_optout; `dart test -p chrome,vm,node`"
- runs-on: ubuntu-latest
- steps:
- - name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
- with:
- path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:legacy_tests/spawn_hybrid_with_optout;commands:test"
- restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:legacy_tests/spawn_hybrid_with_optout
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
- os:ubuntu-latest;pub-cache-hosted
- os:ubuntu-latest
- - name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- with:
- sdk: "2.18.0"
- - id: checkout
- name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- - id: legacy_tests_spawn_hybrid_with_optout_pub_upgrade
- name: legacy_tests/spawn_hybrid_with_optout; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/spawn_hybrid_with_optout
- - name: "legacy_tests/spawn_hybrid_with_optout; dart test -p chrome,vm,node"
- run: "dart test -p chrome,vm,node"
- if: "always() && steps.legacy_tests_spawn_hybrid_with_optout_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/spawn_hybrid_with_optout
- needs:
- - job_001
- - job_002
- - job_003
- - job_004
- - job_005
- - job_006
- job_012:
- name: "unit_test; linux; Dart 2.18.0; PKG: pkgs/checks; `dart test`"
- runs-on: ubuntu-latest
- steps:
- - name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
- with:
- path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/checks;commands:command_00"
- restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/checks
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
- os:ubuntu-latest;pub-cache-hosted
- os:ubuntu-latest
- - name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- with:
- sdk: "2.18.0"
- - id: checkout
- name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_checks_pub_upgrade
name: pkgs/checks; dart pub upgrade
run: dart pub upgrade
@@ -512,29 +268,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_013:
- name: "unit_test; linux; Dart 2.18.0; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 0`"
+ job_007:
+ name: "unit_test; linux; Dart 3.0.0; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 0`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test;commands:command_01"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test;commands:command_02"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -549,29 +303,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_014:
- name: "unit_test; linux; Dart 2.18.0; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 1`"
+ job_008:
+ name: "unit_test; linux; Dart 3.0.0; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 1`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test;commands:command_02"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test;commands:command_03"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -586,29 +338,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_015:
- name: "unit_test; linux; Dart 2.18.0; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 2`"
+ job_009:
+ name: "unit_test; linux; Dart 3.0.0; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 2`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test;commands:command_03"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test;commands:command_04"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -623,29 +373,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_016:
- name: "unit_test; linux; Dart 2.18.0; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 3`"
+ job_010:
+ name: "unit_test; linux; Dart 3.0.0; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 3`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test;commands:command_04"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test;commands:command_05"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -660,29 +408,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_017:
- name: "unit_test; linux; Dart 2.18.0; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 4`"
+ job_011:
+ name: "unit_test; linux; Dart 3.0.0; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 4`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test;commands:command_05"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test;commands:command_06"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -697,29 +443,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_018:
- name: "unit_test; linux; Dart 2.18.0; PKG: pkgs/test_api; `dart test --preset travis -x browser`"
+ job_012:
+ name: "unit_test; linux; Dart 3.0.0; PKG: pkgs/test_api; `dart test --preset travis -x browser`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test_api;commands:command_11"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test_api;commands:command_12"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0;packages:pkgs/test_api
- os:ubuntu-latest;pub-cache-hosted;sdk:2.18.0
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/test_api
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_api_pub_upgrade
name: pkgs/test_api; dart pub upgrade
run: dart pub upgrade
@@ -734,29 +478,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_019:
+ job_013:
name: "unit_test; linux; Dart dev; PKG: integration_tests/spawn_hybrid; `dart test -p chrome,vm,node`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:integration_tests/spawn_hybrid;commands:test"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:integration_tests/spawn_hybrid;commands:test_0"
restore-keys: |
os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:integration_tests/spawn_hybrid
os:ubuntu-latest;pub-cache-hosted;sdk:dev
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: integration_tests_spawn_hybrid_pub_upgrade
name: integration_tests/spawn_hybrid; dart pub upgrade
run: dart pub upgrade
@@ -771,29 +513,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_020:
+ job_014:
name: "unit_test; linux; Dart dev; PKG: pkgs/checks; `dart test`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/checks;commands:command_00"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/checks;commands:command_01"
restore-keys: |
os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/checks
os:ubuntu-latest;pub-cache-hosted;sdk:dev
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_checks_pub_upgrade
name: pkgs/checks; dart pub upgrade
run: dart pub upgrade
@@ -808,51 +548,12 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_021:
+ job_015:
name: "unit_test; linux; Dart dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 0`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
- with:
- path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test;commands:command_01"
- restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test
- os:ubuntu-latest;pub-cache-hosted;sdk:dev
- os:ubuntu-latest;pub-cache-hosted
- os:ubuntu-latest
- - name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- with:
- sdk: dev
- - id: checkout
- name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- - id: pkgs_test_pub_upgrade
- name: pkgs/test; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: pkgs/test
- - name: "pkgs/test; xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 0"
- run: "xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 0"
- if: "always() && steps.pkgs_test_pub_upgrade.conclusion == 'success'"
- working-directory: pkgs/test
- needs:
- - job_001
- - job_002
- - job_003
- - job_004
- - job_005
- - job_006
- job_022:
- name: "unit_test; linux; Dart dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 1`"
- runs-on: ubuntu-latest
- steps:
- - name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test;commands:command_02"
@@ -862,12 +563,47 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
+ - id: pkgs_test_pub_upgrade
+ name: pkgs/test; dart pub upgrade
+ run: dart pub upgrade
+ if: "always() && steps.checkout.conclusion == 'success'"
+ working-directory: pkgs/test
+ - name: "pkgs/test; xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 0"
+ run: "xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 0"
+ if: "always() && steps.pkgs_test_pub_upgrade.conclusion == 'success'"
+ working-directory: pkgs/test
+ needs:
+ - job_001
+ - job_002
+ - job_003
+ - job_004
+ job_016:
+ name: "unit_test; linux; Dart dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 1`"
+ runs-on: ubuntu-latest
+ steps:
+ - name: Cache Pub hosted dependencies
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
+ with:
+ path: "~/.pub-cache/hosted"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test;commands:command_03"
+ restore-keys: |
+ os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test
+ os:ubuntu-latest;pub-cache-hosted;sdk:dev
+ os:ubuntu-latest;pub-cache-hosted
+ os:ubuntu-latest
+ - name: Setup Dart SDK
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ with:
+ sdk: dev
+ - id: checkout
+ name: Checkout repository
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -882,29 +618,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_023:
+ job_017:
name: "unit_test; linux; Dart dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 2`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test;commands:command_03"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test;commands:command_04"
restore-keys: |
os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test
os:ubuntu-latest;pub-cache-hosted;sdk:dev
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -919,29 +653,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_024:
+ job_018:
name: "unit_test; linux; Dart dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 3`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test;commands:command_04"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test;commands:command_05"
restore-keys: |
os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test
os:ubuntu-latest;pub-cache-hosted;sdk:dev
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -956,29 +688,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_025:
+ job_019:
name: "unit_test; linux; Dart dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 4`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test;commands:command_05"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test;commands:command_06"
restore-keys: |
os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test
os:ubuntu-latest;pub-cache-hosted;sdk:dev
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -993,29 +723,27 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_026:
+ job_020:
name: "unit_test; linux; Dart dev; PKG: pkgs/test_api; `dart test --preset travis -x browser`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@627f0f41f6904a5b1efbaed9f96d9eb58e92e920
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test_api;commands:command_11"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test_api;commands:command_12"
restore-keys: |
os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/test_api
os:ubuntu-latest;pub-cache-hosted;sdk:dev
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_api_pub_upgrade
name: pkgs/test_api; dart pub upgrade
run: dart pub upgrade
@@ -1030,19 +758,56 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_027:
- name: "unit_test; windows; Dart 2.18.0; PKG: integration_tests/spawn_hybrid; `dart test -p chrome,vm,node`"
+ job_021:
+ name: "unit_test; linux; Dart main; PKG: integration_tests/wasm; `pushd /tmp && wget https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb && sudo dpkg -i google-chrome-beta_current_amd64.deb && popd && which google-chrome-beta`, `dart test --timeout=60s`"
+ runs-on: ubuntu-latest
+ steps:
+ - name: Cache Pub hosted dependencies
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7
+ with:
+ path: "~/.pub-cache/hosted"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:integration_tests/wasm;commands:command_00-test_1"
+ restore-keys: |
+ os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:integration_tests/wasm
+ os:ubuntu-latest;pub-cache-hosted;sdk:main
+ os:ubuntu-latest;pub-cache-hosted
+ os:ubuntu-latest
+ - name: Setup Dart SDK
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ with:
+ sdk: main
+ - id: checkout
+ name: Checkout repository
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
+ - id: integration_tests_wasm_pub_upgrade
+ name: integration_tests/wasm; dart pub upgrade
+ run: dart pub upgrade
+ if: "always() && steps.checkout.conclusion == 'success'"
+ working-directory: integration_tests/wasm
+ - name: "integration_tests/wasm; pushd /tmp && wget https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb && sudo dpkg -i google-chrome-beta_current_amd64.deb && popd && which google-chrome-beta"
+ run: "pushd /tmp && wget https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb && sudo dpkg -i google-chrome-beta_current_amd64.deb && popd && which google-chrome-beta"
+ if: "always() && steps.integration_tests_wasm_pub_upgrade.conclusion == 'success'"
+ working-directory: integration_tests/wasm
+ - name: "integration_tests/wasm; dart test --timeout=60s"
+ run: "dart test --timeout=60s"
+ if: "always() && steps.integration_tests_wasm_pub_upgrade.conclusion == 'success'"
+ working-directory: integration_tests/wasm
+ needs:
+ - job_001
+ - job_002
+ - job_003
+ - job_004
+ job_022:
+ name: "unit_test; windows; Dart 3.0.0; PKG: integration_tests/spawn_hybrid; `dart test -p chrome,vm,node`"
runs-on: windows-latest
steps:
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: integration_tests_spawn_hybrid_pub_upgrade
name: integration_tests/spawn_hybrid; dart pub upgrade
run: dart pub upgrade
@@ -1057,127 +822,17 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_028:
- name: "unit_test; windows; Dart 2.18.0; PKG: legacy_tests/nnbd_opted_in; `dart test -p chrome,vm,node`"
+ job_023:
+ name: "unit_test; windows; Dart 3.0.0; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 0`"
runs-on: windows-latest
steps:
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- - id: legacy_tests_nnbd_opted_in_pub_upgrade
- name: legacy_tests/nnbd_opted_in; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in
- - name: "legacy_tests/nnbd_opted_in; dart test -p chrome,vm,node"
- run: "dart test -p chrome,vm,node"
- if: "always() && steps.legacy_tests_nnbd_opted_in_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in
- needs:
- - job_001
- - job_002
- - job_003
- - job_004
- - job_005
- - job_006
- job_029:
- name: "unit_test; windows; Dart 2.18.0; PKG: legacy_tests/nnbd_opted_in_with_optout; `dart test -p chrome,vm,node`"
- runs-on: windows-latest
- steps:
- - name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- with:
- sdk: "2.18.0"
- - id: checkout
- name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- - id: legacy_tests_nnbd_opted_in_with_optout_pub_upgrade
- name: legacy_tests/nnbd_opted_in_with_optout; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in_with_optout
- - name: "legacy_tests/nnbd_opted_in_with_optout; dart test -p chrome,vm,node"
- run: "dart test -p chrome,vm,node"
- if: "always() && steps.legacy_tests_nnbd_opted_in_with_optout_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_in_with_optout
- needs:
- - job_001
- - job_002
- - job_003
- - job_004
- - job_005
- - job_006
- job_030:
- name: "unit_test; windows; Dart 2.18.0; PKG: legacy_tests/nnbd_opted_out; `dart test -p chrome,vm,node`"
- runs-on: windows-latest
- steps:
- - name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- with:
- sdk: "2.18.0"
- - id: checkout
- name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- - id: legacy_tests_nnbd_opted_out_pub_upgrade
- name: legacy_tests/nnbd_opted_out; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_out
- - name: "legacy_tests/nnbd_opted_out; dart test -p chrome,vm,node"
- run: "dart test -p chrome,vm,node"
- if: "always() && steps.legacy_tests_nnbd_opted_out_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/nnbd_opted_out
- needs:
- - job_001
- - job_002
- - job_003
- - job_004
- - job_005
- - job_006
- job_031:
- name: "unit_test; windows; Dart 2.18.0; PKG: legacy_tests/spawn_hybrid_with_optout; `dart test -p chrome,vm,node`"
- runs-on: windows-latest
- steps:
- - name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- with:
- sdk: "2.18.0"
- - id: checkout
- name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- - id: legacy_tests_spawn_hybrid_with_optout_pub_upgrade
- name: legacy_tests/spawn_hybrid_with_optout; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: legacy_tests/spawn_hybrid_with_optout
- - name: "legacy_tests/spawn_hybrid_with_optout; dart test -p chrome,vm,node"
- run: "dart test -p chrome,vm,node"
- if: "always() && steps.legacy_tests_spawn_hybrid_with_optout_pub_upgrade.conclusion == 'success'"
- working-directory: legacy_tests/spawn_hybrid_with_optout
- needs:
- - job_001
- - job_002
- - job_003
- - job_004
- - job_005
- - job_006
- job_032:
- name: "unit_test; windows; Dart 2.18.0; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 0`"
- runs-on: windows-latest
- steps:
- - name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- with:
- sdk: "2.18.0"
- - id: checkout
- name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -1192,19 +847,17 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_033:
- name: "unit_test; windows; Dart 2.18.0; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 1`"
+ job_024:
+ name: "unit_test; windows; Dart 3.0.0; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 1`"
runs-on: windows-latest
steps:
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -1219,19 +872,17 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_034:
- name: "unit_test; windows; Dart 2.18.0; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 2`"
+ job_025:
+ name: "unit_test; windows; Dart 3.0.0; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 2`"
runs-on: windows-latest
steps:
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -1246,19 +897,17 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_035:
- name: "unit_test; windows; Dart 2.18.0; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 3`"
+ job_026:
+ name: "unit_test; windows; Dart 3.0.0; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 3`"
runs-on: windows-latest
steps:
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -1273,19 +922,17 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_036:
- name: "unit_test; windows; Dart 2.18.0; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 4`"
+ job_027:
+ name: "unit_test; windows; Dart 3.0.0; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 4`"
runs-on: windows-latest
steps:
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
- sdk: "2.18.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: pkgs_test_pub_upgrade
name: pkgs/test; dart pub upgrade
run: dart pub upgrade
@@ -1300,19 +947,17 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_037:
+ job_028:
name: "unit_test; windows; Dart dev; PKG: integration_tests/spawn_hybrid; `dart test -p chrome,vm,node`"
runs-on: windows-latest
steps:
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- id: integration_tests_spawn_hybrid_pub_upgrade
name: integration_tests/spawn_hybrid; dart pub upgrade
run: dart pub upgrade
@@ -1327,9 +972,7 @@
- job_002
- job_003
- job_004
- - job_005
- - job_006
- job_038:
+ job_029:
name: Notify failure
runs-on: ubuntu-latest
if: "(github.event_name == 'push' || github.event_name == 'schedule') && failure()"
@@ -1369,12 +1012,3 @@
- job_026
- job_027
- job_028
- - job_029
- - job_030
- - job_031
- - job_032
- - job_033
- - job_034
- - job_035
- - job_036
- - job_037
diff --git a/.github/workflows/no-response.yml b/.github/workflows/no-response.yml
index c7574c8..dd7bbbc 100644
--- a/.github/workflows/no-response.yml
+++ b/.github/workflows/no-response.yml
@@ -1,12 +1,10 @@
# A workflow to close issues where the author hasn't responded to a request for
-# more information; see https://github.com/godofredoc/no-response for docs.
+# more information; see https://github.com/actions/stale.
name: No Response
-# Both `issue_comment` and `scheduled` event types are required.
+# Run as a daily cron.
on:
- issue_comment:
- types: [created]
schedule:
# Every day at 8am
- cron: '0 8 * * *'
@@ -14,21 +12,24 @@
# All permissions not specified are set to 'none'.
permissions:
issues: write
+ pull-requests: write
jobs:
- noResponse:
+ no-response:
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'dart-lang' }}
steps:
- - uses: godofredoc/no-response@0ce2dc0e63e1c7d2b87752ceed091f6d32c9df09
+ - uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84
with:
- responseRequiredLabel: "needs-info"
- responseRequiredColor: 4774bc
- daysUntilClose: 14
- # Comment to post when closing an Issue for lack of response.
- closeComment: >
- Without additional information we're not able to resolve this
- issue, so it will be closed at this time. You're still free to add
- more info and respond to any questions above, though. We'll reopen
- the case if you do. Thanks for your contribution!
- token: ${{ github.token }}
+ days-before-stale: -1
+ days-before-close: 14
+ stale-issue-label: "needs-info"
+ close-issue-message: >
+ Without additional information we're not able to resolve this issue.
+ Feel free to add more info or respond to any questions above and we
+ can reopen the case. Thanks for your contribution!
+ stale-pr-label: "needs-info"
+ close-pr-message: >
+ Without additional information we're not able to resolve this PR.
+ Feel free to add more info or respond to any questions above.
+ Thanks for your contribution!
diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml
new file mode 100644
index 0000000..bf40d5f
--- /dev/null
+++ b/.github/workflows/publish.yaml
@@ -0,0 +1,15 @@
+# A CI configuration to auto-publish pub packages.
+
+name: Publish
+
+on:
+ pull_request:
+ branches: [ master ]
+ types: [opened, synchronize, reopened, labeled, unlabeled]
+ push:
+ tags: [ '[A-z]+-v[0-9]+.[0-9]+.[0-9]+*' ]
+
+jobs:
+ publish:
+ if: ${{ github.repository_owner == 'dart-lang' }}
+ uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main
diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml
index 80a463a..fcc94b7 100644
--- a/.github/workflows/scorecards-analysis.yml
+++ b/.github/workflows/scorecards-analysis.yml
@@ -22,12 +22,12 @@
steps:
- name: "Checkout code"
- uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
with:
persist-credentials: false
- name: "Run analysis"
- uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86
+ uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031
with:
results_file: results.sarif
results_format: sarif
@@ -50,6 +50,6 @@
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@3ebbd71c74ef574dbc558c82f70e52732c8b44fe # v2.2.1
+ uses: github/codeql-action/upload-sarif@0ba4244466797eb048eb91a6cd43d5c03ca8bd05 # v2.21.2
with:
sarif_file: results.sarif
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 61f02f2..90003c0 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -39,14 +39,32 @@
`mono_repo` tool. From the root of the repository, run
`pub global run mono_repo presubmit`.
+### Versioning
+
+You will also need to potentially update the pubspec.yaml and/or CHANGELOG.md of
+any package you are updating. If the current version is not a `-dev` version
+then you should update it and add a new header to the changelog. If you have no
+publicly facing change to list, it is OK for there to be no changes listed.
+
+We follow pretty strict semantic versioning, feel free to ask on the PR if you
+are unsure about what version number you should choose (or do your best, and a
+code reviewers will bring it up if it is incorrect).
+
### File headers
All files in the project must start with the following header.
- // Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+ // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+### Publishing
+
+Publishing is done by package owners creating a tag of the form
+`<package>-v<version>`, either manually or through the github release ui
+(preferred). The pubspec and changelog must already be updated to the desired
+release version in the master branch for this process to work.
+
### The small print
Contributions made by corporations are covered by a different agreement than the
diff --git a/README.md b/README.md
deleted file mode 120000
index 789f748..0000000
--- a/README.md
+++ /dev/null
@@ -1 +0,0 @@
-pkgs/test/README.md
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7091bd9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,22 @@
+[![Dart CI](https://github.com/dart-lang/test/actions/workflows/dart.yml/badge.svg)](https://github.com/dart-lang/test/actions/workflows/dart.yml)
+[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/dart-lang/test/badge)](https://deps.dev/project/github/dart-lang%2Ftest)
+
+## What's here?
+
+Welcome! [package:test](pkgs/test/) is the standard testing library for Dart and
+Flutter. If you have questions about Dart testing, please see the docs for
+[package:test](pkgs/test/). `package:test_api` and `package:test_core`
+are implementation details and generally not user-facing.
+
+[package:checks](pkgs/checks/) is a relatively new library for expressing test
+expectations. It's a more modern version of `package:matcher` and features a
+literate API.
+
+## Packages
+
+| Package | Description | Version |
+|---|---|---|
+| [checks](pkgs/checks/) | A framework for checking values against expectations and building custom expectations. | [![pub package](https://img.shields.io/pub/v/checks.svg)](https://pub.dev/packages/checks) |
+| [test](pkgs/test/) | A full featured library for writing and running Dart tests across platforms. | [![pub package](https://img.shields.io/pub/v/test.svg)](https://pub.dev/packages/test) |
+| [test_api](pkgs/test_api/) | | [![pub package](https://img.shields.io/pub/v/test_api.svg)](https://pub.dev/packages/test_api) |
+| [test_core](pkgs/test_core/) | | [![pub package](https://img.shields.io/pub/v/test_core.svg)](https://pub.dev/packages/test_core) |
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 0f13fc8..9913045 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,13 +1,21 @@
-include: package:lints/recommended.yaml
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+
analyzer:
language:
strict-casts: true
errors:
# There are a number of deprecated members used through this package
deprecated_member_use_from_same_package: ignore
+
+ # Ignoring a number of lints from dart_flutter_team_lints – for now
+ avoid_catching_errors: ignore
+ avoid_dynamic_calls: ignore
+ lines_longer_than_80_chars: ignore
+ only_throw_errors: ignore
+ unawaited_futures: ignore
unsafe_html: ignore
+
linter:
rules:
- avoid_private_typedef_functions
- - directives_ordering
- - prefer_single_quotes
diff --git a/integration_tests/spawn_hybrid/pubspec.yaml b/integration_tests/spawn_hybrid/pubspec.yaml
index d5b58e1..de0efaa 100644
--- a/integration_tests/spawn_hybrid/pubspec.yaml
+++ b/integration_tests/spawn_hybrid/pubspec.yaml
@@ -1,7 +1,7 @@
name: spawn_hybrid
publish_to: none
environment:
- sdk: '>=2.18.0 <3.0.0'
+ sdk: ^3.0.0
dependencies:
async: ^2.9.0
path: ^1.8.2
diff --git a/integration_tests/wasm/mono_pkg.yaml b/integration_tests/wasm/mono_pkg.yaml
index 9f50e7b..b09a8da 100644
--- a/integration_tests/wasm/mono_pkg.yaml
+++ b/integration_tests/wasm/mono_pkg.yaml
@@ -8,17 +8,17 @@
- group:
- format
- analyze: --fatal-infos
-# TODO: restore after https://github.com/dart-lang/test/issues/1790
-# - unit_test:
-# - group:
-# - command:
-# - pushd /tmp
-# - wget https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb
-# - sudo dpkg -i google-chrome-beta_current_amd64.deb
-# - popd
-# - which google-chrome-beta
-# os:
-# - linux
-# - test:
-# os:
-# - linux
+- unit_test:
+ - group:
+ - command:
+ - pushd /tmp
+ - wget https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb
+ - sudo dpkg -i google-chrome-beta_current_amd64.deb
+ - popd
+ - which google-chrome-beta
+ os:
+ - linux
+ # The config here is a regression test for https://github.com/dart-lang/test/issues/2006
+ - test: --timeout=60s
+ os:
+ - linux
diff --git a/integration_tests/wasm/pubspec.yaml b/integration_tests/wasm/pubspec.yaml
index 37fed20..136c635 100644
--- a/integration_tests/wasm/pubspec.yaml
+++ b/integration_tests/wasm/pubspec.yaml
@@ -1,6 +1,7 @@
name: wasm_tests
+publish_to: none
environment:
- sdk: ">=2.18.0 <3.0.0"
+ sdk: ^3.0.0
dev_dependencies:
test: any
dependency_overrides:
diff --git a/integration_tests/wasm/test/hello_world_test.dart b/integration_tests/wasm/test/hello_world_test.dart
index 5d911a7..40d4a74 100644
--- a/integration_tests/wasm/test/hello_world_test.dart
+++ b/integration_tests/wasm/test/hello_world_test.dart
@@ -1,7 +1,10 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+
@TestOn('wasm')
+// This retry is a regression test for https://github.com/dart-lang/test/issues/2006
+@Retry(2)
import 'package:test/test.dart';
void main() {
diff --git a/legacy_tests/nnbd_opted_in/mono_pkg.yaml b/legacy_tests/nnbd_opted_in/mono_pkg.yaml
deleted file mode 100644
index 682f76e..0000000
--- a/legacy_tests/nnbd_opted_in/mono_pkg.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-# See https://pub.dev/packages/mono_repo
-
-sdk:
-- pubspec
-
-stages:
-- analyze_and_format:
- - group:
- - format
- - analyze: --fatal-infos
- sdk:
- - dev
-- unit_test:
- - test: -p chrome,vm,node
- os:
- - linux
- - windows
diff --git a/legacy_tests/nnbd_opted_in/pubspec.yaml b/legacy_tests/nnbd_opted_in/pubspec.yaml
deleted file mode 100644
index 61cadf7..0000000
--- a/legacy_tests/nnbd_opted_in/pubspec.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: nnbd_opted_in
-environment:
- sdk: '>=2.18.0 <3.0.0'
-dev_dependencies:
- lints: '>=1.0.0 <3.0.0'
- test: any
-dependency_overrides:
- test:
- path: ../../pkgs/test
- test_api:
- path: ../../pkgs/test_api
- test_core:
- path: ../../pkgs/test_core
diff --git a/legacy_tests/nnbd_opted_in/test/common/is_opted_out.dart b/legacy_tests/nnbd_opted_in/test/common/is_opted_out.dart
deleted file mode 100644
index b661c9d..0000000
--- a/legacy_tests/nnbd_opted_in/test/common/is_opted_out.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-final bool isOptedOut = <int?>[] is List<int>;
diff --git a/legacy_tests/nnbd_opted_in/test/opted_in_test.dart b/legacy_tests/nnbd_opted_in/test/opted_in_test.dart
deleted file mode 100644
index 6f8eb9a..0000000
--- a/legacy_tests/nnbd_opted_in/test/opted_in_test.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test/test.dart';
-
-import 'common/is_opted_out.dart';
-
-void main() {
- test('sound behavior', () async {
- expect(isOptedOut, false);
- });
-}
diff --git a/legacy_tests/nnbd_opted_in_with_optout/mono_pkg.yaml b/legacy_tests/nnbd_opted_in_with_optout/mono_pkg.yaml
deleted file mode 100644
index 5b5ac14..0000000
--- a/legacy_tests/nnbd_opted_in_with_optout/mono_pkg.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-# See https://pub.dev/packages/mono_repo
-
-sdk:
-- pubspec
-
-stages:
-- analyze_and_format:
- - group:
- - format
- - analyze: --fatal-infos
- sdk:
- - pubspec
-- unit_test:
- - test: -p chrome,vm,node
- os:
- - linux
- - windows
diff --git a/legacy_tests/nnbd_opted_in_with_optout/pubspec.yaml b/legacy_tests/nnbd_opted_in_with_optout/pubspec.yaml
deleted file mode 100644
index 11517a6..0000000
--- a/legacy_tests/nnbd_opted_in_with_optout/pubspec.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: nnbd_opted_in_with_optout
-environment:
- sdk: '>=2.18.0 <3.0.0'
-dev_dependencies:
- lints: '>=1.0.0 <3.0.0'
- test: any
-dependency_overrides:
- test:
- path: ../../pkgs/test
- test_api:
- path: ../../pkgs/test_api
- test_core:
- path: ../../pkgs/test_core
diff --git a/legacy_tests/nnbd_opted_in_with_optout/test/common/is_opted_out.dart b/legacy_tests/nnbd_opted_in_with_optout/test/common/is_opted_out.dart
deleted file mode 100644
index b661c9d..0000000
--- a/legacy_tests/nnbd_opted_in_with_optout/test/common/is_opted_out.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-final bool isOptedOut = <int?>[] is List<int>;
diff --git a/legacy_tests/nnbd_opted_in_with_optout/test/opted_out_test.dart b/legacy_tests/nnbd_opted_in_with_optout/test/opted_out_test.dart
deleted file mode 100644
index 291647f..0000000
--- a/legacy_tests/nnbd_opted_in_with_optout/test/opted_out_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart=2.9
-
-import 'package:test/test.dart';
-
-import 'common/is_opted_out.dart';
-
-void main() {
- test('unsound behavior', () async {
- expect(isOptedOut, true);
- });
-}
diff --git a/legacy_tests/nnbd_opted_out/mono_pkg.yaml b/legacy_tests/nnbd_opted_out/mono_pkg.yaml
deleted file mode 100644
index a8c8677..0000000
--- a/legacy_tests/nnbd_opted_out/mono_pkg.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-# See https://pub.dev/packages/mono_repo
-
-sdk:
-- 2.18.0
-
-stages:
-- analyze_and_format:
- - group:
- - format
- - analyze: --fatal-infos
- sdk:
- - stable
-- unit_test:
- - test: -p chrome,vm,node
- os:
- - linux
- - windows
diff --git a/legacy_tests/nnbd_opted_out/pubspec.yaml b/legacy_tests/nnbd_opted_out/pubspec.yaml
deleted file mode 100644
index e73bf9d..0000000
--- a/legacy_tests/nnbd_opted_out/pubspec.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: nnbd_opted_out
-environment:
- sdk: '>=2.11.0 <3.0.0'
-dev_dependencies:
- lints: '>=1.0.0 <3.0.0'
- test: any
-dependency_overrides:
- test:
- path: ../../pkgs/test
- test_api:
- path: ../../pkgs/test_api
- test_core:
- path: ../../pkgs/test_core
diff --git a/legacy_tests/nnbd_opted_out/test/common/is_opted_out.dart b/legacy_tests/nnbd_opted_out/test/common/is_opted_out.dart
deleted file mode 100644
index 7f4b628..0000000
--- a/legacy_tests/nnbd_opted_out/test/common/is_opted_out.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// @dart=2.12
-
-final bool isOptedOut = <int?>[] is List<int>;
diff --git a/legacy_tests/nnbd_opted_out/test/opted_in_test.dart b/legacy_tests/nnbd_opted_out/test/opted_in_test.dart
deleted file mode 100644
index 1d2e5b1..0000000
--- a/legacy_tests/nnbd_opted_out/test/opted_in_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// @dart=2.12
-
-import 'package:test/test.dart';
-
-import 'common/is_opted_out.dart';
-
-void main() {
- test('is opted in to sound null safety', () {
- expect(isOptedOut, isFalse);
- });
-}
diff --git a/legacy_tests/nnbd_opted_out/test/opted_out_test.dart b/legacy_tests/nnbd_opted_out/test/opted_out_test.dart
deleted file mode 100644
index 1f1277d..0000000
--- a/legacy_tests/nnbd_opted_out/test/opted_out_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// @dart=2.9
-
-import 'package:test/test.dart';
-
-import 'common/is_opted_out.dart';
-
-void main() {
- test('is opted out of sound null safety', () {
- expect(isOptedOut, isTrue);
- });
-}
diff --git a/legacy_tests/nnbd_opted_out/test/spawn_hybrid_code_test.dart b/legacy_tests/nnbd_opted_out/test/spawn_hybrid_code_test.dart
deleted file mode 100644
index 5a933d4..0000000
--- a/legacy_tests/nnbd_opted_out/test/spawn_hybrid_code_test.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test/test.dart';
-
-void main() {
- group('spawnHybridCode', () {
- test('uses the current package language version by default', () async {
- final channel = spawnHybridCode(_hybridMain);
- expect(await channel.stream.single, equals(true));
- });
-
- test('can set the language version with a marker', () async {
- final channel = spawnHybridCode('// @dart=2.12\n$_hybridMain');
- expect(await channel.stream.single, equals(false));
- });
- });
-}
-
-const _hybridMain = '''
-final isOptedOut = <int?>[] is List<int>;
-
-void hybridMain(dynamic channel) async {
- channel.sink.add(isOptedOut);
- channel.sink.close();
-}
-''';
diff --git a/legacy_tests/spawn_hybrid_with_optout/mono_pkg.yaml b/legacy_tests/spawn_hybrid_with_optout/mono_pkg.yaml
deleted file mode 100644
index 4ea5861..0000000
--- a/legacy_tests/spawn_hybrid_with_optout/mono_pkg.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-# See https://pub.dev/packages/mono_repo
-
-sdk:
-- pubspec
-
-stages:
-- analyze_and_format:
- - group:
- - format
- - analyze: --fatal-infos
- sdk:
- - stable
-- unit_test:
- - test: -p chrome,vm,node
- os:
- - linux
- - windows
diff --git a/legacy_tests/spawn_hybrid_with_optout/pubspec.yaml b/legacy_tests/spawn_hybrid_with_optout/pubspec.yaml
deleted file mode 100644
index d02bf9f..0000000
--- a/legacy_tests/spawn_hybrid_with_optout/pubspec.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: spawn_hybrid_with_optout
-publish_to: none
-environment:
- sdk: '>=2.18.0 <3.0.0'
-dev_dependencies:
- lints: '>=1.0.0 <3.0.0'
- test: any
-dependency_overrides:
- test:
- path: ../../pkgs/test
- test_api:
- path: ../../pkgs/test_api
- test_core:
- path: ../../pkgs/test_core
diff --git a/legacy_tests/spawn_hybrid_with_optout/test/hybrid_test.dart b/legacy_tests/spawn_hybrid_with_optout/test/hybrid_test.dart
deleted file mode 100644
index 5e2ff41..0000000
--- a/legacy_tests/spawn_hybrid_with_optout/test/hybrid_test.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test/test.dart';
-
-void main() {
- group('spawnHybridCode()', () {
- test('can opt out of null safety', () async {
- expect(spawnHybridCode('''
- // @dart=2.9
- import "package:stream_channel/stream_channel.dart";
-
- // Would cause an error in null safety mode.
- int x;
-
- void hybridMain(StreamChannel channel) {
- channel.sink..add(1)..add(2)..add(3)..close();
- }
- ''').stream.toList(), completion(equals([1, 2, 3])));
- });
-
- test('opts in to null safety by default', () async {
- expect(spawnHybridCode('''
- import "package:stream_channel/stream_channel.dart";
-
- // Use some null safety syntax
- int? x;
-
- void hybridMain(StreamChannel channel) {
- channel.sink..add(1)..add(2)..add(3)..close();
- }
- ''').stream.toList(), completion(equals([1, 2, 3])));
- });
- });
-}
diff --git a/legacy_tests/unit_tests/mono_repo.yaml b/legacy_tests/unit_tests/mono_repo.yaml
deleted file mode 100644
index 4ea5861..0000000
--- a/legacy_tests/unit_tests/mono_repo.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-# See https://pub.dev/packages/mono_repo
-
-sdk:
-- pubspec
-
-stages:
-- analyze_and_format:
- - group:
- - format
- - analyze: --fatal-infos
- sdk:
- - stable
-- unit_test:
- - test: -p chrome,vm,node
- os:
- - linux
- - windows
diff --git a/legacy_tests/unit_tests/pubspec.yaml b/legacy_tests/unit_tests/pubspec.yaml
deleted file mode 100644
index 4703f1e..0000000
--- a/legacy_tests/unit_tests/pubspec.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: legacy_unit_tests
-publish_to: none
-environment:
- sdk: '>=2.18.0 <3.0.0'
-dev_dependencies:
- lints: '>=1.0.0 <3.0.0'
- package_config: ^2.0.0
- path: ^1.8.0
- test: any
- test_descriptor: ^2.0.0
- test_process: ^2.0.0
-dependency_overrides:
- test:
- path: ../../pkgs/test
- test_api:
- path: ../../pkgs/test_api
- test_core:
- path: ../../pkgs/test_core
diff --git a/legacy_tests/unit_tests/test/io.dart b/legacy_tests/unit_tests/test/io.dart
deleted file mode 100644
index b86b4c7..0000000
--- a/legacy_tests/unit_tests/test/io.dart
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-import 'dart:isolate';
-
-import 'package:path/path.dart' as p;
-import 'package:test/test.dart';
-import 'package:test_descriptor/test_descriptor.dart' as d;
-import 'package:test_process/test_process.dart';
-
-/// The path to the root directory of the `test` package.
-final Future<String> packageDir =
- Isolate.resolvePackageUri(Uri(scheme: 'package', path: 'test/'))
- .then((uri) {
- var dir = p.dirname(uri!.path);
- // If it starts with a `/C:` or other drive letter, remove the leading `/`.
- if (dir[0] == '/' && dir[2] == ':') dir = dir.substring(1);
- return dir;
-});
-
-/// The path to the `pub` executable in the current Dart SDK.
-final _pubPath = p.absolute(p.join(p.dirname(Platform.resolvedExecutable),
- Platform.isWindows ? 'pub.bat' : 'pub'));
-
-/// The platform-specific message emitted when a nonexistent file is loaded.
-final String noSuchFileMessage = Platform.isWindows
- ? 'The system cannot find the file specified.'
- : 'No such file or directory';
-
-/// A regular expression that matches the output of "pub serve".
-final _servingRegExp =
- RegExp(r'^Serving myapp [a-z]+ on http://localhost:(\d+)$');
-
-/// An operating system name that's different than the current operating system.
-final otherOS = Platform.isWindows ? 'mac-os' : 'windows';
-
-/// The port of a pub serve instance run via [runPubServe].
-///
-/// This is only set after [runPubServe] is called.
-int get pubServePort => _pubServePort!;
-int? _pubServePort;
-
-/// Expects that the entire stdout stream of [test] equals [expected].
-void expectStdoutEquals(TestProcess test, String expected) =>
- _expectStreamEquals(test.stdoutStream(), expected);
-
-/// Expects that the entire stderr stream of [test] equals [expected].
-void expectStderrEquals(TestProcess test, String expected) =>
- _expectStreamEquals(test.stderrStream(), expected);
-
-/// Expects that the entirety of the line stream [stream] equals [expected].
-void _expectStreamEquals(Stream<String> stream, String expected) {
- expect((() async {
- var lines = await stream.toList();
- expect(lines.join('\n').trim(), equals(expected.trim()));
- })(), completes);
-}
-
-/// Returns a [StreamMatcher] that asserts that the stream emits strings
-/// containing each string in [strings] in order.
-///
-/// This expects each string in [strings] to match a different string in the
-/// stream.
-StreamMatcher containsInOrder(Iterable<String> strings) =>
- emitsInOrder(strings.map((string) => emitsThrough(contains(string))));
-
-/// Lazily compile the test package to kernel and re-use that, initialized with
-/// [precompileTestExecutable].
-String? _testExecutablePath;
-
-/// Must be invoked before any call to [runTests], should be invoked in a top
-/// level `setUpAll` for best caching results.
-Future<void> precompileTestExecutable() async {
- if (_testExecutablePath != null) {
- throw StateError('Test executable already precompiled');
- }
- var tmpDirectory = await Directory.systemTemp.createTemp('test');
- var precompiledPath = p.join(tmpDirectory.path, 'test_runner.dill');
- var result = await Process.run(Platform.executable, [
- 'compile',
- 'kernel',
- p.url.join(await packageDir, 'bin', 'test.dart'),
- '-o',
- precompiledPath,
- ]);
- if (result.exitCode != 0) {
- throw StateError(
- 'Failed to compile test runner:\n${result.stdout}\n${result.stderr}');
- }
-
- addTearDown(() async {
- await tmpDirectory.delete(recursive: true);
- });
- _testExecutablePath = precompiledPath;
-}
-
-/// Runs the test executable with the package root set properly.
-///
-/// You must invoke [precompileTestExecutable] before invoking this function.
-Future<TestProcess> runTest(Iterable<String> args,
- {String? reporter,
- String? fileReporter,
- int? concurrency,
- Map<String, String>? environment,
- bool forwardStdio = false,
- String? packageConfig,
- Iterable<String>? vmArgs}) async {
- concurrency ??= 1;
- var testExecutablePath = _testExecutablePath;
- if (testExecutablePath == null) {
- throw StateError(
- 'You must call `precompileTestExecutable` before calling `runTest`');
- }
-
- var allArgs = [
- ...?vmArgs,
- testExecutablePath,
- '--concurrency=$concurrency',
- if (reporter != null) '--reporter=$reporter',
- if (fileReporter != null) '--file-reporter=$fileReporter',
- ...args,
- ];
-
- environment ??= {};
- environment.putIfAbsent('_DART_TEST_TESTING', () => 'true');
-
- return await runDart(allArgs,
- environment: environment,
- description: 'dart bin/test.dart',
- forwardStdio: forwardStdio,
- packageConfig: packageConfig);
-}
-
-/// Runs Dart.
-///
-/// If [packageConfig] is provided then that is passed for the `--packages`
-/// arg, otherwise the current isolate config is passed.
-Future<TestProcess> runDart(Iterable<String> args,
- {Map<String, String>? environment,
- String? description,
- bool forwardStdio = false,
- String? packageConfig}) async {
- var allArgs = <String>[
- ...Platform.executableArguments.where((arg) =>
- !arg.startsWith('--package-root=') && !arg.startsWith('--packages=')),
- '--packages=${packageConfig ?? await Isolate.packageConfig}',
- ...args
- ];
-
- return await TestProcess.start(
- p.absolute(Platform.resolvedExecutable), allArgs,
- workingDirectory: d.sandbox,
- environment: environment,
- description: description,
- forwardStdio: forwardStdio);
-}
-
-/// Runs Pub.
-Future<TestProcess> runPub(Iterable<String> args,
- {Map<String, String>? environment}) {
- return TestProcess.start(_pubPath, args,
- workingDirectory: d.sandbox,
- environment: environment,
- description: 'pub ${args.first}');
-}
-
-/// Runs "pub serve".
-///
-/// This returns assigns [_pubServePort] to a future that will complete to the
-/// port of the "pub serve" instance.
-Future<TestProcess> runPubServe(
- {Iterable<String>? args,
- String? workingDirectory,
- Map<String, String>? environment}) async {
- var allArgs = ['serve', '--port', '0'];
- if (args != null) allArgs.addAll(args);
-
- var pub = await runPub(allArgs, environment: environment);
-
- Match? match;
- while (match == null) {
- match = _servingRegExp.firstMatch(await pub.stdout.next);
- }
- _pubServePort = int.parse(match[1]!);
-
- return pub;
-}
diff --git a/legacy_tests/unit_tests/test/runner_test.dart b/legacy_tests/unit_tests/test/runner_test.dart
deleted file mode 100644
index 5f67759..0000000
--- a/legacy_tests/unit_tests/test/runner_test.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-import 'dart:convert';
-import 'dart:isolate';
-
-import 'package:package_config/package_config.dart';
-import 'package:path/path.dart' as p;
-import 'package:test/test.dart';
-import 'package:test_descriptor/test_descriptor.dart' as d;
-
-import 'io.dart';
-
-void main() {
- setUpAll(precompileTestExecutable);
-
- group('nnbd', () {
- final testContents = '''
-import 'package:test/test.dart';
-import 'opted_out.dart';
-
-void main() {
- test("success", () {
- expect(foo, true);
- });
-}''';
-
- setUp(() async {
- await d.file('opted_out.dart', '''
-// @dart=2.8
-final foo = true;''').create();
- });
-
- test('sound null safety is enabled if the entrypoint opts in explicitly',
- () async {
- await d.file('test.dart', '''
-// @dart=2.12
-$testContents
-''').create();
- var test = await runTest(['test.dart']);
-
- expect(
- test.stdout,
- emitsThrough(contains(
- 'Error: A library can\'t opt out of null safety by default, '
- 'when using sound null safety.')));
- await test.shouldExit(1);
- });
-
- test('sound null safety is disabled if the entrypoint opts out explicitly',
- () async {
- await d.file('test.dart', '''
-// @dart=2.8
-$testContents''').create();
- var test = await runTest(['test.dart']);
-
- expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
- await test.shouldExit(0);
- });
-
- group('defaults', () {
- late PackageConfig currentPackageConfig;
-
- setUpAll(() async {
- currentPackageConfig =
- await loadPackageConfigUri((await Isolate.packageConfig)!);
- });
-
- setUp(() async {
- await d.file('test.dart', testContents).create();
- });
-
- test('sound null safety is enabled if the package is opted in', () async {
- var newPackageConfig = PackageConfig([
- ...currentPackageConfig.packages,
- Package('example', Uri.file('${d.sandbox}/'),
- languageVersion: LanguageVersion(2, 12),
- // TODO: https://github.com/dart-lang/package_config/issues/81
- packageUriRoot: Uri.file('${d.sandbox}/')),
- ]);
-
- await d
- .file('package_config.json',
- jsonEncode(PackageConfig.toJson(newPackageConfig)))
- .create();
-
- var test = await runTest(['test.dart'],
- packageConfig: p.join(d.sandbox, 'package_config.json'));
-
- expect(
- test.stdout,
- emitsThrough(contains(
- 'Error: A library can\'t opt out of null safety by default, '
- 'when using sound null safety.')));
- await test.shouldExit(1);
- });
-
- test('sound null safety is disabled if the package is opted out',
- () async {
- var newPackageConfig = PackageConfig([
- ...currentPackageConfig.packages,
- Package('example', Uri.file('${d.sandbox}/'),
- languageVersion: LanguageVersion(2, 8),
- // TODO: https://github.com/dart-lang/package_config/issues/81
- packageUriRoot: Uri.file('${d.sandbox}/')),
- ]);
-
- await d
- .file('package_config.json',
- jsonEncode(PackageConfig.toJson(newPackageConfig)))
- .create();
-
- var test = await runTest(['test.dart'],
- packageConfig: p.join(d.sandbox, 'package_config.json'));
-
- expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
- await test.shouldExit(0);
- });
- });
- });
-}
diff --git a/pkgs/checks/CHANGELOG.md b/pkgs/checks/CHANGELOG.md
index b38ba42..8f6105c 100644
--- a/pkgs/checks/CHANGELOG.md
+++ b/pkgs/checks/CHANGELOG.md
@@ -1,9 +1,42 @@
-# 0.1.1-dev
+## 0.3.0-wip
+- **Breaking Changes**
+ - Remove the `Condition` class and the `it()` utility. Replace calls to
+ `(it()..someExpectation())` with `((it) => it.someExpectation())`.
+- Add class modifiers to restrict extension of implementation classes.
+
+## 0.2.2
+
+- Return the first failure from `softCheck` and `softCheckAsync` as
+ documented, instead of the last failure when there are multiple failures.
+- Add example `because` usage and mention the "reason" name in the migration
+ guide.
+- Add `ComparableChecks` with comparison expectations for subject types that
+ implement `Comparable`.
+
+## 0.2.1
+
+- Add a link to file issues with feedback in the README.
+
+## 0.2.0
+
+- **Breaking Changes**
+ - `checkThat` renamed to `check`.
+ - `nest` and `nestAsync` take `Iterable<String> Function()` arguments for
+ `label` instead of `String`.
+ - Async expectation extensions `completes`, `throws`, `emits`, and
+ `emitsError` no longer return a `Future<Subject>`. Instead they take an
+ optional `Condition` argument which can check expectations that would
+ have been checked on the returned subject.
+ - `nestAsync` no longer returns a `Subject`, callers must pass the
+ followup `Condition` to the nullable argument.
+ - Remove the `which` extension on `Future<Subject>`.
+ - `matches` renamed to `matchesPattern` and now accepts a `Pattern`
+ argument, instead of limiting to `RegExp`.
- Added an example.
- Include a stack trace in the failure description for unexpected errors from
Futures or Streams.
-# 0.1.0
+## 0.1.0
- Initial release.
diff --git a/pkgs/checks/README.md b/pkgs/checks/README.md
index 1c06f68..5415f11 100644
--- a/pkgs/checks/README.md
+++ b/pkgs/checks/README.md
@@ -1,80 +1,176 @@
-# Checking expectations with `checks`
+[![pub package](https://img.shields.io/pub/v/checks.svg)](https://pub.dev/packages/checks)
+[![package publisher](https://img.shields.io/pub/publisher/checks.svg)](https://pub.dev/packages/checks/publisher)
-Expectations start with `checkThat`. This utility returns a `Subject`, and
+`package:checks` is a library for expressing test expectations and it features
+a literate API.
+
+## package:checks preview
+
+`package:checks` is in preview; to provide feedback on the API, please file
+[an issue][] with questions, suggestions, feature requests, or general
+feedback.
+
+For documentation about migrating from `package:matcher` to `checks`, see the
+[migration guide][].
+
+[an issue]:https://github.com/dart-lang/test/issues/new?labels=package%3Achecks&template=03_checks_feedback.md
+[migration guide]:https://github.com/dart-lang/test/blob/master/pkgs/checks/doc/migrating_from_matcher.md
+
+## Quickstart
+
+1. Add a `dev_dependency` on `checks: ^0.2.0`.
+
+1. Add an import for `package:checks/checks.dart`.
+
+1. Use `checks` in your test code:
+
+```dart
+void main() {
+ test('sample test', () {
+ // test code here
+ ...
+
+ check(actual).equals(expected);
+ check(someList).isNotEmpty();
+ check(someObject).isA<Map>();
+ check(someString)..startsWith('a')..endsWith('z')..contains('lmno');
+ });
+}
+```
+
+## Checking expectations with `checks`
+
+Expectations start with `check`. This utility returns a `Subject`, and
expectations can be checked against the subject. Expectations are defined as
extension methods, and different expectations will be available for subjects
with different value types.
```dart
-checkThat(someValue).equals(expectedValue);
-checkThat(someList).deepEquals(expectedList);
-checkThat(someString).contains('expected pattern');
+check(someValue).equals(expectedValue);
+check(someList).deepEquals(expectedList);
+check(someString).contains('expected pattern');
```
+If a failure may not have enough context about the actual or expected values
+from the expectation calls alone, add a "Reason" in the failure message by
+passing a `because:` argument to `check()`.
+
+```dart
+check(
+ because: 'log lines must start with the severity',
+ logLines,
+).every((l) => l
+ ..anyOf([
+ (l) => l.startsWith('ERROR'),
+ (l) => l.startsWith('WARNING'),
+ (l) => l.startsWith('INFO'),
+ ]));
+```
+
+
+### Composing expectations
+
+
Multiple expectations can be checked against the same value using cascade
syntax. When multiple expectations are checked against a single value, a failure
will included descriptions of the expectations that already passed.
```dart
-checkThat(someString)
+check(someString)
..startsWith('a')
..endsWith('z')
..contains('lmno');
```
-Some expectations return a `Subject` for another value derived from the original
-value - for instance reading a field or awaiting the result of a Future.
+Some nested checks may be not be possible to write with cascade syntax.
+There is a `which` utility for this use case which takes a `Condition`.
```dart
-checkThat(someString).length.equals(expectedLength);
-(await checkThat(someFuture).completes()).equals(expectedCompletion);
+check(someString)
+ ..startsWith('a')
+ // A cascade would not be possible on `length`
+ ..length.which((l) => l
+ ..isGreatherThan(10)
+ ..isLessThan(100));
```
-Fields can be extracted from objects for checking further properties with the
-`has` utility.
+
+Some expectations return a `Subject` for another value derived from the original
+value, such as the `length` extension.
```dart
-checkThat(someValue)
+check(someString).length.equals(expectedLength);
+```
+
+Fields or derived values can be extracted from objects for checking further
+properties with the `has` utility.
+
+```dart
+check(someValue)
.has((value) => value.property, 'property')
.equals(expectedPropertyValue);
```
+### Passing a set of expectations as an argument
+
Some expectations take arguments which are themselves expectations to apply to
-other values. These expectations take `Condition` arguments, which check
-expectations when they are applied to a `Subject`. The `ConditionSubject`
-utility acts as both a condition and a subject. Any expectations checked on the
-value as a subject will be recorded and replayed when it is applied as a
-condition. The `it()` utility returns a `ConditionSubject`.
+other values. These expectations take `Condition` arguments which have the
+signature void Function(Subject)`. The conditions check expectations when they
+are called with a `Subject` argument.
```dart
-checkThat(someList).any(it()..isGreaterThan(0));
+check(someList).any((e) => e.isGreaterThan(0));
```
-Some complicated checks may be difficult to write with parenthesized awaited
-expressions, or impossible to write with cascade syntax. There are `which`
-utilities for both use cases which take a `Condition`.
+### Checking asynchronous expectations
+
+Expectation extension methods checking asynchronous behavior return a `Future`.
+The future should typically be awaited within the test body, however
+asynchronous expectations will also ensure that the test is not considered
+complete before the expectation is complete.
+Expectations with no concrete end conditions, such as an expectation that a
+future never completes, cannot be awaited and may cause a failure after the test
+has already appeared to complete.
+
+Asynchronous expectations do not return a `Subject`. When an expectation
+extracts a derived value further expectations can be checked by passing a
+`Condition`.
```dart
-checkThat(someString)
- ..startsWith('a')
- // A cascade would not be possible on `length`
- ..length.which(it()
- ..isGreatherThan(10)
- ..isLessThan(100));
-
-await checkThat(someFuture)
- .completes()
- .which(equals(expectedCompletion));
+await check(someFuture).completes((r) => r.isGreaterThan(0));
```
-# Writing custom expectations
+Subjects for `Stream` instances must first be wrapped into a `StreamQueue` to
+allow multiple expectations to test against the stream from the same state.
+The `withQueue` extension can be used when a given stream instance only needs to
+be checked once, or if it is a broadcast stream, but if single subscription
+stream needs to have multiple expectations checked separately it should be
+wrapped with a `StreamQueue`.
-Expectations are written as extension on `Subject` with specific generics. The
+```dart
+await check(someStream).withQueue.inOrder([
+ (s) => s.emits((e) => e.equals(1)),
+ (s) => s.emits((e) => e.equals(2)),
+ (s) => s.emits((e) => e.equals(3)),
+ (s) => s.isDone(),
+]);
+
+var someQueue = StreamQueue(someOtherStream);
+await check(someQueue).emits((e) => e.equals(1));
+// do something
+await check(someQueue).emits((e) => e.equals(2));
+// do something
+```
+
+
+## Writing custom expectations
+
+Expectations are written as extensions on `Subject` with specific generics. The
library `package:checks/context.dart` gives access to a `context` getter on
`Subject` which offers capabilities for defining expectations on the subject's
value.
-The `Context` allows checking a expectation with `expect`, `expectAsync` and
+The `Context` allows checking an expectation with `expect`, `expectAsync` and
`expectUnawaited`, or extracting a derived value for performing other checks
with `nest` and `nestAsync`. Failures are reported by returning a `Rejection`,
or an `Extracted.rejection`, extensions should avoid throwing exceptions.
@@ -82,9 +178,10 @@
Descriptions of the clause checked by an expectations are passed through a
separate callback from the predicate which checks the value. Nesting calls are
made with a label directly. When there are no failures the clause callbacks are
-not called. When a `Condition` is described, the clause callbacks are called,
-but the predicate callbacks are not called. Conditions can be checked against
-values without throwing an exception using `softCheck` or `softCheckAsync`.
+not called. When a condition callback is described, the clause callbacks are
+called, but the predicate callbacks are not called. Conditions can be checked
+against values without throwing an exception using `softCheck` or
+`softCheckAsync`.
```dart
extension CustomChecks on Subject<CustomType> {
@@ -96,7 +193,7 @@
}
Subject<Foo> get someDerivedValue =>
- context.nest('has someDerivedValue', (actual) {
+ context.nest(() => ['has someDerivedValue'], (actual) {
if (_cannotReadDerivedValue(actual)) {
return Extracted.rejection(which: ['cannot read someDerivedValue']);
}
@@ -108,42 +205,16 @@
}
```
-# Trying Checks as a Preview
-
-1. Add a `dev_dependency` on `checks: ^0.1.0`.
-
-1. Replace the existing `package:test/test.dart` import with
- `package:test/scaffolding.dart`.
-
-1. Add an import to `package:checks/checks.dart`.
-
-1. For an incremental migration within the test, add an import to
- `package:test/expect.dart`. Remove it to surface errors in tests that still
- need to be migrated, or keep it in so the tests work without being fully
- migrated.
-
-1. Migrate the test cases.
-
-# Migrating from Matchers
-
-Replace calls to `expect` with a call to `checkThat` passing the first argument.
-When a direct replacement is available, change the second argument from calling
-a function returning a Matcher, to calling the extension method on the
-`Subject`.
-
-When a non-matcher argument is used for the expected value, it would have been
-wrapped with `equals` automatically. See below, `.equals` may not always be the
-correct replacement in `package:checks`.
+Extensions may also compose existing expectations under a single name. When
+such expectations fail, the test output will refer to the individual
+expectations that were called.
```dart
-expect(actual, expected);
-checkThat(actual).equals(expected);
-// or maybe
-checkThat(actual).deepEquals(expected);
+extension ComposedChecks on Subject<Iterable> {
+ void hasLengthInRange(int min, int max) {
+ length
+ ..isGreaterThan(min)
+ ..isLessThan(max);
+ }
+}
```
-
-## Differences in behavior from matcher
-
-- The `equals` Matcher performed a deep equality check on collections.
- `.equals()` expectation will only correspond to [operator ==] so some tests
- may need to replace `.equals()` with `.deepEquals()`.
diff --git a/pkgs/checks/doc/migrating_from_matcher.md b/pkgs/checks/doc/migrating_from_matcher.md
new file mode 100644
index 0000000..82c4e3c
--- /dev/null
+++ b/pkgs/checks/doc/migrating_from_matcher.md
@@ -0,0 +1,198 @@
+## Migrating from package:matcher
+
+`package:checks` is currently in preview. Once this package reaches a stable
+version, it will be the recommended package by the Dart team to use for most
+tests.
+
+[`package:matcher`][matcher] is the legacy package with an API exported from
+`package:test/test.dart` and `package:test/expect.dart`.
+
+**Do I have to migrate all at once?** No. `package:matcher` will be compatible
+with `package:checks`, and old tests can continue to use matchers. Test cases
+within the same file can use a mix of `expect` and `check`.
+
+**_Should_ I migrate all at once?** Probably not, it depends on your tolerance
+for having tests use a mix of APIs. As you add new tests, or need to make
+updates to existing tests, using `checks` will make testing easier. Tests which
+are stable and passing will not get significant benefits from a migration.
+
+**Do I need to migrate at all?** No. When `package:test`stops exporting
+these members it will be possible to add a dependency on `package:matcher` and
+continue to use them. `package:matcher` will continue to be available.
+
+**Why is the Dart team adding a second framework?** The `matcher` package has a
+design which is fundamentally incompatible with using static types to validate
+correct use. With an entirely new design, the static types in `checks` give
+confidence that the expectation is appropriate for the value, and can narrow
+autocomplete choices in the IDE for a better editing experience. The clean break
+from the legacy implementation and API also gives an opportunity to make small
+behavior and signature changes to align with modern Dart idioms.
+
+**Should I start using checks right away?** There is still a
+high potential for minor or major breaking changes during the preview window.
+Once this package is stable, yes! The experience of using `checks` improves on
+`matcher`. See some of the [improvements to look forward to in checks
+below](#improvements-you-can-expect).
+
+[matcher]: https://pub.dev/packages/matcher
+
+## Trying Checks as a Preview
+
+1. Add a `dev_dependency` on `checks: ^0.2.0`.
+
+1. Replace the existing `package:test/test.dart` import with
+ `package:test/scaffolding.dart`.
+
+1. Add an import to `package:checks/checks.dart`.
+
+1. For an incremental migration within the test, add an import to
+ `package:test/expect.dart`. Remove it to surface errors in tests that still
+ need to be migrated, or keep it in so the tests work without being fully
+ migrated.
+
+1. Migrate the test cases.
+
+## Migrating from Matchers
+
+Replace calls to `expect` or `expectLater` with a call to `check` passing the
+first argument.
+When a direct replacement is available, change the second argument from calling
+a function returning a Matcher, to calling the relevant extension method on the
+`Subject`.
+
+Whenever you see a bare non-matcher value argument for `expected`, assume it
+should use the `equals` expectation, although take care when the subject is a
+collection.
+See below, `.equals` may not always be the correct replacement in
+`package:checks`.
+
+```dart
+expect(actual, expected);
+check(actual).equals(expected);
+// or maybe
+check(actualCollection).deepEquals(expected);
+
+await expectLater(actual, completes());
+await check(actual).completes();
+```
+
+If you use the `reason` argument to `expect`, rename it to `because`.
+
+```dart
+expect(actual, expectation(), reason: 'some explanation');
+check(because: 'some explanation', actual).expectation();
+```
+
+### Differences in behavior from matcher
+
+- The `equals` Matcher performed a deep equality check on collections.
+ `.equals()` expectation will only correspond to [operator ==] so some tests
+ may need to replace `.equals()` with `.deepEquals()`.
+- Streams must be explicitly wrapped into a `StreamQueue` before they can be
+ tested for behavior. Use `check(actualStream).withQueue`.
+- `emitsAnyOf` is `Subject<StreamQueue>.anyOf`. `emitsInOrder` is `inOrder`.
+ The arguments are `FutureOr<void> Function(Subject<StreamQueue>)` and match
+ a behavior of the entire stream. In `matcher` the elements to expect could
+ have been a bare value to check for equality, a matcher for the emitted
+ value, or a matcher for the entire queue which would match multiple values.
+ Use `(s) => s.emits((e) => e.interestingCheck())` to check the emitted
+ elements.
+- In `package:matcher` the [`matches` Matcher][matches] converted a `String`
+ argument into a `Regex`, so `matches(r'\d')` would match the value `'1'`.
+ This was potentially confusing, because even though `String` is a subtype of
+ `Pattern`, it wasn't used as a pattern directly.
+ With `matchesPattern` a `String` argument is used as a `Pattern` and
+ comparison uses [`String.allMatches`][allMatches].
+ For backwards compatibility change `matches(regexString)` to
+ `matchesPattern(RegExp(regexString))`.
+- The `TypeMatcher.having` API is replace by the more general`.has`. While
+ `.having` could only be called on a `TypeMatcher` using `.isA`, `.has` works
+ on any `Subject`. `CoreChecks.has` takes 1 fewer arguments - instead of
+ taking the last argument, a `matcher` to apply to the field, it returns a
+ `Subject` for the field.
+
+[matches]:https://pub.dev/documentation/matcher/latest/matcher/Matcher/matches.html
+[allMatches]:https://api.dart.dev/stable/2.19.1/dart-core/Pattern/allMatches.html
+
+### Matchers with replacements under a different name
+
+- `anyElement` -> `Subject<Iterable>.any`
+- `everyElement` -> `Subject<Iterable>.every`
+- `completion(Matcher)` -> `completes(conditionCallback)`
+- `containsPair(key, value)` -> Use `Subject<Map>[key].equals(value)`
+- `hasLength(expected)` -> `length.equals(expected)`
+- `isNot(Matcher)` -> `not(conditionCallback)`
+- `pairwiseCompare` -> `pairwiseComparesTo`
+- `same` -> `identicalTo`
+- `stringContainsInOrder` -> `Subject<String>.containsInOrder`
+
+### Members from `package:test/expect.dart` without a direct replacement
+
+- `checks` does not ship with any type checking matchers for specific types.
+ Instead of, for example, `isArgumentError` use `isA<ArgumentError>`, and
+ similary `throws<ArgumentError>` over `throwsArgumentError`.
+- `anything`. When a condition callback is needed that should accept any
+ value, pass `(_) {}`.
+- Specific numeric comparison - `isNegative`, `isPositive`, `isZero` and their
+ inverses. Use `isLessThan`, `isGreaterThan`, `isLessOrEqual`, and
+ `isGreaterOrEqual` with appropriate numeric arguments.
+- Numeric range comparison, `inClosedOpenRange`, `inExclusiveRange`,
+ `inInclusiveRange`, `inOpenClosedRange`. Use cascades to chain a check for
+ both ends of the range onto the same subject.
+- `containsOnce`: TODO add missing expectation
+- `emitsInAnyOrder`: TODO add missing expectation
+- `expectAsync` and `expectAsyncUntil`. Continue to import
+ `package:test/expect.dart` for these APIs.
+- `isIn`: TODO add missing expectation
+- `orderedEquals`: Use `deepEquals`. If the equality needs to specifically
+ *not* be deep equality (this is unusual, nested collections are unlikely to
+ have a meaningful equality), force using `operator ==` at the first level
+ with `.deepEquals(expected.map((e) => (Subject<Object?> s) => s.equals(e)))`;
+- `prints`: TODO add missing expectation? Is this one worth replacing?
+- `predicate`: TODO add missing expectation
+
+## Improvements you can expect
+
+Expectations are statically restricted to those which are appropriate for the
+type. So while the following is statically allowed with `matcher` but always
+fails at runtime, the expectation cannot be written at all with `checks`.
+
+```dart
+expect(1, contains(1)); // No static error, always fails
+check(1).contains(1); // Static error. The method 'contains' isn't defined
+```
+
+These static restrictions also improve the relevance of IDE autocomplete
+suggestions. While editing with the cursor at `_`, the suggestions provided
+in the `matcher` example can include _any_ top level element including matchers
+appropriate for other types of value, type names, and top level definitions from
+other packages. With the cursor following a `.` in the `checks` example the
+suggestions will only be expectations or utilities appropriate for the value
+type.
+
+```dart
+expect(actual, _ // many unrelated suggestions
+check(actual)._ // specific suggestions
+```
+
+Asynchronous matchers in `matcher` are a subtype of synchronous matchers, but do
+not satisfy the same behavior contract. Some APIs which use a matcher could not
+validate whether it would satisfy the behavior it needs, and it could result in
+a false success, false failure, or misleading errors. APIs which correctly use
+asynchronous matchers need to do a type check and change their interaction based
+on the runtime type. Asynchronous expectations in `checks` are refused at
+runtime when a synchronous answer is required. The error will help solve the
+specific misuse, instead of resulting in a confusing error, or worse a missed
+failure. The reason for the poor compatibility in `matcher` is due to some
+history of implementation - asynchronous matchers were written in `test`
+alongside `expect`, and synchronous matchers have no dependency on the
+asynchronous implementation.
+
+Asynchronous expectations always return a `Future`, and with the
+[`unawaited_futures` lint][unawaited lint] should more safely ensure that
+asynchronous expectation work is completed within the test body. With `matcher`
+it was up to the author to correctly use `await expecLater` for asynchronous
+cases, and `expect` for synchronous cases, and if `expect` was used with an
+asynchronous matcher the expectation could fail at any point.
+
+[unawaited lint]: https://dart.dev/lints/unawaited_futures
diff --git a/pkgs/checks/example/example.dart b/pkgs/checks/example/example.dart
index 621d42d..88bec0b 100644
--- a/pkgs/checks/example/example.dart
+++ b/pkgs/checks/example/example.dart
@@ -8,14 +8,17 @@
void main() {
test('sample test', () {
final someValue = 5;
- checkThat(someValue).equals(5);
+ check(someValue).equals(5);
final someList = [1, 2, 3, 4, 5];
- checkThat(someList).deepEquals([1, 2, 3, 4, 5]);
+ check(someList).deepEquals([1, 2, 3, 4, 5]);
final someString = 'abcdefghijklmnopqrstuvwxyz';
- checkThat(someString)
+ check(
+ because: 'it should contain the beginning, middle and end',
+ someString,
+ )
..startsWith('a')
..endsWith('z')
..contains('lmno');
diff --git a/pkgs/checks/lib/checks.dart b/pkgs/checks/lib/checks.dart
index 59cfb5f..a390e75 100644
--- a/pkgs/checks/lib/checks.dart
+++ b/pkgs/checks/lib/checks.dart
@@ -2,12 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-export 'src/checks.dart' show checkThat, Subject, Skip, it;
+export 'src/checks.dart'
+ show AsyncCondition, Condition, SkipExtension, Subject, check;
export 'src/extensions/async.dart'
- show ChainAsync, FutureChecks, StreamChecks, StreamQueueWrap;
+ show FutureChecks, StreamChecks, WithQueueExtension;
export 'src/extensions/core.dart'
- show BoolChecks, CoreChecks, NullabilityChecks, equals;
-export 'src/extensions/function.dart' show ThrowsCheck;
+ show BoolChecks, ComparableChecks, CoreChecks, NullableChecks, equals;
+export 'src/extensions/function.dart' show FunctionChecks;
export 'src/extensions/iterable.dart' show IterableChecks;
export 'src/extensions/map.dart' show MapChecks;
export 'src/extensions/math.dart' show NumChecks;
diff --git a/pkgs/checks/lib/context.dart b/pkgs/checks/lib/context.dart
index c0a2311..cebba71 100644
--- a/pkgs/checks/lib/context.dart
+++ b/pkgs/checks/lib/context.dart
@@ -4,7 +4,7 @@
export 'src/checks.dart'
show
- Subject,
+ AsyncCondition,
CheckFailure,
Condition,
Context,
@@ -12,6 +12,7 @@
Extracted,
FailureDetail,
Rejection,
+ Subject,
describe,
describeAsync,
softCheck,
diff --git a/pkgs/checks/lib/src/checks.dart b/pkgs/checks/lib/src/checks.dart
index 3a43fd1..75107ba 100644
--- a/pkgs/checks/lib/src/checks.dart
+++ b/pkgs/checks/lib/src/checks.dart
@@ -2,13 +2,15 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// TODO Add doc about how failure strings work.
import 'dart:async';
import 'package:meta/meta.dart' as meta;
import 'package:test_api/hooks.dart';
import 'describe.dart';
+import 'extensions/async.dart';
+import 'extensions/core.dart';
+import 'extensions/iterable.dart';
/// A target for checking expectations against a value in a test.
///
@@ -16,15 +18,29 @@
/// validated or rejected; or it may be a placeholder, in which case
/// expectations describe what would be checked but cannot be rejected.
///
-/// Expectations are defined as extension methods specialized on the generic
-/// [T]. Expectations can use the [ContextExtension] to interact with the
-/// [Context] for this subject.
-class Subject<T> {
+/// Expectation methods are defined in extensions `on Subject`, specialized on
+/// the generic [T].
+/// Expectation extension methods can use the [ContextExtension] to interact
+/// with the [Context] for this subject.
+///
+/// Create a subject that throws an exception for missed expectations with the
+/// [check] function.
+final class Subject<T> {
final Context<T> _context;
Subject._(this._context);
}
-extension Skip<T> on Subject<T> {
+/// A callback that synchronously checks expectations against a subject.
+///
+/// Asynchronous expectations should not be used within a `Condition` callback.
+typedef Condition<T> = void Function(Subject<T>);
+
+/// A callback that asynchronously checks expectations against a subject.
+///
+/// Any expectations may be used within an `AsyncCondition` callback.
+typedef AsyncCondition<T> = FutureOr<void> Function(Subject<T>);
+
+extension SkipExtension<T> on Subject<T> {
/// Mark the currently running test as skipped and return a [Subject] that
/// will ignore all expectations.
///
@@ -33,7 +49,7 @@
/// failure.
///
/// ```dart
- /// checkThat(actual)
+ /// check(actual)
/// ..stillChecked()
/// ..skip('reason the expectation is temporarily not met').notChecked();
/// ```
@@ -57,11 +73,10 @@
/// messages.
///
/// ```dart
-/// checkThat(actual).equals(expected);
+/// check(actual).equals(expected);
/// ```
@meta.useResult
-Subject<T> checkThat<T>(T value, {String? because}) =>
- Subject._(_TestContext._root(
+Subject<T> check<T>(T value, {String? because}) => Subject._(_TestContext._root(
value: _Present(value),
// TODO - switch between "a" and "an"
label: 'a $T',
@@ -94,12 +109,12 @@
final subject = Subject<T>._(_TestContext._root(
value: _Present(value),
fail: (f) {
- failure = f;
+ failure ??= f;
},
allowAsync: false,
allowUnawaited: false,
));
- condition.apply(subject);
+ condition(subject);
return failure;
}
@@ -112,17 +127,18 @@
///
/// In contrast to [softCheck], asynchronous expectations are allowed in
/// [condition].
-Future<CheckFailure?> softCheckAsync<T>(T value, Condition<T> condition) async {
+Future<CheckFailure?> softCheckAsync<T>(
+ T value, AsyncCondition<T> condition) async {
CheckFailure? failure;
final subject = Subject<T>._(_TestContext._root(
value: _Present(value),
fail: (f) {
- failure = f;
+ failure ??= f;
},
allowAsync: true,
allowUnawaited: false,
));
- await condition.applyAsync(subject);
+ await condition(subject);
return failure;
}
@@ -146,7 +162,7 @@
allowAsync: false,
allowUnawaited: true,
);
- condition.apply(Subject._(context));
+ condition(Subject._(context));
return context.detail(context).expected.skip(1);
}
@@ -161,7 +177,7 @@
///
/// In contrast to [describe], asynchronous expectations are allowed in
/// [condition].
-Future<Iterable<String>> describeAsync<T>(Condition<T> condition) async {
+Future<Iterable<String>> describeAsync<T>(AsyncCondition<T> condition) async {
final context = _TestContext<T>._root(
value: _Absent(),
fail: (_) {
@@ -170,58 +186,253 @@
allowAsync: true,
allowUnawaited: true,
);
- await condition.applyAsync(Subject._(context));
+ await condition(Subject._(context));
return context.detail(context).expected.skip(1);
}
-/// A set of expectations that are checked against the value when applied to a
-/// [Subject].
-abstract class Condition<T> {
- void apply(Subject<T> subject);
- Future<void> applyAsync(Subject<T> subject);
-}
-
-ConditionSubject<T> it<T>() => ConditionSubject._();
-
extension ContextExtension<T> on Subject<T> {
/// The expectations and nesting context for this subject.
Context<T> get context => _context;
}
-/// The expectation and nesting context already applied to a [Subject].
+/// The context for a [Subject] that allows asserting expectations and creating
+/// nested subjects.
///
-/// This is the surface of interaction for expectation extension method
-/// implementations.
+/// A [Subject] is the target for checking expectations in a test.
+/// Every subject has a [Context] which holds the "actual" value, tracks how the
+/// value was obtained, and can check expectations about the value.
///
-/// The `expect` and `expectAsync` can test the value and optionally reject it.
-/// The `nest` and `nestAsync` can test the value, and also extract some other
-/// property from it for further checking.
-abstract class Context<T> {
+/// The user focused APIs called within tests are expectation extension methods
+/// written in an extension `on Subject`, typically specialized to a specific
+/// generic.
+///
+/// Expectation extension methods will make a call to one of the APIs on the
+/// subject's [Context], and can perform one of two types of operations:
+///
+/// - Expect something of the current value (such as [CoreChecks.equals] or
+/// [IterableChecks.contains]) by calling [expect], [expectAsync], or
+/// [expectUnawaited].
+/// - Expect that a new subject can be extracted from the current value (such
+/// as [CoreChecks.has] or [FutureChecks.completes]) by calling [nest] or
+/// [nestAsync].
+///
+///
+/// Whichever type of operation, an expectation extension method provides two
+/// callbacks.
+/// The first callback is an `Iterable<String> Function()` returning a
+/// description of the expectation.
+/// The second callback always takes the actual value as an argument, and the
+/// specific signature varies by operation.
+///
+///
+/// In expectation extension methods calling [expect], [expectAync], or
+/// [expectUnawaited], the `predicate` callback can report a [Rejection] if the
+/// value fails to satisfy the expectation.
+/// The description will be passed in a "clause" callback.
+/// {@template clause_description}
+/// The clause callback returns a description of what is checked which stands
+/// on its own.
+/// For instance the `is equal to <1>` in:
+///
+/// ```
+/// Expected: a int that:
+/// is equal to <1>
+/// ```
+/// {@endtemplate}
+///
+///
+/// In expectation extension methods calling [nest] or [nestAsync], the
+/// `extract` callback can return a [Extracted.rejection] if the value fails to
+/// satisfy an expectation which disallows extracting the value, or an
+/// [Extracted.value] to become the value in a nested subject.
+/// The description will be passed in a "label" callback.
+/// {@template label_description}
+/// The label callback returns a description of the extracted subject as it
+/// relates to the original subject.
+/// For instance the `completes to a value` in:
+///
+/// ```
+/// Expected a Future<int> that:
+/// completes to a value that:
+/// is equal to <1>
+/// ```
+///
+/// A label should also be sensible when it is read as a clause.
+/// If no further expectations are checked on the extracted subject, or if the
+/// extraction is rejected, the "that:" is omitted in the output.
+///
+/// ```
+/// Expected a Future<int> that:
+/// completes to a value
+/// ```
+/// {@endtemplate}
+///
+///
+/// A rejection carries two descriptions, one description of the "actual" value
+/// that was tested, and an optional "which" with further details about how the
+/// result different from the expectation.
+/// If the "actual" argument is omitted it will be filled with a representation
+/// of the value passed to the expectation callback formatted with [literal].
+/// If an expectation extension method is written on a type of subject without a
+/// useful `toString()`, the rejection can provide a string representation to
+/// use instead.
+/// The "which" argument may be omitted if the reason is very obvious based on
+/// the clause and "actual" description, but most expectations should include a
+/// "which".
+///
+/// The behavior of a context following a rejection depends on the source of the
+/// [Subject].
+///
+/// When an expectation is rejected for a [check] subject, an exception is
+/// thrown to interrupt the test, so no further checks should happen. The
+/// failure message will include:
+/// - An "Expected" section with descriptions of all the expectations that
+/// were checked, including the ones that passed, and the last one that
+/// failed.
+/// - An "Actual" section, which may be the description directly from the
+/// [Rejection] if the failure was on the root subject, or may start with a
+/// partial version of the "Expected" description up to the label for the
+/// nesting subject that saw a failure, then the "actual" from the rejection.
+/// - A "Which" description from the rejection, if it was included.
+///
+/// For example, if a failure happens on the root subject, the "actual" is taken
+/// directly from the rejection.
+///
+/// ```
+/// Expected: a Future<int> that:
+/// completes to a value
+/// Actual: a future that completes as an error
+/// Which: threw <UnimplementedError> at:
+/// <stack trace>
+/// ```
+///
+/// But if the failure happens on a nested subject, the actual starts with a
+/// description of the nesting or non-nesting expectations that succeeded, up
+/// to nesting point of the failure, then the "actual" and "which" from the
+/// rejection are indented to that level of nesting.
+///
+/// ```
+/// Expected: a Future<int> that:
+/// completes to a value that:
+/// equals <1>
+/// Actual: a Future<int> that:
+/// completes to a value that:
+/// Actual: <0>
+/// Which: are not equal
+/// ```
+///
+/// ```dart
+/// extension CustomChecks on Subject<CustomType> {
+/// void someExpectation() {
+/// context.expect(() => ['meets this expectation'], (actual) {
+/// if (_expectationIsMet(actual)) return null;
+/// return Rejection(which: ['does not meet this expectation']);
+/// });
+/// }
+///
+/// Subject<Foo> get someDerivedValue =>
+/// context.nest('has someDerivedValue', (actual) {
+/// if (_cannotReadDerivedValue(actual)) {
+/// return Extracted.rejection(which: ['cannot read someDerivedValue']);
+/// }
+/// return Extracted.value(_readDerivedValue(actual));
+/// });
+///
+/// // for field reads that will not get rejected, use `has`
+/// Subject<Bar> get someField => has((a) => a.someField, 'someField');
+/// }
+/// ```
+///
+/// When an expectation is rejected for a subject within a call to [softCheck]
+/// or [softCheckAsync] a [CheckFailure] will be returned with the rejection, as
+/// well as a [FailureDetail] which could be used to format the same failure
+/// message thrown by the [check] subject.
+///
+/// {@template callbacks_may_be_unused}
+/// The description of an expectation may never be shown to the user, so the
+/// callback may never be invoked.
+/// If all the conditions on a subject succeed, or if the failure detail for a
+/// failed [softCheck] is never read, the descriptions will be unused.
+/// String formatting for the descriptions should be performed in the callback,
+/// not ahead of time.
+///
+///
+/// The context for a subject may hold a real "actual" value to test against, or
+/// it may have a placeholder within a call to [describe].
+/// A context with a placeholder value will not invoke the callback to check
+/// expectations.
+///
+/// If both callbacks are invoked, the description callback will always be
+/// called strictly after the expectation callback is called.
+///
+/// Callbacks passed to a context should not throw.
+/// {@endtemplate}
+///
+///
+/// Some contexts disallow certain interactions.
+/// {@template async_limitations}
+/// Calls to [expectAsync] or [nestAsync] must not be performed by a condition
+/// callback passed to [softCheck] or [describe].
+/// Use [softCheckAsync] or [describeAsync] for any condition which checks async
+/// expectations.
+/// {@endtemplate}
+/// {@template unawaited_limitations}
+/// Calls to [expectUnawaited] may not be performed by a condition callback
+/// passed to [softCheck] or [softCheckAsync].
+/// {@endtemplate}
+///
+/// Expectation extension methods can access the context for the subject with
+/// the [ContextExtension].
+///
+/// {@template description_lines}
+/// Description callbacks return an `Iterable<String>` where each element is a
+/// line in the output. Individual elements should not contain newlines.
+/// Utilities such as [prefixFirst], [postfixLast], and [literal] may be useful
+/// to format values which are potentially multiline.
+/// {@endtemplate}
+abstract final class Context<T> {
/// Expect that [predicate] will not return a [Rejection] for the checked
/// value.
///
- /// The property that is asserted by this expectation is described by
- /// [clause]. Often this is a single statement like "equals <1>" or "is
- /// greater than 10", but it may be multiple lines such as describing that an
- /// Iterable contains an element meeting a complex expectation. If any element
- /// in the returned iterable contains a newline it may cause problems with
- /// indentation in the output.
+ /// {@macro clause_description}
+ ///
+ /// {@macro description_lines}
+ ///
+ /// {@macro callbacks_may_be_unused}
+ ///
+ /// ```dart
+ /// void someExpectation() {
+ /// context.expect(() => ['meets this expectation'], (actual) {
+ /// if (_expectationIsMet(actual)) return null;
+ /// return Rejection(which: ['does not meet this expectation']);
+ /// });
+ /// }
+ /// ```
void expect(
Iterable<String> Function() clause, Rejection? Function(T) predicate);
/// Expect that [predicate] will not result in a [Rejection] for the checked
/// value.
///
- /// The property that is asserted by this expectation is described by
- /// [clause]. Often this is a single statement like "equals <1>" or "is
- /// greater than 10", but it may be multiple lines such as describing that an
- /// Iterable contains an element meeting a complex expectation. If any element
- /// in the returned iterable contains a newline it may cause problems with
- /// indentation in the output.
+ /// {@macro clause_description}
///
- /// Some context may disallow asynchronous expectations, for instance in
- /// [softCheck] which must synchronously check the value. In those contexts
- /// this method will throw.
+ /// {@macro description_lines}
+ ///
+ /// {@macro callbacks_may_be_unused}
+ ///
+ /// {@macro async_limitations}
+ ///
+ /// ```dart
+ /// extension CustomChecks on Subject<CustomType> {
+ /// Future<void> someAsyncExpectation() async {
+ /// await context.expectAsync(() => ['meets this async expectation'],
+ /// (actual) async {
+ /// if (await _expectationIsMet(actual)) return null;
+ /// return Rejection(which: ['does not meet this async expectation']);
+ /// });
+ /// }
+ /// }
+ /// ```
Future<void> expectAsync<R>(Iterable<String> Function() clause,
FutureOr<Rejection?> Function(T) predicate);
@@ -237,10 +448,29 @@
/// listening for the event, there is no way to complete a returned future and
/// consider the check "complete".
///
- /// May not be used from the context for a [Subject] created by [softCheck] or
- /// [softCheckAsync]. The only useful effect of a late rejection is to throw a
- /// [TestFailure] when used with a [checkThat] subject. Most conditions should
- /// prefer to use [expect] or [expectAsync].
+ /// {@macro clause_description}
+ ///
+ /// {@macro description_lines}
+ ///
+ /// {@macro callbacks_may_be_unused}
+ ///
+ /// {@macro unawaited_limitations}
+ /// The only useful effect of a late rejection is to throw a [TestFailure]
+ /// when used with a [check] subject. Most conditions should prefer to use
+ /// [expect] or [expectAsync].
+ ///
+ /// ```dart
+ /// void someUnawaitableExpectation() async {
+ /// await context.expectUnawaited(
+ /// () => ['meets this unawaitable expectation'], (actual, reject) {
+ /// final failureSignal = _completeIfFailed(actual);
+ /// unawaited(failureSignal.then((_) {
+ /// reject(Reject(
+ /// which: ['unexpectedly failed this unawaited expectation']));
+ /// }));
+ /// });
+ /// }
+ /// ```
void expectUnawaited(Iterable<String> Function() clause,
void Function(T, void Function(Rejection)) predicate);
@@ -250,19 +480,38 @@
/// [Extracted.rejection] describing the problem. Otherwise it should return
/// an [Extracted.value].
///
- /// The [label] will be used preceding "that:" in a description. Expectations
- /// applied to the returned [Subject] will follow the label, indented by two
- /// more spaces.
+ /// Subsequent expectations can be checked for the extracted value on the
+ /// returned [Subject].
///
- /// If [atSameLevel] is true then [R] should be a subtype of [T], and a
- /// returned [Extracted.value] should be the same instance as the passed
- /// value, or an object which is is equivalent but has a type which is more
- /// convenient to test. In this case expectations applied to the return
- /// [Subject] will behave as if they were applied to the subject for this
- /// context. The [label] will be used as if it were a single line "clause"
- /// passed to [expect]. If the label is empty, the clause will be omitted. The
- /// label should only be left empty if the value extraction cannot fail.
- Subject<R> nest<R>(String label, Extracted<R> Function(T) extract,
+ /// {@macro label_description}
+ ///
+ /// If [atSameLevel] is true then the returned [Extracted.value] should hold
+ /// the same instance as the passed value, or an object which is is equivalent
+ /// but has a type that is more convenient to test.
+ /// In this case expectations applied to the returned [Subject] will behave as
+ /// if they were applied to the subject for this context.
+ /// The [label] will be used as if it were a "clause" argument passed to
+ /// [expect].
+ /// If the label returns an empty iterable, the clause will be omitted.
+ /// The label should only be left empty if the value extraction cannot be
+ /// rejected.
+ ///
+ /// {@macro description_lines}
+ ///
+ /// {@macro callbacks_may_be_unused}
+ ///
+ /// ```dart
+ /// Subject<Foo> get someDerivedValue =>
+ /// context.nest(() => ['has someDerivedValue'], (actual) {
+ /// if (_cannotReadDerivedValue(actual)) {
+ /// return Extracted.rejection(
+ /// which: ['cannot read someDerivedValue']);
+ /// }
+ /// return Extracted.value(_readDerivedValue(actual));
+ /// });
+ /// ```
+ Subject<R> nest<R>(
+ Iterable<String> Function() label, Extracted<R> Function(T) extract,
{bool atSameLevel = false});
/// Extract an asynchronous property from the value for further checking.
@@ -271,21 +520,39 @@
/// [Extracted.rejection] describing the problem. Otherwise it should return
/// an [Extracted.value].
///
- /// The [label] will be used preceding "that:" in a description. Expectations
- /// applied to the returned [Subject] will follow the label, indented by two
- /// more spaces.
+ /// In contrast to [nest], subsequent expectations need to be passed in
+ /// [nestedCondition] which will be applied to the subject for the extracted
+ /// value.
///
- /// Some context may disallow asynchronous expectations, for instance in
- /// [softCheck] which must synchronously check the value. In those contexts
- /// this method will throw.
- Future<Subject<R>> nestAsync<R>(
- String label, FutureOr<Extracted<R>> Function(T) extract);
+ /// {@macro label_description}
+ ///
+ /// {@macro description_lines}
+ ///
+ /// {@macro callbacks_may_be_unused}
+ ///
+ /// {@macro async_limitations}
+ ///
+ /// ```dart
+ /// Future<void> someAsyncResult(
+ /// [AsyncCondition<Result> resultCondition]) async {
+ /// await context.nestAsync(() => ['has someAsyncResult'], (actual) async {
+ /// if (await _asyncOperationFailed(actual)) {
+ /// return Extracted.rejection(which: ['cannot read someAsyncResult']);
+ /// }
+ /// return Extracted.value(await _readAsyncResult(actual));
+ /// }, resultCondition);
+ /// }
+ /// ```
+ Future<void> nestAsync<R>(
+ Iterable<String> Function() label,
+ FutureOr<Extracted<R>> Function(T) extract,
+ AsyncCondition<R>? nestedCondition);
}
/// A property extracted from a value being checked, or a rejection.
-class Extracted<T> {
- final Rejection? rejection;
- final T? value;
+final class Extracted<T> {
+ final Rejection? _rejection;
+ final T? _value;
/// Creates a rejected extraction to indicate a failure trying to read the
/// value.
@@ -294,25 +561,25 @@
/// will be filled in with the [literal] representation of the value.
Extracted.rejection(
{Iterable<String> actual = const [], Iterable<String>? which})
- : rejection = Rejection(actual: actual, which: which),
- value = null;
- Extracted.value(T this.value) : rejection = null;
+ : _rejection = Rejection(actual: actual, which: which),
+ _value = null;
+ Extracted.value(T this._value) : _rejection = null;
- Extracted._(Rejection this.rejection) : value = null;
+ Extracted._(Rejection this._rejection) : _value = null;
Extracted<R> _map<R>(R Function(T) transform) {
- final rejection = this.rejection;
+ final rejection = _rejection;
if (rejection != null) return Extracted._(rejection);
- return Extracted.value(transform(value as T));
+ return Extracted.value(transform(_value as T));
}
- Extracted<T> _fillActual(Object? actual) => rejection == null ||
- rejection!.actual.isNotEmpty
+ Extracted<T> _fillActual(Object? actual) => _rejection == null ||
+ _rejection!.actual.isNotEmpty
? this
- : Extracted.rejection(actual: literal(actual), which: rejection!.which);
+ : Extracted.rejection(actual: literal(actual), which: _rejection!.which);
}
-abstract class _Optional<T> {
+abstract interface class _Optional<T> {
R? apply<R extends FutureOr<Rejection?>>(R Function(T) callback);
Future<Extracted<_Optional<R>>> mapAsync<R>(
FutureOr<Extracted<R>> Function(T) transform);
@@ -330,12 +597,12 @@
Future<Extracted<_Present<R>>> mapAsync<R>(
FutureOr<Extracted<R>> Function(T) transform) async {
final transformed = await transform(value);
- return transformed._map((v) => _Present(v));
+ return transformed._map(_Present.new);
}
@override
Extracted<_Present<R>> map<R>(Extracted<R> Function(T) transform) =>
- transform(value)._map((v) => _Present(v));
+ transform(value)._map(_Present.new);
}
class _Absent<T> implements _Optional<T> {
@@ -352,7 +619,7 @@
Extracted.value(_Absent<R>());
}
-class _TestContext<T> implements Context<T>, _ClauseDescription {
+final class _TestContext<T> implements Context<T>, _ClauseDescription {
final _Optional<T> _value;
/// A reference to find the root context which this context is nested under.
@@ -363,14 +630,37 @@
final List<_ClauseDescription> _clauses;
final List<_TestContext> _aliases;
- // The "a value" in "a value that:".
- final String _label;
-
final void Function(CheckFailure) _fail;
final bool _allowAsync;
final bool _allowUnawaited;
+ /// A callback that returns a label for this context.
+ ///
+ /// If this context is the root the label should return a phrase like
+ /// "a List" in
+ ///
+ /// ```
+ /// Expected: a List that:
+ /// ```
+ ///
+ /// If this context is nested under another context the lable should return a
+ /// phrase like "completes to a value" in
+ ///
+ ///
+ /// ```
+ /// Expected: a Future<int> that:
+ /// completes to a value that:
+ /// ```
+ ///
+ /// In cases where a nested context does not have any expectations checked on
+ /// it, the "that:" will be will be omitted.
+ final Iterable<String> Function() _label;
+
+ static Iterable<String> _emptyLabel() => const [];
+
+ /// Create a context appropriate for a subject which is not nested under any
+ /// other subject.
_TestContext._root({
required _Optional<T> value,
required void Function(CheckFailure) fail,
@@ -378,7 +668,7 @@
required bool allowUnawaited,
String? label,
}) : _value = value,
- _label = label ?? '',
+ _label = (() => [label ?? '']),
_fail = fail,
_allowAsync = allowAsync,
_allowUnawaited = allowUnawaited,
@@ -395,8 +685,11 @@
_allowUnawaited = original._allowUnawaited,
// Never read from an aliased context because they are never present in
// `_clauses`.
- _label = '';
+ _label = _emptyLabel;
+ /// Create a context nested under [parent].
+ ///
+ /// The [_label] callback should not return an empty iterable.
_TestContext._child(this._value, this._label, _TestContext<dynamic> parent)
: _parent = parent,
_fail = parent._fail,
@@ -408,7 +701,7 @@
@override
void expect(
Iterable<String> Function() clause, Rejection? Function(T) predicate) {
- _clauses.add(_StringClause(clause));
+ _clauses.add(_ExpectationClause(clause));
final rejection =
_value.apply((actual) => predicate(actual)?._fillActual(actual));
if (rejection != null) {
@@ -423,13 +716,16 @@
throw StateError(
'Async expectations cannot be used on a synchronous subject');
}
- _clauses.add(_StringClause(clause));
+ _clauses.add(_ExpectationClause(clause));
final outstandingWork = TestHandle.current.markPending();
- final rejection = await _value.apply(
- (actual) async => (await predicate(actual))?._fillActual(actual));
- outstandingWork.complete();
- if (rejection == null) return;
- _fail(_failure(rejection));
+ try {
+ final rejection = await _value.apply(
+ (actual) async => (await predicate(actual))?._fillActual(actual));
+ if (rejection == null) return;
+ _fail(_failure(rejection));
+ } finally {
+ outstandingWork.complete();
+ }
}
@override
@@ -438,27 +734,28 @@
if (!_allowUnawaited) {
throw StateError('Late expectations cannot be used for soft checks');
}
- _clauses.add(_StringClause(clause));
+ _clauses.add(_ExpectationClause(clause));
_value.apply((actual) {
predicate(actual, (r) => _fail(_failure(r._fillActual(actual))));
});
}
@override
- Subject<R> nest<R>(String label, Extracted<R> Function(T) extract,
+ Subject<R> nest<R>(
+ Iterable<String> Function() label, Extracted<R> Function(T) extract,
{bool atSameLevel = false}) {
final result = _value.map((actual) => extract(actual)._fillActual(actual));
- final rejection = result.rejection;
+ final rejection = result._rejection;
if (rejection != null) {
- _clauses.add(_StringClause(() => [label]));
+ _clauses.add(_ExpectationClause(label));
_fail(_failure(rejection));
}
- final value = result.value ?? _Absent<R>();
+ final value = result._value ?? _Absent<R>();
final _TestContext<R> context;
if (atSameLevel) {
context = _TestContext._alias(this, value);
_aliases.add(context);
- if (label.isNotEmpty) _clauses.add(_StringClause(() => [label]));
+ _clauses.add(_ExpectationClause(label));
} else {
context = _TestContext._child(value, label, this);
_clauses.add(context);
@@ -467,25 +764,30 @@
}
@override
- Future<Subject<R>> nestAsync<R>(
- String label, FutureOr<Extracted<R>> Function(T) extract) async {
+ Future<void> nestAsync<R>(
+ Iterable<String> Function() label,
+ FutureOr<Extracted<R>> Function(T) extract,
+ AsyncCondition<R>? nestedCondition) async {
if (!_allowAsync) {
throw StateError(
'Async expectations cannot be used on a synchronous subject');
}
final outstandingWork = TestHandle.current.markPending();
- final result = await _value.mapAsync(
- (actual) async => (await extract(actual))._fillActual(actual));
- outstandingWork.complete();
- final rejection = result.rejection;
- if (rejection != null) {
- _clauses.add(_StringClause(() => [label]));
- _fail(_failure(rejection));
+ try {
+ final result = await _value.mapAsync(
+ (actual) async => (await extract(actual))._fillActual(actual));
+ final rejection = result._rejection;
+ if (rejection != null) {
+ _clauses.add(_ExpectationClause(label));
+ _fail(_failure(rejection));
+ }
+ final value = result._value ?? _Absent<R>();
+ final context = _TestContext<R>._child(value, label, this);
+ _clauses.add(context);
+ await nestedCondition?.call(Subject<R>._(context));
+ } finally {
+ outstandingWork.complete();
}
- final value = result.value ?? _Absent<R>();
- final context = _TestContext<R>._child(value, label, this);
- _clauses.add(context);
- return Subject._(context);
}
CheckFailure _failure(Rejection rejection) =>
@@ -508,9 +810,9 @@
var successfulOverlap = 0;
final expected = <String>[];
if (_clauses.isEmpty) {
- expected.add(_label);
+ expected.addAll(_label());
} else {
- expected.add('$_label that:');
+ expected.addAll(postfixLast(' that:', _label()));
for (var clause in _clauses) {
final details = clause.detail(failingContext);
expected.addAll(indent(details.expected));
@@ -531,7 +833,7 @@
}
/// A context which never runs expectations and can never fail.
-class _SkippedContext<T> implements Context<T> {
+final class _SkippedContext<T> implements Context<T> {
@override
void expect(
Iterable<String> Function() clause, Rejection? Function(T) predicate) {
@@ -551,32 +853,35 @@
}
@override
- Subject<R> nest<R>(String label, Extracted<R> Function(T p1) extract,
+ Subject<R> nest<R>(
+ Iterable<String> Function() label, Extracted<R> Function(T p1) extract,
{bool atSameLevel = false}) {
return Subject._(_SkippedContext());
}
@override
- Future<Subject<R>> nestAsync<R>(
- String label, FutureOr<Extracted<R>> Function(T p1) extract) async {
- return Subject._(_SkippedContext());
+ Future<void> nestAsync<R>(
+ Iterable<String> Function() label,
+ FutureOr<Extracted<R>> Function(T p1) extract,
+ AsyncCondition<R>? nestedCondition) async {
+ // no-op
}
}
-abstract class _ClauseDescription {
+abstract interface class _ClauseDescription {
FailureDetail detail(_TestContext failingContext);
}
-class _StringClause implements _ClauseDescription {
+class _ExpectationClause implements _ClauseDescription {
final Iterable<String> Function() _expected;
- _StringClause(this._expected);
+ _ExpectationClause(this._expected);
@override
FailureDetail detail(_TestContext failingContext) =>
FailureDetail(_expected(), -1, -1);
}
/// The result an expectation that failed for a subject..
-class CheckFailure {
+final class CheckFailure {
/// The specific rejected value within the overall subject that caused the
/// failure.
///
@@ -597,10 +902,10 @@
///
/// A subject may have some number of succeeding expectations, and the failure may
/// be for an expectation against a property derived from the value at the root
-/// of the subject. For example, in `checkThat([]).length.equals(1)` the
+/// of the subject. For example, in `check([]).length.equals(1)` the
/// specific value that gets rejected is `0` from the length of the list, and
/// the subject that sees the rejection is nested with the label "has length".
-class FailureDetail {
+final class FailureDetail {
/// A description of all the conditions the subject was expected to satisfy.
///
/// Each subject has a label. At the root the label is typically "a <Type>"
@@ -662,7 +967,7 @@
}
/// A description of a value that failed an expectation.
-class Rejection {
+final class Rejection {
/// A description of the actual value as it relates to the expectation.
///
/// This may use [literal] to show a String representation of the value, or it
@@ -702,89 +1007,3 @@
Rejection({this.actual = const [], this.which});
}
-
-class ConditionSubject<T> implements Subject<T>, Condition<T> {
- ConditionSubject._();
-
- @override
- void apply(Subject<T> subject) {
- _context.apply(subject);
- }
-
- @override
- Future<void> applyAsync(Subject<T> subject) async {
- await _context.applyAsync(subject);
- }
-
- @override
- final _ReplayContext<T> _context = _ReplayContext();
-
- @override
- String toString() {
- return ['A value that:', ...describe(_context)].join('\n');
- }
-}
-
-class _ReplayContext<T> implements Context<T>, Condition<T> {
- final _interactions = <FutureOr<void> Function(Context<T>)>[];
-
- @override
- void apply(Subject<T> subject) {
- for (var interaction in _interactions) {
- interaction(subject.context);
- }
- }
-
- @override
- Future<void> applyAsync(Subject<T> subject) async {
- for (var interaction in _interactions) {
- await interaction(subject.context);
- }
- }
-
- @override
- void expect(
- Iterable<String> Function() clause, Rejection? Function(T) predicate) {
- _interactions.add((c) {
- c.expect(clause, predicate);
- });
- }
-
- @override
- Future<void> expectAsync<R>(Iterable<String> Function() clause,
- FutureOr<Rejection?> Function(T) predicate) async {
- _interactions.add((c) async {
- await c.expectAsync(clause, predicate);
- });
- }
-
- @override
- void expectUnawaited(Iterable<String> Function() clause,
- void Function(T, void Function(Rejection)) predicate) {
- _interactions.add((c) {
- c.expectUnawaited(clause, predicate);
- });
- }
-
- @override
- Subject<R> nest<R>(String label, Extracted<R> Function(T p1) extract,
- {bool atSameLevel = false}) {
- final nestedContext = _ReplayContext<R>();
- _interactions.add((c) {
- var result = c.nest(label, extract, atSameLevel: atSameLevel);
- nestedContext.apply(result);
- });
- return Subject._(nestedContext);
- }
-
- @override
- Future<Subject<R>> nestAsync<R>(
- String label, FutureOr<Extracted<R>> Function(T) extract) async {
- final nestedContext = _ReplayContext<R>();
- _interactions.add((c) async {
- var result = await c.nestAsync(label, extract);
- await nestedContext.applyAsync(result);
- });
- return Subject._(nestedContext);
- }
-}
diff --git a/pkgs/checks/lib/src/collection_equality.dart b/pkgs/checks/lib/src/collection_equality.dart
index bd11947..aa11bcf 100644
--- a/pkgs/checks/lib/src/collection_equality.dart
+++ b/pkgs/checks/lib/src/collection_equality.dart
@@ -10,12 +10,22 @@
/// are unequal to the elements of [expected].
///
/// {@template deep_collection_equals}
-/// Elements, keys, or values, which are a collections are deeply compared for
-/// equality, and do not use the native identity based equality or custom
-/// equality operator overrides.
-/// Elements, keys, or values, which are a [Condition] instances are checked
-/// against actual values.
-/// All other value or key types use `operator ==`.
+/// Elements, keys, or values within [expected] which are a collections are
+/// deeply compared for equality with a collection in the same position within
+/// [actual]. Elements which are collection types are note compared with the
+/// native identity based equality or custom equality operator overrides.
+///
+/// Elements, keys, or values within [expected] which are `Condition` callbacks
+/// are run against the value in the same position within [actual].
+/// Condition callbacks must take a `Subject<Object?>` or `Subject<dynamic>` and
+/// may not use a more specific generic.
+/// Use `(Subject<Object?> s) => s.isA<Type>()` to check expectations for
+/// specific element types.
+/// Note also that the argument type `Subject<Object?>` cannot be inferred and
+/// must be explicit in the function definition.
+///
+/// Elements, keys, or values within [expected] which are any other type are
+/// compared using `operator ==` equality.
///
/// Comparing sets or maps will have a runtime which is polynomial on the the
/// size of those collections. Does not use [Set.contains] or [Map.containsKey],
@@ -250,7 +260,7 @@
final indexedExpected = expected.toList();
final indexedActual = actual.toList();
final adjacency = <List<int>>[];
- for (int i = 0; i < indexedExpected.length; i++) {
+ for (var i = 0; i < indexedExpected.length; i++) {
final expectedElement = indexedExpected[i];
final pairs = [
for (var j = 0; j < indexedActual.length; j++)
@@ -303,7 +313,7 @@
bool bfs() {
final queue = Queue<int>();
- for (int leftIndex = 0; leftIndex < leftLength; leftIndex++) {
+ for (var leftIndex = 0; leftIndex < leftLength; leftIndex++) {
if (leftPairs[leftIndex] == rightLength) {
distances[leftIndex] = 0;
queue.add(leftIndex);
@@ -342,7 +352,7 @@
}
while (bfs()) {
- for (int leftIndex = 0; leftIndex < leftLength; leftIndex++) {
+ for (var leftIndex = 0; leftIndex < leftLength; leftIndex++) {
if (leftPairs[leftIndex] == rightLength) {
dfs(leftIndex);
}
diff --git a/pkgs/checks/lib/src/describe.dart b/pkgs/checks/lib/src/describe.dart
index 7493c12..c0c3560 100644
--- a/pkgs/checks/lib/src/describe.dart
+++ b/pkgs/checks/lib/src/describe.dart
@@ -4,6 +4,8 @@
import 'dart:convert';
+import 'checks.dart' show Condition, describe;
+
/// Returns a pretty-printed representation of [object].
///
/// When possible, lines will be kept under [_maxLineLength]. This isn't
@@ -59,6 +61,9 @@
.map((line) => line.replaceAll("'", r"\'"))
.toList();
return prefixFirst("'", postfixLast("'", escaped));
+ } else if (object is Condition) {
+ final value = ['A value that:', ...describe(object)];
+ return isTopLevel ? prefixFirst('<', postfixLast('>', value)) : value;
} else {
final value = const LineSplitter().convert(object.toString());
return isTopLevel ? prefixFirst('<', postfixLast('>', value)) : value;
diff --git a/pkgs/checks/lib/src/extensions/async.dart b/pkgs/checks/lib/src/extensions/async.dart
index ff54f4e..8f2f073 100644
--- a/pkgs/checks/lib/src/extensions/async.dart
+++ b/pkgs/checks/lib/src/extensions/async.dart
@@ -11,23 +11,26 @@
extension FutureChecks<T> on Subject<Future<T>> {
/// Expects that the `Future` completes to a value without throwing.
///
- /// Returns a future that completes to a [Subject] on the result once the
- /// future completes.
- ///
/// Fails if the future completes as an error.
- Future<Subject<T>> completes() =>
- context.nestAsync<T>('completes to a value', (actual) async {
- try {
- return Extracted.value(await actual);
- } catch (e, st) {
- return Extracted.rejection(actual: [
- 'a future that completes as an error'
- ], which: [
- ...prefixFirst('threw ', postfixLast(' at:', literal(e))),
- ...(const LineSplitter()).convert(st.toString())
- ]);
- }
- });
+ ///
+ /// Pass [completionCondition] to check expectations on the completion result.
+ ///
+ /// The returned future will complete when the subject future has completed,
+ /// and [completionCondition] has optionally been checked.
+ Future<void> completes([AsyncCondition<T>? completionCondition]) async {
+ await context.nestAsync<T>(() => ['completes to a value'], (actual) async {
+ try {
+ return Extracted.value(await actual);
+ } catch (e, st) {
+ return Extracted.rejection(actual: [
+ 'a future that completes as an error'
+ ], which: [
+ ...prefixFirst('threw ', postfixLast(' at:', literal(e))),
+ ...const LineSplitter().convert(st.toString())
+ ]);
+ }
+ }, completionCondition);
+ }
/// Expects that the `Future` never completes as a value or an error.
///
@@ -48,7 +51,7 @@
'a future that completed as an error:'
], which: [
...prefixFirst('threw ', literal(e)),
- ...(const LineSplitter()).convert(st.toString())
+ ...const LineSplitter().convert(st.toString())
]));
}));
});
@@ -56,28 +59,34 @@
/// Expects that the `Future` completes as an error.
///
- /// Returns a future that completes to a [Subject] on the error once the
- /// future completes as an error.
- ///
/// Fails if the future completes to a value.
- Future<Subject<E>> throws<E extends Object>() => context.nestAsync<E>(
- 'completes to an error${E == Object ? '' : ' of type $E'}',
- (actual) async {
- try {
- return Extracted.rejection(
- actual: prefixFirst('completed to ', literal(await actual)),
- which: ['did not throw']);
- } on E catch (e) {
- return Extracted.value(e);
- } catch (e, st) {
- return Extracted.rejection(
- actual: prefixFirst('completed to error ', literal(e)),
- which: [
- 'threw an exception that is not a $E at:',
- ...(const LineSplitter()).convert(st.toString())
- ]);
- }
- });
+ ///
+ /// Pass [errorCondition] to check expectations on the error thrown by the
+ /// future.
+ ///
+ /// The returned future will complete when the subject future has completed,
+ /// and [errorCondition] has optionally been checked.
+ Future<void> throws<E extends Object>(
+ [AsyncCondition<E>? errorCondition]) async {
+ await context.nestAsync<E>(
+ () => ['completes to an error${E == Object ? '' : ' of type $E'}'],
+ (actual) async {
+ try {
+ return Extracted.rejection(
+ actual: prefixFirst('completed to ', literal(await actual)),
+ which: ['did not throw']);
+ } on E catch (e) {
+ return Extracted.value(e);
+ } catch (e, st) {
+ return Extracted.rejection(
+ actual: prefixFirst('completed to error ', literal(e)),
+ which: [
+ 'threw an exception that is not a $E at:',
+ ...const LineSplitter().convert(st.toString())
+ ]);
+ }
+ }, errorCondition);
+ }
}
/// Expectations on a [StreamQueue].
@@ -104,67 +113,82 @@
/// Expect that the `Stream` emits a value without first emitting an error.
///
- /// Returns a `Future` that completes to a [Subject] on the next event emitted
- /// by the stream.
- ///
/// Fails if the stream emits an error instead of a value, or closes without
/// emitting a value.
- Future<Subject<T>> emits() =>
- context.nestAsync<T>('emits a value', (actual) async {
- if (!await actual.hasNext) {
- return Extracted.rejection(
- actual: ['a stream'],
- which: ['closed without emitting enough values']);
- }
- try {
- await actual.peek;
- return Extracted.value(await actual.next);
- } catch (e, st) {
- return Extracted.rejection(
- actual: prefixFirst('a stream with error ', literal(e)),
- which: [
- 'emitted an error instead of a value at:',
- ...(const LineSplitter()).convert(st.toString())
- ]);
- }
- });
+ ///
+ /// If an error is emitted the queue will be left in its original state, the
+ /// error will not be consumed.
+ /// If an event is emitted, it will be consumed from the queue.
+ ///
+ /// Pass [emittedCondition] to check expectations on the value emitted by the
+ /// stream.
+ ///
+ /// The returned future will complete when the stream has emitted, errored, or
+ /// ended, and the [emittedCondition] has optionally been checked.
+ Future<void> emits([AsyncCondition<T>? emittedCondition]) async {
+ await context.nestAsync<T>(() => ['emits a value'], (actual) async {
+ if (!await actual.hasNext) {
+ return Extracted.rejection(
+ actual: ['a stream'],
+ which: ['closed without emitting enough values']);
+ }
+ try {
+ await actual.peek;
+ return Extracted.value(await actual.next);
+ } catch (e, st) {
+ return Extracted.rejection(
+ actual: prefixFirst('a stream with error ', literal(e)),
+ which: [
+ 'emitted an error instead of a value at:',
+ ...const LineSplitter().convert(st.toString())
+ ]);
+ }
+ }, emittedCondition);
+ }
/// Expects that the stream emits an error of type [E].
///
- /// Returns a [Subject] on the error's value.
- ///
/// Fails if the stream emits any value.
/// Fails if the stream emits an error with an incorrect type.
/// Fails if the stream closes without emitting an error.
///
- /// If this expectation fails, the source queue will be left in it's original
- /// state.
- /// If this expectation succeeds, consumes the error event.
- Future<Subject<E>> emitsError<E extends Object>() =>
- context.nestAsync('emits an error${E == Object ? '' : ' of type $E'}',
- (actual) async {
- if (!await actual.hasNext) {
- return Extracted.rejection(
- actual: ['a stream'],
- which: ['closed without emitting an expected error']);
- }
- try {
- final value = await actual.peek;
- return Extracted.rejection(
- actual: prefixFirst('a stream emitting value ', literal(value)),
- which: ['closed without emitting an error']);
- } on E catch (e) {
- await actual.next.then<void>((_) {}, onError: (_) {});
- return Extracted.value(e);
- } catch (e, st) {
- return Extracted.rejection(
- actual: prefixFirst('a stream with error ', literal(e)),
- which: [
- 'emitted an error which is not $E at:',
- ...(const LineSplitter()).convert(st.toString())
- ]);
- }
- });
+ /// If an event is emitted the queue will be left in its original state, the
+ /// event will not be consumed.
+ /// If an error is emitted, it will be consumed from the queue.
+ ///
+ /// Pass [errorCondition] to check expectations on the error emitted by the
+ /// stream.
+ ///
+ /// The returned future will complete when the stream has emitted, errored, or
+ /// ended, and the [errorCondition] has optionally been checked.
+ Future<void> emitsError<E extends Object>(
+ [AsyncCondition<E>? errorCondition]) async {
+ await context.nestAsync<E>(
+ () => ['emits an error${E == Object ? '' : ' of type $E'}'],
+ (actual) async {
+ if (!await actual.hasNext) {
+ return Extracted.rejection(
+ actual: ['a stream'],
+ which: ['closed without emitting an expected error']);
+ }
+ try {
+ final value = await actual.peek;
+ return Extracted.rejection(
+ actual: prefixFirst('a stream emitting value ', literal(value)),
+ which: ['closed without emitting an error']);
+ } on E catch (e) {
+ await actual.next.then<void>((_) {}, onError: (_) {});
+ return Extracted.value(e);
+ } catch (e, st) {
+ return Extracted.rejection(
+ actual: prefixFirst('a stream with error ', literal(e)),
+ which: [
+ 'emitted an error which is not $E at:',
+ ...const LineSplitter().convert(st.toString())
+ ]);
+ }
+ }, errorCondition);
+ }
/// Expects that the `Stream` emits any number of events before emitting an
/// event that satisfies [condition].
@@ -179,7 +203,7 @@
/// state.
/// If this expectation succeeds, consumes the matching event and all prior
/// events.
- Future<void> emitsThrough(Condition<T> condition) async {
+ Future<void> emitsThrough(AsyncCondition<T> condition) async {
await _expectAsync(
() => [
'emits any values then emits a value that:',
@@ -205,9 +229,9 @@
/// conditions.
///
/// ```dart
- /// await checkThat(StreamQueue(someStream)).inOrder([
- /// it()..emits().that(equals(0)),
- /// it()..emits().that(equals(1)),
+ /// await check(someStream).withQueue.inOrder([
+ /// (s) => s.emits(equals(0)),
+ /// (s) => s.emits(equals(1)),
// ]);
/// ```
///
@@ -215,7 +239,8 @@
/// state.
/// If this expectation succeeds, consumes as many events from the source
/// stream as are consumed by all the conditions.
- Future<void> inOrder(Iterable<Condition<StreamQueue<T>>> conditions) async {
+ Future<void> inOrder(
+ Iterable<AsyncCondition<StreamQueue<T>>> conditions) async {
conditions = conditions.toList();
final descriptions = <String>[];
await _expectAsync(
@@ -260,7 +285,8 @@
/// If this expectation succeeds, consumes the same events from the source
/// queue as the satisfied condition. If multiple conditions are satisfied,
/// chooses the condition which consumed the most events.
- Future<void> anyOf(Iterable<Condition<StreamQueue<T>>> conditions) async {
+ Future<void> anyOf(
+ Iterable<AsyncCondition<StreamQueue<T>>> conditions) async {
conditions = conditions.toList();
if (conditions.isEmpty) {
throw ArgumentError('conditions may not be empty');
@@ -341,7 +367,7 @@
/// state.
/// If this expectation succeeds, consumes all the events that did not satisfy
/// [condition] until the end of the stream.
- Future<void> neverEmits(Condition<T> condition) async {
+ Future<void> neverEmits(AsyncCondition<T> condition) async {
await _expectAsync(
() => ['never emits a value that:', ...describe(condition)],
(actual) async {
@@ -367,7 +393,7 @@
///
/// If a non-matching event is emitted, no events are consumed.
/// If a matching event is emitted, that event is consumed.
- Future<void> mayEmit(Condition<T> condition) async {
+ Future<void> mayEmit(AsyncCondition<T> condition) async {
await context
.expectAsync(() => ['may emit a value that:', ...describe(condition)],
(actual) async {
@@ -392,7 +418,7 @@
/// - A non-matching event is emitted.
/// - An error is emitted.
/// - The stream closes.
- Future<void> mayEmitMultiple(Condition<T> condition) async {
+ Future<void> mayEmitMultiple(AsyncCondition<T> condition) async {
await context
.expectAsync(() => ['may emit a value that:', ...describe(condition)],
(actual) async {
@@ -429,32 +455,14 @@
'a stream'
], which: [
...prefixFirst('emitted an unexpected error: ', literal(e)),
- ...(const LineSplitter()).convert(st.toString())
+ ...const LineSplitter().convert(st.toString())
]);
}
});
}
}
-extension ChainAsync<T> on Future<Subject<T>> {
- /// Checks the expectations in [condition] against the result of this
- /// `Future`.
- ///
- /// Extensions written on [Subject] cannot be invoked on a `Future<Subject>`.
- /// This method allows adding expectations for the value without awaiting an
- /// expression that would need parenthesis.
- ///
- /// ```dart
- /// await checkThat(someFuture).completes().which(equals('expected'));
- /// // or, with the intermediate `await`:
- /// (await checkThat(someFuture).completes()).equals('expected');
- /// ```
- Future<void> which(Condition<T> condition) async {
- await condition.applyAsync(await this);
- }
-}
-
-extension StreamQueueWrap<T> on Subject<Stream<T>> {
+extension WithQueueExtension<T> on Subject<Stream<T>> {
/// Wrap the stream in a [StreamQueue] to allow using checks from
/// [StreamChecks].
///
@@ -462,6 +470,6 @@
/// so that they can support conditional expectations and check multiple
/// possibilities from the same point in the stream.
Subject<StreamQueue<T>> get withQueue =>
- context.nest('', (actual) => Extracted.value(StreamQueue(actual)),
+ context.nest(() => [], (actual) => Extracted.value(StreamQueue(actual)),
atSameLevel: true);
}
diff --git a/pkgs/checks/lib/src/extensions/core.dart b/pkgs/checks/lib/src/extensions/core.dart
index 1fc34be..da1eac1 100644
--- a/pkgs/checks/lib/src/extensions/core.dart
+++ b/pkgs/checks/lib/src/extensions/core.dart
@@ -2,21 +2,26 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:checks/checks.dart';
+import 'dart:convert';
+
import 'package:checks/context.dart';
+import 'package:meta/meta.dart' as meta;
extension CoreChecks<T> on Subject<T> {
/// Extracts a property of the value for further expectations.
///
/// Sets up a clause that the value "has [name] that:" followed by any
/// expectations applied to the returned [Subject].
+ @meta.useResult
Subject<R> has<R>(R Function(T) extract, String name) {
- return context.nest('has $name', (T value) {
+ return context.nest(() => ['has $name'], (value) {
try {
return Extracted.value(extract(value));
- } catch (_) {
- return Extracted.rejection(
- which: ['threw while trying to read property']);
+ } catch (e, st) {
+ return Extracted.rejection(which: [
+ ...prefixFirst('threw while trying to read $name: ', literal(e)),
+ ...const LineSplitter().convert(st.toString())
+ ]);
}
});
}
@@ -28,13 +33,13 @@
/// in a way that would conflict.
///
/// ```
- /// checkThat(something)
+ /// check(something)
/// ..has((s) => s.foo, 'foo').equals(expectedFoo)
- /// ..has((s) => s.bar, 'bar').which(it()
+ /// ..has((s) => s.bar, 'bar').which((b) => b
/// ..isLessThan(10)
/// ..isGreaterThan(0));
/// ```
- void which(Condition<T> condition) => condition.apply(this);
+ void which(Condition<T> condition) => condition(this);
/// Check that the expectations invoked in [condition] are not satisfied by
/// this value.
@@ -71,7 +76,7 @@
///
/// If the value is a [T], returns a [Subject] for further expectations.
Subject<R> isA<R>() {
- return context.nest<R>('is a $R', (actual) {
+ return context.nest<R>(() => ['is a $R'], (actual) {
if (actual is! R) {
return Extracted.rejection(which: ['Is a ${actual.runtimeType}']);
}
@@ -100,11 +105,15 @@
/// Returns a [Condition] checking that the actual value is equal to [expected]
/// by operator `==`.
///
-/// This is a shortcut for `it<T>()..equals(expected)`.
-Condition<T> equals<T>(T expected) => T == String
- // String specializes `equals` with a better failure
- ? ((it<String>()..equals(expected as String)) as Condition<T>)
- : (it<T>()..equals(expected));
+/// This is a shortcut for `(Subject<T> it) => it..equals(expected)`.
+Condition<T> equals<T>(T expected) => (Subject<T> subject) {
+ if (subject is Subject<String> && expected is String) {
+ // String specializes `equals` with a better failure
+ (subject as Subject<String>).equals(expected);
+ } else {
+ subject.equals(expected);
+ }
+ };
extension BoolChecks on Subject<bool> {
void isTrue() {
@@ -126,9 +135,9 @@
}
}
-extension NullabilityChecks<T> on Subject<T?> {
+extension NullableChecks<T> on Subject<T?> {
Subject<T> isNotNull() {
- return context.nest<T>('is not null', (actual) {
+ return context.nest<T>(() => ['is not null'], (actual) {
if (actual == null) return Extracted.rejection();
return Extracted.value(actual);
}, atSameLevel: true);
@@ -141,3 +150,47 @@
});
}
}
+
+extension ComparableChecks<T> on Subject<Comparable<T>> {
+ /// Expects that this value is greater than [other].
+ void isGreaterThan(T other) {
+ context.expect(() => prefixFirst('is greater than ', literal(other)),
+ (actual) {
+ if (actual.compareTo(other) > 0) return null;
+ return Rejection(
+ which: prefixFirst('is not greater than ', literal(other)));
+ });
+ }
+
+ /// Expects that this value is greater than or equal to [other].
+ void isGreaterOrEqual(T other) {
+ context.expect(
+ () => prefixFirst('is greater than or equal to ', literal(other)),
+ (actual) {
+ if (actual.compareTo(other) >= 0) return null;
+ return Rejection(
+ which:
+ prefixFirst('is not greater than or equal to ', literal(other)));
+ });
+ }
+
+ /// Expects that this value is less than [other].
+ void isLessThan(T other) {
+ context.expect(() => prefixFirst('is less than ', literal(other)),
+ (actual) {
+ if (actual.compareTo(other) < 0) return null;
+ return Rejection(which: prefixFirst('is not less than ', literal(other)));
+ });
+ }
+
+ /// Expects that this value is less than or equal to [other].
+ void isLessOrEqual(T other) {
+ context
+ .expect(() => prefixFirst('is less than or equal to ', literal(other)),
+ (actual) {
+ if (actual.compareTo(other) <= 0) return null;
+ return Rejection(
+ which: prefixFirst('is not less than or equal to ', literal(other)));
+ });
+ }
+}
diff --git a/pkgs/checks/lib/src/extensions/function.dart b/pkgs/checks/lib/src/extensions/function.dart
index 7e20aca..5246cba 100644
--- a/pkgs/checks/lib/src/extensions/function.dart
+++ b/pkgs/checks/lib/src/extensions/function.dart
@@ -4,7 +4,7 @@
import 'package:checks/context.dart';
-extension ThrowsCheck<T> on Subject<T Function()> {
+extension FunctionChecks<T> on Subject<T Function()> {
/// Expects that a function throws synchronously when it is called.
///
/// If the function synchronously throws a value of type [E], return a
@@ -17,7 +17,7 @@
/// fail. Instead invoke the function and check the expectation on the
/// returned [Future].
Subject<E> throws<E>() {
- return context.nest<E>('throws an error of type $E', (actual) {
+ return context.nest<E>(() => ['throws an error of type $E'], (actual) {
try {
final result = actual();
return Extracted.rejection(
@@ -40,7 +40,7 @@
///
/// If the function throws synchronously, this expectation will fail.
Subject<T> returnsNormally() {
- return context.nest<T>('returns a value', (actual) {
+ return context.nest<T>(() => ['returns a value'], (actual) {
try {
return Extracted.value(actual());
} catch (e, st) {
diff --git a/pkgs/checks/lib/src/extensions/iterable.dart b/pkgs/checks/lib/src/extensions/iterable.dart
index 9cf67ba..d53ea54 100644
--- a/pkgs/checks/lib/src/extensions/iterable.dart
+++ b/pkgs/checks/lib/src/extensions/iterable.dart
@@ -9,9 +9,38 @@
extension IterableChecks<T> on Subject<Iterable<T>> {
Subject<int> get length => has((l) => l.length, 'length');
- Subject<T> get first => has((l) => l.first, 'first element');
- Subject<T> get last => has((l) => l.last, 'last element');
- Subject<T> get single => has((l) => l.single, 'single element');
+
+ Subject<T> get first => context.nest(() => ['has first element'], (actual) {
+ final iterator = actual.iterator;
+ if (!iterator.moveNext()) {
+ return Extracted.rejection(which: ['has no elements']);
+ }
+ return Extracted.value(iterator.current);
+ });
+
+ Subject<T> get last => context.nest(() => ['has last element'], (actual) {
+ final iterator = actual.iterator;
+ if (!iterator.moveNext()) {
+ return Extracted.rejection(which: ['has no elements']);
+ }
+ var current = iterator.current;
+ while (iterator.moveNext()) {
+ current = iterator.current;
+ }
+ return Extracted.value(current);
+ });
+
+ Subject<T> get single => context.nest(() => ['has single element'], (actual) {
+ final iterator = actual.iterator;
+ if (!iterator.moveNext()) {
+ return Extracted.rejection(which: ['has no elements']);
+ }
+ final value = iterator.current;
+ if (iterator.moveNext()) {
+ return Extracted.rejection(which: ['has more than one element']);
+ }
+ return Extracted.value(value);
+ });
void isEmpty() {
context.expect(() => const ['is empty'], (actual) {
@@ -23,7 +52,7 @@
void isNotEmpty() {
context.expect(() => const ['is not empty'], (actual) {
if (actual.isNotEmpty) return null;
- return Rejection(which: ['is not empty']);
+ return Rejection(which: ['is empty']);
});
}
@@ -47,18 +76,18 @@
/// For example, the following will succeed:
///
/// ```dart
- /// checkThat([1, 0, 2, 0, 3]).containsInOrder([1, 2, 3]);
+ /// check([1, 0, 2, 0, 3]).containsInOrder([1, 2, 3]);
/// ```
///
/// Values in [elements] may be a `T`, a `Condition<T>`, or a
- /// `Condition<dynamic>`. If an expectation is a [Condition] it will be
+ /// `Condition<Object?>`. If an expectation is a condition callback it will be
/// checked against the actual values, and any other expectations, including
- /// those that are not a `T` or a `Condition`, will be compared with the
- /// equality operator.
+ /// those that are not a `T` or a condition callback, will be compared with
+ /// the equality operator.
///
/// ```dart
- /// checkThat([1, 0, 2, 0, 3])
- /// .containsInOrder([1, it<int>()..isGreaterThan(1), 3]);
+ /// check([1, 0, 2, 0, 3])
+ /// .containsInOrder([1, (Subject<int> v) => v.isGreaterThan(1), 3]);
/// ```
void containsInOrder(Iterable<Object?> elements) {
context.expect(() => prefixFirst('contains, in order: ', literal(elements)),
diff --git a/pkgs/checks/lib/src/extensions/map.dart b/pkgs/checks/lib/src/extensions/map.dart
index b836f1e..4984b5f 100644
--- a/pkgs/checks/lib/src/extensions/map.dart
+++ b/pkgs/checks/lib/src/extensions/map.dart
@@ -14,11 +14,11 @@
Subject<Iterable<V>> get values => has((m) => m.values, 'values');
Subject<int> get length => has((m) => m.length, 'length');
Subject<V> operator [](K key) {
- final keyString = literal(key).join(r'\n');
- return context.nest('contains a value for $keyString', (actual) {
+ return context.nest(
+ () => prefixFirst('contains a value for ', literal(key)), (actual) {
if (!actual.containsKey(key)) {
return Extracted.rejection(
- which: ['does not contain the key $keyString']);
+ which: prefixFirst('does not contain the key ', literal(key)));
}
return Extracted.value(actual[key] as V);
});
@@ -40,10 +40,10 @@
/// Expects that the map contains [key] according to [Map.containsKey].
void containsKey(K key) {
- final keyString = literal(key).join(r'\n');
- context.expect(() => ['contains key $keyString'], (actual) {
+ context.expect(() => prefixFirst('contains key ', literal(key)), (actual) {
if (actual.containsKey(key)) return null;
- return Rejection(which: ['does not contain key $keyString']);
+ return Rejection(
+ which: prefixFirst('does not contain key ', literal(key)));
});
}
@@ -68,10 +68,11 @@
/// Expects that the map contains [value] according to [Map.containsValue].
void containsValue(V value) {
- final valueString = literal(value).join(r'\n');
- context.expect(() => ['contains value $valueString'], (actual) {
+ context.expect(() => prefixFirst('contains value ', literal(value)),
+ (actual) {
if (actual.containsValue(value)) return null;
- return Rejection(which: ['does not contain value $valueString']);
+ return Rejection(
+ which: prefixFirst('does not contain value ', literal(value)));
});
}
diff --git a/pkgs/checks/lib/src/extensions/math.dart b/pkgs/checks/lib/src/extensions/math.dart
index b087aef..c201b7a 100644
--- a/pkgs/checks/lib/src/extensions/math.dart
+++ b/pkgs/checks/lib/src/extensions/math.dart
@@ -5,38 +5,6 @@
import 'package:checks/context.dart';
extension NumChecks on Subject<num> {
- /// Expects that this number is greater than [other].
- void isGreaterThan(num other) {
- context.expect(() => ['is greater than <$other>'], (actual) {
- if (actual > other) return null;
- return Rejection(which: ['is not greater than <$other>']);
- });
- }
-
- /// Expects that this number is greater than or equal to [other].
- void isGreaterOrEqual(num other) {
- context.expect(() => ['is greater than or equal to <$other>'], (actual) {
- if (actual >= other) return null;
- return Rejection(which: ['is not greater than or equal to <$other>']);
- });
- }
-
- /// Expects that this number is less than [other].
- void isLessThan(num other) {
- context.expect(() => ['is less than <$other>'], (actual) {
- if (actual < other) return null;
- return Rejection(which: ['is not less than <$other>']);
- });
- }
-
- /// Expects that this number is less than or equal to [other].
- void isLessOrEqual(num other) {
- context.expect(() => ['is less than or equal to <$other>'], (actual) {
- if (actual <= other) return null;
- return Rejection(which: ['is not less than or equal to <$other>']);
- });
- }
-
/// Expects that [num.isNaN] is true.
void isNaN() {
context.expect(() => ['is not a number (NaN)'], (actual) {
diff --git a/pkgs/checks/lib/src/extensions/string.dart b/pkgs/checks/lib/src/extensions/string.dart
index 9c790cd..1a00ef8 100644
--- a/pkgs/checks/lib/src/extensions/string.dart
+++ b/pkgs/checks/lib/src/extensions/string.dart
@@ -59,10 +59,18 @@
);
}
- /// Expects that the string matches the regular expression [expected].
- void matches(RegExp expected) {
+ /// Expects that the string matches the pattern [expected].
+ ///
+ /// Fails if [expected] returns an empty result from calling `allMatches` with
+ /// the value.
+ ///
+ /// ```
+ /// check(actual).matchesPattern('abc');
+ /// check(actual).matchesPattern(RegExp(r'\d'));
+ /// ```
+ void matchesPattern(Pattern expected) {
context.expect(() => prefixFirst('matches ', literal(expected)), (actual) {
- if (expected.hasMatch(actual)) return null;
+ if (expected.allMatches(actual).isNotEmpty) return null;
return Rejection(
which: prefixFirst('does not match ', literal(expected)));
});
@@ -73,7 +81,7 @@
///
/// For example, the following will succeed:
///
- /// checkThat('abcdefg').containsInOrder(['a','e']);
+ /// check('abcdefg').containsInOrder(['a','e']);
void containsInOrder(Iterable<String> expected) {
context.expect(() => prefixFirst('contains, in order: ', literal(expected)),
(actual) {
@@ -118,12 +126,12 @@
///
/// For example the following will succeed:
///
- /// checkThat(' hello world ').equalsIgnoringWhitespace('hello world');
+ /// check(' hello world ').equalsIgnoringWhitespace('hello world');
///
/// While the following will fail:
///
- /// checkThat('helloworld').equalsIgnoringWhitespace('hello world');
- /// checkThat('he llo world').equalsIgnoringWhitespace('hello world');
+ /// check('helloworld').equalsIgnoringWhitespace('hello world');
+ /// check('he llo world').equalsIgnoringWhitespace('hello world');
void equalsIgnoringWhitespace(String expected) {
context.expect(
() => prefixFirst('equals ignoring whitespace ', literal(expected)),
diff --git a/pkgs/checks/pubspec.yaml b/pkgs/checks/pubspec.yaml
index 7702773..10e3728 100644
--- a/pkgs/checks/pubspec.yaml
+++ b/pkgs/checks/pubspec.yaml
@@ -1,18 +1,18 @@
name: checks
-version: 0.1.1-dev
+version: 0.3.0-wip
description: >-
A framework for checking values against expectations and building custom
expectations.
repository: https://github.com/dart-lang/test/tree/master/pkgs/checks
environment:
- sdk: ">=2.18.0 <3.0.0"
+ sdk: ^3.0.0
dependencies:
async: ^2.8.0
meta: ^1.9.0
- test_api: ^0.4.0
+ test_api: ">=0.5.0 <0.7.0"
dev_dependencies:
+ dart_flutter_team_lints: ^1.0.0
test: ^1.21.3
- lints: ^2.0.0
diff --git a/pkgs/checks/pubspec_overrides.yaml b/pkgs/checks/pubspec_overrides.yaml
new file mode 100644
index 0000000..7d9aba4
--- /dev/null
+++ b/pkgs/checks/pubspec_overrides.yaml
@@ -0,0 +1,7 @@
+dependency_overrides:
+ test_api:
+ path: ../test_api
+ test_core:
+ path: ../test_core
+ test:
+ path: ../test
diff --git a/pkgs/checks/test/context_test.dart b/pkgs/checks/test/context_test.dart
new file mode 100644
index 0000000..f523115
--- /dev/null
+++ b/pkgs/checks/test/context_test.dart
@@ -0,0 +1,172 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:async/async.dart' hide Result;
+import 'package:checks/checks.dart';
+import 'package:checks/context.dart';
+import 'package:test/scaffolding.dart';
+import 'package:test_api/hooks.dart';
+import 'package:test_api/hooks_testing.dart';
+
+void main() {
+ group('Context', () {
+ test('expectAsync holds test open', () async {
+ late void Function() callback;
+ final monitor = TestCaseMonitor.start(() {
+ check(null).context.expectAsync(() => [''], (actual) async {
+ final completer = Completer<void>();
+ callback = completer.complete;
+ await completer.future;
+ return null;
+ });
+ });
+ await pumpEventQueue();
+ check(monitor).state.equals(State.running);
+ callback();
+ await monitor.onDone;
+ check(monitor).didPass();
+ });
+
+ test('expectAsync does not hold test open past exception', () async {
+ late void Function() callback;
+ final monitor = TestCaseMonitor.start(() {
+ check(null).context.expectAsync(() => [''], (actual) async {
+ final completer = Completer<void>();
+ callback = completer.complete;
+ await completer.future;
+ throw 'oh no!';
+ });
+ });
+ await pumpEventQueue();
+ check(monitor).state.equals(State.running);
+ callback();
+ await monitor.onDone;
+ check(monitor)
+ ..state.equals(State.failed)
+ ..errors.single.has((e) => e.error, 'error').equals('oh no!');
+ });
+
+ test('nestAsync holds test open', () async {
+ late void Function() callback;
+ final monitor = TestCaseMonitor.start(() {
+ check(null).context.nestAsync(() => [''], (actual) async {
+ final completer = Completer<void>();
+ callback = completer.complete;
+ await completer.future;
+ return Extracted.value(null);
+ }, null);
+ });
+ await pumpEventQueue();
+ check(monitor).state.equals(State.running);
+ callback();
+ await monitor.onDone;
+ check(monitor).didPass();
+ });
+
+ test('nestAsync holds test open past async condition', () async {
+ late void Function() callback;
+ final monitor = TestCaseMonitor.start(() {
+ check(null).context.nestAsync(() => [''], (actual) async {
+ return Extracted.value(null);
+ }, (it) async {
+ final completer = Completer<void>();
+ callback = completer.complete;
+ await completer.future;
+ });
+ });
+ await pumpEventQueue();
+ check(monitor).state.equals(State.running);
+ callback();
+ await monitor.onDone;
+ check(monitor).didPass();
+ });
+
+ test('nestAsync does not hold test open past exception', () async {
+ late void Function() callback;
+ final monitor = TestCaseMonitor.start(() {
+ check(null).context.nestAsync(() => [''], (actual) async {
+ final completer = Completer<void>();
+ callback = completer.complete;
+ await completer.future;
+ throw 'oh no!';
+ }, null);
+ });
+ await pumpEventQueue();
+ check(monitor).state.equals(State.running);
+ callback();
+ await monitor.onDone;
+ check(monitor)
+ ..state.equals(State.failed)
+ ..errors.single.has((e) => e.error, 'error').equals('oh no!');
+ });
+
+ test('expectUnawaited can fail the test after it completes', () async {
+ late void Function() callback;
+ final monitor = await TestCaseMonitor.run(() {
+ check(null).context.expectUnawaited(() => [''], (actual, reject) {
+ final completer = Completer<void>()
+ ..future.then((_) {
+ reject(Rejection(which: ['foo']));
+ });
+ callback = completer.complete;
+ });
+ });
+ check(monitor).state.equals(State.passed);
+ callback();
+ await pumpEventQueue();
+ check(monitor)
+ ..state.equals(State.failed)
+ ..errors.unorderedMatches([
+ (it) => it
+ .has((e) => e.error, 'error')
+ .isA<TestFailure>()
+ .has((f) => f.message, 'message')
+ .isNotNull()
+ .endsWith('Which: foo'),
+ (it) => it
+ .has((e) => e.error, 'error')
+ .isA<String>()
+ .startsWith('This test failed after it had already completed.')
+ ]);
+ });
+ });
+
+ group('SkipExtension', () {
+ test('marks the test as skipped', () async {
+ final monitor = await TestCaseMonitor.run(() {
+ check(null).skip('skip').isNotNull();
+ });
+ check(monitor).state.equals(State.skipped);
+ });
+ });
+}
+
+extension _MonitorChecks on Subject<TestCaseMonitor> {
+ Subject<State> get state => has((m) => m.state, 'state');
+ Subject<Iterable<AsyncError>> get errors => has((m) => m.errors, 'errors');
+ Subject<StreamQueue<AsyncError>> get onError =>
+ has((m) => m.onError, 'onError').withQueue;
+
+ /// Expects that the monitored test is completed as success with no errors.
+ ///
+ /// Sets up an unawaited expectation that the test does not emit errors in the
+ /// future in addition to checking there have been no errors yet.
+ void didPass() {
+ errors.isEmpty();
+ state.equals(State.passed);
+ onError.context.expectUnawaited(() => ['emits no further errors'],
+ (actual, reject) async {
+ await for (var error in actual.rest) {
+ reject(Rejection(which: [
+ ...prefixFirst('threw late error', literal(error.error)),
+ ...const LineSplitter().convert(
+ TestHandle.current.formatStackTrace(error.stackTrace).toString())
+ ]));
+ }
+ });
+ }
+}
diff --git a/pkgs/checks/test/describe_test.dart b/pkgs/checks/test/describe_test.dart
index b9b335c..fedd620 100644
--- a/pkgs/checks/test/describe_test.dart
+++ b/pkgs/checks/test/describe_test.dart
@@ -9,13 +9,13 @@
void main() {
group('describe', () {
test('succeeds for empty conditions', () {
- checkThat(describe(it())).isEmpty();
+ check(describe((_) {})).isEmpty();
});
test('includes condition clauses', () {
- checkThat(describe(equals(1))).deepEquals([' equals <1>']);
+ check(describe(equals(1))).deepEquals([' equals <1>']);
});
test('includes nested clauses', () {
- checkThat(describe(it<String>()..length.equals(1))).deepEquals([
+ check(describe<String>((it) => it.length.equals(1))).deepEquals([
' has length that:',
' equals <1>',
]);
diff --git a/pkgs/checks/test/extensions/async_test.dart b/pkgs/checks/test/extensions/async_test.dart
index 280ba54..3484fb2 100644
--- a/pkgs/checks/test/extensions/async_test.dart
+++ b/pkgs/checks/test/extensions/async_test.dart
@@ -16,26 +16,24 @@
group('FutureChecks', () {
group('completes', () {
test('succeeds for a future that completes to a value', () async {
- await checkThat(_futureSuccess()).completes().which(equals(42));
+ await check(_futureSuccess()).completes(equals(42));
});
test('rejects futures which complete as errors', () async {
- await checkThat(_futureFail()).isRejectedByAsync(
- it()..completes().which(equals(1)),
+ await check(_futureFail()).isRejectedByAsync(
+ (it) => it.completes(equals(1)),
actual: ['a future that completes as an error'],
which: ['threw <UnimplementedError> at:', 'fake trace'],
);
});
test('can be described', () async {
- await checkThat(it<Future<void>>()..completes())
- .asyncDescription
- .which(it()..deepEquals([' completes to a value']));
- await checkThat(it<Future<int>>()..completes().which(equals(42)))
- .asyncDescription
- .which(it()
- ..deepEquals([
- ' completes to a value that:',
- ' equals <42>',
- ]));
+ await check((Subject<Future> it) => it.completes())
+ .hasAsyncDescriptionWhich(
+ (it) => it.deepEquals([' completes to a value']));
+ await check((Subject<Future> it) => it.completes(equals(42)))
+ .hasAsyncDescriptionWhich((it) => it.deepEquals([
+ ' completes to a value that:',
+ ' equals <42>',
+ ]));
});
});
@@ -43,21 +41,20 @@
test(
'succeeds for a future that compeletes to an error of the expected type',
() async {
- await checkThat(_futureFail())
- .throws<UnimplementedError>()
- .which(it()..has((p0) => p0.message, 'message').isNull());
+ await check(_futureFail()).throws<UnimplementedError>(
+ (it) => it.has((p0) => p0.message, 'message').isNull());
});
test('fails for futures that complete to a value', () async {
- await checkThat(_futureSuccess()).isRejectedByAsync(
- it()..throws(),
+ await check(_futureSuccess()).isRejectedByAsync(
+ (it) => it.throws(),
actual: ['completed to <42>'],
which: ['did not throw'],
);
});
test('failes for futures that complete to an error of the wrong type',
() async {
- await checkThat(_futureFail()).isRejectedByAsync(
- it()..throws<StateError>(),
+ await check(_futureFail()).isRejectedByAsync(
+ (it) => it.throws<StateError>(),
actual: ['completed to error <UnimplementedError>'],
which: [
'threw an exception that is not a StateError at:',
@@ -66,31 +63,30 @@
);
});
test('can be described', () async {
- await checkThat(it<Future<void>>()..throws())
- .asyncDescription
- .which(it()..deepEquals([' completes to an error']));
- await checkThat(it<Future<void>>()..throws<StateError>())
- .asyncDescription
- .which(it()
- ..deepEquals([' completes to an error of type StateError']));
+ await check((Subject<Future<void>> it) => it.throws())
+ .hasAsyncDescriptionWhich(
+ (it) => it.deepEquals([' completes to an error']));
+ await check((Subject<Future<void>> it) => it.throws<StateError>())
+ .hasAsyncDescriptionWhich((it) =>
+ it.deepEquals([' completes to an error of type StateError']));
});
});
group('doesNotComplete', () {
test('succeeds for a Future that never completes', () async {
- checkThat(Completer<void>().future).doesNotComplete();
+ check(Completer<void>().future).doesNotComplete();
});
test('fails for a Future that completes as a value', () async {
Object? testFailure;
runZonedGuarded(() {
final completer = Completer<String>();
- checkThat(completer.future).doesNotComplete();
+ check(completer.future).doesNotComplete();
completer.complete('value');
}, (e, st) {
testFailure = e;
});
await pumpEventQueue();
- checkThat(testFailure)
+ check(testFailure)
.isA<TestFailure>()
.has((f) => f.message, 'message')
.isNotNull()
@@ -103,13 +99,13 @@
Object? testFailure;
runZonedGuarded(() {
final completer = Completer<String>();
- checkThat(completer.future).doesNotComplete();
+ check(completer.future).doesNotComplete();
completer.completeError('error', StackTrace.fromString('fake trace'));
}, (e, st) {
testFailure = e;
});
await pumpEventQueue();
- checkThat(testFailure)
+ check(testFailure)
.isA<TestFailure>()
.has((f) => f.message, 'message')
.isNotNull()
@@ -121,9 +117,9 @@
fake trace''');
});
test('can be described', () async {
- await checkThat(it<Future<void>>()..doesNotComplete())
- .asyncDescription
- .which(it()..deepEquals([' does not complete']));
+ await check((Subject<Future<void>> it) => it.doesNotComplete())
+ .hasAsyncDescriptionWhich(
+ (it) => it.deepEquals([' does not complete']));
});
});
});
@@ -131,140 +127,136 @@
group('StreamChecks', () {
group('emits', () {
test('succeeds for a stream that emits a value', () async {
- await checkThat(_countingStream(5)).emits().which(equals(0));
+ await check(_countingStream(5)).emits(equals(0));
});
test('fails for a stream that closes without emitting', () async {
- await checkThat(_countingStream(0)).isRejectedByAsync(
- it()..emits(),
+ await check(_countingStream(0)).isRejectedByAsync(
+ (it) => it.emits(),
actual: ['a stream'],
which: ['closed without emitting enough values'],
);
});
test('fails for a stream that emits an error', () async {
- await checkThat(_countingStream(1, errorAt: 0)).isRejectedByAsync(
- it()..emits(),
+ await check(_countingStream(1, errorAt: 0)).isRejectedByAsync(
+ (it) => it.emits(),
actual: ['a stream with error <UnimplementedError: Error at 1>'],
which: ['emitted an error instead of a value at:', 'fake trace'],
);
});
test('can be described', () async {
- await checkThat(it<StreamQueue<void>>()..emits())
- .asyncDescription
- .which(it()..deepEquals([' emits a value']));
- await checkThat(it<StreamQueue<int>>()..emits().which(equals(42)))
- .asyncDescription
- .which(it()
- ..deepEquals([
- ' emits a value that:',
- ' equals <42>',
- ]));
+ await check((Subject<StreamQueue<void>> it) => it.emits())
+ .hasAsyncDescriptionWhich(
+ (it) => it.deepEquals([' emits a value']));
+ await check((Subject<StreamQueue<int>> it) => it.emits(equals(42)))
+ .hasAsyncDescriptionWhich((it) => it.deepEquals([
+ ' emits a value that:',
+ ' equals <42>',
+ ]));
});
- test('uses a transaction', () async {
+ test('does not consume error', () async {
final queue = _countingStream(1, errorAt: 0);
- await softCheckAsync<StreamQueue<int>>(queue, it()..emits());
- await checkThat(queue).emitsError();
+ await softCheckAsync<StreamQueue<int>>(queue, (it) => it.emits());
+ await check(queue).emitsError();
});
});
group('emitsError', () {
test('succeeds for a stream that emits an error', () async {
- await checkThat(_countingStream(1, errorAt: 0))
+ await check(_countingStream(1, errorAt: 0))
.emitsError<UnimplementedError>();
});
test('fails for a stream that closes without emitting an error',
() async {
- await checkThat(_countingStream(0)).isRejectedByAsync(
- it()..emitsError(),
+ await check(_countingStream(0)).isRejectedByAsync(
+ (it) => it.emitsError(),
actual: ['a stream'],
which: ['closed without emitting an expected error'],
);
});
test('fails for a stream that emits value', () async {
- await checkThat(_countingStream(1)).isRejectedByAsync(
- it()..emitsError(),
+ await check(_countingStream(1)).isRejectedByAsync(
+ (it) => it.emitsError(),
actual: ['a stream emitting value <0>'],
which: ['closed without emitting an error'],
);
});
test('fails for a stream that emits an error of the incorrect type',
() async {
- await checkThat(_countingStream(1, errorAt: 0)).isRejectedByAsync(
- it()..emitsError<StateError>(),
+ await check(_countingStream(1, errorAt: 0)).isRejectedByAsync(
+ (it) => it.emitsError<StateError>(),
actual: ['a stream with error <UnimplementedError: Error at 1>'],
which: ['emitted an error which is not StateError at:', 'fake trace'],
);
});
test('can be described', () async {
- await checkThat(it<StreamQueue<void>>()..emitsError())
- .asyncDescription
- .which(it()..deepEquals([' emits an error']));
- await checkThat(it<StreamQueue<void>>()..emitsError<StateError>())
- .asyncDescription
- .which(it()..deepEquals([' emits an error of type StateError']));
- await checkThat(it<StreamQueue<void>>()
- ..emitsError<StateError>()
- .which(it()..has((e) => e.message, 'message').equals('foo')))
- .asyncDescription
- .which(it()
- ..deepEquals([
- ' emits an error of type StateError that:',
- ' has message that:',
- ' equals \'foo\''
- ]));
+ await check((Subject<StreamQueue<void>> it) => it.emitsError())
+ .hasAsyncDescriptionWhich(
+ (it) => it.deepEquals([' emits an error']));
+ await check(
+ (Subject<StreamQueue<void>> it) => it.emitsError<StateError>())
+ .hasAsyncDescriptionWhich(
+ (it) => it.deepEquals([' emits an error of type StateError']));
+ await check((Subject<StreamQueue<void>> it) => it
+ ..emitsError<StateError>(
+ (it) => it.has((e) => e.message, 'message').equals('foo')))
+ .hasAsyncDescriptionWhich((it) => it.deepEquals([
+ ' emits an error of type StateError that:',
+ ' has message that:',
+ ' equals \'foo\''
+ ]));
});
test('uses a transaction', () async {
final queue = _countingStream(1);
- await softCheckAsync<StreamQueue<int>>(queue, it()..emitsError());
- await checkThat(queue).emits().which((equals(0)));
+ await softCheckAsync<StreamQueue<int>>(queue, (it) => it.emitsError());
+ await check(queue).emits(equals(0));
});
});
group('emitsThrough', () {
test('succeeds for a stream that eventuall emits a matching value',
() async {
- await checkThat(_countingStream(5)).emitsThrough(equals(4));
+ await check(_countingStream(5)).emitsThrough(equals(4));
});
test('fails for a stream that closes without emitting a matching value',
() async {
- await checkThat(_countingStream(4)).isRejectedByAsync(
- it()..emitsThrough(equals(5)),
+ await check(_countingStream(4)).isRejectedByAsync(
+ (it) => it.emitsThrough(equals(5)),
actual: ['a stream'],
which: ['ended after emitting 4 elements with none matching'],
);
});
test('can be described', () async {
- await checkThat(it<StreamQueue<int>>()..emitsThrough(equals(42)))
- .asyncDescription
- .which(it()
- ..deepEquals([
- ' emits any values then emits a value that:',
- ' equals <42>'
- ]));
+ await check(
+ (Subject<StreamQueue<int>> it) => it.emitsThrough(equals(42)))
+ .hasAsyncDescriptionWhich((it) => it.deepEquals([
+ ' emits any values then emits a value that:',
+ ' equals <42>'
+ ]));
});
test('uses a transaction', () async {
final queue = _countingStream(1);
- await softCheckAsync(
- queue, it<StreamQueue<int>>()..emitsThrough(equals(42)));
- checkThat(queue).emits().which(equals(0));
+ await softCheckAsync(queue,
+ (Subject<StreamQueue<int>> it) => it.emitsThrough(equals(42)));
+ check(queue).emits(equals(0));
});
test('consumes events', () async {
final queue = _countingStream(3);
- await checkThat(queue).emitsThrough(equals(1));
- await checkThat(queue).emits().which((equals(2)));
+ await check(queue).emitsThrough(equals(1));
+ await check(queue).emits(equals(2));
});
});
group('emitsInOrder', () {
test('succeeds for happy case', () async {
- await checkThat(_countingStream(2)).inOrder([
- it()..emits().which(equals(0)),
- it()..emits().which((equals(1))),
- it()..isDone(),
+ await check(_countingStream(2)).inOrder([
+ (it) => it.emits(equals(0)),
+ (it) => it.emits(equals(1)),
+ (it) => it.isDone(),
]);
});
test('reports which condition failed', () async {
- await checkThat(_countingStream(1)).isRejectedByAsync(
- it()..inOrder([it()..emits(), it()..emits()]),
+ await check(_countingStream(1)).isRejectedByAsync(
+ (it) => it.inOrder([(it) => it.emits(), (it) => it.emits()]),
actual: ['a stream'],
which: [
'satisfied 1 conditions then',
@@ -274,8 +266,8 @@
);
});
test('nestes the report for deep failures', () async {
- await checkThat(_countingStream(2)).isRejectedByAsync(
- it()..inOrder([it()..emits(), it()..emits().which(equals(2))]),
+ await check(_countingStream(2)).isRejectedByAsync(
+ (it) => it.inOrder([(it) => it.emits(), (it) => it.emits(equals(2))]),
actual: ['a stream'],
which: [
'satisfied 1 conditions then',
@@ -288,31 +280,31 @@
);
});
test('gets described with the number of conditions', () async {
- await checkThat(it<StreamQueue<int>>()..inOrder([it(), it()]))
- .asyncDescription
- .which(it()..deepEquals([' satisfies 2 conditions in order']));
+ await check(
+ (Subject<StreamQueue<int>> it) => it.inOrder([(_) {}, (_) {}]))
+ .hasAsyncDescriptionWhich(
+ (it) => it.deepEquals([' satisfies 2 conditions in order']));
});
test('uses a transaction', () async {
final queue = _countingStream(3);
await softCheckAsync<StreamQueue<int>>(
queue,
- it()
- ..inOrder([
- it()..emits().which(equals(0)),
- it()..emits().which(equals(1)),
- it()..emits().which(equals(42)),
- ]));
- await checkThat(queue).inOrder([
- it()..emits().which(equals(0)),
- it()..emits().which(equals(1)),
- it()..emits().which(equals(2)),
- it()..isDone(),
+ (it) => it.inOrder([
+ (it) => it.emits(equals(0)),
+ (it) => it.emits(equals(1)),
+ (it) => it.emits(equals(42)),
+ ]));
+ await check(queue).inOrder([
+ (it) => it.emits(equals(0)),
+ (it) => it.emits(equals(1)),
+ (it) => it.emits(equals(2)),
+ (it) => it.isDone(),
]);
});
test('consumes events', () async {
final queue = _countingStream(3);
- await checkThat(queue).inOrder([it()..emits(), it()..emits()]);
- await checkThat(queue).emits().which(equals(2));
+ await check(queue).inOrder([(it) => it.emits(), (it) => it.emits()]);
+ await check(queue).emits(equals(2));
});
});
@@ -320,140 +312,134 @@
test(
'succeeds for a stream that closes without emitting a matching value',
() async {
- await checkThat(_countingStream(5)).neverEmits(equals(5));
+ await check(_countingStream(5)).neverEmits(equals(5));
});
test('fails for a stream that emits a matching value', () async {
- await checkThat(_countingStream(6)).isRejectedByAsync(
- it()..neverEmits(equals(5)),
+ await check(_countingStream(6)).isRejectedByAsync(
+ (it) => it.neverEmits(equals(5)),
actual: ['a stream'],
which: ['emitted <5>', 'following 5 other items'],
);
});
test('can be described', () async {
- await checkThat(it<StreamQueue<int>>()..neverEmits(equals(42)))
- .asyncDescription
- .which(it()
- ..deepEquals([
- ' never emits a value that:',
- ' equals <42>',
- ]));
+ await check((Subject<StreamQueue<int>> it) => it.neverEmits(equals(42)))
+ .hasAsyncDescriptionWhich((it) => it.deepEquals([
+ ' never emits a value that:',
+ ' equals <42>',
+ ]));
});
test('uses a transaction', () async {
final queue = _countingStream(2);
await softCheckAsync<StreamQueue<int>>(
- queue, it()..neverEmits(equals(1)));
- await checkThat(queue).inOrder([
- it()..emits().which(equals(0)),
- it()..emits().which(equals(1)),
- it()..isDone(),
+ queue, (it) => it.neverEmits(equals(1)));
+ await check(queue).inOrder([
+ (it) => it.emits(equals(0)),
+ (it) => it.emits(equals(1)),
+ (it) => it.isDone(),
]);
});
});
group('mayEmit', () {
test('succeeds for a stream that emits a matching value', () async {
- await checkThat(_countingStream(1)).mayEmit(equals(0));
+ await check(_countingStream(1)).mayEmit(equals(0));
});
test('succeeds for a stream that emits an error', () async {
- await checkThat(_countingStream(1, errorAt: 0)).mayEmit(equals(0));
+ await check(_countingStream(1, errorAt: 0)).mayEmit(equals(0));
});
test('succeeds for a stream that closes', () async {
- await checkThat(_countingStream(0)).mayEmit(equals(42));
+ await check(_countingStream(0)).mayEmit(equals(42));
});
test('consumes a matching event', () async {
final queue = _countingStream(2);
- await softCheckAsync<StreamQueue<int>>(queue, it()..mayEmit(equals(0)));
- await checkThat(queue).emits().which(equals(1));
+ await softCheckAsync<StreamQueue<int>>(
+ queue, (it) => it.mayEmit(equals(0)));
+ await check(queue).emits(equals(1));
});
test('does not consume a non-matching event', () async {
final queue = _countingStream(2);
- await softCheckAsync<StreamQueue<int>>(queue, it()..mayEmit(equals(1)));
- await checkThat(queue).emits().which(equals(0));
+ await softCheckAsync<StreamQueue<int>>(
+ queue, (it) => it.mayEmit(equals(1)));
+ await check(queue).emits(equals(0));
});
test('does not consume an error', () async {
final queue = _countingStream(1, errorAt: 0);
- await softCheckAsync<StreamQueue<int>>(queue, it()..mayEmit(equals(0)));
- await checkThat(queue)
- .emitsError<UnimplementedError>()
- .which(it()..has((e) => e.message, 'message').equals('Error at 1'));
+ await softCheckAsync<StreamQueue<int>>(
+ queue, (it) => it.mayEmit(equals(0)));
+ await check(queue).emitsError<UnimplementedError>(
+ (it) => it.has((e) => e.message, 'message').equals('Error at 1'));
});
});
group('mayEmitMultiple', () {
test('succeeds for a stream that emits a matching value', () async {
- await checkThat(_countingStream(1)).mayEmitMultiple(equals(0));
+ await check(_countingStream(1)).mayEmitMultiple(equals(0));
});
test('succeeds for a stream that emits an error', () async {
- await checkThat(_countingStream(1, errorAt: 0))
- .mayEmitMultiple(equals(0));
+ await check(_countingStream(1, errorAt: 0)).mayEmitMultiple(equals(0));
});
test('succeeds for a stream that closes', () async {
- await checkThat(_countingStream(0)).mayEmitMultiple(equals(42));
+ await check(_countingStream(0)).mayEmitMultiple(equals(42));
});
test('consumes matching events', () async {
final queue = _countingStream(3);
await softCheckAsync<StreamQueue<int>>(
- queue, it()..mayEmitMultiple(it()..isLessThan(2)));
- await checkThat(queue).emits().which(equals(2));
+ queue, (it) => it.mayEmitMultiple((it) => it.isLessThan(2)));
+ await check(queue).emits(equals(2));
});
test('consumes no events if no events match', () async {
final queue = _countingStream(2);
await softCheckAsync<StreamQueue<int>>(
- queue, it()..mayEmitMultiple(it()..isLessThan(0)));
- await checkThat(queue).emits().which(equals(0));
+ queue, (it) => it.mayEmitMultiple((it) => it.isLessThan(0)));
+ await check(queue).emits(equals(0));
});
test('does not consume an error', () async {
final queue = _countingStream(1, errorAt: 0);
await softCheckAsync<StreamQueue<int>>(
- queue, it()..mayEmitMultiple(equals(0)));
- await checkThat(queue)
- .emitsError<UnimplementedError>()
- .which(it()..has((e) => e.message, 'message').equals('Error at 1'));
+ queue, (it) => it.mayEmitMultiple(equals(0)));
+ await check(queue).emitsError<UnimplementedError>(
+ (it) => it.has((e) => e.message, 'message').equals('Error at 1'));
});
});
group('isDone', () {
test('succeeds for an empty stream', () async {
- await checkThat(_countingStream(0)).isDone();
+ await check(_countingStream(0)).isDone();
});
test('fails for a stream that emits a value', () async {
- await checkThat(_countingStream(1)).isRejectedByAsync(it()..isDone(),
+ await check(_countingStream(1)).isRejectedByAsync((it) => it.isDone(),
actual: ['a stream'], which: ['emitted an unexpected value: <0>']);
});
test('fails for a stream that emits an error', () async {
final controller = StreamController<void>();
controller.addError('sad', StackTrace.fromString('fake trace'));
- await checkThat(StreamQueue(controller.stream)).isRejectedByAsync(
- it()..isDone(),
+ await check(StreamQueue(controller.stream)).isRejectedByAsync(
+ (it) => it.isDone(),
actual: ['a stream'],
which: ['emitted an unexpected error: \'sad\'', 'fake trace']);
});
test('uses a transaction', () async {
final queue = _countingStream(1);
- await softCheckAsync<StreamQueue<int>>(queue, it()..isDone());
- await checkThat(queue).emits().which(equals(0));
+ await softCheckAsync<StreamQueue<int>>(queue, (it) => it.isDone());
+ await check(queue).emits(equals(0));
});
test('can be described', () async {
- await checkThat(it<StreamQueue<int>>()..isDone())
- .asyncDescription
- .which(it()..deepEquals([' is done']));
+ await check((Subject<StreamQueue<int>> it) => it.isDone())
+ .hasAsyncDescriptionWhich((it) => it.deepEquals([' is done']));
});
});
group('emitsAnyOf', () {
test('succeeds for a stream that matches one condition', () async {
- await checkThat(_countingStream(1)).anyOf([
- it()..emits().which(equals(42)),
- it()..emits().which((equals(0)))
- ]);
+ await check(_countingStream(1))
+ .anyOf([(it) => it.emits(equals(42)), (it) => it.emits(equals(0))]);
});
test('fails for a stream that matches no conditions', () async {
- await checkThat(_countingStream(0)).isRejectedByAsync(
- it()
- ..anyOf([
- it()..emits(),
- it()..emitsThrough(equals(1)),
- ]),
+ await check(_countingStream(0)).isRejectedByAsync(
+ (it) => it.anyOf([
+ (it) => it.emits(),
+ (it) => it.emitsThrough(equals(1)),
+ ]),
actual: [
'a stream'
],
@@ -466,12 +452,11 @@
]);
});
test('includes nested details for nested failures', () async {
- await checkThat(_countingStream(1)).isRejectedByAsync(
- it()
- ..anyOf([
- it()..emits().which(equals(42)),
- it()..emitsThrough(equals(10)),
- ]),
+ await check(_countingStream(1)).isRejectedByAsync(
+ (it) => it.anyOf([
+ (it) => it.emits(equals(42)),
+ (it) => it.emitsThrough(equals(10)),
+ ]),
actual: [
'a stream'
],
@@ -486,40 +471,33 @@
]);
});
test('gets described with the number of conditions', () async {
- await checkThat(
- it<StreamQueue<int>>()..anyOf([it()..emits(), it()..emits()]))
- .asyncDescription
- .which(it()..deepEquals([' satisfies any of 2 conditions']));
+ await check((Subject<StreamQueue<int>> it) =>
+ it..anyOf([(it) => it.emits(), (it) => it.emits()]))
+ .hasAsyncDescriptionWhich(
+ (it) => it.deepEquals([' satisfies any of 2 conditions']));
});
test('uses a transaction', () async {
final queue = _countingStream(1);
await softCheckAsync<StreamQueue<int>>(
queue,
- it()
- ..anyOf([
- it()..emits().which(equals(10)),
- it()..emitsThrough(equals(42)),
- ]));
- await checkThat(queue).emits().which(equals(0));
+ (it) => it.anyOf([
+ (it) => it.emits(equals(10)),
+ (it) => it.emitsThrough(equals(42)),
+ ]));
+ await check(queue).emits(equals(0));
});
test('consumes events', () async {
final queue = _countingStream(3);
- await checkThat(queue).anyOf(
- [it()..emits().which(equals(1)), it()..emitsThrough(equals(1))]);
- await checkThat(queue).emits().which(equals(2));
+ await check(queue).anyOf(
+ [(it) => it.emits(equals(1)), (it) => it.emitsThrough(equals(1))]);
+ await check(queue).emits(equals(2));
});
});
});
- group('ChainAsync', () {
- test('which', () async {
- await checkThat(_futureSuccess()).completes().which(equals(42));
- });
- });
-
group('StreamQueueWrap', () {
test('can wrap streams in a queue', () async {
- await checkThat(Stream.value(1)).withQueue.emits();
+ await check(Stream.value(1)).withQueue.emits();
});
});
}
diff --git a/pkgs/checks/test/extensions/collection_equality_test.dart b/pkgs/checks/test/extensions/collection_equality_test.dart
index 6ab362b..3259461 100644
--- a/pkgs/checks/test/extensions/collection_equality_test.dart
+++ b/pkgs/checks/test/extensions/collection_equality_test.dart
@@ -9,7 +9,7 @@
void main() {
group('deepCollectionEquals', () {
test('allows nested collections with equal elements', () {
- checkThat(deepCollectionEquals([
+ check(deepCollectionEquals([
'a',
{'b': 1},
{'c', 'd'},
@@ -27,7 +27,7 @@
});
test('allows collections inside sets', () {
- checkThat(deepCollectionEquals({
+ check(deepCollectionEquals({
{'a': 1}
}, {
{'a': 1}
@@ -35,7 +35,7 @@
});
test('allows collections as Map keys', () {
- checkThat(deepCollectionEquals([
+ check(deepCollectionEquals([
{
{'a': 1}: {'b': 2}
}
@@ -47,38 +47,45 @@
});
test('allows conditions in place of elements in lists', () {
- checkThat(deepCollectionEquals([
+ check(deepCollectionEquals([
'a',
'b'
], [
- it()
- ..isA<String>().which(it()
- ..startsWith('a')
- ..length.isLessThan(2)),
- it()..isA<String>().startsWith('b')
+ (Subject<dynamic> it) => it.isA<String>().which((it) => it
+ ..startsWith('a')
+ ..length.isLessThan(2)),
+ (Subject<dynamic> it) => it.isA<String>().startsWith('b')
])).isNull();
});
test('allows conditions in place of values in maps', () {
- checkThat(deepCollectionEquals([
+ check(deepCollectionEquals([
{'a': 'b'}
], [
- {'a': it()..isA<String>().startsWith('b')}
+ {'a': (Subject<dynamic> it) => it.isA<String>().startsWith('b')}
])).isNull();
});
test('allows conditions in place of elements in sets', () {
- checkThat(deepCollectionEquals(
- {'b', 'a'}, {'a', it()..isA<String>().startsWith('b')})).isNull();
+ check(deepCollectionEquals({
+ 'b',
+ 'a'
+ }, {
+ 'a',
+ (Subject<dynamic> it) => it.isA<String>().startsWith('b')
+ })).isNull();
});
test('allows conditions in place of keys in maps', () {
- checkThat(deepCollectionEquals(
- {'a': 'b'}, {it()..isA<String>().startsWith('a'): 'b'})).isNull();
+ check(deepCollectionEquals({
+ 'a': 'b'
+ }, {
+ (Subject<dynamic> it) => it.isA<String>().startsWith('a'): 'b'
+ })).isNull();
});
test('reports non-Set elements', () {
- checkThat(deepCollectionEquals([
+ check(deepCollectionEquals([
['a']
], [
{'a'}
@@ -86,27 +93,28 @@
});
test('reports long iterables', () {
- checkThat(deepCollectionEquals([0], [])).isNotNull().deepEquals([
+ check(deepCollectionEquals([0], [])).isNotNull().deepEquals([
'has more elements than expected',
'expected an iterable with 0 element(s)'
]);
});
test('reports short iterables', () {
- checkThat(deepCollectionEquals([], [0])).isNotNull().deepEquals([
+ check(deepCollectionEquals([], [0])).isNotNull().deepEquals([
'has too few elements',
'expected an iterable with at least 1 element(s)'
]);
});
test('reports unequal elements in iterables', () {
- checkThat(deepCollectionEquals([0], [1]))
+ check(deepCollectionEquals([0], [1]))
.isNotNull()
.deepEquals(['at [<0>] is <0>', 'which does not equal <1>']);
});
test('reports unmet conditions in iterables', () {
- checkThat(deepCollectionEquals([0], [it()..isA<int>().isGreaterThan(0)]))
+ check(deepCollectionEquals(
+ [0], [(Subject<dynamic> it) => it.isA<int>().isGreaterThan(0)]))
.isNotNull()
.deepEquals([
'has an element at [<0>] that:',
@@ -116,10 +124,11 @@
});
test('reports unmet conditions in map values', () {
- checkThat(deepCollectionEquals(
- {'a': 'b'}, {'a': it()..isA<String>().startsWith('a')}))
- .isNotNull()
- .deepEquals([
+ check(deepCollectionEquals({
+ 'a': 'b'
+ }, {
+ 'a': (Subject<dynamic> it) => it.isA<String>().startsWith('a')
+ })).isNotNull().deepEquals([
"has no entry to match 'a': <A value that:",
' is a String',
" starts with 'a'>",
@@ -127,10 +136,11 @@
});
test('reports unmet conditions in map keys', () {
- checkThat(deepCollectionEquals(
- {'b': 'a'}, {it()..isA<String>().startsWith('a'): 'a'}))
- .isNotNull()
- .deepEquals([
+ check(deepCollectionEquals({
+ 'b': 'a'
+ }, {
+ (Subject<dynamic> it) => it.isA<String>().startsWith('a'): 'a'
+ })).isNotNull().deepEquals([
'has no entry to match <A value that:',
' is a String',
" starts with 'a'>: 'a'",
@@ -140,7 +150,7 @@
test('reports recursive lists', () {
var l = [];
l.add(l);
- checkThat(deepCollectionEquals(l, l))
+ check(deepCollectionEquals(l, l))
.isNotNull()
.deepEquals(['exceeds the depth limit of 1000']);
});
@@ -148,7 +158,7 @@
test('reports recursive sets', () {
var s = <Object>{};
s.add(s);
- checkThat(deepCollectionEquals(s, s))
+ check(deepCollectionEquals(s, s))
.isNotNull()
.deepEquals(['exceeds the depth limit of 1000']);
});
@@ -156,7 +166,7 @@
test('reports maps with recursive keys', () {
var m = <Object, Object>{};
m[m] = 0;
- checkThat(deepCollectionEquals(m, m))
+ check(deepCollectionEquals(m, m))
.isNotNull()
.deepEquals(['exceeds the depth limit of 1000']);
});
@@ -164,7 +174,7 @@
test('reports maps with recursive values', () {
var m = <Object, Object>{};
m[0] = m;
- checkThat(deepCollectionEquals(m, m))
+ check(deepCollectionEquals(m, m))
.isNotNull()
.deepEquals(['exceeds the depth limit of 1000']);
});
diff --git a/pkgs/checks/test/extensions/core_test.dart b/pkgs/checks/test/extensions/core_test.dart
index 411562e..f220e78 100644
--- a/pkgs/checks/test/extensions/core_test.dart
+++ b/pkgs/checks/test/extensions/core_test.dart
@@ -10,28 +10,33 @@
void main() {
group('TypeChecks', () {
test('isA', () {
- checkThat(1).isA<int>();
+ check(1).isA<int>();
- checkThat(1).isRejectedBy(it()..isA<String>(), which: ['Is a int']);
+ check(1).isRejectedBy((it) => it.isA<String>(), which: ['Is a int']);
});
});
group('HasField', () {
test('has', () {
- checkThat(1).has((v) => v.isOdd, 'isOdd').isTrue();
+ check(1).has((v) => v.isOdd, 'isOdd').isTrue();
- checkThat(2).isRejectedBy(
- it()..has((v) => throw UnimplementedError(), 'isOdd'),
- which: ['threw while trying to read property']);
+ check(null).isRejectedBy(
+ (it) => it.has((v) {
+ Error.throwWithStackTrace(
+ UnimplementedError(), StackTrace.fromString('fake trace'));
+ }, 'foo').isNotNull(),
+ which: [
+ 'threw while trying to read foo: <UnimplementedError>',
+ 'fake trace'
+ ]);
});
test('which', () {
- checkThat(true).which(it()..isTrue());
+ check(true).which((it) => it.isTrue());
});
test('not', () {
- checkThat(false).not(it()..isTrue());
-
- checkThat(true).isRejectedBy(it()..not(it()..isTrue()), which: [
+ check(false).not((it) => it.isTrue());
+ check(true).isRejectedBy((it) => it.not((it) => it.isTrue()), which: [
'is a value that: ',
' is true',
]);
@@ -39,12 +44,13 @@
group('anyOf', () {
test('succeeds for happy case', () {
- checkThat(-10).anyOf([it()..isGreaterThan(1), it()..isLessThan(-1)]);
+ check(-10)
+ .anyOf([(it) => it.isGreaterThan(1), (it) => it.isLessThan(-1)]);
});
-
test('rejects values that do not satisfy any condition', () {
- checkThat(0).isRejectedBy(
- it()..anyOf([it()..isGreaterThan(1), it()..isLessThan(-1)]),
+ check(0).isRejectedBy(
+ (it) => it.anyOf(
+ [(it) => it.isGreaterThan(1), (it) => it.isLessThan(-1)]),
which: ['did not match any condition']);
});
});
@@ -52,41 +58,100 @@
group('BoolChecks', () {
test('isTrue', () {
- checkThat(true).isTrue();
+ check(true).isTrue();
- checkThat(false).isRejectedBy(it()..isTrue());
+ check(false).isRejectedBy((it) => it.isTrue());
});
test('isFalse', () {
- checkThat(false).isFalse();
+ check(false).isFalse();
- checkThat(true).isRejectedBy(it()..isFalse());
+ check(true).isRejectedBy((it) => it.isFalse());
});
});
group('EqualityChecks', () {
test('equals', () {
- checkThat(1).equals(1);
+ check(1).equals(1);
- checkThat(1).isRejectedBy(equals(2), which: ['are not equal']);
+ check(1).isRejectedBy((it) => it.equals(2), which: ['are not equal']);
});
test('identical', () {
- checkThat(1).identicalTo(1);
+ check(1).identicalTo(1);
- checkThat(1)
- .isRejectedBy(it()..identicalTo(2), which: ['is not identical']);
+ check(1)
+ .isRejectedBy((it) => it.identicalTo(2), which: ['is not identical']);
});
});
group('NullabilityChecks', () {
test('isNotNull', () {
- checkThat(1).isNotNull();
+ check(1).isNotNull();
- checkThat(null).isRejectedBy(it()..isNotNull());
+ check(null).isRejectedBy((it) => it.isNotNull());
});
test('isNull', () {
- checkThat(null).isNull();
+ check(null).isNull();
- checkThat(1).isRejectedBy(it()..isNull());
+ check(1).isRejectedBy((it) => it.isNull());
+ });
+ });
+
+ group('ComparableChecks on Duration', () {
+ group('isGreaterThan', () {
+ test('succeeds for greater', () {
+ check(Duration(seconds: 10)).isGreaterThan(Duration(seconds: 1));
+ });
+ test('fails for equal', () {
+ check(Duration(seconds: 10)).isRejectedBy(
+ (it) => it.isGreaterThan(Duration(seconds: 10)),
+ which: ['is not greater than <0:00:10.000000>']);
+ });
+ test('fails for less', () {
+ check(Duration(seconds: 10)).isRejectedBy(
+ (it) => it.isGreaterThan(Duration(seconds: 50)),
+ which: ['is not greater than <0:00:50.000000>']);
+ });
+ });
+ group('isGreaterOrEqual', () {
+ test('succeeds for greater', () {
+ check(Duration(seconds: 10)).isGreaterOrEqual(Duration(seconds: 1));
+ });
+ test('succeeds for equal', () {
+ check(Duration(seconds: 10)).isGreaterOrEqual(Duration(seconds: 10));
+ });
+ test('fails for less', () {
+ check(Duration(seconds: 10)).isRejectedBy(
+ (it) => it.isGreaterOrEqual(Duration(seconds: 50)),
+ which: ['is not greater than or equal to <0:00:50.000000>']);
+ });
+ });
+ group('isLessThan', () {
+ test('succeeds for less', () {
+ check(Duration(seconds: 1)).isLessThan(Duration(seconds: 10));
+ });
+ test('fails for equal', () {
+ check(Duration(seconds: 10)).isRejectedBy(
+ (it) => it.isLessThan(Duration(seconds: 10)),
+ which: ['is not less than <0:00:10.000000>']);
+ });
+ test('fails for greater', () {
+ check(Duration(seconds: 50)).isRejectedBy(
+ (it) => it.isLessThan(Duration(seconds: 10)),
+ which: ['is not less than <0:00:10.000000>']);
+ });
+ });
+ group('isLessOrEqual', () {
+ test('succeeds for less', () {
+ check(Duration(seconds: 10)).isLessOrEqual(Duration(seconds: 50));
+ });
+ test('succeeds for equal', () {
+ check(Duration(seconds: 10)).isLessOrEqual(Duration(seconds: 10));
+ });
+ test('fails for greater', () {
+ check(Duration(seconds: 10)).isRejectedBy(
+ (it) => it.isLessOrEqual(Duration(seconds: 1)),
+ which: ['is not less than or equal to <0:00:01.000000>']);
+ });
});
});
}
diff --git a/pkgs/checks/test/extensions/function_test.dart b/pkgs/checks/test/extensions/function_test.dart
index c44ff1f..034d8fe 100644
--- a/pkgs/checks/test/extensions/function_test.dart
+++ b/pkgs/checks/test/extensions/function_test.dart
@@ -11,16 +11,16 @@
group('ThrowsChecks', () {
group('throws', () {
test('succeeds for happy case', () {
- checkThat(() => throw StateError('oops!')).throws<StateError>();
+ check(() => throw StateError('oops!')).throws<StateError>();
});
test('fails for functions that return normally', () {
- checkThat(() {}).isRejectedBy(it()..throws<StateError>(),
+ check(() {}).isRejectedBy((it) => it.throws<StateError>(),
actual: ['a function that returned <null>'],
which: ['did not throw']);
});
test('fails for functions that throw the wrong type', () {
- checkThat(() => throw StateError('oops!')).isRejectedBy(
- it()..throws<ArgumentError>(),
+ check(() => throw StateError('oops!')).isRejectedBy(
+ (it) => it.throws<ArgumentError>(),
actual: ['a function that threw error <Bad state: oops!>'],
which: ['did not throw an ArgumentError'],
);
@@ -29,13 +29,13 @@
group('returnsNormally', () {
test('succeeds for happy case', () {
- checkThat(() => 1).returnsNormally().equals(1);
+ check(() => 1).returnsNormally().equals(1);
});
test('fails for functions that throw', () {
- checkThat(() {
+ check(() {
Error.throwWithStackTrace(
StateError('oops!'), StackTrace.fromString('fake trace'));
- }).isRejectedBy(it()..returnsNormally(),
+ }).isRejectedBy((it) => it.returnsNormally(),
actual: ['a function that throws'],
which: ['threw <Bad state: oops!>', 'fake trace']);
});
diff --git a/pkgs/checks/test/extensions/iterable_test.dart b/pkgs/checks/test/extensions/iterable_test.dart
index 2081ecb..73c0881 100644
--- a/pkgs/checks/test/extensions/iterable_test.dart
+++ b/pkgs/checks/test/extensions/iterable_test.dart
@@ -11,59 +11,86 @@
void main() {
test('length', () {
- checkThat(_testIterable).length.equals(2);
+ check(_testIterable).length.equals(2);
});
- test('first', () {
- checkThat(_testIterable).first.equals(0);
+
+ group('first', () {
+ test('succeeds for happy case', () {
+ check(_testIterable).first.equals(0);
+ });
+ test('rejects empty iterable', () {
+ check([])
+ .isRejectedBy((it) => it.first.equals(0), which: ['has no elements']);
+ });
});
- test('last', () {
- checkThat(_testIterable).last.equals(1);
+
+ group('last', () {
+ test('succeeds for happy case', () {
+ check(_testIterable).last.equals(1);
+ });
+ test('rejects empty iterable', () {
+ check([])
+ .isRejectedBy((it) => it.last.equals(0), which: ['has no elements']);
+ });
});
- test('single', () {
- checkThat([42]).single.equals(42);
+
+ group('single', () {
+ test('succeeds for happy case', () {
+ check([42]).single.equals(42);
+ });
+ test('rejects empty iterable', () {
+ check([]).isRejectedBy((it) => it.single.equals(0),
+ which: ['has no elements']);
+ });
+ test('rejects iterable with too many elements', () {
+ check(_testIterable).isRejectedBy((it) => it.single.equals(0),
+ which: ['has more than one element']);
+ });
});
test('isEmpty', () {
- checkThat([]).isEmpty();
- checkThat(_testIterable)
- .isRejectedBy(it()..isEmpty(), which: ['is not empty']);
+ check([]).isEmpty();
+ check(_testIterable)
+ .isRejectedBy((it) => it.isEmpty(), which: ['is not empty']);
});
test('isNotEmpty', () {
- checkThat(_testIterable).isNotEmpty();
- checkThat(Iterable<int>.empty())
- .isRejectedBy(it()..isNotEmpty(), which: ['is not empty']);
+ check(_testIterable).isNotEmpty();
+ check(Iterable<int>.empty())
+ .isRejectedBy((it) => it.isNotEmpty(), which: ['is empty']);
});
test('contains', () {
- checkThat(_testIterable).contains(0);
- checkThat(_testIterable)
- .isRejectedBy(it()..contains(2), which: ['does not contain <2>']);
+ check(_testIterable).contains(0);
+ check(_testIterable)
+ .isRejectedBy((it) => it.contains(2), which: ['does not contain <2>']);
});
test('any', () {
- checkThat(_testIterable).any(equals(1));
- checkThat(_testIterable).isRejectedBy(it()..any(equals(2)),
+ check(_testIterable).any(equals(1));
+ check(_testIterable).isRejectedBy((it) => it.any(equals(2)),
which: ['Contains no matching element']);
});
group('containsInOrder', () {
test('succeeds for happy case', () {
- checkThat([0, 1, 0, 2, 0, 3]).containsInOrder([1, 2, 3]);
+ check([0, 1, 0, 2, 0, 3]).containsInOrder([1, 2, 3]);
});
test('can use Condition<dynamic>', () {
- checkThat([0, 1]).containsInOrder([it()..isA<int>().isGreaterThan(0)]);
+ check([0, 1]).containsInOrder(
+ [(Subject<dynamic> it) => it.isA<int>().isGreaterThan(0)]);
});
test('can use Condition<T>', () {
- checkThat([0, 1]).containsInOrder([it<int>()..isGreaterThan(0)]);
+ check([0, 1]).containsInOrder([(Subject<int> it) => it.isGreaterThan(0)]);
});
test('fails for not found elements by equality', () async {
- checkThat([0]).isRejectedBy(it()..containsInOrder([1]), which: [
+ check([0]).isRejectedBy((it) => it.containsInOrder([1]), which: [
'did not have an element matching the expectation at index 0 <1>'
]);
});
test('fails for not found elements by condition', () async {
- checkThat([0]).isRejectedBy(
- it()..containsInOrder([it()..isA<int>().isGreaterThan(0)]),
+ check([0]).isRejectedBy(
+ (it) => it.containsInOrder(
+ [(Subject<dynamic> it) => it.isA<int>().isGreaterThan(0)]),
which: [
'did not have an element matching the expectation at index 0 '
'<A value that:',
@@ -72,10 +99,11 @@
]);
});
test('can be described', () {
- checkThat(it<Iterable>()..containsInOrder([1, 2, 3]))
+ check((Subject<Iterable> it) => it.containsInOrder([1, 2, 3]))
.description
.deepEquals([' contains, in order: [1, 2, 3]']);
- checkThat(it<Iterable>()..containsInOrder([1, equals(2)]))
+ check((Subject<Iterable> it) =>
+ it.containsInOrder([1, (Subject<dynamic> it) => it.equals(2)]))
.description
.deepEquals([
' contains, in order: [1,',
@@ -86,12 +114,12 @@
});
group('every', () {
test('succeeds for the happy path', () {
- checkThat(_testIterable).every(it()..isGreaterOrEqual(-1));
+ check(_testIterable).every((it) => it.isGreaterOrEqual(-1));
});
test('includes details of first failing element', () async {
- checkThat(_testIterable)
- .isRejectedBy(it()..every(it()..isLessThan(0)), which: [
+ check(_testIterable)
+ .isRejectedBy((it) => it.every((it) => it.isLessThan(0)), which: [
'has an element at index 0 that:',
' Actual: <0>',
' Which: is not less than <0>',
@@ -101,12 +129,12 @@
group('unorderedEquals', () {
test('success for happy case', () {
- checkThat(_testIterable).unorderedEquals(_testIterable.toList().reversed);
+ check(_testIterable).unorderedEquals(_testIterable.toList().reversed);
});
test('reports unmatched elements', () {
- checkThat(_testIterable).isRejectedBy(
- it()..unorderedEquals(_testIterable.followedBy([42, 100])),
+ check(_testIterable).isRejectedBy(
+ (it) => it.unorderedEquals(_testIterable.followedBy([42, 100])),
which: [
'has no element equal to the expected element at index 2: <42>',
'or 1 other elements'
@@ -114,8 +142,8 @@
});
test('reports unexpected elements', () {
- checkThat(_testIterable.followedBy([42, 100]))
- .isRejectedBy(it()..unorderedEquals(_testIterable), which: [
+ check(_testIterable.followedBy([42, 100]))
+ .isRejectedBy((it) => it.unorderedEquals(_testIterable), which: [
'has an unexpected element at index 2: <42>',
'and 1 other unexpected elements'
]);
@@ -124,15 +152,14 @@
group('unorderedMatches', () {
test('success for happy case', () {
- checkThat(_testIterable).unorderedMatches(
- _testIterable.toList().reversed.map((i) => equals(i)));
+ check(_testIterable)
+ .unorderedMatches(_testIterable.toList().reversed.map(equals));
});
test('reports unmatched elements', () {
- checkThat(_testIterable).isRejectedBy(
- it()
- ..unorderedMatches(
- _testIterable.followedBy([42, 100]).map((i) => equals(i))),
+ check(_testIterable).isRejectedBy(
+ (it) => it.unorderedMatches(
+ _testIterable.followedBy([42, 100]).map(equals)),
which: [
'has no element matching the condition at index 2:',
' equals <42>',
@@ -141,8 +168,8 @@
});
test('reports unexpected elements', () {
- checkThat(_testIterable.followedBy([42, 100])).isRejectedBy(
- it()..unorderedMatches(_testIterable.map((i) => equals(i))),
+ check(_testIterable.followedBy([42, 100])).isRejectedBy(
+ (it) => it.unorderedMatches(_testIterable.map(equals)),
which: [
'has an unmatched element at index 2: <42>',
'and 1 other unmatched elements'
@@ -152,14 +179,13 @@
group('pairwiseComparesTo', () {
test('succeeds for the happy path', () {
- checkThat(_testIterable).pairwiseComparesTo(
- [1, 2], (expected) => it()..isLessThan(expected), 'is less than');
+ check(_testIterable).pairwiseComparesTo([1, 2],
+ (expected) => (it) => it.isLessThan(expected), 'is less than');
});
test('fails for mismatched element', () async {
- checkThat(_testIterable).isRejectedBy(
- it()
- ..pairwiseComparesTo([1, 1],
- (expected) => it()..isLessThan(expected), 'is less than'),
+ check(_testIterable).isRejectedBy(
+ (it) => it.pairwiseComparesTo([1, 1],
+ (expected) => (it) => it.isLessThan(expected), 'is less than'),
which: [
'does not have an element at index 1 that:',
' is less than <1>',
@@ -168,19 +194,17 @@
]);
});
test('fails for too few elements', () {
- checkThat(_testIterable).isRejectedBy(
- it()
- ..pairwiseComparesTo([1, 2, 3],
- (expected) => it()..isLessThan(expected), 'is less than'),
+ check(_testIterable).isRejectedBy(
+ (it) => it.pairwiseComparesTo([1, 2, 3],
+ (expected) => (it) => it.isLessThan(expected), 'is less than'),
which: [
'has too few elements, there is no element to match at index 2'
]);
});
test('fails for too many elements', () {
- checkThat(_testIterable).isRejectedBy(
- it()
- ..pairwiseComparesTo(
- [1], (expected) => it()..isLessThan(expected), 'is less than'),
+ check(_testIterable).isRejectedBy(
+ (it) => it.pairwiseComparesTo([1],
+ (expected) => (it) => it.isLessThan(expected), 'is less than'),
which: ['has too many elements, expected exactly 1']);
});
});
diff --git a/pkgs/checks/test/extensions/map_test.dart b/pkgs/checks/test/extensions/map_test.dart
index 0aaef0d..1b2684c 100644
--- a/pkgs/checks/test/extensions/map_test.dart
+++ b/pkgs/checks/test/extensions/map_test.dart
@@ -14,61 +14,104 @@
void main() {
test('length', () {
- checkThat(_testMap).length.equals(2);
+ check(_testMap).length.equals(2);
});
test('entries', () {
- checkThat(_testMap).entries.any(
- it()
+ check(_testMap).entries.any(
+ (it) => it
..has((p0) => p0.key, 'key').equals('a')
..has((p0) => p0.value, 'value').equals(1),
);
});
test('keys', () {
- checkThat(_testMap).keys.contains('a');
+ check(_testMap).keys.contains('a');
});
test('values', () {
- checkThat(_testMap).values.contains(1);
+ check(_testMap).values.contains(1);
});
- test('operator []', () async {
- checkThat(_testMap)['a'].equals(1);
- checkThat(_testMap)
- .isRejectedBy(it()..['z'], which: ['does not contain the key \'z\'']);
+ group('operator []', () {
+ test('succeeds for a key that exists', () {
+ check(_testMap)['a'].equals(1);
+ });
+ test('fails for a missing key', () {
+ check(_testMap).isRejectedBy((it) => it['z'],
+ which: ["does not contain the key 'z'"]);
+ });
+ test('can be described', () {
+ check((Subject<Map<String, Object>> it) => it['some\nlong\nkey'])
+ .description
+ .deepEquals([
+ " contains a value for 'some",
+ ' long',
+ " key'",
+ ]);
+ check((Subject<Map<String, Object>> it) =>
+ it['some\nlong\nkey'].equals(1)).description.deepEquals([
+ " contains a value for 'some",
+ ' long',
+ " key' that:",
+ ' equals <1>',
+ ]);
+ });
});
test('isEmpty', () {
- checkThat(<String, int>{}).isEmpty();
- checkThat(_testMap).isRejectedBy(it()..isEmpty(), which: ['is not empty']);
+ check(<String, int>{}).isEmpty();
+ check(_testMap).isRejectedBy((it) => it.isEmpty(), which: ['is not empty']);
});
test('isNotEmpty', () {
- checkThat(_testMap).isNotEmpty();
- checkThat({}).isRejectedBy(it()..isNotEmpty(), which: ['is not empty']);
+ check(_testMap).isNotEmpty();
+ check({}).isRejectedBy((it) => it.isNotEmpty(), which: ['is not empty']);
});
- test('containsKey', () {
- checkThat(_testMap).containsKey('a');
-
- checkThat(_testMap).isRejectedBy(
- it()..containsKey('c'),
- which: ["does not contain key 'c'"],
- );
+ group('containsKey', () {
+ test('succeeds for a key that exists', () {
+ check(_testMap).containsKey('a');
+ });
+ test('fails for a missing key', () {
+ check(_testMap).isRejectedBy(
+ (it) => it.containsKey('c'),
+ which: ["does not contain key 'c'"],
+ );
+ });
+ test('can be described', () {
+ check((Subject<Map<String, Object>> it) =>
+ it.containsKey('some\nlong\nkey')).description.deepEquals([
+ " contains key 'some",
+ ' long',
+ " key'",
+ ]);
+ });
});
test('containsKeyThat', () {
- checkThat(_testMap).containsKeyThat(equals('a'));
- checkThat(_testMap).isRejectedBy(
- it()..containsKeyThat(equals('c')),
+ check(_testMap).containsKeyThat(equals('a'));
+ check(_testMap).isRejectedBy(
+ (it) => it.containsKeyThat(equals('c')),
which: ['Contains no matching key'],
);
});
- test('containsValue', () {
- checkThat(_testMap).containsValue(1);
- checkThat(_testMap).isRejectedBy(
- it()..containsValue(3),
- which: ['does not contain value <3>'],
- );
+ group('containsValue', () {
+ test('succeeds for happy case', () {
+ check(_testMap).containsValue(1);
+ });
+ test('fails for missing value', () {
+ check(_testMap).isRejectedBy(
+ (it) => it.containsValue(3),
+ which: ['does not contain value <3>'],
+ );
+ });
+ test('can be described', () {
+ check((Subject<Map<String, String>> it) =>
+ it.containsValue('some\nlong\nkey')).description.deepEquals([
+ " contains value 'some",
+ ' long',
+ " key'",
+ ]);
+ });
});
test('containsValueThat', () {
- checkThat(_testMap).containsValueThat(equals(1));
- checkThat(_testMap).isRejectedBy(
- it()..containsValueThat(equals(3)),
+ check(_testMap).containsValueThat(equals(1));
+ check(_testMap).isRejectedBy(
+ (it) => it.containsValueThat(equals(3)),
which: ['Contains no matching value'],
);
});
diff --git a/pkgs/checks/test/extensions/math_test.dart b/pkgs/checks/test/extensions/math_test.dart
index 131cfa6..0f346d3 100644
--- a/pkgs/checks/test/extensions/math_test.dart
+++ b/pkgs/checks/test/extensions/math_test.dart
@@ -9,194 +9,140 @@
void main() {
group('num checks', () {
- group('greater than', () {
- test('succeeds for happy case', () {
- checkThat(42).isGreaterThan(7);
- });
- test('fails for less than', () {
- checkThat(42).isRejectedBy(it()..isGreaterThan(50),
- which: ['is not greater than <50>']);
- });
- test('fails for equal', () {
- checkThat(42).isRejectedBy(it()..isGreaterThan(42),
- which: ['is not greater than <42>']);
- });
- });
-
- group('greater than or equal', () {
- test('succeeds for happy case', () {
- checkThat(42).isGreaterOrEqual(7);
- });
- test('fails for less than', () {
- checkThat(42).isRejectedBy(it()..isGreaterOrEqual(50),
- which: ['is not greater than or equal to <50>']);
- });
- test('succeeds for equal', () {
- checkThat(42).isGreaterOrEqual(42);
- });
- });
-
- group('less than', () {
- test('succeeds for happy case', () {
- checkThat(42).isLessThan(50);
- });
- test('fails for greater than', () {
- checkThat(42)
- .isRejectedBy(it()..isLessThan(7), which: ['is not less than <7>']);
- });
- test('fails for equal', () {
- checkThat(42).isRejectedBy(it()..isLessThan(42),
- which: ['is not less than <42>']);
- });
- });
-
- group('less than or equal', () {
- test('succeeds for happy case', () {
- checkThat(42).isLessOrEqual(50);
- });
- test('fails for greater than', () {
- checkThat(42).isRejectedBy(it()..isLessOrEqual(7),
- which: ['is not less than or equal to <7>']);
- });
- test('succeeds for equal', () {
- checkThat(42).isLessOrEqual(42);
- });
- });
-
group('isNaN', () {
test('succeeds for happy case', () {
- checkThat(double.nan).isNaN();
+ check(double.nan).isNaN();
});
test('fails for ints', () {
- checkThat(42).isRejectedBy(it()..isNaN(), which: ['is a number']);
+ check(42).isRejectedBy((it) => it.isNaN(), which: ['is a number']);
});
test('fails for numeric doubles', () {
- checkThat(42.1).isRejectedBy(it()..isNaN(), which: ['is a number']);
+ check(42.1).isRejectedBy((it) => it.isNaN(), which: ['is a number']);
});
});
group('isNotNan', () {
test('succeeds for ints', () {
- checkThat(42).isNotNaN();
+ check(42).isNotNaN();
});
test('succeeds numeric doubles', () {
- checkThat(42.1).isNotNaN();
+ check(42.1).isNotNaN();
});
test('fails for NaN', () {
- checkThat(double.nan)
- .isRejectedBy(it()..isNotNaN(), which: ['is not a number (NaN)']);
+ check(double.nan).isRejectedBy((it) => it.isNotNaN(),
+ which: ['is not a number (NaN)']);
});
});
group('isNegative', () {
test('succeeds for negative ints', () {
- checkThat(-1).isNegative();
+ check(-1).isNegative();
});
test('succeeds for -0.0', () {
- checkThat(-0.0).isNegative();
+ check(-0.0).isNegative();
});
test('fails for zero', () {
- checkThat(0)
- .isRejectedBy(it()..isNegative(), which: ['is not negative']);
+ check(0)
+ .isRejectedBy((it) => it.isNegative(), which: ['is not negative']);
});
});
group('isNotNegative', () {
test('succeeds for positive ints', () {
- checkThat(1).isNotNegative();
+ check(1).isNotNegative();
});
test('succeeds for 0', () {
- checkThat(0).isNotNegative();
+ check(0).isNotNegative();
});
test('fails for -0.0', () {
- checkThat(-0.0)
- .isRejectedBy(it()..isNotNegative(), which: ['is negative']);
+ check(-0.0)
+ .isRejectedBy((it) => it.isNotNegative(), which: ['is negative']);
});
test('fails for negative numbers', () {
- checkThat(-1)
- .isRejectedBy(it()..isNotNegative(), which: ['is negative']);
+ check(-1)
+ .isRejectedBy((it) => it.isNotNegative(), which: ['is negative']);
});
});
group('isFinite', () {
test('succeeds for finite numbers', () {
- checkThat(1).isFinite();
+ check(1).isFinite();
});
test('fails for NaN', () {
- checkThat(double.nan)
- .isRejectedBy(it()..isFinite(), which: ['is not finite']);
+ check(double.nan)
+ .isRejectedBy((it) => it.isFinite(), which: ['is not finite']);
});
test('fails for infinity', () {
- checkThat(double.infinity)
- .isRejectedBy(it()..isFinite(), which: ['is not finite']);
+ check(double.infinity)
+ .isRejectedBy((it) => it.isFinite(), which: ['is not finite']);
});
test('fails for negative infinity', () {
- checkThat(double.negativeInfinity)
- .isRejectedBy(it()..isFinite(), which: ['is not finite']);
+ check(double.negativeInfinity)
+ .isRejectedBy((it) => it.isFinite(), which: ['is not finite']);
});
});
group('isNotFinite', () {
test('succeeds for infinity', () {
- checkThat(double.infinity).isNotFinite();
+ check(double.infinity).isNotFinite();
});
test('succeeds for negative infinity', () {
- checkThat(double.negativeInfinity).isNotFinite();
+ check(double.negativeInfinity).isNotFinite();
});
test('succeeds for NaN', () {
- checkThat(double.nan).isNotFinite();
+ check(double.nan).isNotFinite();
});
test('fails for finite numbers', () {
- checkThat(1).isRejectedBy(it()..isNotFinite(), which: ['is finite']);
+ check(1).isRejectedBy((it) => it.isNotFinite(), which: ['is finite']);
});
});
group('isInfinite', () {
test('succeeds for infinity', () {
- checkThat(double.infinity).isInfinite();
+ check(double.infinity).isInfinite();
});
test('succeeds for negative infinity', () {
- checkThat(double.negativeInfinity).isInfinite();
+ check(double.negativeInfinity).isInfinite();
});
test('fails for NaN', () {
- checkThat(double.nan)
- .isRejectedBy(it()..isInfinite(), which: ['is not infinite']);
+ check(double.nan)
+ .isRejectedBy((it) => it.isInfinite(), which: ['is not infinite']);
});
test('fails for finite numbers', () {
- checkThat(1)
- .isRejectedBy(it()..isInfinite(), which: ['is not infinite']);
+ check(1)
+ .isRejectedBy((it) => it.isInfinite(), which: ['is not infinite']);
});
});
group('isNotInfinite', () {
test('succeeds for finite numbers', () {
- checkThat(1).isNotInfinite();
+ check(1).isNotInfinite();
});
test('succeeds for NaN', () {
- checkThat(double.nan).isNotInfinite();
+ check(double.nan).isNotInfinite();
});
test('fails for infinity', () {
- checkThat(double.infinity)
- .isRejectedBy(it()..isNotInfinite(), which: ['is infinite']);
+ check(double.infinity)
+ .isRejectedBy((it) => it.isNotInfinite(), which: ['is infinite']);
});
test('fails for negative infinity', () {
- checkThat(double.negativeInfinity)
- .isRejectedBy(it()..isNotInfinite(), which: ['is infinite']);
+ check(double.negativeInfinity)
+ .isRejectedBy((it) => it.isNotInfinite(), which: ['is infinite']);
});
});
group('closeTo', () {
test('succeeds for equal numbers', () {
- checkThat(1).isCloseTo(1, 1);
+ check(1).isCloseTo(1, 1);
});
test('succeeds at less than delta away', () {
- checkThat(1).isCloseTo(2, 2);
+ check(1).isCloseTo(2, 2);
});
test('succeeds at exactly delta away', () {
- checkThat(1).isCloseTo(2, 1);
+ check(1).isCloseTo(2, 1);
});
test('fails for low values', () {
- checkThat(1)
- .isRejectedBy(it()..isCloseTo(3, 1), which: ['differs by <2>']);
+ check(1).isRejectedBy((it) => it.isCloseTo(3, 1),
+ which: ['differs by <2>']);
});
test('fails for high values', () {
- checkThat(5)
- .isRejectedBy(it()..isCloseTo(3, 1), which: ['differs by <2>']);
+ check(5).isRejectedBy((it) => it.isCloseTo(3, 1),
+ which: ['differs by <2>']);
});
});
});
diff --git a/pkgs/checks/test/extensions/string_test.dart b/pkgs/checks/test/extensions/string_test.dart
index 7327f9c..2b651f1 100644
--- a/pkgs/checks/test/extensions/string_test.dart
+++ b/pkgs/checks/test/extensions/string_test.dart
@@ -10,58 +10,70 @@
void main() {
group('StringChecks', () {
test('contains', () {
- checkThat('bob').contains('bo');
- checkThat('bob').isRejectedBy(it()..contains('kayleb'),
+ check('bob').contains('bo');
+ check('bob').isRejectedBy((it) => it.contains('kayleb'),
which: ["Does not contain 'kayleb'"]);
});
test('length', () {
- checkThat('bob').length.equals(3);
+ check('bob').length.equals(3);
});
test('isEmpty', () {
- checkThat('').isEmpty();
- checkThat('bob').isRejectedBy(it()..isEmpty(), which: ['is not empty']);
+ check('').isEmpty();
+ check('bob').isRejectedBy((it) => it.isEmpty(), which: ['is not empty']);
});
test('isNotEmpty', () {
- checkThat('bob').isNotEmpty();
- checkThat('').isRejectedBy(it()..isNotEmpty(), which: ['is empty']);
+ check('bob').isNotEmpty();
+ check('').isRejectedBy((it) => it.isNotEmpty(), which: ['is empty']);
});
test('startsWith', () {
- checkThat('bob').startsWith('bo');
- checkThat('bob').isRejectedBy(it()..startsWith('kayleb'),
+ check('bob').startsWith('bo');
+ check('bob').isRejectedBy((it) => it.startsWith('kayleb'),
which: ["does not start with 'kayleb'"]);
});
test('endsWith', () {
- checkThat('bob').endsWith('ob');
- checkThat('bob').isRejectedBy(it()..endsWith('kayleb'),
+ check('bob').endsWith('ob');
+ check('bob').isRejectedBy((it) => it.endsWith('kayleb'),
which: ["does not end with 'kayleb'"]);
});
group('matches', () {
- test('succeeds for strings that match', () {
- checkThat('123').matches(RegExp(r'\d\d\d'));
+ test('succeeds for strings that match a regex', () {
+ check('123').matchesPattern(RegExp(r'\d\d\d'));
});
- test('fails for non-matching strings', () {
- checkThat('abc').isRejectedBy(it()..matches(RegExp(r'\d\d\d')),
+ test('succeeds for strings that match a string pattern', () {
+ check(r'\d').matchesPattern(r'\d');
+ });
+ test('fails for non-matching regex', () {
+ check('abc').isRejectedBy((it) => it.matchesPattern(RegExp(r'\d\d\d')),
which: [r'does not match <RegExp: pattern=\d\d\d flags=>']);
});
+ test('fails for non-matching string pattern', () {
+ // A string is _not_ converted to a regex, string patterns must match
+ // directly.
+ check('123').isRejectedBy((it) => it.matchesPattern(r'\d\d\d'),
+ which: [r"does not match '\\d\\d\\d'"]);
+ });
test('can be described', () {
- checkThat(it<String>()..matches(RegExp(r'\d\d\d')))
+ check((Subject<String> it) => it.matchesPattern(RegExp(r'\d\d\d')))
.description
.deepEquals([r' matches <RegExp: pattern=\d\d\d flags=>']);
+ check((Subject<String> it) => it.matchesPattern('abc'))
+ .description
+ .deepEquals([r" matches 'abc'"]);
});
});
group('containsInOrder', () {
test('happy case', () {
- checkThat('foo bar baz').containsInOrder(['foo', 'baz']);
+ check('foo bar baz').containsInOrder(['foo', 'baz']);
});
test('reports when first substring is missing', () {
- checkThat('baz').isRejectedBy(it()..containsInOrder(['foo', 'baz']),
+ check('baz').isRejectedBy((it) => it.containsInOrder(['foo', 'baz']),
which: ['does not have a match for the substring \'foo\'']);
});
test('reports when substring is missing following a match', () {
- checkThat('foo bar')
- .isRejectedBy(it()..containsInOrder(['foo', 'baz']), which: [
+ check('foo bar')
+ .isRejectedBy((it) => it.containsInOrder(['foo', 'baz']), which: [
'does not have a match for the substring \'baz\'',
'following the other matches up to character 3'
]);
@@ -70,42 +82,44 @@
group('equals', () {
test('succeeeds for happy case', () {
- checkThat('foo').equals('foo');
+ check('foo').equals('foo');
});
test('succeeeds for equal empty strings', () {
- checkThat('').equals('');
+ check('').equals('');
});
test('reports extra characters for long string', () {
- checkThat('foobar').isRejectedBy(equals('foo'),
+ check('foobar').isRejectedBy((it) => it.equals('foo'),
which: ['is too long with unexpected trailing characters:', 'bar']);
});
test('reports extra characters for long string against empty', () {
- checkThat('foo')
- .isRejectedBy(equals(''), which: ['is not the empty string']);
+ check('foo').isRejectedBy((it) => it.equals(''),
+ which: ['is not the empty string']);
});
test('reports truncated extra characters for very long string', () {
- checkThat('foobar baz more stuff').isRejectedBy(equals('foo'), which: [
- 'is too long with unexpected trailing characters:',
- 'bar baz mo ...'
- ]);
+ check('foobar baz more stuff').isRejectedBy((it) => it.equals('foo'),
+ which: [
+ 'is too long with unexpected trailing characters:',
+ 'bar baz mo ...'
+ ]);
});
test('reports missing characters for short string', () {
- checkThat('foo').isRejectedBy(equals('foobar'),
+ check('foo').isRejectedBy((it) => it.equals('foobar'),
which: ['is too short with missing trailing characters:', 'bar']);
});
test('reports missing characters for empty string', () {
- checkThat('').isRejectedBy(equals('foo bar baz'),
+ check('').isRejectedBy((it) => it.equals('foo bar baz'),
actual: ['an empty string'],
which: ['is missing all expected characters:', 'foo bar ba ...']);
});
test('reports truncated missing characters for very short string', () {
- checkThat('foo').isRejectedBy(equals('foobar baz more stuff'), which: [
- 'is too short with missing trailing characters:',
- 'bar baz mo ...'
- ]);
+ check('foo').isRejectedBy((it) => it.equals('foobar baz more stuff'),
+ which: [
+ 'is too short with missing trailing characters:',
+ 'bar baz mo ...'
+ ]);
});
test('reports index of different character', () {
- checkThat('hit').isRejectedBy(equals('hat'), which: [
+ check('hit').isRejectedBy((it) => it.equals('hat'), which: [
'differs at offset 1:',
'hat',
'hit',
@@ -114,31 +128,32 @@
});
test('reports truncated index of different character in large string',
() {
- checkThat('blah blah blah hit blah blah blah')
- .isRejectedBy(equals('blah blah blah hat blah blah blah'), which: [
- 'differs at offset 16:',
- '... lah blah hat blah bl ...',
- '... lah blah hit blah bl ...',
- ' ^',
- ]);
+ check('blah blah blah hit blah blah blah').isRejectedBy(
+ (it) => it.equals('blah blah blah hat blah blah blah'),
+ which: [
+ 'differs at offset 16:',
+ '... lah blah hat blah bl ...',
+ '... lah blah hit blah bl ...',
+ ' ^',
+ ]);
});
});
group('equalsIgnoringCase', () {
test('succeeeds for happy case', () {
- checkThat('FOO').equalsIgnoringCase('foo');
- checkThat('foo').equalsIgnoringCase('FOO');
+ check('FOO').equalsIgnoringCase('foo');
+ check('foo').equalsIgnoringCase('FOO');
});
test('reports original extra characters for long string', () {
- checkThat('FOOBAR').isRejectedBy(it()..equalsIgnoringCase('foo'),
+ check('FOOBAR').isRejectedBy((it) => it.equalsIgnoringCase('foo'),
which: ['is too long with unexpected trailing characters:', 'BAR']);
});
test('reports original missing characters for short string', () {
- checkThat('FOO').isRejectedBy(it()..equalsIgnoringCase('fooBAR'),
+ check('FOO').isRejectedBy((it) => it.equalsIgnoringCase('fooBAR'),
which: ['is too short with missing trailing characters:', 'BAR']);
});
test('reports index of different character with original characters', () {
- checkThat('HiT').isRejectedBy(it()..equalsIgnoringCase('hAt'), which: [
+ check('HiT').isRejectedBy((it) => it.equalsIgnoringCase('hAt'), which: [
'differs at offset 1:',
'hAt',
'HiT',
@@ -149,34 +164,36 @@
group('equalsIgnoringWhitespace', () {
test('allows differing internal whitespace', () {
- checkThat('foo \t\n bar').equalsIgnoringWhitespace('foo bar');
+ check('foo \t\n bar').equalsIgnoringWhitespace('foo bar');
});
test('allows extra leading/trailing whitespace', () {
- checkThat(' foo ').equalsIgnoringWhitespace('foo');
+ check(' foo ').equalsIgnoringWhitespace('foo');
});
test('allows missing leading/trailing whitespace', () {
- checkThat('foo').equalsIgnoringWhitespace(' foo ');
+ check('foo').equalsIgnoringWhitespace(' foo ');
});
test('reports original extra characters for long string', () {
- checkThat('foo \t bar \n baz')
- .isRejectedBy(it()..equalsIgnoringWhitespace('foo bar'), which: [
- 'is too long with unexpected trailing characters:',
- ' baz'
- ]);
+ check('foo \t bar \n baz').isRejectedBy(
+ (it) => it.equalsIgnoringWhitespace('foo bar'),
+ which: [
+ 'is too long with unexpected trailing characters:',
+ ' baz'
+ ]);
});
test('reports original missing characters for short string', () {
- checkThat('foo bar').isRejectedBy(
- it()..equalsIgnoringWhitespace('foo bar baz'),
+ check('foo bar').isRejectedBy(
+ (it) => it.equalsIgnoringWhitespace('foo bar baz'),
which: ['is too short with missing trailing characters:', ' baz']);
});
test('reports index of different character with original characters', () {
- checkThat('x hit x')
- .isRejectedBy(it()..equalsIgnoringWhitespace('x hat x'), which: [
- 'differs at offset 3:',
- 'x hat x',
- 'x hit x',
- ' ^',
- ]);
+ check('x hit x').isRejectedBy(
+ (it) => it.equalsIgnoringWhitespace('x hat x'),
+ which: [
+ 'differs at offset 3:',
+ 'x hat x',
+ 'x hit x',
+ ' ^',
+ ]);
});
});
});
diff --git a/pkgs/checks/test/failure_message_test.dart b/pkgs/checks/test/failure_message_test.dart
index 0c6fbb7..217d287 100644
--- a/pkgs/checks/test/failure_message_test.dart
+++ b/pkgs/checks/test/failure_message_test.dart
@@ -5,8 +5,8 @@
void main() {
group('failures', () {
test('includes expected, actual, and which', () {
- checkThat(() {
- checkThat(1).isGreaterThan(2);
+ check(() {
+ check(1).isGreaterThan(2);
}).throwsFailure().equals('''
Expected: a int that:
is greater than <2>
@@ -15,8 +15,8 @@
});
test('includes matching portions of actual', () {
- checkThat(() {
- checkThat([]).length.equals(1);
+ check(() {
+ check([]).length.equals(1);
}).throwsFailure().equals('''
Expected: a List<dynamic> that:
has length that:
@@ -28,20 +28,20 @@
});
test('include a reason when provided', () {
- checkThat(() {
- checkThat(because: 'Some reason', 1).isGreaterThan(2);
+ check(() {
+ check(because: 'Some reason', 1).isGreaterThan(2);
}).throwsFailure().endsWith('Reason: Some reason');
});
test('retain type label following isNotNull', () {
- checkThat(() {
- checkThat<int?>(1).isNotNull().isGreaterThan(2);
+ check(() {
+ check<int?>(1).isNotNull().isGreaterThan(2);
}).throwsFailure().startsWith('Expected: a int? that:\n');
});
test('retain reason following isNotNull', () {
- checkThat(() {
- checkThat<int?>(because: 'Some reason', 1).isNotNull().isGreaterThan(2);
+ check(() {
+ check<int?>(because: 'Some reason', 1).isNotNull().isGreaterThan(2);
}).throwsFailure().endsWith('Reason: Some reason');
});
});
diff --git a/pkgs/checks/test/soft_check_test.dart b/pkgs/checks/test/soft_check_test.dart
new file mode 100644
index 0000000..87c9b27
--- /dev/null
+++ b/pkgs/checks/test/soft_check_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:checks/checks.dart';
+import 'package:test/scaffolding.dart';
+
+import 'test_shared.dart';
+
+void main() {
+ group('softCheck', () {
+ test('returns the first failure', () {
+ check(0).isRejectedBy(
+ (it) => it
+ ..isGreaterThan(1)
+ ..isGreaterThan(2),
+ which: ['is not greater than <1>']);
+ });
+ });
+ group('softCheckAsync', () {
+ test('returns the first failure', () async {
+ check(Future.value(0)).isRejectedByAsync(
+ (it) => it
+ ..completes((it) => it.isGreaterThan(1))
+ ..completes((it) => it.isGreaterThan(2)),
+ actual: ['<0>'],
+ which: ['is not greater than <1>']);
+ });
+ });
+}
diff --git a/pkgs/checks/test/test_shared.dart b/pkgs/checks/test/test_shared.dart
index 325c632..87401ca 100644
--- a/pkgs/checks/test/test_shared.dart
+++ b/pkgs/checks/test/test_shared.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:async';
+
import 'package:checks/checks.dart';
import 'package:checks/context.dart';
@@ -10,8 +12,8 @@
{Iterable<String>? actual, Iterable<String>? which}) {
late T actualValue;
var didRunCallback = false;
- final rejection = context
- .nest<Rejection>('does not meet a condition with a Rejection', (value) {
+ final rejection = context.nest<Rejection>(
+ () => ['does not meet a condition with a Rejection'], (value) {
actualValue = value;
didRunCallback = true;
final failure = softCheck(value, condition);
@@ -44,8 +46,9 @@
{Iterable<String>? actual, Iterable<String>? which}) async {
late T actualValue;
var didRunCallback = false;
- final rejection = (await context.nestAsync<Rejection>(
- 'does not meet an async condition with a Rejection', (value) async {
+ await context.nestAsync<Rejection>(
+ () => ['does not meet an async condition with a Rejection'],
+ (value) async {
actualValue = value;
didRunCallback = true;
final failure = await softCheckAsync(value, condition);
@@ -56,31 +59,34 @@
]);
}
return Extracted.value(failure.rejection);
- }));
- if (didRunCallback) {
- rejection
- .has((r) => r.actual, 'actual')
- .deepEquals(actual ?? literal(actualValue));
- } else {
- rejection
- .has((r) => r.actual, 'actual')
- .context
- .expect(() => ['is left default'], (_) => null);
- }
- if (which == null) {
- rejection.has((r) => r.which, 'which').isNull();
- } else {
- rejection.has((r) => r.which, 'which').isNotNull().deepEquals(which);
- }
+ }, (rejection) {
+ if (didRunCallback) {
+ rejection
+ .has((r) => r.actual, 'actual')
+ .deepEquals(actual ?? literal(actualValue));
+ } else {
+ rejection
+ .has((r) => r.actual, 'actual')
+ .context
+ .expect(() => ['is left default'], (_) => null);
+ }
+ if (which == null) {
+ rejection.has((r) => r.which, 'which').isNull();
+ } else {
+ rejection.has((r) => r.which, 'which').isNotNull().deepEquals(which);
+ }
+ });
}
}
extension ConditionChecks<T> on Subject<Condition<T>> {
Subject<Iterable<String>> get description =>
has((c) => describe<T>(c), 'description');
- Future<Subject<Iterable<String>>> get asyncDescription async =>
+ Future<void> hasAsyncDescriptionWhich(
+ Condition<Iterable<String>> descriptionCondition) =>
context.nestAsync(
- 'has description',
+ () => ['has description'],
(condition) async =>
- Extracted.value(await describeAsync<T>(condition)));
+ Extracted.value(await describeAsync<T>(condition)),
+ descriptionCondition);
}
diff --git a/pkgs/test/CHANGELOG.md b/pkgs/test/CHANGELOG.md
index 2a5651c..8e3b429 100644
--- a/pkgs/test/CHANGELOG.md
+++ b/pkgs/test/CHANGELOG.md
@@ -1,9 +1,86 @@
-## 1.23.0-dev
+## 1.24.7-wip
+
+* Simplify the initialization of the per-suite message channel within browser
+ tests. See https://github.com/dart-lang/test/issues/2065
+* Add a timeout to browser test suite loads.
+
+## 1.24.6
+
+* Fix communication failures between minified test apps and the non-minified
+ host app.
+* Add support for discontinuing after the first failing test with `--fail-fast`.
+
+## 1.24.5
+
+* Change `compiling <path>` to `loading <path>` message in all cases. Surface
+ the "loading" messages in the situations where previously only the
+ "compiling" message would be used.
+* Support browser tests where the frame creates the message channel.
+
+## 1.24.4
+
+* Drop support for null unsafe Dart, bump SDK constraint to `3.0.0`.
+* Make some annotation classes `final`: `OnPlatform`, `Retry`, `Skip`, `Tags`,
+ `TestOn`, `Timeout`.
+* Fix the `root_` fields in the JSON reporter when running a test on Windows
+ with an absolute path.
+* Add support for `SAFARI_EXECUTABLE`, `FIREFOX_EXECUTABLE` and
+ `MS_EDGE_EXECUTABLE` for custom browser installations.
+* Allow the latest analyzer (6.x.x).
+* Add `MOZ_AUTOMATION=1` environmental variable to Firefox runner, to make
+ launcher process on Windows wait for browser exit.
+
+## 1.24.3
+
+* Fix compatibility with wasm number semantics.
+
+## 1.24.2
+
+* Copy an existing nonce from a script on the test HTML page to the script
+ created by the test runner host javascript. This only impacts environments
+ testing with custom HTML that includes a nonce.
+* Support the Microsoft Edge browser (use the `edge` platform in your test
+ configuration file or `-p edge` on the command line).
+
+## 1.24.1
+
+* Handle a missing `'compiler'` value when running a test compiled against a
+ newer `test_api` than the runner back end is using. The expectation was that
+ the json protocol is only used across packages compatible with the same major
+ version of the `test_api` package, but `flutter test` does not check the
+ version of packages in the pub solve for user test code.
+
+## 1.24.0
+
+* Support the `--compiler` flag, which can be used to configure which compiler
+ to use.
+ * To specify a compiler by platform, the argument supports platform selectors
+ through this syntax `[<platform>:]<compiler>`. For example the command line
+ argument `--compiler vm:source` would run all vm tests from source instead
+ of compiling to kernel first.
+ * If no given compiler is compatible for a platform, it will use its default
+ compiler instead.
+* Add support for running tests as native executables (vm platform only).
+ * You can run tests this way with `--compiler exe`.
+* Support compiler identifiers in platform selectors.
+* List the supported compilers for each platform in the usage text.
+* Update all reporters to print the compiler along with the platform name
+ when configured to print the platform. Extend the logic for printing platofrm
+ information to do so if any compilers are explicitly configured.
+* Deprecate `--use-data-isolate-strategy`. It is now an alias for `-c vm:source`
+ which is roughly equivalent. If this is breaking for you please file an issue.
+
+## 1.23.1
+
+* Fix running paths by absolute path (with drive letter) on windows.
+
+## 1.23.0
* Avoid empty expandable groups for tests without extra output in Github
reporter.
* Add support for CHROME_EXECUTABLE environment variable. This overrides any
config file settings.
+* Support running tests by absolute file uri.
## 1.22.2
diff --git a/pkgs/test/README.md b/pkgs/test/README.md
index 14db941..4bc1c82 100644
--- a/pkgs/test/README.md
+++ b/pkgs/test/README.md
@@ -1,15 +1,20 @@
-[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/dart-lang/test/badge)](https://api.securityscorecards.dev/projects/github.com/dart-lang/test)
+[![pub package](https://img.shields.io/pub/v/test.svg)](https://pub.dev/packages/test)
+[![package publisher](https://img.shields.io/pub/publisher/test.svg)](https://pub.dev/packages/test/publisher)
`test` provides a standard way of writing and running tests in Dart.
+## Using package:test
+
* [Writing Tests](#writing-tests)
* [Running Tests](#running-tests)
* [Sharding Tests](#sharding-tests)
+ * [Test Concurrency](#test-concurrency)
* [Shuffling Tests](#shuffling-tests)
* [Selecting a Test Reporter](#selecting-a-test-reporter)
* [Collecting Code Coverage](#collecting-code-coverage)
* [Restricting Tests to Certain Platforms](#restricting-tests-to-certain-platforms)
* [Platform Selectors](#platform-selectors)
+ * [Compiler Selectors](#compiler-selectors)
* [Running Tests on Node.js](#running-tests-on-nodejs)
* [Asynchronous Tests](#asynchronous-tests)
* [Stream Matchers](#stream-matchers)
@@ -30,12 +35,12 @@
## Writing Tests
-Tests are specified using the top-level [`test()`] function, and test assertions
-are made using [`expect()`]:
+Tests are specified using the top-level [`test()`] function.
+Test asserts can be made using [`expect` from `package:matcher`][expect]
[`test()`]: https://pub.dev/documentation/test_core/latest/test_core.scaffolding/test.html
-[`expect()`]: https://pub.dev/documentation/test_api/latest/expect/expect.html
+[expect]: https://pub.dev/documentation/matcher/latest/expect/expect.html
```dart
import 'package:test/test.dart';
@@ -86,42 +91,6 @@
}
```
-Any matchers from the [`matcher`] package can be used with `expect()` to do
-complex validations:
-
-[`matcher`]: https://pub.dev/documentation/matcher/latest/matcher/matcher-library.html
-
-```dart
-import 'package:test/test.dart';
-
-void main() {
- test('.split() splits the string on the delimiter', () {
- expect('foo,bar,baz', allOf([
- contains('foo'),
- isNot(startsWith('bar')),
- endsWith('baz')
- ]));
- });
-}
-```
-
-You can also test exceptions with the [`throwsA()`] function or a matcher
-such as [`throwsFormatException`]:
-
-[`throwsA()`]: https://pub.dev/documentation/test_api/latest/expect/throwsA.html
-
-[`throwsFormatException`]: https://pub.dev/documentation/test_api/latest/expect/throwsFormatException-constant.html
-
-```dart
-import 'package:test/test.dart';
-
-void main() {
- test('.parse() fails on invalid input', () {
- expect(() => int.parse('X'), throwsFormatException);
- });
-}
-```
-
You can use the [`setUp()`] and [`tearDown()`] functions to share code between
tests. The `setUp()` callback will run before every test in a group or test
suite, and `tearDown()` will run after. `tearDown()` will run even if a test
@@ -167,9 +136,14 @@
path/to/test.dart`, but this doesn't load the full test runner and will be
missing some features.
-The test runner considers any file that ends with `_test.dart` to be a test
-file. If you don't pass any paths, it will run all the test files in your
-`test/` directory, making it easy to test your entire application at once.
+The test runner accepts one or more path arguments. If there are no path
+arguments the runner defaults to running tests under the `test/` directory. When
+running for `test/` or any other directory, the runner will recursively search
+the directory for files that match the test name pattern `*_test.dart`. The
+pattern can be overridden in `dart_test.yaml`. When a path argument is a file
+instead of a directory it will be run as a test, regardless of the file name.
+Arguments which use shell globbing should avoid including non-test files in the
+path argument.
You can select specific tests cases to run by name using `dart test -n "test
name"`. The string is interpreted as a regular expression, and only tests whose
@@ -184,6 +158,12 @@
tests on both platforms with a single command: `dart test -p "chrome,vm"
path/to/test.dart`.
+By default each platform has a default compiler, but some of them support
+more than one compiler. You can choose which compiler to use by passing
+`dart test -c source`, which would run all VM tests from source instead of
+compiling them to kernel. This also supports targeting a specific platform
+using normal platform selectors, like this `dart test -c vm:source`.
+
### Test Path Queries
Some query parameters are supported on test paths, which allow you to filter the
@@ -223,6 +203,26 @@
dart test --total-shards 3 --shard-index 1 path/to/test.dart
dart test --total-shards 3 --shard-index 2 path/to/test.dart
```
+Sharding: This refers to the process of splitting up a large test suite into
+smaller subsets (called shards) that can be run independently. Sharding is
+particularly useful for distributed testing, where multiple machines are used
+to run tests simultaneously. By dividing the test suite into smaller subsets,
+you can run tests in parallel across multiple machines, which can significantly
+reduce the overall testing time.
+
+### Test concurrency
+
+Test suites run concurrently by default, using half of the host's CPU cores. Use
+`--concurrency` to control the number of test suites that runs concurrently,
+meaning that multiple tests in independent suites or platforms can run at the
+same time. For example, if you wanted to run the tests on 4 threads, you could
+run the tests as follows:
+
+```bash
+dart test --concurrency=4
+```
+This can speed up the overall testing process, especially if you have a large
+number of test suites.
### Shuffling Tests
@@ -381,6 +381,14 @@
* `posix`: Whether the test is running on a POSIX operating system. This is
equivalent to `!windows`.
+* `dart2js`: Whether the test has been compiled with Dart2Js.
+
+* `dart2wasm`: Whether the test has been compiled with Dart2Wasm.
+
+* `kernel`: Whether the test has been compiled to kernel.
+
+* `source`: Whether the test has been run with no compiler (from source).
+
For example, if you wanted to run a test on every browser but Chrome, you would
write `@TestOn('browser && !chrome')`.
@@ -439,189 +447,6 @@
[early-handler]:https://dart.dev/guides/libraries/futures-error-handling#potential-problem-failing-to-register-error-handlers-early
-### Future Matchers
-
-There are a number of useful functions and matchers for more advanced
-asynchrony. The [`completion()`] matcher can be used to test `Futures`; it
-ensures that the test doesn't finish until the `Future` completes, and runs a
-matcher against that `Future`'s value.
-
-[`completion()`]: https://pub.dev/documentation/test_api/latest/expect/completion.html
-
-```dart
-import 'dart:async';
-
-import 'package:test/test.dart';
-
-void main() {
- test('Future.value() returns the value', () {
- expect(Future.value(10), completion(equals(10)));
- });
-}
-```
-
-The [`throwsA()`] matcher and the various [`throwsExceptionType`] matchers work
-with both synchronous callbacks and asynchronous `Future`s. They ensure that a
-particular type of exception is thrown:
-
-[`throwsExceptionType`]: https://pub.dev/documentation/test_api/latest/expect/throwsException-constant.html
-
-```dart
-import 'dart:async';
-
-import 'package:test/test.dart';
-
-void main() {
- test('Future.error() throws the error', () {
- expect(Future.error('oh no'), throwsA(equals('oh no')));
- expect(Future.error(StateError('bad state')), throwsStateError);
- });
-}
-```
-
-The [`expectAsync()`] function wraps another function and has two jobs. First,
-it asserts that the wrapped function is called a certain number of times, and
-will cause the test to fail if it's called too often; second, it keeps the test
-from finishing until the function is called the requisite number of times.
-
-```dart
-import 'dart:async';
-
-import 'package:test/test.dart';
-
-void main() {
- test('Stream.fromIterable() emits the values in the iterable', () {
- var stream = Stream.fromIterable([1, 2, 3]);
-
- stream.listen(expectAsync1((number) {
- expect(number, inInclusiveRange(1, 3));
- }, count: 3));
- });
-}
-```
-
-[`expectAsync()`]: https://pub.dev/documentation/test_api/latest/test_api/expectAsync.html
-
-### Stream Matchers
-
-The `test` package provides a suite of powerful matchers for dealing with
-[asynchronous streams][Stream]. They're expressive and composable, and make it
-easy to write complex expectations about the values emitted by a stream. For
-example:
-
-[Stream]: https://api.dart.dev/stable/dart-async/Stream-class.html
-
-```dart
-import 'dart:async';
-
-import 'package:test/test.dart';
-
-void main() {
- test('process emits status messages', () {
- // Dummy data to mimic something that might be emitted by a process.
- var stdoutLines = Stream.fromIterable([
- 'Ready.',
- 'Loading took 150ms.',
- 'Succeeded!'
- ]);
-
- expect(stdoutLines, emitsInOrder([
- // Values match individual events.
- 'Ready.',
-
- // Matchers also run against individual events.
- startsWith('Loading took'),
-
- // Stream matchers can be nested. This asserts that one of two events are
- // emitted after the "Loading took" line.
- emitsAnyOf(['Succeeded!', 'Failed!']),
-
- // By default, more events are allowed after the matcher finishes
- // matching. This asserts instead that the stream emits a done event and
- // nothing else.
- emitsDone
- ]));
- });
-}
-```
-
-A stream matcher can also match the [`async`] package's [`StreamQueue`] class,
-which allows events to be requested from a stream rather than pushed to the
-consumer. The matcher will consume the matched events, but leave the rest of the
-queue alone so that it can still be used by the test, unlike a normal `Stream`
-which can only have one subscriber. For example:
-
-[`async`]: https://pub.dev/packages/async
-
-[`StreamQueue`]: https://pub.dev/documentation/async/latest/async/StreamQueue-class.html
-
-```dart
-import 'dart:async';
-
-import 'package:async/async.dart';
-import 'package:test/test.dart';
-
-void main() {
- test('process emits a WebSocket URL', () async {
- // Wrap the Stream in a StreamQueue so that we can request events.
- var stdout = StreamQueue(Stream.fromIterable([
- 'WebSocket URL:',
- 'ws://localhost:1234/',
- 'Waiting for connection...'
- ]));
-
- // Ignore lines from the process until it's about to emit the URL.
- await expectLater(stdout, emitsThrough('WebSocket URL:'));
-
- // Parse the next line as a URL.
- var url = Uri.parse(await stdout.next);
- expect(url.host, equals('localhost'));
-
- // You can match against the same StreamQueue multiple times.
- await expectLater(stdout, emits('Waiting for connection...'));
- });
-}
-```
-
-The following built-in stream matchers are available:
-
-* [`emits()`] matches a single data event.
-* [`emitsError()`] matches a single error event.
-* [`emitsDone`] matches a single done event.
-* [`mayEmit()`] consumes events if they match an inner matcher, without
- requiring them to match.
-* [`mayEmitMultiple()`] works like `mayEmit()`, but it matches events against
- the matcher as many times as possible.
-* [`emitsAnyOf()`] consumes events matching one (or more) of several possible
- matchers.
-* [`emitsInOrder()`] consumes events matching multiple matchers in a row.
-* [`emitsInAnyOrder()`] works like `emitsInOrder()`, but it allows the matchers
- to match in any order.
-* [`neverEmits()`] matches a stream that finishes *without* matching an inner
- matcher.
-
-You can also define your own custom stream matchers with [`StreamMatcher()`].
-
-[`emits()`]: https://pub.dev/documentation/test_api/latest/expect/emits.html
-
-[`emitsError()`]: https://pub.dev/documentation/test_api/latest/expect/emitsError.html
-
-[`emitsDone`]: https://pub.dev/documentation/test_api/latest/expect/emitsDone.html
-
-[`mayEmit()`]: https://pub.dev/documentation/test_api/latest/expect/mayEmit.html
-
-[`mayEmitMultiple()`]: https://pub.dev/documentation/test_api/latest/expect/mayEmitMultiple.html
-
-[`emitsAnyOf()`]: https://pub.dev/documentation/test_api/latest/expect/emitsAnyOf.html
-
-[`emitsInOrder()`]: https://pub.dev/documentation/test_api/latest/expect/emitsInOrder.html
-
-[`emitsInAnyOrder()`]: https://pub.dev/documentation/test_api/latest/expect/emitsInAnyOrder.html
-
-[`neverEmits()`]: https://pub.dev/documentation/test_api/latest/expect/neverEmits.html
-
-[`StreamMatcher()`]: https://pub.dev/documentation/test_api/latest/expect/StreamMatcher-class.html
-
## Running Tests With Custom HTML
By default, the test runner will generate its own empty HTML file for browser
@@ -914,9 +739,9 @@
Tests can be debugged interactively using platforms' built-in development tools.
Tests running on browsers can use those browsers' development consoles to inspect
the document, set breakpoints, and step through code. Those running on the Dart
-VM use [the Dart Observatory][observatory]'s .
+VM use [Dart DevTools][devtools].
-[observatory]: https://dart-lang.github.io/observatory/
+[devtools]: https://dart.dev/tools/dart-devtools
The first step when debugging is to pass the `--pause-after-load` flag to the
test runner. This pauses the browser after each test suite has loaded, so that
diff --git a/pkgs/test/dart_test.yaml b/pkgs/test/dart_test.yaml
index 68ba562..d51aebf 100644
--- a/pkgs/test/dart_test.yaml
+++ b/pkgs/test/dart_test.yaml
@@ -43,6 +43,9 @@
add_tags: [dart2js]
test_on: windows
skip: https://github.com/dart-lang/test/issues/1614
+ edge:
+ add_tags: [dart2js]
+ test_on: windows
# Tests that run pub. These tests may need to be excluded when there are local
# dependency_overrides.
diff --git a/pkgs/test/doc/architecture.md b/pkgs/test/doc/architecture.md
index 7f9843a..110b51f 100644
--- a/pkgs/test/doc/architecture.md
+++ b/pkgs/test/doc/architecture.md
@@ -100,6 +100,7 @@
by printing human-readable text. [`CompactReporter`][CompactReporter] is the
default on Posix platforms, but others may be selected based on the
`Configuration`. Nearly everything the user sees comes through the reporter.
+
[Reporter]: https://github.com/dart-lang/test/tree/master/lib/src/runner/reporter.dart
[CompactReporter]: https://github.com/dart-lang/test/tree/master/lib/src/runner/reporter/compact.dart
diff --git a/pkgs/test/doc/configuration.md b/pkgs/test/doc/configuration.md
index ee8f0a7..509ee1c 100644
--- a/pkgs/test/doc/configuration.md
+++ b/pkgs/test/doc/configuration.md
@@ -121,14 +121,14 @@
### `chain_stack_traces`
-This boolean field controls whether or not stack traces are chained.
+This boolean field controls whether or not stack traces are chained.
Disabling [`stack trace chaining`][stack trace chaining] will improve
-performance for heavily asynchronous code at the cost of debuggability.
+performance for heavily asynchronous code at the cost of debuggability.
[stack trace chaining]: https://github.com/dart-lang/stack_trace/blob/master/README.md#stack-chains
```yaml
-chain_stack_traces: false
+chain_stack_traces: false
```
### `js_trace`
@@ -163,7 +163,7 @@
### `retry`
-This int field controls how many times a test is retried upon failure.
+This int field controls how many times a test is retried upon failure.
```yaml
tags:
@@ -417,6 +417,19 @@
- firefox
```
+### `compilers`
+
+This field indicates which compilers tests should be compiled with by default.
+It allows the same compiler selectors that can be passed to `--compiler`. If
+a given platform has no supported compiler configured, it will use its default.
+
+```yaml
+compilers: [source]
+
+compilers:
+- source
+```
+
### `concurrency`
This field indicates the default number of test suites to run in parallel. More
@@ -511,8 +524,8 @@
```yaml
fold_stack_frames:
except:
- - test
- - stream_channel
+ - test
+ - stream_channel
```
Sample stack trace, note the absence of `package:test`
diff --git a/pkgs/test/lib/dart.js b/pkgs/test/lib/dart.js
index 9b49485..4a090ef 100644
--- a/pkgs/test/lib/dart.js
+++ b/pkgs/test/lib/dart.js
@@ -12,6 +12,7 @@
// This mimics a MultiChannel-formatted message.
var sendLoadException = function(message) {
window.parent.postMessage({
+ // TODO: https://github.com/dart-lang/test/issues/2065 - remove href
"href": window.location.href,
"data": [0, {"type": "loadException", "message": message}],
"exception": true,
@@ -65,7 +66,14 @@
var message = "Failed to load script at " + script.src +
(event.message ? ": " + event.message : ".");
sendLoadException(message);
-}
+};
+
+Array.from(document.querySelectorAll('script')).some(currentScript => {
+ if (currentScript.nonce) {
+ script.nonce = currentScript.nonce;
+ return true;
+ }
+});
var parent = link.parentNode;
document.currentScript = script;
diff --git a/pkgs/test/lib/expect.dart b/pkgs/test/lib/expect.dart
index 28f64f7..5e62622 100644
--- a/pkgs/test/lib/expect.dart
+++ b/pkgs/test/lib/expect.dart
@@ -2,4 +2,4 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-export 'package:test_api/expect.dart';
+export 'package:matcher/expect.dart';
diff --git a/pkgs/test/lib/src/executable.dart b/pkgs/test/lib/src/executable.dart
index 7daa8fd..6202c5a 100644
--- a/pkgs/test/lib/src/executable.dart
+++ b/pkgs/test/lib/src/executable.dart
@@ -12,16 +12,17 @@
import 'runner/wasm/platform.dart';
Future<void> main(List<String> args) async {
- registerPlatformPlugin([Runtime.nodeJS], () => NodePlatform());
+ registerPlatformPlugin([Runtime.nodeJS], NodePlatform.new);
registerPlatformPlugin([
Runtime.chrome,
+ Runtime.edge,
Runtime.firefox,
Runtime.safari,
Runtime.internetExplorer
- ], () => BrowserPlatform.start());
+ ], BrowserPlatform.start);
registerPlatformPlugin([
Runtime.experimentalChromeWasm,
- ], () => BrowserWasmPlatform.start());
+ ], BrowserWasmPlatform.start);
await executable.main(args);
}
diff --git a/pkgs/test/lib/src/runner/browser/browser.dart b/pkgs/test/lib/src/runner/browser/browser.dart
index 12f7fb8..be6d747 100644
--- a/pkgs/test/lib/src/runner/browser/browser.dart
+++ b/pkgs/test/lib/src/runner/browser/browser.dart
@@ -8,7 +8,6 @@
import 'package:test_core/src/runner/application_exception.dart'; // ignore: implementation_imports
import 'package:test_core/src/util/errors.dart'; // ignore: implementation_imports
-import 'package:typed_data/typed_data.dart';
/// An interface for running browser instances.
///
@@ -21,12 +20,6 @@
abstract class Browser {
String get name;
- /// The Observatory URL for this browser.
- ///
- /// This will complete to `null` for browsers that aren't running the Dart VM,
- /// or if the Observatory URL can't be found.
- Future<Uri?> get observatoryUrl async => null;
-
/// The remote debugger URL for this browser.
///
/// This will complete to `null` for browsers that don't support remote
@@ -50,9 +43,9 @@
final _onExitCompleter = Completer<void>();
/// Standard IO streams for the underlying browser process.
- final _ioSubscriptions = <StreamSubscription<List<int>>>[];
+ final _ioSubscriptions = <StreamSubscription<String>>[];
- final output = Uint8Buffer();
+ final output = <String>[];
/// Creates a new browser.
///
@@ -70,8 +63,10 @@
void drainOutput(Stream<List<int>> stream) {
try {
- _ioSubscriptions
- .add(stream.listen(output.addAll, cancelOnError: true));
+ _ioSubscriptions.add(stream
+ .transform(utf8.decoder)
+ .transform(const LineSplitter())
+ .listen(output.add, cancelOnError: true));
} on StateError catch (_) {}
}
@@ -96,7 +91,7 @@
}
if (!_closed && exitCode != 0) {
- var outputString = utf8.decode(output);
+ var outputString = output.join('\n');
var message = '$name failed with exit code $exitCode.';
if (outputString.isNotEmpty) {
message += '\nStandard output:\n$outputString';
diff --git a/pkgs/test/lib/src/runner/browser/browser_manager.dart b/pkgs/test/lib/src/runner/browser/browser_manager.dart
index b5d2abb..c38e103 100644
--- a/pkgs/test/lib/src/runner/browser/browser_manager.dart
+++ b/pkgs/test/lib/src/runner/browser/browser_manager.dart
@@ -8,11 +8,11 @@
import 'package:async/async.dart';
import 'package:pool/pool.dart';
import 'package:stream_channel/stream_channel.dart';
-// ignore: deprecated_member_use
-import 'package:test_api/backend.dart' show Runtime, StackTraceMapper;
+import 'package:test_api/backend.dart' show Compiler, Runtime, StackTraceMapper;
import 'package:test_core/src/runner/application_exception.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/environment.dart'; // ignore: implementation_imports
+import 'package:test_core/src/runner/load_exception.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/plugin/platform_helpers.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/runner_suite.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports
@@ -24,6 +24,7 @@
import 'chrome.dart';
import 'firefox.dart';
import 'internet_explorer.dart';
+import 'microsoft_edge.dart';
import 'safari.dart';
/// A class that manages the connection to a single running browser.
@@ -142,7 +143,7 @@
if (attempt >= _maxRetries) {
throw ApplicationException(
'Timed out waiting for ${runtime.name} to connect.\n'
- 'Browser output: ${utf8.decode(browser.output)}');
+ 'Browser output: ${browser.output.join('\n')}');
}
return _start(runtime, url, future, settings, configuration, ++attempt);
});
@@ -152,21 +153,17 @@
///
/// If [debug] is true, starts the browser in debug mode.
static Browser _newBrowser(Uri url, Runtime browser,
- ExecutableSettings settings, Configuration configuration) {
- switch (browser.root) {
- case Runtime.chrome:
- case Runtime.experimentalChromeWasm:
- return Chrome(url, configuration, settings: settings);
- case Runtime.firefox:
- return Firefox(url, settings: settings);
- case Runtime.safari:
- return Safari(url, settings: settings);
- case Runtime.internetExplorer:
- return InternetExplorer(url, settings: settings);
- default:
- throw ArgumentError('$browser is not a browser.');
- }
- }
+ ExecutableSettings settings, Configuration configuration) =>
+ switch (browser.root) {
+ Runtime.chrome ||
+ Runtime.experimentalChromeWasm =>
+ Chrome(url, configuration, settings: settings),
+ Runtime.firefox => Firefox(url, settings: settings),
+ Runtime.safari => Safari(url, settings: settings),
+ Runtime.internetExplorer => InternetExplorer(url, settings: settings),
+ Runtime.edge => MicrosoftEdge(url, configuration, settings: settings),
+ _ => throw ArgumentError('$browser is not a browser.'),
+ };
/// Creates a new BrowserManager that communicates with [browser] over
/// [webSocket].
@@ -205,10 +202,9 @@
}
/// Loads [_BrowserEnvironment].
- Future<_BrowserEnvironment> _loadBrowserEnvironment() async {
- return _BrowserEnvironment(this, await _browser.observatoryUrl,
- await _browser.remoteDebuggerUrl, _onRestartController.stream);
- }
+ Future<_BrowserEnvironment> _loadBrowserEnvironment() async =>
+ _BrowserEnvironment(
+ this, await _browser.remoteDebuggerUrl, _onRestartController.stream);
/// Tells the browser the load a test suite from the URL [url].
///
@@ -219,12 +215,13 @@
/// If [mapper] is passed, it's used to map stack traces for errors coming
/// from this test suite.
Future<RunnerSuite> load(String path, Uri url, SuiteConfiguration suiteConfig,
- Map<String, Object?> message,
- {StackTraceMapper? mapper}) async {
+ Map<String, Object?> message, Compiler compiler,
+ {StackTraceMapper? mapper, Duration? timeout}) async {
url = url.replace(
fragment: Uri.encodeFull(jsonEncode({
'metadata': suiteConfig.metadata.serialize(),
- 'browser': _runtime.identifier
+ 'browser': _runtime.identifier,
+ 'compiler': compiler.serialize(),
})));
var suiteID = _suiteID++;
@@ -245,7 +242,7 @@
sink.close();
}));
- return await _pool.withResource<RunnerSuite>(() async {
+ var suite = _pool.withResource<RunnerSuite>(() async {
_channel.sink.add({
'command': 'loadSuite',
'url': url.toString(),
@@ -256,7 +253,7 @@
try {
controller = deserializeSuite(
path,
- currentPlatform(_runtime),
+ currentPlatform(_runtime, compiler),
suiteConfig,
await _environment,
suiteChannel.cast(),
@@ -278,6 +275,15 @@
rethrow;
}
});
+ if (timeout != null) {
+ suite = suite.timeout(timeout, onTimeout: () {
+ throw LoadException(
+ path,
+ 'Timed out waiting for browser to load test suite. '
+ 'Browser output: ${_browser.output.join('\n')}');
+ });
+ }
+ return suite;
}
/// An implementation of [Environment.displayPause].
@@ -342,7 +348,7 @@
final supportsDebugging = true;
@override
- final Uri? observatoryUrl;
+ Null get observatoryUrl => null;
@override
final Uri? remoteDebuggerUrl;
@@ -350,8 +356,7 @@
@override
final Stream<void> onRestart;
- _BrowserEnvironment(this._manager, this.observatoryUrl,
- this.remoteDebuggerUrl, this.onRestart);
+ _BrowserEnvironment(this._manager, this.remoteDebuggerUrl, this.onRestart);
@override
CancelableOperation<void> displayPause() => _manager._displayPause();
diff --git a/pkgs/test/lib/src/runner/browser/chrome.dart b/pkgs/test/lib/src/runner/browser/chrome.dart
index 0feb397..a67b8ee 100644
--- a/pkgs/test/lib/src/runner/browser/chrome.dart
+++ b/pkgs/test/lib/src/runner/browser/chrome.dart
@@ -16,6 +16,7 @@
import '../executable_settings.dart';
import 'browser.dart';
+import 'chromium.dart';
import 'default_settings.dart';
/// A class for running an instance of Chrome.
@@ -45,39 +46,20 @@
var idToUrl = <String, String>{};
return Chrome._(() async {
Future<Process> tryPort([int? port]) async {
- var dir = createTempDir();
- var args = [
- '--user-data-dir=$dir',
- url.toString(),
- '--enable-logging=stdout',
- '--v=1',
- '--disable-extensions',
- '--disable-popup-blocking',
- '--bwsi',
- '--no-first-run',
- '--no-default-browser-check',
- '--disable-default-apps',
- '--disable-translate',
- '--disable-dev-shm-usage',
- if (settings!.headless && !configuration.pauseAfterLoad) ...[
- '--headless',
- '--disable-gpu',
+ var process = await ChromiumBasedBrowser.chrome.spawn(
+ url,
+ configuration,
+ settings: settings,
+ additionalArgs: [
+ if (port != null)
+ // Chrome doesn't provide any way of ensuring that this port was
+ // successfully bound. It produces an error if the binding fails,
+ // but without a reliable and fast way to tell if it succeeded
+ // that doesn't provide us much. It's very unlikely that this port
+ // will fail, though.
+ '--remote-debugging-port=$port',
],
- if (!configuration.debug)
- // We don't actually connect to the remote debugger, but Chrome will
- // close as soon as the page is loaded if we don't turn it on.
- '--remote-debugging-port=0',
- ...settings.arguments,
- if (port != null)
- // Chrome doesn't provide any way of ensuring that this port was
- // successfully bound. It produces an error if the binding fails,
- // but without a reliable and fast way to tell if it succeeded that
- // doesn't provide us much. It's very unlikely that this port will
- // fail, though.
- '--remote-debugging-port=$port',
- ];
-
- var process = await Process.start(settings.executable, args);
+ );
if (port != null) {
remoteDebuggerCompleter.complete(
@@ -88,9 +70,6 @@
remoteDebuggerCompleter.complete(null);
}
- unawaited(process.exitCode
- .then((_) => Directory(dir).deleteSync(recursive: true)));
-
return process;
}
diff --git a/pkgs/test/lib/src/runner/browser/chromium.dart b/pkgs/test/lib/src/runner/browser/chromium.dart
new file mode 100644
index 0000000..e2a456f
--- /dev/null
+++ b/pkgs/test/lib/src/runner/browser/chromium.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:test/src/runner/browser/default_settings.dart';
+import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
+import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
+import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
+
+import '../executable_settings.dart';
+
+enum ChromiumBasedBrowser {
+ chrome(Runtime.chrome),
+ microsoftEdge(Runtime.edge);
+
+ final Runtime runtime;
+
+ const ChromiumBasedBrowser(this.runtime);
+
+ Future<Process> spawn(
+ Uri url,
+ Configuration configuration, {
+ ExecutableSettings? settings,
+ List<String> additionalArgs = const [],
+ }) async {
+ settings ??= defaultSettings[runtime];
+
+ var dir = createTempDir();
+ var args = [
+ '--user-data-dir=$dir',
+ url.toString(),
+ '--enable-logging=stderr',
+ '--v=0',
+ '--disable-extensions',
+ '--disable-popup-blocking',
+ '--bwsi',
+ '--no-first-run',
+ '--no-default-browser-check',
+ '--disable-default-apps',
+ '--disable-translate',
+ '--disable-dev-shm-usage',
+ if (settings!.headless && !configuration.pauseAfterLoad) ...[
+ '--headless',
+ '--disable-gpu',
+ ],
+ if (!configuration.debug)
+ // We don't actually connect to the remote debugger, but Chrome will
+ // close as soon as the page is loaded if we don't turn it on.
+ '--remote-debugging-port=0',
+ ...settings.arguments,
+ ...additionalArgs,
+ ];
+
+ var process = await Process.start(settings.executable, args);
+
+ unawaited(process.exitCode.then((_) => Directory(dir).deleteWithRetry()));
+
+ return process;
+ }
+}
diff --git a/pkgs/test/lib/src/runner/browser/default_settings.dart b/pkgs/test/lib/src/runner/browser/default_settings.dart
index d608804..929d777 100644
--- a/pkgs/test/lib/src/runner/browser/default_settings.dart
+++ b/pkgs/test/lib/src/runner/browser/default_settings.dart
@@ -13,13 +13,23 @@
linuxExecutable: 'google-chrome',
macOSExecutable:
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
- windowsExecutable: r'Google\Chrome\Application\chrome.exe'),
+ windowsExecutable: r'Google\Chrome\Application\chrome.exe',
+ environmentOverride: 'CHROME_EXECUTABLE'),
+ Runtime.edge: ExecutableSettings(
+ linuxExecutable: 'microsoft-edge-stable',
+ windowsExecutable: r'Microsoft\Edge\Application\msedge.exe',
+ macOSExecutable:
+ '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
+ environmentOverride: 'MS_EDGE_EXECUTABLE',
+ ),
Runtime.firefox: ExecutableSettings(
linuxExecutable: 'firefox',
macOSExecutable: '/Applications/Firefox.app/Contents/MacOS/firefox-bin',
- windowsExecutable: r'Mozilla Firefox\firefox.exe'),
+ windowsExecutable: r'Mozilla Firefox\firefox.exe',
+ environmentOverride: 'FIREFOX_EXECUTABLE'),
Runtime.internetExplorer:
ExecutableSettings(windowsExecutable: r'Internet Explorer\iexplore.exe'),
Runtime.safari: ExecutableSettings(
- macOSExecutable: '/Applications/Safari.app/Contents/MacOS/Safari')
+ macOSExecutable: '/Applications/Safari.app/Contents/MacOS/Safari',
+ environmentOverride: 'SAFARI_EXECUTABLE'),
});
diff --git a/pkgs/test/lib/src/runner/browser/dom.dart b/pkgs/test/lib/src/runner/browser/dom.dart
index 98ed0e9..2783e92 100644
--- a/pkgs/test/lib/src/runner/browser/dom.dart
+++ b/pkgs/test/lib/src/runner/browser/dom.dart
@@ -11,6 +11,8 @@
class Window extends EventTarget {}
extension WindowExtension on Window {
+ @pragma('dart2js:as:trust')
+ Window get parent => js_util.getProperty<dynamic>(this, 'parent') as Window;
external Location get location;
CSSStyleDeclaration? getComputedStyle(Element elt, [String? pseudoElt]) =>
js_util.callMethod(this, 'getComputedStyle', <Object>[
@@ -85,7 +87,7 @@
external Node appendChild(Node node);
void remove() {
if (parentNode != null) {
- final Node parent = parentNode!;
+ final parent = parentNode!;
parent.removeChild(this);
}
}
@@ -135,10 +137,22 @@
external String get origin;
List<MessagePort> get ports =>
js_util.getProperty<List>(this, 'ports').cast<MessagePort>();
+
+ /// The source may be a `WindowProxy`, a `MessagePort`, or a `ServiceWorker`.
+ ///
+ /// When a message is sent from an iframe through `window.parent.postMessage`
+ /// the source will be a `WindowProxy` which has the same methods as [Window].
+ @pragma('dart2js:as:trust')
+ MessageEventSource get source =>
+ js_util.getProperty<dynamic>(this, 'source') as MessageEventSource;
}
@JS()
@staticInterop
+class MessageEventSource {}
+
+@JS()
+@staticInterop
class Location {}
extension LocationExtension on Location {
@@ -221,7 +235,7 @@
js_util.getProperty(window, constructorName);
Object? _callConstructor(String constructorName, List<Object?> args) {
- final Object? constructor = _findConstructor(constructorName);
+ final constructor = _findConstructor(constructorName);
if (constructor == null) {
return null;
}
diff --git a/pkgs/test/lib/src/runner/browser/firefox.dart b/pkgs/test/lib/src/runner/browser/firefox.dart
index 5b68018..39e1ac5 100644
--- a/pkgs/test/lib/src/runner/browser/firefox.dart
+++ b/pkgs/test/lib/src/runner/browser/firefox.dart
@@ -47,11 +47,11 @@
'--no-remote',
...settings.arguments,
], environment: {
- 'MOZ_CRASHREPORTER_DISABLE': '1'
+ 'MOZ_CRASHREPORTER_DISABLE': '1',
+ 'MOZ_AUTOMATION': '1',
});
- unawaited(process.exitCode
- .then((_) => Directory(dir).deleteSync(recursive: true)));
+ unawaited(process.exitCode.then((_) => Directory(dir).deleteWithRetry()));
return process;
}
diff --git a/pkgs/test/lib/src/runner/browser/microsoft_edge.dart b/pkgs/test/lib/src/runner/browser/microsoft_edge.dart
new file mode 100644
index 0000000..08fa8e2
--- /dev/null
+++ b/pkgs/test/lib/src/runner/browser/microsoft_edge.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
+
+import '../executable_settings.dart';
+import 'browser.dart';
+import 'chromium.dart';
+
+/// A class for running an instance of Microsoft Edge, a Chromium-based browser.
+class MicrosoftEdge extends Browser {
+ @override
+ String get name => 'Edge';
+
+ MicrosoftEdge(Uri url, Configuration configuration,
+ {ExecutableSettings? settings})
+ : super(() => ChromiumBasedBrowser.microsoftEdge.spawn(
+ url,
+ configuration,
+ settings: settings,
+ ));
+}
diff --git a/pkgs/test/lib/src/runner/browser/platform.dart b/pkgs/test/lib/src/runner/browser/platform.dart
index 089a175..55ff255 100644
--- a/pkgs/test/lib/src/runner/browser/platform.dart
+++ b/pkgs/test/lib/src/runner/browser/platform.dart
@@ -15,9 +15,8 @@
import 'package:shelf_packages_handler/shelf_packages_handler.dart';
import 'package:shelf_static/shelf_static.dart';
import 'package:shelf_web_socket/shelf_web_socket.dart';
-// ignore: deprecated_member_use
import 'package:test_api/backend.dart'
- show Runtime, StackTraceMapper, SuitePlatform;
+ show Compiler, Runtime, StackTraceMapper, SuitePlatform;
import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/dart2js_compiler_pool.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/load_exception.dart'; // ignore: implementation_imports
@@ -215,6 +214,14 @@
throw ArgumentError('$browser is not a browser.');
}
+ var compiler = platform.compiler;
+ // Technically, ddc is supported through --precompiled. But we don't expect
+ // any specific compiler setting in that case.
+ if (compiler != Compiler.dart2js) {
+ throw StateError('Unsupported compiler for $browser platform '
+ '$compiler');
+ }
+
var htmlPathFromTestPath = '${p.withoutExtension(path)}.html';
if (File(htmlPathFromTestPath).existsSync()) {
if (_config.customHtmlTemplatePath != null &&
@@ -271,8 +278,14 @@
var browserManager = await _browserManagerFor(browser);
if (_closed || browserManager == null) return null;
- var suite = await browserManager.load(path, suiteUrl, suiteConfig, message,
- mapper: _mappers[path]);
+ var timeout = const Duration(seconds: 30);
+ if (suiteConfig.metadata.timeout.apply(timeout) case final suiteTimeout?
+ when suiteTimeout > timeout) {
+ timeout = suiteTimeout;
+ }
+ var suite = await browserManager.load(
+ path, suiteUrl, suiteConfig, message, platform.compiler,
+ mapper: _mappers[path], timeout: timeout);
if (_closed) return null;
return suite;
}
@@ -463,7 +476,7 @@
]);
if (_config.pubServeUrl == null) {
- Directory(_compiledDir!).deleteSync(recursive: true);
+ await Directory(_compiledDir!).deleteWithRetry();
} else {
_http!.close();
}
diff --git a/pkgs/test/lib/src/runner/browser/post_message_channel.dart b/pkgs/test/lib/src/runner/browser/post_message_channel.dart
index fbb6cfc..fa71d3d 100644
--- a/pkgs/test/lib/src/runner/browser/post_message_channel.dart
+++ b/pkgs/test/lib/src/runner/browser/post_message_channel.dart
@@ -2,60 +2,29 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.runner.browser.post_message_channel;
-
import 'dart:js_util';
-import 'package:js/js.dart';
import 'package:stream_channel/stream_channel.dart';
import 'dom.dart' as dom;
-// Avoid using this from dart:html to work around dart-lang/sdk#32113.
-@JS('window.parent.postMessage')
-external void _postParentMessage(Object message, String targetOrigin);
-
-/// Constructs a [StreamChannel] wrapping [MessageChannel] communication with
-/// the host page.
+/// Constructs a [StreamChannel] wrapping a new [MessageChannel] communicating
+/// with the host page.
+///
+/// Sends a [MessagePort] to the host page for the channel.
StreamChannel<Object?> postMessageChannel() {
var controller = StreamChannelController<Object?>(sync: true);
-
- // Listen for a message from the host that transfers a message port, then
- // cancel the subscription. This is important to prevent multiple
- // subscriptions if the test is ever hot restarted.
- late final dom.Subscription subscription;
- subscription =
- dom.Subscription(dom.window, 'message', allowInterop((dom.Event event) {
- // A message on the Window can theoretically come from any website. It's
- // very unlikely that a malicious site would care about hacking someone's
- // unit tests, let alone be able to find the test server while it's
- // running, but it's good practice to check the origin anyway.
- final message = event as dom.MessageEvent;
- if (message.origin == dom.window.location.origin &&
- message.data == 'port') {
- subscription.cancel();
- var port = message.ports.first;
- port.start();
- var portSubscription =
- dom.Subscription(port, 'message', allowInterop((dom.Event event) {
- controller.local.sink.add((event as dom.MessageEvent).data);
- }));
-
- controller.local.stream.listen((data) {
- port.postMessage({'data': data});
- }, onDone: () {
- port.postMessage({'event': 'done'});
- portSubscription.cancel();
- });
- }
+ var channel = dom.createMessageChannel();
+ dom.window.parent
+ .postMessage('port', dom.window.location.origin, [channel.port2]);
+ var portSubscription = dom.Subscription(channel.port1, 'message',
+ allowInterop((dom.Event event) {
+ controller.local.sink.add((event as dom.MessageEvent).data);
}));
+ channel.port1.start();
- // Send a ready message once we're listening so the host knows it's safe to
- // start sending events.
- // TODO(nweiz): Stop manually adding href here once issue 22554 is fixed.
- _postParentMessage(
- jsify({'href': dom.window.location.href, 'ready': true}) as Object,
- dom.window.location.origin);
+ controller.local.stream
+ .listen(channel.port1.postMessage, onDone: portSubscription.cancel);
return controller.foreign;
}
diff --git a/pkgs/test/lib/src/runner/browser/safari.dart b/pkgs/test/lib/src/runner/browser/safari.dart
index 41cd896..6689a8b 100644
--- a/pkgs/test/lib/src/runner/browser/safari.dart
+++ b/pkgs/test/lib/src/runner/browser/safari.dart
@@ -40,8 +40,7 @@
var process = await Process.start(
settings.executable, settings.arguments.toList()..add(redirect));
- unawaited(process.exitCode
- .then((_) => Directory(dir).deleteSync(recursive: true)));
+ unawaited(process.exitCode.then((_) => Directory(dir).deleteWithRetry()));
return process;
}
diff --git a/pkgs/test/lib/src/runner/browser/static/host.dart.js b/pkgs/test/lib/src/runner/browser/static/host.dart.js
index 86173e4..ff080c0 100644
--- a/pkgs/test/lib/src/runner/browser/static/host.dart.js
+++ b/pkgs/test/lib/src/runner/browser/static/host.dart.js
@@ -1,4 +1,4 @@
-// Generated by dart2js (NullSafetyMode.sound, csp, deferred-serialization, intern-composite-values), the Dart to JavaScript compiler version: 2.19.0-edge.e4643b54dfba2a4362e47874e742cdffa2892171.
+// Generated by dart2js (NullSafetyMode.sound, csp, deferred-serialization, intern-composite-values), the Dart to JavaScript compiler version: 3.2.0-36.0.dev.
// The code supports the following hooks:
// dartPrint(message):
// if this function is defined it is called instead of the Dart [print]
@@ -9,12 +9,14 @@
// directly. Instead, a closure that will invoke [main], and its arguments
// [args] is passed to [dartMainRunner].
//
-// dartDeferredLibraryLoader(uri, successCallback, errorCallback, loadId):
+// dartDeferredLibraryLoader(uri, successCallback, errorCallback, loadId, loadPriority):
// if this function is defined, it will be called when a deferred library
// is loaded. It should load and eval the javascript of `uri`, and call
// successCallback. If it fails to do so, it should call errorCallback with
// an error. The loadId argument is the deferred import that resulted in
-// this uri being loaded.
+// this uri being loaded. The loadPriority argument is the priority the
+// library should be loaded with as specified in the code via the
+// load-priority annotation (0: normal, 1: high).
//
// dartCallInstrumentation(id, qualifiedName):
// if this function is defined, it will be called at each entry of a
@@ -44,7 +46,7 @@
};
cls.prototype = {p: {}};
var object = new cls();
- if (!(object.__proto__ && object.__proto__.p === cls.prototype.p))
+ if (!(Object.getPrototypeOf(object) && Object.getPrototypeOf(object).p === cls.prototype.p))
return false;
try {
if (typeof navigator != "undefined" && typeof navigator.userAgent == "string" && navigator.userAgent.indexOf("Chrome/") >= 0)
@@ -63,7 +65,7 @@
cls.prototype["$is" + cls.name] = cls;
if (sup != null) {
if (supportsDirectProtoAccess) {
- cls.prototype.__proto__ = sup.prototype;
+ Object.setPrototypeOf(cls.prototype, sup.prototype);
return;
}
var clsPrototype = Object.create(sup.prototype);
@@ -236,14 +238,10 @@
}
var A = {JS_CONST: function JS_CONST() {
},
- LateError$fieldADI(fieldName) {
- return new A.LateError("Field '" + fieldName + "' has been assigned during initialization.");
- },
- LateError$fieldNI(fieldName) {
- return new A.LateError("Field '" + fieldName + "' has not been initialized.");
- },
- LateError$fieldAI(fieldName) {
- return new A.LateError("Field '" + fieldName + "' has already been initialized.");
+ CastIterable_CastIterable(source, $S, $T) {
+ if ($S._eval$1("EfficientLengthIterable<0>")._is(source))
+ return new A._EfficientLengthCastIterable(source, $S._eval$1("@<0>")._bind$1($T)._eval$1("_EfficientLengthCastIterable<1,2>"));
+ return new A.CastIterable(source, $S._eval$1("@<0>")._bind$1($T)._eval$1("CastIterable<1,2>"));
},
hexDigitValue(char) {
var letter,
@@ -268,6 +266,13 @@
checkNotNullable(value, $name, $T) {
return value;
},
+ isToStringVisiting(object) {
+ var t1, i;
+ for (t1 = $.toStringVisiting.length, i = 0; i < t1; ++i)
+ if (object === $.toStringVisiting[i])
+ return true;
+ return false;
+ },
SubListIterable$(_iterable, _start, _endOrLength, $E) {
A.RangeError_checkNotNegative(_start, "start");
if (_endOrLength != null) {
@@ -290,6 +295,17 @@
return new A.EfficientLengthTakeIterable(iterable, takeCount, $E._eval$1("EfficientLengthTakeIterable<0>"));
return new A.TakeIterable(iterable, takeCount, $E._eval$1("TakeIterable<0>"));
},
+ SkipIterable_SkipIterable(iterable, count, $E) {
+ var _s5_ = "count";
+ if (type$.EfficientLengthIterable_dynamic._is(iterable)) {
+ A.ArgumentError_checkNotNull(count, _s5_, type$.int);
+ A.RangeError_checkNotNegative(count, _s5_);
+ return new A.EfficientLengthSkipIterable(iterable, count, $E._eval$1("EfficientLengthSkipIterable<0>"));
+ }
+ A.ArgumentError_checkNotNull(count, _s5_, type$.int);
+ A.RangeError_checkNotNegative(count, _s5_);
+ return new A.SkipIterable(iterable, count, $E._eval$1("SkipIterable<0>"));
+ },
IterableElementError_noElement() {
return new A.StateError("No element");
},
@@ -307,6 +323,26 @@
_._handleError = _._handleData = null;
_.$ti = t2;
},
+ _CastIterableBase: function _CastIterableBase() {
+ },
+ CastIterator: function CastIterator(t0, t1) {
+ this._source = t0;
+ this.$ti = t1;
+ },
+ CastIterable: function CastIterable(t0, t1) {
+ this._source = t0;
+ this.$ti = t1;
+ },
+ _EfficientLengthCastIterable: function _EfficientLengthCastIterable(t0, t1) {
+ this._source = t0;
+ this.$ti = t1;
+ },
+ _CastListBase: function _CastListBase() {
+ },
+ CastList: function CastList(t0, t1) {
+ this._source = t0;
+ this.$ti = t1;
+ },
LateError: function LateError(t0) {
this._message = t0;
},
@@ -324,7 +360,7 @@
SubListIterable: function SubListIterable(t0, t1, t2, t3) {
var _ = this;
_.__internal$_iterable = t0;
- _.__internal$_start = t1;
+ _._start = t1;
_._endOrLength = t2;
_.$ti = t3;
},
@@ -396,6 +432,21 @@
this._remaining = t1;
this.$ti = t2;
},
+ SkipIterable: function SkipIterable(t0, t1, t2) {
+ this.__internal$_iterable = t0;
+ this._skipCount = t1;
+ this.$ti = t2;
+ },
+ EfficientLengthSkipIterable: function EfficientLengthSkipIterable(t0, t1, t2) {
+ this.__internal$_iterable = t0;
+ this._skipCount = t1;
+ this.$ti = t2;
+ },
+ SkipIterator: function SkipIterator(t0, t1, t2) {
+ this._iterator = t0;
+ this._skipCount = t1;
+ this.$ti = t2;
+ },
SkipWhileIterable: function SkipWhileIterable(t0, t1, t2) {
this.__internal$_iterable = t0;
this._f = t1;
@@ -408,6 +459,9 @@
_._hasSkipped = false;
_.$ti = t2;
},
+ EmptyIterable: function EmptyIterable(t0) {
+ this.$ti = t0;
+ },
EmptyIterator: function EmptyIterator(t0) {
this.$ti = t0;
},
@@ -432,6 +486,8 @@
Symbol: function Symbol(t0) {
this._name = t0;
},
+ __CastListBase__CastIterableBase_ListMixin: function __CastListBase__CastIterableBase_ListMixin() {
+ },
ConstantMap__throwUnmodifiable() {
throw A.wrapException(A.UnsupportedError$("Cannot modify unmodifiable Map"));
},
@@ -501,7 +557,7 @@
maxCharCode = radix <= 10 ? 47 + radix : 86 + radix;
digitsPart = match[1];
for (t1 = digitsPart.length, i = 0; i < t1; ++i)
- if ((B.JSString_methods._codeUnitAt$1(digitsPart, i) | 32) > maxCharCode)
+ if ((digitsPart.charCodeAt(i) | 32) > maxCharCode)
return _null;
}
return parseInt(source, radix);
@@ -527,6 +583,15 @@
}
return A._rtiToString(A.instanceType(object), null);
},
+ Primitives_safeToString(object) {
+ if (typeof object == "number" || A._isBool(object))
+ return J.toString$0$(object);
+ if (typeof object == "string")
+ return JSON.stringify(object);
+ if (object instanceof A.Closure)
+ return object.toString$0(0);
+ return "Instance of '" + A.Primitives_objectTypeName(object) + "'";
+ },
Primitives_currentUri() {
if (!!self.location)
return self.location.href;
@@ -599,7 +664,7 @@
},
Primitives_lazyAsJsDate(receiver) {
if (receiver.date === void 0)
- receiver.date = new Date(receiver._value);
+ receiver.date = new Date(receiver._core$_value);
return receiver.date;
},
Primitives_getYear(receiver) {
@@ -754,7 +819,7 @@
return new A.ArgumentError(true, index, _s5_, null);
$length = A._asInt(J.get$length$asx(indexable));
if (index < 0 || index >= $length)
- return A.IndexError$(index, indexable, _s5_, null, $length);
+ return A.IndexError$withLength(index, $length, indexable, _s5_);
return A.RangeError$value(index, _s5_);
},
diagnoseRangeError(start, end, $length) {
@@ -769,10 +834,12 @@
return new A.ArgumentError(true, object, null, null);
},
wrapException(ex) {
- var wrapper, t1;
+ return A.initializeExceptionWrapper(new Error(), ex);
+ },
+ initializeExceptionWrapper(wrapper, ex) {
+ var t1;
if (ex == null)
- ex = new A.NullThrownError();
- wrapper = new Error();
+ ex = new A.TypeError();
wrapper.dartException = ex;
t1 = A.toStringWrapper;
if ("defineProperty" in Object) {
@@ -788,6 +855,9 @@
throwExpression(ex) {
throw A.wrapException(ex);
},
+ throwExpressionWithWrapper(ex, wrapper) {
+ throw A.initializeExceptionWrapper(wrapper, ex);
+ },
throwConcurrentModificationError(collection) {
throw A.wrapException(A.ConcurrentModificationError$(collection));
},
@@ -829,13 +899,8 @@
return new A.JsNoSuchMethodError(_message, t2, t1 ? null : match.receiver);
},
unwrapException(ex) {
- var t1;
if (ex == null)
return new A.NullThrownFromJavaScriptException(ex);
- if (ex instanceof A.ExceptionAndStackTrace) {
- t1 = ex.dartException;
- return A.saveStackTrace(ex, t1 == null ? type$.Object._as(t1) : t1);
- }
if (typeof ex !== "object")
return ex;
if ("dartException" in ex)
@@ -943,8 +1008,6 @@
},
getTraceFromException(exception) {
var trace;
- if (exception instanceof A.ExceptionAndStackTrace)
- return exception.stackTrace;
if (exception == null)
return new A._StackTrace(exception);
trace = exception.$cachedTrace;
@@ -953,10 +1016,11 @@
return exception.$cachedTrace = new A._StackTrace(exception);
},
objectHashCode(object) {
- if (object == null || typeof object != "object")
+ if (object == null)
return J.get$hashCode$(object);
- else
+ if (typeof object == "object")
return A.Primitives_objectHashCode(object);
+ return J.get$hashCode$(object);
},
fillLiteralMap(keyValuePairs, result) {
var index, index0, index1,
@@ -968,7 +1032,7 @@
}
return result;
},
- invokeClosure(closure, numberOfArguments, arg1, arg2, arg3, arg4) {
+ _invokeClosure(closure, numberOfArguments, arg1, arg2, arg3, arg4) {
type$.Function._as(closure);
switch (A._asInt(numberOfArguments)) {
case 0:
@@ -985,19 +1049,41 @@
throw A.wrapException(new A._Exception("Unsupported number of arguments for wrapped closure"));
},
convertDartClosureToJS(closure, arity) {
- var $function;
- if (closure == null)
- return null;
- $function = closure.$identity;
+ var $function = closure.$identity;
if (!!$function)
return $function;
- $function = function(closure, arity, invoke) {
+ $function = A.convertDartClosureToJSUncached(closure, arity);
+ closure.$identity = $function;
+ return $function;
+ },
+ convertDartClosureToJSUncached(closure, arity) {
+ var entry;
+ switch (arity) {
+ case 0:
+ entry = closure.call$0;
+ break;
+ case 1:
+ entry = closure.call$1;
+ break;
+ case 2:
+ entry = closure.call$2;
+ break;
+ case 3:
+ entry = closure.call$3;
+ break;
+ case 4:
+ entry = closure.call$4;
+ break;
+ default:
+ entry = null;
+ }
+ if (entry != null)
+ return entry.bind(closure);
+ return function(closure, arity, invoke) {
return function(a1, a2, a3, a4) {
return invoke(closure, arity, a1, a2, a3, a4);
};
- }(closure, arity, A.invokeClosure);
- closure.$identity = $function;
- return $function;
+ }(closure, arity, A._invokeClosure);
},
Closure_fromTearOff(parameters) {
var $prototype, $constructor, t2, trampoline, applyTrampoline, i, stub, stub0, stubName, stubCallName,
@@ -1221,7 +1307,7 @@
throw A.wrapException(new A._AssertionError(message));
},
throwCyclicInit(staticName) {
- throw A.wrapException(new A.CyclicInitializationError(staticName));
+ throw A.wrapException(new A._CyclicInitializationError(staticName));
},
getIsolateAffinityTag($name) {
return init.getIsolateTag($name);
@@ -1350,7 +1436,7 @@
transformers = dartNativeDispatchHooksTransformer;
if (typeof transformers == "function")
transformers = [transformers];
- if (transformers.constructor == Array)
+ if (Array.isArray(transformers))
for (i = 0; i < transformers.length; ++i) {
transformer = transformers[i];
if (typeof transformer == "function")
@@ -1367,6 +1453,17 @@
applyHooksTransformer(transformer, hooks) {
return transformer(hooks) || hooks;
},
+ createRecordTypePredicate(shape, fieldRtis) {
+ var $length = fieldRtis.length,
+ $function = init.rttc["" + $length + ";" + shape];
+ if ($function == null)
+ return null;
+ if ($length === 0)
+ return $function;
+ if ($length === $function.length)
+ return $function.apply(null, fieldRtis);
+ return $function(fieldRtis);
+ },
JSSyntaxRegExp_makeNative(source, multiLine, caseSensitive, unicode, dotAll, global) {
var m = multiLine ? "m" : "",
i = caseSensitive ? "" : "i",
@@ -1434,7 +1531,7 @@
return t1.charCodeAt(0) == 0 ? t1 : t1;
},
stringReplaceAllUncheckedString(receiver, pattern, replacement) {
- var $length, t1, i, index;
+ var $length, t1, i;
if (pattern === "") {
if (receiver === "")
return replacement;
@@ -1444,8 +1541,7 @@
t1 = t1 + receiver[i] + replacement;
return t1.charCodeAt(0) == 0 ? t1 : t1;
}
- index = receiver.indexOf(pattern, 0);
- if (index < 0)
+ if (receiver.indexOf(pattern, 0) < 0)
return receiver;
if (receiver.length < 500 || replacement.indexOf("$", 0) >= 0)
return receiver.split(pattern).join(replacement);
@@ -1477,17 +1573,23 @@
},
ConstantMap: function ConstantMap() {
},
- ConstantStringMap: function ConstantStringMap(t0, t1, t2, t3) {
- var _ = this;
- _._length = t0;
- _._jsObject = t1;
- _.__js_helper$_keys = t2;
- _.$ti = t3;
+ ConstantStringMap: function ConstantStringMap(t0, t1, t2) {
+ this._jsIndex = t0;
+ this._values = t1;
+ this.$ti = t2;
},
- _ConstantMapKeyIterable: function _ConstantMapKeyIterable(t0, t1) {
- this._map = t0;
+ _KeysOrValues: function _KeysOrValues(t0, t1) {
+ this._elements = t0;
this.$ti = t1;
},
+ _KeysOrValuesOrElementsIterator: function _KeysOrValuesOrElementsIterator(t0, t1, t2) {
+ var _ = this;
+ _._elements = t0;
+ _._length = t1;
+ _.__js_helper$_index = 0;
+ _.__js_helper$_current = null;
+ _.$ti = t2;
+ },
Instantiation: function Instantiation() {
},
Instantiation1: function Instantiation1(t0, t1) {
@@ -1531,10 +1633,6 @@
NullThrownFromJavaScriptException: function NullThrownFromJavaScriptException(t0) {
this._irritant = t0;
},
- ExceptionAndStackTrace: function ExceptionAndStackTrace(t0, t1) {
- this.dartException = t0;
- this.stackTrace = t1;
- },
_StackTrace: function _StackTrace(t0) {
this._exception = t0;
this._trace = null;
@@ -1553,6 +1651,9 @@
this._receiver = t0;
this._interceptor = t1;
},
+ _CyclicInitializationError: function _CyclicInitializationError(t0) {
+ this.variableName = t0;
+ },
RuntimeError: function RuntimeError(t0) {
this.message = t0;
},
@@ -1609,7 +1710,7 @@
_AllMatchesIterable: function _AllMatchesIterable(t0, t1, t2) {
this._re = t0;
this.__js_helper$_string = t1;
- this._start = t2;
+ this.__js_helper$_start = t2;
},
_AllMatchesIterator: function _AllMatchesIterator(t0, t1, t2) {
var _ = this;
@@ -1635,21 +1736,30 @@
_.__js_helper$_current = null;
},
throwLateFieldNI(fieldName) {
- return A.throwExpression(A.LateError$fieldNI(fieldName));
+ A.throwExpressionWithWrapper(new A.LateError("Field '" + fieldName + "' has not been initialized."), new Error());
},
throwLateFieldAI(fieldName) {
- return A.throwExpression(A.LateError$fieldAI(fieldName));
+ A.throwExpressionWithWrapper(new A.LateError("Field '" + fieldName + "' has already been initialized."), new Error());
},
throwLateFieldADI(fieldName) {
- return A.throwExpression(A.LateError$fieldADI(fieldName));
+ A.throwExpressionWithWrapper(new A.LateError("Field '" + fieldName + string$.x27_has_), new Error());
},
_Cell$named(_name) {
var t1 = new A._Cell(_name);
- return t1.__late_helper$_value = t1;
+ return t1._value = t1;
+ },
+ _InitializedCell$named(_name, _initializer) {
+ var t1 = new A._InitializedCell(_name, _initializer);
+ return t1._value = t1;
},
_Cell: function _Cell(t0) {
this.__late_helper$_name = t0;
- this.__late_helper$_value = null;
+ this._value = null;
+ },
+ _InitializedCell: function _InitializedCell(t0, t1) {
+ this.__late_helper$_name = t0;
+ this._value = null;
+ this._initializer = t1;
},
_ensureNativeList(list) {
return list;
@@ -1671,14 +1781,22 @@
throw A.wrapException(A.diagnoseRangeError(start, end, $length));
return end;
},
+ NativeByteBuffer: function NativeByteBuffer() {
+ },
NativeTypedData: function NativeTypedData() {
},
+ NativeByteData: function NativeByteData() {
+ },
NativeTypedArray: function NativeTypedArray() {
},
NativeTypedArrayOfDouble: function NativeTypedArrayOfDouble() {
},
NativeTypedArrayOfInt: function NativeTypedArrayOfInt() {
},
+ NativeFloat32List: function NativeFloat32List() {
+ },
+ NativeFloat64List: function NativeFloat64List() {
+ },
NativeInt16List: function NativeInt16List() {
},
NativeInt32List: function NativeInt32List() {
@@ -1713,7 +1831,7 @@
var kind = rti._kind;
if (kind === 6 || kind === 7 || kind === 8)
return A.Rti__isUnionOfFunctionType(rti._primary);
- return kind === 11 || kind === 12;
+ return kind === 12 || kind === 13;
},
Rti__getCanonicalRecipe(rti) {
return rti._canonicalRecipe;
@@ -1779,7 +1897,7 @@
if (substitutedBase === base && substitutedArguments === $arguments)
return rti;
return A._Universe__lookupBindingRti(universe, substitutedBase, substitutedArguments);
- case 11:
+ case 12:
returnType = rti._primary;
substitutedReturnType = A._substitute(universe, returnType, typeArguments, depth);
functionParameters = rti._rest;
@@ -1787,7 +1905,7 @@
if (substitutedReturnType === returnType && substitutedFunctionParameters === functionParameters)
return rti;
return A._Universe__lookupFunctionRti(universe, substitutedReturnType, substitutedFunctionParameters);
- case 12:
+ case 13:
bounds = rti._rest;
depth += bounds.length;
substitutedBounds = A._substituteArray(universe, bounds, typeArguments, depth);
@@ -1796,7 +1914,7 @@
if (substitutedBounds === bounds && substitutedBase === base)
return rti;
return A._Universe__lookupGenericFunctionRti(universe, substitutedBase, substitutedBounds, true);
- case 13:
+ case 14:
index = rti._primary;
if (index < depth)
return rti;
@@ -1857,11 +1975,13 @@
return target;
},
closureFunctionType(closure) {
- var signature = closure.$signature;
+ var t1,
+ signature = closure.$signature;
if (signature != null) {
if (typeof signature == "number")
return A.getTypeFromTypesTable(signature);
- return closure.$signature();
+ t1 = closure.$signature();
+ return t1;
}
return null;
},
@@ -1876,11 +1996,8 @@
return A.instanceType(object);
},
instanceType(object) {
- var rti;
- if (object instanceof A.Object) {
- rti = object.$ti;
- return rti != null ? rti : A._instanceTypeFromConstructor(object);
- }
+ if (object instanceof A.Object)
+ return A._instanceType(object);
if (Array.isArray(object))
return A._arrayInstanceType(object);
return A._instanceTypeFromConstructor(J.getInterceptor$(object));
@@ -1906,7 +2023,7 @@
return A._instanceTypeFromConstructorMiss(instance, $constructor);
},
_instanceTypeFromConstructorMiss(instance, $constructor) {
- var effectiveConstructor = instance instanceof A.Closure ? instance.__proto__.__proto__.constructor : $constructor,
+ var effectiveConstructor = instance instanceof A.Closure ? Object.getPrototypeOf(Object.getPrototypeOf(instance)).constructor : $constructor,
rti = A._Universe_findErasedType(init.typeUniverse, effectiveConstructor.name);
$constructor.$ccache = rti;
return rti;
@@ -1922,28 +2039,42 @@
}
return type;
},
- getRuntimeType(object) {
- var rti = object instanceof A.Closure ? A.closureFunctionType(object) : null;
- return A.createRuntimeType(rti == null ? A.instanceType(object) : rti);
+ getRuntimeTypeOfDartObject(object) {
+ return A.createRuntimeType(A._instanceType(object));
+ },
+ getRuntimeTypeOfClosure(closure) {
+ var rti = A.closureFunctionType(closure);
+ return A.createRuntimeType(rti == null ? A.instanceType(closure) : rti);
+ },
+ _structuralTypeOf(object) {
+ var functionRti = object instanceof A.Closure ? A.closureFunctionType(object) : null;
+ if (functionRti != null)
+ return functionRti;
+ if (type$.TrustedGetRuntimeType._is(object))
+ return J.get$runtimeType$(object)._rti;
+ if (Array.isArray(object))
+ return A._arrayInstanceType(object);
+ return A.instanceType(object);
},
createRuntimeType(rti) {
- var recipe, starErasedRecipe, starErasedRti,
- type = rti._cachedRuntimeType;
- if (type != null)
- return type;
- recipe = rti._canonicalRecipe;
- starErasedRecipe = recipe.replace(/\*/g, "");
- if (starErasedRecipe === recipe)
+ var t1 = rti._cachedRuntimeType;
+ return t1 == null ? rti._cachedRuntimeType = A._createRuntimeType(rti) : t1;
+ },
+ _createRuntimeType(rti) {
+ var starErasedRti, t1,
+ s = rti._canonicalRecipe,
+ starErasedRecipe = s.replace(/\*/g, "");
+ if (starErasedRecipe === s)
return rti._cachedRuntimeType = new A._Type(rti);
starErasedRti = A._Universe_eval(init.typeUniverse, starErasedRecipe, true);
- type = starErasedRti._cachedRuntimeType;
- return rti._cachedRuntimeType = type == null ? starErasedRti._cachedRuntimeType = new A._Type(starErasedRti) : type;
+ t1 = starErasedRti._cachedRuntimeType;
+ return t1 == null ? starErasedRti._cachedRuntimeType = A._createRuntimeType(starErasedRti) : t1;
},
typeLiteral(recipe) {
return A.createRuntimeType(A._Universe_eval(init.typeUniverse, recipe, false));
},
_installSpecializedIsTest(object) {
- var t1, unstarred, isFn, $name, testRti = this;
+ var t1, unstarred, isFn, $name, predicate, testRti = this;
if (testRti === type$.Object)
return A._finishIsFn(testRti, object, A._isObject);
if (!A.isStrongTopType(testRti))
@@ -1956,7 +2087,14 @@
if (t1)
return A._finishIsFn(testRti, object, A._isTop);
t1 = testRti._kind;
+ if (t1 === 7)
+ return A._finishIsFn(testRti, object, A._generalNullableIsTestImplementation);
+ if (t1 === 1)
+ return A._finishIsFn(testRti, object, A._isNever);
unstarred = t1 === 6 ? testRti._primary : testRti;
+ t1 = unstarred._kind;
+ if (t1 === 8)
+ return A._finishIsFn(testRti, object, A._isFutureOr);
if (unstarred === type$.int)
isFn = A._isInt;
else if (unstarred === type$.double || unstarred === type$.num)
@@ -1967,7 +2105,7 @@
isFn = unstarred === type$.bool ? A._isBool : null;
if (isFn != null)
return A._finishIsFn(testRti, object, isFn);
- if (unstarred._kind === 9) {
+ if (t1 === 9) {
$name = unstarred._primary;
if (unstarred._rest.every(A.isTopType)) {
testRti._specializedTestResource = "$is" + $name;
@@ -1975,8 +2113,10 @@
return A._finishIsFn(testRti, object, A._isListTestViaProperty);
return A._finishIsFn(testRti, object, A._isTestViaProperty);
}
- } else if (t1 === 7)
- return A._finishIsFn(testRti, object, A._generalNullableIsTestImplementation);
+ } else if (t1 === 11) {
+ predicate = A.createRecordTypePredicate(unstarred._primary, unstarred._rest);
+ return A._finishIsFn(testRti, object, predicate == null ? A._isNever : predicate);
+ }
return A._finishIsFn(testRti, object, A._generalIsTestImplementation);
},
_finishIsFn(testRti, object, isFn) {
@@ -2012,7 +2152,10 @@
if (!(testRti === type$.legacy_Object))
if (!(testRti === type$.legacy_Never))
if (kind !== 7)
- t1 = kind === 8 && A._nullIs(testRti._primary) || testRti === type$.Null || testRti === type$.JSNull;
+ if (!(kind === 6 && A._nullIs(testRti._primary)))
+ t1 = kind === 8 && A._nullIs(testRti._primary) || testRti === type$.Null || testRti === type$.JSNull;
+ else
+ t1 = true;
else
t1 = true;
else
@@ -2075,7 +2218,7 @@
A._failedAsCheck(object, testRti);
},
_failedAsCheck(object, testRti) {
- throw A.wrapException(A._TypeError$fromMessage(A._Error_compose(object, A.instanceOrFunctionType(object, testRti), A._rtiToString(testRti, null))));
+ throw A.wrapException(A._TypeError$fromMessage(A._Error_compose(object, A._rtiToString(testRti, null))));
},
checkTypeBound(type, bound, variable, methodName) {
var _null = null;
@@ -2083,15 +2226,19 @@
return type;
throw A.wrapException(A._TypeError$fromMessage("The type argument '" + A._rtiToString(type, _null) + "' is not a subtype of the type variable bound '" + A._rtiToString(bound, _null) + "' of type variable '" + variable + "' in '" + methodName + "'."));
},
- _Error_compose(object, objectRti, checkedTypeDescription) {
- var objectDescription = A.Error_safeToString(object);
- return objectDescription + ": type '" + A._rtiToString(objectRti == null ? A.instanceType(object) : objectRti, null) + "' is not a subtype of type '" + checkedTypeDescription + "'";
+ _Error_compose(object, checkedTypeDescription) {
+ return A.Error_safeToString(object) + ": type '" + A._rtiToString(A._structuralTypeOf(object), null) + "' is not a subtype of type '" + checkedTypeDescription + "'";
},
_TypeError$fromMessage(message) {
return new A._TypeError("TypeError: " + message);
},
_TypeError__TypeError$forType(object, type) {
- return new A._TypeError("TypeError: " + A._Error_compose(object, null, type));
+ return new A._TypeError("TypeError: " + A._Error_compose(object, type));
+ },
+ _isFutureOr(object) {
+ var testRti = this,
+ unstarred = testRti._kind === 6 ? testRti._primary : testRti;
+ return unstarred._primary._is(object) || A.Rti__getFutureFromFutureOr(init.typeUniverse, unstarred)._is(object);
},
_isObject(object) {
return object != null;
@@ -2107,6 +2254,9 @@
_asTop(object) {
return object;
},
+ _isNever(object) {
+ return false;
+ },
_isBool(object) {
return true === object || false === object;
},
@@ -2226,6 +2376,26 @@
s += sep + A._rtiToString(array[i], genericContext);
return s;
},
+ _recordRtiToString(recordType, genericContext) {
+ var fieldCount, names, namesIndex, s, comma, i,
+ partialShape = recordType._primary,
+ fields = recordType._rest;
+ if ("" === partialShape)
+ return "(" + A._rtiArrayToString(fields, genericContext) + ")";
+ fieldCount = fields.length;
+ names = partialShape.split(",");
+ namesIndex = names.length - fieldCount;
+ for (s = "(", comma = "", i = 0; i < fieldCount; ++i, comma = ", ") {
+ s += comma;
+ if (namesIndex === 0)
+ s += "{";
+ s += A._rtiToString(fields[i], genericContext);
+ if (namesIndex >= 0)
+ s += " " + names[namesIndex];
+ ++namesIndex;
+ }
+ return s + "})";
+ },
_functionRtiToString(functionType, genericContext, bounds) {
var boundsLength, outerContextLength, offset, i, t1, t2, typeParametersText, typeSep, t3, t4, boundRti, kind, parameters, requiredPositional, requiredPositionalLength, optionalPositional, optionalPositionalLength, named, namedLength, returnTypeText, argumentsText, sep, _s2_ = ", ";
if (bounds != null) {
@@ -2315,7 +2485,7 @@
questionArgument = rti._primary;
s = A._rtiToString(questionArgument, genericContext);
argumentKind = questionArgument._kind;
- return (argumentKind === 11 || argumentKind === 12 ? "(" + s + ")" : s) + "?";
+ return (argumentKind === 12 || argumentKind === 13 ? "(" + s + ")" : s) + "?";
}
if (kind === 8)
return "FutureOr<" + A._rtiToString(rti._primary, genericContext) + ">";
@@ -2325,10 +2495,12 @@
return $arguments.length > 0 ? $name + ("<" + A._rtiArrayToString($arguments, genericContext) + ">") : $name;
}
if (kind === 11)
- return A._functionRtiToString(rti, genericContext, null);
+ return A._recordRtiToString(rti, genericContext);
if (kind === 12)
+ return A._functionRtiToString(rti, genericContext, null);
+ if (kind === 13)
return A._functionRtiToString(rti._primary, genericContext, rti._rest);
- if (kind === 13) {
+ if (kind === 14) {
t1 = rti._primary;
t2 = genericContext.length;
t1 = t2 - 1 - t1;
@@ -2536,7 +2708,7 @@
if (probe != null)
return probe;
rti = new A.Rti(null, null);
- rti._kind = 13;
+ rti._kind = 14;
rti._primary = index;
rti._canonicalRecipe = key;
t1 = A._Universe__installTypeTests(universe, rti);
@@ -2601,6 +2773,21 @@
universe.eC.set(key, t1);
return t1;
},
+ _Universe__lookupRecordRti(universe, partialShapeTag, fields) {
+ var rti, t1,
+ key = "+" + (partialShapeTag + "(" + A._Universe__canonicalRecipeJoin(fields) + ")"),
+ probe = universe.eC.get(key);
+ if (probe != null)
+ return probe;
+ rti = new A.Rti(null, null);
+ rti._kind = 11;
+ rti._primary = partialShapeTag;
+ rti._rest = fields;
+ rti._canonicalRecipe = key;
+ t1 = A._Universe__installTypeTests(universe, rti);
+ universe.eC.set(key, t1);
+ return t1;
+ },
_Universe__lookupFunctionRti(universe, returnType, parameters) {
var sep, key, probe, rti, t1,
s = returnType._canonicalRecipe,
@@ -2624,7 +2811,7 @@
if (probe != null)
return probe;
rti = new A.Rti(null, null);
- rti._kind = 11;
+ rti._kind = 12;
rti._primary = returnType;
rti._rest = parameters;
rti._canonicalRecipe = key;
@@ -2661,7 +2848,7 @@
}
}
rti = new A.Rti(null, null);
- rti._kind = 12;
+ rti._kind = 13;
rti._primary = baseFunctionType;
rti._rest = bounds;
rti._canonicalRecipe = key;
@@ -2671,14 +2858,14 @@
return {u: universe, e: environment, r: recipe, s: [], p: 0, n: normalize};
},
_Parser_parse(parser) {
- var t2, i, ch, t3, array, head, base, parameters, optionalPositional, named, item,
+ var t2, i, ch, t3, array, end, item,
source = parser.r,
t1 = parser.s;
for (t2 = source.length, i = 0; i < t2;) {
ch = source.charCodeAt(i);
if (ch >= 48 && ch <= 57)
i = A._Parser_handleDigit(i + 1, ch, source, t1);
- else if ((((ch | 32) >>> 0) - 97 & 65535) < 26 || ch === 95 || ch === 36)
+ else if ((((ch | 32) >>> 0) - 97 & 65535) < 26 || ch === 95 || ch === 36 || ch === 124)
i = A._Parser_handleIdentifier(parser, i, source, t1, false);
else if (ch === 46)
i = A._Parser_handleIdentifier(parser, i, source, t1, true);
@@ -2713,24 +2900,7 @@
parser.p = t1.length;
break;
case 62:
- t3 = parser.u;
- array = t1.splice(parser.p);
- A._Parser_toTypes(parser.u, parser.e, array);
- parser.p = t1.pop();
- head = t1.pop();
- if (typeof head == "string")
- t1.push(A._Universe__lookupInterfaceRti(t3, head, array));
- else {
- base = A._Parser_toType(t3, parser.e, head);
- switch (base._kind) {
- case 11:
- t1.push(A._Universe__lookupGenericFunctionRti(t3, base, array, parser.n));
- break;
- default:
- t1.push(A._Universe__lookupBindingRti(t3, base, array));
- break;
- }
- }
+ A._Parser_handleTypeArguments(parser, t1);
break;
case 38:
A._Parser_handleExtendedOperations(parser, t1);
@@ -2748,36 +2918,12 @@
t1.push(A._Universe__lookupFutureOrRti(t3, A._Parser_toType(t3, parser.e, t1.pop()), parser.n));
break;
case 40:
+ t1.push(-3);
t1.push(parser.p);
parser.p = t1.length;
break;
case 41:
- t3 = parser.u;
- parameters = new A._FunctionParameters();
- optionalPositional = t3.sEA;
- named = t3.sEA;
- head = t1.pop();
- if (typeof head == "number")
- switch (head) {
- case -1:
- optionalPositional = t1.pop();
- break;
- case -2:
- named = t1.pop();
- break;
- default:
- t1.push(head);
- break;
- }
- else
- t1.push(head);
- array = t1.splice(parser.p);
- A._Parser_toTypes(parser.u, parser.e, array);
- parser.p = t1.pop();
- parameters._requiredPositional = array;
- parameters._optionalPositional = optionalPositional;
- parameters._named = named;
- t1.push(A._Universe__lookupFunctionRti(t3, A._Parser_toType(t3, parser.e, t1.pop()), parameters));
+ A._Parser_handleArguments(parser, t1);
break;
case 91:
t1.push(parser.p);
@@ -2801,6 +2947,14 @@
t1.push(array);
t1.push(-2);
break;
+ case 43:
+ end = source.indexOf("(", i);
+ t1.push(source.substring(i, end));
+ t1.push(-4);
+ t1.push(parser.p);
+ parser.p = t1.length;
+ i = end + 1;
+ break;
default:
throw "Bad character " + ch;
}
@@ -2831,7 +2985,7 @@
break;
hasPeriod = true;
} else {
- if (!((((ch | 32) >>> 0) - 97 & 65535) < 26 || ch === 95 || ch === 36))
+ if (!((((ch | 32) >>> 0) - 97 & 65535) < 26 || ch === 95 || ch === 36 || ch === 124))
t2 = ch >= 48 && ch <= 57;
else
t2 = true;
@@ -2853,6 +3007,73 @@
stack.push(string);
return i;
},
+ _Parser_handleTypeArguments(parser, stack) {
+ var base,
+ t1 = parser.u,
+ $arguments = A._Parser_collectArray(parser, stack),
+ head = stack.pop();
+ if (typeof head == "string")
+ stack.push(A._Universe__lookupInterfaceRti(t1, head, $arguments));
+ else {
+ base = A._Parser_toType(t1, parser.e, head);
+ switch (base._kind) {
+ case 12:
+ stack.push(A._Universe__lookupGenericFunctionRti(t1, base, $arguments, parser.n));
+ break;
+ default:
+ stack.push(A._Universe__lookupBindingRti(t1, base, $arguments));
+ break;
+ }
+ }
+ },
+ _Parser_handleArguments(parser, stack) {
+ var optionalPositional, named, requiredPositional, returnType, parameters, _null = null,
+ t1 = parser.u,
+ head = stack.pop();
+ if (typeof head == "number")
+ switch (head) {
+ case -1:
+ optionalPositional = stack.pop();
+ named = _null;
+ break;
+ case -2:
+ named = stack.pop();
+ optionalPositional = _null;
+ break;
+ default:
+ stack.push(head);
+ named = _null;
+ optionalPositional = named;
+ break;
+ }
+ else {
+ stack.push(head);
+ named = _null;
+ optionalPositional = named;
+ }
+ requiredPositional = A._Parser_collectArray(parser, stack);
+ head = stack.pop();
+ switch (head) {
+ case -3:
+ head = stack.pop();
+ if (optionalPositional == null)
+ optionalPositional = t1.sEA;
+ if (named == null)
+ named = t1.sEA;
+ returnType = A._Parser_toType(t1, parser.e, head);
+ parameters = new A._FunctionParameters();
+ parameters._requiredPositional = requiredPositional;
+ parameters._optionalPositional = optionalPositional;
+ parameters._named = named;
+ stack.push(A._Universe__lookupFunctionRti(t1, returnType, parameters));
+ return;
+ case -4:
+ stack.push(A._Universe__lookupRecordRti(t1, stack.pop(), requiredPositional));
+ return;
+ default:
+ throw A.wrapException(A.AssertionError$("Unexpected state under `()`: " + A.S(head)));
+ }
+ },
_Parser_handleExtendedOperations(parser, stack) {
var $top = stack.pop();
if (0 === $top) {
@@ -2865,6 +3086,12 @@
}
throw A.wrapException(A.AssertionError$("Unexpected extended operation " + A.S($top)));
},
+ _Parser_collectArray(parser, stack) {
+ var array = stack.splice(parser.p);
+ A._Parser_toTypes(parser.u, parser.e, array);
+ parser.p = stack.pop();
+ return array;
+ },
_Parser_toType(universe, environment, item) {
if (typeof item == "string")
return A._Universe__lookupInterfaceRti(universe, item, universe.sEA);
@@ -2909,7 +3136,7 @@
throw A.wrapException(A.AssertionError$("Bad index " + index + " for " + environment.toString$0(0)));
},
_isSubtype(universe, s, sEnv, t, tEnv) {
- var t1, sKind, leftTypeVariable, tKind, sBounds, tBounds, sLength, i, sBound, tBound;
+ var t1, sKind, leftTypeVariable, tKind, t2, sBounds, tBounds, sLength, i, sBound, tBound;
if (s === t)
return true;
if (!A.isStrongTopType(t))
@@ -2932,7 +3159,7 @@
t1 = true;
if (t1)
return true;
- leftTypeVariable = sKind === 13;
+ leftTypeVariable = sKind === 14;
if (leftTypeVariable)
if (A._isSubtype(universe, sEnv[s._primary], sEnv, t, tEnv))
return true;
@@ -2976,13 +3203,16 @@
}
if (leftTypeVariable)
return false;
- t1 = sKind !== 11;
- if ((!t1 || sKind === 12) && t === type$.Function)
+ t1 = sKind !== 12;
+ if ((!t1 || sKind === 13) && t === type$.Function)
return true;
- if (tKind === 12) {
+ t2 = sKind === 11;
+ if (t2 && t === type$.Record)
+ return true;
+ if (tKind === 13) {
if (s === type$.JavaScriptFunction)
return true;
- if (sKind !== 12)
+ if (sKind !== 13)
return false;
sBounds = s._rest;
tBounds = t._rest;
@@ -2999,7 +3229,7 @@
}
return A._isFunctionSubtype(universe, s._primary, sEnv, t._primary, tEnv);
}
- if (tKind === 11) {
+ if (tKind === 12) {
if (s === type$.JavaScriptFunction)
return true;
if (t1)
@@ -3011,6 +3241,8 @@
return false;
return A._isInterfaceSubtype(universe, s, sEnv, t, tEnv);
}
+ if (t2 && tKind === 11)
+ return A._isRecordSubtype(universe, s, sEnv, t, tEnv);
return false;
},
_isFunctionSubtype(universe, s, sEnv, t, tEnv) {
@@ -3118,6 +3350,20 @@
}
return true;
},
+ _isRecordSubtype(universe, s, sEnv, t, tEnv) {
+ var i,
+ sFields = s._rest,
+ tFields = t._rest,
+ sCount = sFields.length;
+ if (sCount !== tFields.length)
+ return false;
+ if (s._primary !== t._primary)
+ return false;
+ for (i = 0; i < sCount; ++i)
+ if (!A._isSubtype(universe, sFields[i], sEnv, tFields[i], tEnv))
+ return false;
+ return true;
+ },
isNullable(t) {
var t1,
kind = t._kind;
@@ -3223,56 +3469,6 @@
t1._TimerImpl$periodic$2(milliseconds, callback);
return t1;
},
- _makeAsyncAwaitCompleter($T) {
- return new A._AsyncAwaitCompleter(new A._Future($.Zone__current, $T._eval$1("_Future<0>")), $T._eval$1("_AsyncAwaitCompleter<0>"));
- },
- _asyncStartSync(bodyFunction, completer) {
- bodyFunction.call$2(0, null);
- completer.isSync = true;
- return completer._future;
- },
- _asyncAwait(object, bodyFunction) {
- A._awaitOnObject(object, bodyFunction);
- },
- _asyncReturn(object, completer) {
- completer.complete$1(0, object);
- },
- _asyncRethrow(object, completer) {
- completer.completeError$2(A.unwrapException(object), A.getTraceFromException(object));
- },
- _awaitOnObject(object, bodyFunction) {
- var t1, future,
- thenCallback = new A._awaitOnObject_closure(bodyFunction),
- errorCallback = new A._awaitOnObject_closure0(bodyFunction);
- if (object instanceof A._Future)
- object._thenAwait$1$2(thenCallback, errorCallback, type$.dynamic);
- else {
- t1 = type$.dynamic;
- if (type$.Future_dynamic._is(object))
- object.then$1$2$onError(thenCallback, errorCallback, t1);
- else {
- future = new A._Future($.Zone__current, type$._Future_dynamic);
- future._async$_state = 8;
- future._resultOrListeners = object;
- future._thenAwait$1$2(thenCallback, errorCallback, t1);
- }
- }
- },
- _wrapJsFunctionForAsync($function) {
- var $protected = function(fn, ERROR) {
- return function(errorCode, result) {
- while (true)
- try {
- fn(errorCode, result);
- break;
- } catch (error) {
- result = error;
- errorCode = ERROR;
- }
- };
- }($function, 1);
- return $.Zone__current.registerBinaryCallback$3$1(new A._wrapJsFunctionForAsync_closure($protected), type$.void, type$.int, type$.dynamic);
- },
AsyncError$(error, stackTrace) {
var t1 = A.checkNotNullable(error, "error", type$.Object);
return new A.AsyncError(t1, stackTrace == null ? A.AsyncError_defaultStackTrace(error) : stackTrace);
@@ -3287,14 +3483,13 @@
return B._StringStackTrace_3uE;
},
Future_Future$value(value, $T) {
- var t1, t2;
+ var t1;
$T._as(value);
- t1 = value;
- t2 = new A._Future($.Zone__current, $T._eval$1("_Future<0>"));
- t2._asyncComplete$1(t1);
- return t2;
+ t1 = new A._Future($.Zone__current, $T._eval$1("_Future<0>"));
+ t1._asyncComplete$1(value);
+ return t1;
},
- _Future__chainCoreFuture(source, target) {
+ _Future__chainCoreFutureSync(source, target) {
var t1, t2, listeners;
for (t1 = type$._Future_dynamic; t2 = source._async$_state, (t2 & 4) !== 0;)
source = t1._as(source._resultOrListeners);
@@ -3304,11 +3499,30 @@
A._Future__propagateToListeners(target, listeners);
} else {
listeners = type$.nullable__FutureListener_dynamic_dynamic._as(target._resultOrListeners);
- target._async$_state = target._async$_state & 1 | 4;
- target._resultOrListeners = source;
+ target._setChained$1(source);
source._prependListeners$1(listeners);
}
},
+ _Future__chainCoreFutureAsync(source, target) {
+ var t2, t3, listeners, _box_0 = {},
+ t1 = _box_0.source = source;
+ for (t2 = type$._Future_dynamic; t3 = t1._async$_state, (t3 & 4) !== 0; t1 = source) {
+ source = t2._as(t1._resultOrListeners);
+ _box_0.source = source;
+ }
+ if ((t3 & 24) === 0) {
+ listeners = type$.nullable__FutureListener_dynamic_dynamic._as(target._resultOrListeners);
+ target._setChained$1(t1);
+ _box_0.source._prependListeners$1(listeners);
+ return;
+ }
+ if ((t3 & 16) === 0 && target._resultOrListeners == null) {
+ target._cloneResult$1(t1);
+ return;
+ }
+ target._async$_state ^= 2;
+ target._zone.scheduleMicrotask$1(new A._Future__chainCoreFutureAsync_closure(_box_0, target));
+ },
_Future__propagateToListeners(source, listeners) {
var t2, t3, t4, _box_0, t5, t6, hasError, asyncError, nextListener, nextListener0, sourceResult, t7, zone, oldZone, result, current, _box_1 = {},
t1 = _box_1.source = source;
@@ -3370,7 +3584,7 @@
if (oldZone != null)
$.Zone__current = oldZone;
t1 = _box_0.listenerValueOrError;
- if (t4._is(t1)) {
+ if (t1 instanceof A._Future) {
t5 = _box_0.listener.$ti;
t5 = t5._eval$1("Future<2>")._is(t1) || !t5._rest[1]._is(t1);
} else
@@ -3387,7 +3601,7 @@
_box_1.source = t1;
continue;
} else
- A._Future__chainCoreFuture(t1, result);
+ A._Future__chainCoreFutureSync(t1, result);
return;
}
}
@@ -3488,10 +3702,6 @@
t1 = $.Zone__current;
t1.scheduleMicrotask$1(t1.bindCallbackGuarded$1(callback));
},
- StreamIterator_StreamIterator(stream, $T) {
- A.checkNotNullable(stream, "stream", type$.Object);
- return new A._StreamIterator($T._eval$1("_StreamIterator<0>"));
- },
StreamController_StreamController(onCancel, onListen, sync, $T) {
return new A._SyncStreamController(onListen, null, null, onCancel, $T._eval$1("_SyncStreamController<0>"));
},
@@ -3649,7 +3859,6 @@
type$.nullable_Map_of_nullable_Object_and_nullable_Object._as(zoneValues);
$.printToZone = A.async___printToZone$closure();
valueMap = zone.get$_async$_map();
- valueMap = valueMap;
t1 = new A._CustomZone(zone.get$_run(), zone.get$_runUnary(), zone.get$_runBinary(), zone.get$_registerCallback(), zone.get$_registerUnaryCallback(), zone.get$_registerBinaryCallback(), zone.get$_errorCallback(), zone.get$_scheduleMicrotask(), zone.get$_createTimer(), zone.get$_createPeriodicTimer(), zone.get$_print(), zone.get$_fork(), zone.get$_handleUncaughtError(), zone, valueMap);
handleUncaughtError = specification.handleUncaughtError;
if (handleUncaughtError != null)
@@ -3704,20 +3913,6 @@
_.start = t2;
_.callback = t3;
},
- _AsyncAwaitCompleter: function _AsyncAwaitCompleter(t0, t1) {
- this._future = t0;
- this.isSync = false;
- this.$ti = t1;
- },
- _awaitOnObject_closure: function _awaitOnObject_closure(t0) {
- this.bodyFunction = t0;
- },
- _awaitOnObject_closure0: function _awaitOnObject_closure0(t0) {
- this.bodyFunction = t0;
- },
- _wrapJsFunctionForAsync_closure: function _wrapJsFunctionForAsync_closure(t0) {
- this.$protected = t0;
- },
AsyncError: function AsyncError(t0, t1) {
this.error = t0;
this.stackTrace = t1;
@@ -3767,11 +3962,11 @@
this.e = t1;
this.s = t2;
},
- _Future__asyncCompleteWithValue_closure: function _Future__asyncCompleteWithValue_closure(t0, t1) {
- this.$this = t0;
- this.value = t1;
+ _Future__chainCoreFutureAsync_closure: function _Future__chainCoreFutureAsync_closure(t0, t1) {
+ this._box_0 = t0;
+ this.target = t1;
},
- _Future__chainFuture_closure: function _Future__chainFuture_closure(t0, t1) {
+ _Future__asyncCompleteWithValue_closure: function _Future__asyncCompleteWithValue_closure(t0, t1) {
this.$this = t0;
this.value = t1;
},
@@ -3813,8 +4008,6 @@
this._box_0 = t0;
this.future = t1;
},
- StreamTransformerBase: function StreamTransformerBase() {
- },
_StreamController: function _StreamController() {
},
_StreamController__subscribe_closure: function _StreamController__subscribe_closure(t0) {
@@ -3901,9 +4094,6 @@
_._onDone = t1;
_.$ti = t2;
},
- _StreamIterator: function _StreamIterator(t0) {
- this.$ti = t0;
- },
_EmptyStream: function _EmptyStream(t0) {
this.$ti = t0;
},
@@ -4038,146 +4228,26 @@
delete table["<non-identifier-key>"];
return table;
},
- IterableBase_iterableToShortString(iterable, leftDelimiter, rightDelimiter) {
- var parts, t1;
- if (A._isToStringVisiting(iterable)) {
- if (leftDelimiter === "(" && rightDelimiter === ")")
- return "(...)";
- return leftDelimiter + "..." + rightDelimiter;
- }
- parts = A._setArrayType([], type$.JSArray_String);
- B.JSArray_methods.add$1($._toStringVisiting, iterable);
- try {
- A._iterablePartsToStrings(iterable, parts);
- } finally {
- if (0 >= $._toStringVisiting.length)
- return A.ioore($._toStringVisiting, -1);
- $._toStringVisiting.pop();
- }
- t1 = A.StringBuffer__writeAll(leftDelimiter, type$.Iterable_dynamic._as(parts), ", ") + rightDelimiter;
- return t1.charCodeAt(0) == 0 ? t1 : t1;
- },
- IterableBase_iterableToFullString(iterable, leftDelimiter, rightDelimiter) {
- var buffer, t1;
- if (A._isToStringVisiting(iterable))
- return leftDelimiter + "..." + rightDelimiter;
- buffer = new A.StringBuffer(leftDelimiter);
- B.JSArray_methods.add$1($._toStringVisiting, iterable);
- try {
- t1 = buffer;
- t1._contents = A.StringBuffer__writeAll(t1._contents, iterable, ", ");
- } finally {
- if (0 >= $._toStringVisiting.length)
- return A.ioore($._toStringVisiting, -1);
- $._toStringVisiting.pop();
- }
- buffer._contents += rightDelimiter;
- t1 = buffer._contents;
- return t1.charCodeAt(0) == 0 ? t1 : t1;
- },
- _isToStringVisiting(o) {
- var t1, i;
- for (t1 = $._toStringVisiting.length, i = 0; i < t1; ++i)
- if (o === $._toStringVisiting[i])
- return true;
- return false;
- },
- _iterablePartsToStrings(iterable, parts) {
- var next, ultimateString, penultimateString, penultimate, ultimate, ultimate0, elision,
- it = iterable.get$iterator(iterable),
- $length = 0, count = 0;
- while (true) {
- if (!($length < 80 || count < 3))
- break;
- if (!it.moveNext$0())
- return;
- next = A.S(it.get$current(it));
- B.JSArray_methods.add$1(parts, next);
- $length += next.length + 2;
- ++count;
- }
- if (!it.moveNext$0()) {
- if (count <= 5)
- return;
- if (0 >= parts.length)
- return A.ioore(parts, -1);
- ultimateString = parts.pop();
- if (0 >= parts.length)
- return A.ioore(parts, -1);
- penultimateString = parts.pop();
- } else {
- penultimate = it.get$current(it);
- ++count;
- if (!it.moveNext$0()) {
- if (count <= 4) {
- B.JSArray_methods.add$1(parts, A.S(penultimate));
- return;
- }
- ultimateString = A.S(penultimate);
- if (0 >= parts.length)
- return A.ioore(parts, -1);
- penultimateString = parts.pop();
- $length += ultimateString.length + 2;
- } else {
- ultimate = it.get$current(it);
- ++count;
- for (; it.moveNext$0(); penultimate = ultimate, ultimate = ultimate0) {
- ultimate0 = it.get$current(it);
- ++count;
- if (count > 100) {
- while (true) {
- if (!($length > 75 && count > 3))
- break;
- if (0 >= parts.length)
- return A.ioore(parts, -1);
- $length -= parts.pop().length + 2;
- --count;
- }
- B.JSArray_methods.add$1(parts, "...");
- return;
- }
- }
- penultimateString = A.S(penultimate);
- ultimateString = A.S(ultimate);
- $length += ultimateString.length + penultimateString.length + 4;
- }
- }
- if (count > parts.length + 2) {
- $length += 5;
- elision = "...";
- } else
- elision = null;
- while (true) {
- if (!($length > 80 && parts.length > 3))
- break;
- if (0 >= parts.length)
- return A.ioore(parts, -1);
- $length -= parts.pop().length + 2;
- if (elision == null) {
- $length += 5;
- elision = "...";
- }
- }
- if (elision != null)
- B.JSArray_methods.add$1(parts, elision);
- B.JSArray_methods.add$1(parts, penultimateString);
- B.JSArray_methods.add$1(parts, ultimateString);
+ _LinkedHashSetIterator$(_set, _modifications, $E) {
+ var t1 = new A._LinkedHashSetIterator(_set, _modifications, $E._eval$1("_LinkedHashSetIterator<0>"));
+ t1._collection$_cell = _set._collection$_first;
+ return t1;
},
MapBase_mapToString(m) {
var result, t1 = {};
- if (A._isToStringVisiting(m))
+ if (A.isToStringVisiting(m))
return "{...}";
result = new A.StringBuffer("");
try {
- B.JSArray_methods.add$1($._toStringVisiting, m);
+ B.JSArray_methods.add$1($.toStringVisiting, m);
result._contents += "{";
t1.first = true;
J.forEach$1$x(m, new A.MapBase_mapToString_closure(t1, result));
result._contents += "}";
} finally {
- if (0 >= $._toStringVisiting.length)
- return A.ioore($._toStringVisiting, -1);
- $._toStringVisiting.pop();
+ if (0 >= $.toStringVisiting.length)
+ return A.ioore($.toStringVisiting, -1);
+ $.toStringVisiting.pop();
}
t1 = result._contents;
return t1.charCodeAt(0) == 0 ? t1 : t1;
@@ -4224,20 +4294,14 @@
_._collection$_current = _._collection$_cell = null;
_.$ti = t2;
},
- IterableBase: function IterableBase() {
- },
ListBase: function ListBase() {
},
- ListMixin: function ListMixin() {
- },
MapBase: function MapBase() {
},
MapBase_mapToString_closure: function MapBase_mapToString_closure(t0, t1) {
this._box_0 = t0;
this.result = t1;
},
- MapMixin: function MapMixin() {
- },
_UnmodifiableMapMixin: function _UnmodifiableMapMixin() {
},
MapView: function MapView() {
@@ -4246,16 +4310,12 @@
this._collection$_map = t0;
this.$ti = t1;
},
- SetMixin: function SetMixin() {
+ SetBase: function SetBase() {
},
_SetBase: function _SetBase() {
},
- _ListBase_Object_ListMixin: function _ListBase_Object_ListMixin() {
- },
_UnmodifiableMapView_MapView__UnmodifiableMapMixin: function _UnmodifiableMapView_MapView__UnmodifiableMapMixin() {
},
- __SetBase_Object_SetMixin: function __SetBase_Object_SetMixin() {
- },
_parseJson(source, reviver) {
var e, exception, t1, parsed = null;
try {
@@ -4457,11 +4517,6 @@
return value;
throw A.wrapException(A.FormatException$(source, null, null));
},
- Error__objectToString(object) {
- if (object instanceof A.Closure)
- return object.toString$0(0);
- return "Instance of '" + A.Primitives_objectTypeName(object) + "'";
- },
Error__throw(error, stackTrace) {
error = A.wrapException(error);
if (error == null)
@@ -4470,17 +4525,6 @@
throw error;
throw A.wrapException("unreachable");
},
- DateTime$fromMillisecondsSinceEpoch(millisecondsSinceEpoch, isUtc) {
- var t1;
- if (Math.abs(millisecondsSinceEpoch) <= 864e13)
- t1 = false;
- else
- t1 = true;
- if (t1)
- A.throwExpression(A.ArgumentError$("DateTime is outside valid range: " + millisecondsSinceEpoch, null));
- A.checkNotNullable(true, "isUtc", type$.bool);
- return new A.DateTime(millisecondsSinceEpoch, true);
- },
List_List$filled($length, fill, growable, $E) {
var i,
result = growable ? J.JSArray_JSArray$growable($length, $E) : J.JSArray_JSArray$fixed($length, $E);
@@ -4499,7 +4543,10 @@
return J.JSArray_markFixedList(list, $E);
},
List_List$of(elements, growable, $E) {
- var t1 = A.List_List$_of(elements, $E);
+ var t1;
+ if (growable)
+ return A.List_List$_of(elements, $E);
+ t1 = J.JSArray_markFixedList(A.List_List$_of(elements, $E), $E);
return t1;
},
List_List$_of(elements, $E) {
@@ -4570,27 +4617,33 @@
}
return string;
},
- NoSuchMethodError$(receiver, memberName, positionalArguments, namedArguments) {
- return new A.NoSuchMethodError(receiver, memberName, positionalArguments, namedArguments);
+ NoSuchMethodError_NoSuchMethodError$withInvocation(receiver, invocation) {
+ return new A.NoSuchMethodError(receiver, invocation.get$memberName(), invocation.get$positionalArguments(), invocation.get$namedArguments());
},
Uri_base() {
- var uri = A.Primitives_currentUri();
- if (uri != null)
- return A.Uri_parse(uri);
- throw A.wrapException(A.UnsupportedError$("'Uri.base' is not supported"));
+ var cachedUri, uri,
+ current = A.Primitives_currentUri();
+ if (current == null)
+ throw A.wrapException(A.UnsupportedError$("'Uri.base' is not supported"));
+ cachedUri = $.Uri__cachedBaseUri;
+ if (cachedUri != null && current === $.Uri__cachedBaseString)
+ return cachedUri;
+ uri = A.Uri_parse(current);
+ $.Uri__cachedBaseUri = uri;
+ $.Uri__cachedBaseString = current;
+ return uri;
},
_Uri__uriEncode(canonicalTable, text, encoding, spaceToPlus) {
var t1, bytes, i, t2, byte, t3,
_s16_ = "0123456789ABCDEF";
if (encoding === B.C_Utf8Codec) {
- t1 = $.$get$_Uri__needsNoEncoding()._nativeRegExp;
- t1 = t1.test(text);
+ t1 = $.$get$_Uri__needsNoEncoding();
+ t1 = t1._nativeRegExp.test(text);
} else
t1 = false;
if (t1)
return text;
- A._instanceType(encoding)._eval$1("Codec.S")._as(text);
- bytes = encoding.get$encoder().convert$1(text);
+ bytes = B.C_Utf8Encoder.convert$1(text);
for (t1 = bytes.length, i = 0, t2 = ""; i < t1; ++i) {
byte = bytes[i];
if (byte < 128) {
@@ -4635,7 +4688,12 @@
return J.toString$0$(object);
if (typeof object == "string")
return JSON.stringify(object);
- return A.Error__objectToString(object);
+ return A.Primitives_safeToString(object);
+ },
+ Error_throwWithStackTrace(error, stackTrace) {
+ A.checkNotNullable(error, "error", type$.Object);
+ A.checkNotNullable(stackTrace, "stackTrace", type$.StackTrace);
+ A.Error__throw(error, stackTrace);
},
AssertionError$(message) {
return new A.AssertionError(message);
@@ -4675,9 +4733,8 @@
throw A.wrapException(A.RangeError$range(value, 0, null, $name, null));
return value;
},
- IndexError$(invalidValue, indexable, $name, message, $length) {
- var t1 = A._asInt($length == null ? J.get$length$asx(indexable) : $length);
- return new A.IndexError(t1, true, invalidValue, $name, "Index out of range");
+ IndexError$withLength(invalidValue, $length, indexable, $name) {
+ return new A.IndexError($length, true, invalidValue, $name, "Index out of range");
},
UnsupportedError$(message) {
return new A.UnsupportedError(message);
@@ -4694,8 +4751,126 @@
FormatException$(message, source, offset) {
return new A.FormatException(message, source, offset);
},
+ Iterable_iterableToShortString(iterable, leftDelimiter, rightDelimiter) {
+ var parts, t1;
+ if (A.isToStringVisiting(iterable)) {
+ if (leftDelimiter === "(" && rightDelimiter === ")")
+ return "(...)";
+ return leftDelimiter + "..." + rightDelimiter;
+ }
+ parts = A._setArrayType([], type$.JSArray_String);
+ B.JSArray_methods.add$1($.toStringVisiting, iterable);
+ try {
+ A._iterablePartsToStrings(iterable, parts);
+ } finally {
+ if (0 >= $.toStringVisiting.length)
+ return A.ioore($.toStringVisiting, -1);
+ $.toStringVisiting.pop();
+ }
+ t1 = A.StringBuffer__writeAll(leftDelimiter, type$.Iterable_dynamic._as(parts), ", ") + rightDelimiter;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ Iterable_iterableToFullString(iterable, leftDelimiter, rightDelimiter) {
+ var buffer, t1;
+ if (A.isToStringVisiting(iterable))
+ return leftDelimiter + "..." + rightDelimiter;
+ buffer = new A.StringBuffer(leftDelimiter);
+ B.JSArray_methods.add$1($.toStringVisiting, iterable);
+ try {
+ t1 = buffer;
+ t1._contents = A.StringBuffer__writeAll(t1._contents, iterable, ", ");
+ } finally {
+ if (0 >= $.toStringVisiting.length)
+ return A.ioore($.toStringVisiting, -1);
+ $.toStringVisiting.pop();
+ }
+ buffer._contents += rightDelimiter;
+ t1 = buffer._contents;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ _iterablePartsToStrings(iterable, parts) {
+ var next, ultimateString, penultimateString, penultimate, ultimate, ultimate0, elision,
+ it = iterable.get$iterator(iterable),
+ $length = 0, count = 0;
+ while (true) {
+ if (!($length < 80 || count < 3))
+ break;
+ if (!it.moveNext$0())
+ return;
+ next = A.S(it.get$current(it));
+ B.JSArray_methods.add$1(parts, next);
+ $length += next.length + 2;
+ ++count;
+ }
+ if (!it.moveNext$0()) {
+ if (count <= 5)
+ return;
+ if (0 >= parts.length)
+ return A.ioore(parts, -1);
+ ultimateString = parts.pop();
+ if (0 >= parts.length)
+ return A.ioore(parts, -1);
+ penultimateString = parts.pop();
+ } else {
+ penultimate = it.get$current(it);
+ ++count;
+ if (!it.moveNext$0()) {
+ if (count <= 4) {
+ B.JSArray_methods.add$1(parts, A.S(penultimate));
+ return;
+ }
+ ultimateString = A.S(penultimate);
+ if (0 >= parts.length)
+ return A.ioore(parts, -1);
+ penultimateString = parts.pop();
+ $length += ultimateString.length + 2;
+ } else {
+ ultimate = it.get$current(it);
+ ++count;
+ for (; it.moveNext$0(); penultimate = ultimate, ultimate = ultimate0) {
+ ultimate0 = it.get$current(it);
+ ++count;
+ if (count > 100) {
+ while (true) {
+ if (!($length > 75 && count > 3))
+ break;
+ if (0 >= parts.length)
+ return A.ioore(parts, -1);
+ $length -= parts.pop().length + 2;
+ --count;
+ }
+ B.JSArray_methods.add$1(parts, "...");
+ return;
+ }
+ }
+ penultimateString = A.S(penultimate);
+ ultimateString = A.S(ultimate);
+ $length += ultimateString.length + penultimateString.length + 4;
+ }
+ }
+ if (count > parts.length + 2) {
+ $length += 5;
+ elision = "...";
+ } else
+ elision = null;
+ while (true) {
+ if (!($length > 80 && parts.length > 3))
+ break;
+ if (0 >= parts.length)
+ return A.ioore(parts, -1);
+ $length -= parts.pop().length + 2;
+ if (elision == null) {
+ $length += 5;
+ elision = "...";
+ }
+ }
+ if (elision != null)
+ B.JSArray_methods.add$1(parts, elision);
+ B.JSArray_methods.add$1(parts, penultimateString);
+ B.JSArray_methods.add$1(parts, ultimateString);
+ },
Object_hash(object1, object2, object3, object4) {
- var t1, t2;
+ var t1;
if (B.C_SentinelValue === object3) {
t1 = J.get$hashCode$(object1);
object2 = J.get$hashCode$(object2);
@@ -4711,8 +4886,8 @@
object2 = J.get$hashCode$(object2);
object3 = J.get$hashCode$(object3);
object4 = J.get$hashCode$(object4);
- t2 = $.$get$_hashSeed();
- return A.SystemHash_finish(A.SystemHash_combine(A.SystemHash_combine(A.SystemHash_combine(A.SystemHash_combine(t2, t1), object2), object3), object4));
+ object4 = A.SystemHash_finish(A.SystemHash_combine(A.SystemHash_combine(A.SystemHash_combine(A.SystemHash_combine($.$get$_hashSeed(), t1), object2), object3), object4));
+ return object4;
},
Uri_Uri$dataFromString($content) {
var t1, _null = null,
@@ -4721,7 +4896,7 @@
A.UriData__writeUri(_null, _null, _null, buffer, indices);
B.JSArray_methods.add$1(indices, buffer._contents.length);
buffer._contents += ",";
- A.UriData__uriEncodeBytes(B.List_CVk, B.C_AsciiCodec.encode$1($content), buffer);
+ A.UriData__uriEncodeBytes(B.List_oFp, B.C_AsciiCodec.encode$1($content), buffer);
t1 = buffer._contents;
return new A.UriData(t1.charCodeAt(0) == 0 ? t1 : t1, indices, _null).get$uri();
},
@@ -4729,7 +4904,9 @@
var delta, indices, schemeEnd, hostStart, portStart, pathStart, queryStart, fragmentStart, isSimple, scheme, t1, t2, schemeAuth, queryStart0, pathStart0, userInfoStart, userInfo, host, portNumber, port, path, query, _null = null,
end = uri.length;
if (end >= 5) {
- delta = ((B.JSString_methods._codeUnitAt$1(uri, 4) ^ 58) * 3 | B.JSString_methods._codeUnitAt$1(uri, 0) ^ 100 | B.JSString_methods._codeUnitAt$1(uri, 1) ^ 97 | B.JSString_methods._codeUnitAt$1(uri, 2) ^ 116 | B.JSString_methods._codeUnitAt$1(uri, 3) ^ 97) >>> 0;
+ if (4 >= end)
+ return A.ioore(uri, 4);
+ delta = ((uri.charCodeAt(4) ^ 58) * 3 | uri.charCodeAt(0) ^ 100 | uri.charCodeAt(1) ^ 97 | uri.charCodeAt(2) ^ 116 | uri.charCodeAt(3) ^ 97) >>> 0;
if (delta === 0)
return A.UriData__parse(end < end ? B.JSString_methods.substring$2(uri, 0, end) : uri, 5, _null).get$uri();
else if (delta === 32)
@@ -4774,66 +4951,78 @@
scheme = _null;
isSimple = false;
} else {
- if (!(queryStart < end && queryStart === pathStart + 2 && B.JSString_methods.startsWith$2(uri, "..", pathStart)))
- t2 = queryStart > pathStart + 2 && B.JSString_methods.startsWith$2(uri, "/..", queryStart - 3);
+ if (!B.JSString_methods.startsWith$2(uri, "\\", pathStart))
+ if (hostStart > 0)
+ t2 = B.JSString_methods.startsWith$2(uri, "\\", hostStart - 1) || B.JSString_methods.startsWith$2(uri, "\\", hostStart - 2);
+ else
+ t2 = false;
else
t2 = true;
if (t2) {
scheme = _null;
isSimple = false;
} else {
- if (schemeEnd === 4)
- if (B.JSString_methods.startsWith$2(uri, "file", 0)) {
- if (hostStart <= 0) {
- if (!B.JSString_methods.startsWith$2(uri, "/", pathStart)) {
- schemeAuth = "file:///";
- delta = 3;
- } else {
- schemeAuth = "file://";
- delta = 2;
+ if (!(queryStart < end && queryStart === pathStart + 2 && B.JSString_methods.startsWith$2(uri, "..", pathStart)))
+ t2 = queryStart > pathStart + 2 && B.JSString_methods.startsWith$2(uri, "/..", queryStart - 3);
+ else
+ t2 = true;
+ if (t2) {
+ scheme = _null;
+ isSimple = false;
+ } else {
+ if (schemeEnd === 4)
+ if (B.JSString_methods.startsWith$2(uri, "file", 0)) {
+ if (hostStart <= 0) {
+ if (!B.JSString_methods.startsWith$2(uri, "/", pathStart)) {
+ schemeAuth = "file:///";
+ delta = 3;
+ } else {
+ schemeAuth = "file://";
+ delta = 2;
+ }
+ uri = schemeAuth + B.JSString_methods.substring$2(uri, pathStart, end);
+ schemeEnd -= 0;
+ t1 = delta - 0;
+ queryStart += t1;
+ fragmentStart += t1;
+ end = uri.length;
+ hostStart = 7;
+ portStart = 7;
+ pathStart = 7;
+ } else if (pathStart === queryStart) {
+ ++fragmentStart;
+ queryStart0 = queryStart + 1;
+ uri = B.JSString_methods.replaceRange$3(uri, pathStart, queryStart, "/");
+ ++end;
+ queryStart = queryStart0;
}
- uri = schemeAuth + B.JSString_methods.substring$2(uri, pathStart, end);
- schemeEnd -= 0;
- t1 = delta - 0;
- queryStart += t1;
- fragmentStart += t1;
- end = uri.length;
- hostStart = 7;
- portStart = 7;
- pathStart = 7;
- } else if (pathStart === queryStart) {
- ++fragmentStart;
- queryStart0 = queryStart + 1;
- uri = B.JSString_methods.replaceRange$3(uri, pathStart, queryStart, "/");
- ++end;
- queryStart = queryStart0;
- }
- scheme = "file";
- } else if (B.JSString_methods.startsWith$2(uri, "http", 0)) {
- if (t1 && portStart + 3 === pathStart && B.JSString_methods.startsWith$2(uri, "80", portStart + 1)) {
- fragmentStart -= 3;
- pathStart0 = pathStart - 3;
- queryStart -= 3;
+ scheme = "file";
+ } else if (B.JSString_methods.startsWith$2(uri, "http", 0)) {
+ if (t1 && portStart + 3 === pathStart && B.JSString_methods.startsWith$2(uri, "80", portStart + 1)) {
+ fragmentStart -= 3;
+ pathStart0 = pathStart - 3;
+ queryStart -= 3;
+ uri = B.JSString_methods.replaceRange$3(uri, portStart, pathStart, "");
+ end -= 3;
+ pathStart = pathStart0;
+ }
+ scheme = "http";
+ } else
+ scheme = _null;
+ else if (schemeEnd === 5 && B.JSString_methods.startsWith$2(uri, "https", 0)) {
+ if (t1 && portStart + 4 === pathStart && B.JSString_methods.startsWith$2(uri, "443", portStart + 1)) {
+ fragmentStart -= 4;
+ pathStart0 = pathStart - 4;
+ queryStart -= 4;
uri = B.JSString_methods.replaceRange$3(uri, portStart, pathStart, "");
end -= 3;
pathStart = pathStart0;
}
- scheme = "http";
+ scheme = "https";
} else
scheme = _null;
- else if (schemeEnd === 5 && B.JSString_methods.startsWith$2(uri, "https", 0)) {
- if (t1 && portStart + 4 === pathStart && B.JSString_methods.startsWith$2(uri, "443", portStart + 1)) {
- fragmentStart -= 4;
- pathStart0 = pathStart - 4;
- queryStart -= 4;
- uri = B.JSString_methods.replaceRange$3(uri, portStart, pathStart, "");
- end -= 3;
- pathStart = pathStart0;
- }
- scheme = "https";
- } else
- scheme = _null;
- isSimple = true;
+ isSimple = true;
+ }
}
}
}
@@ -4887,13 +5076,15 @@
return B.JSArray_methods.fold$1$2(A._setArrayType(query.split("&"), type$.JSArray_String), A.LinkedHashMap_LinkedHashMap$_empty(t1, t1), new A.Uri_splitQueryString_closure(B.C_Utf8Codec), type$.Map_String_String);
},
Uri__parseIPv4Address(host, start, end) {
- var i, partStart, partIndex, char, part, partIndex0,
+ var t1, i, partStart, partIndex, char, part, partIndex0,
_s43_ = "IPv4 address should contain exactly 4 parts",
_s37_ = "each part must be in the range 0..255",
error = new A.Uri__parseIPv4Address_error(host),
result = new Uint8Array(4);
- for (i = start, partStart = i, partIndex = 0; i < end; ++i) {
- char = B.JSString_methods.codeUnitAt$1(host, i);
+ for (t1 = host.length, i = start, partStart = i, partIndex = 0; i < end; ++i) {
+ if (!(i >= 0 && i < t1))
+ return A.ioore(host, i);
+ char = host.charCodeAt(i);
if (char !== 46) {
if ((char ^ 48) > 9)
error.call$2("invalid character", i);
@@ -4922,18 +5113,23 @@
return result;
},
Uri_parseIPv6Address(host, start, end) {
- var parts, i, partStart, wildcardSeen, seenDot, char, atEnd, t1, last, bytes, wildCardLength, index, value, j, t2, _null = null,
+ var parts, i, partStart, wildcardSeen, seenDot, char, atEnd, last, bytes, wildCardLength, index, value, j, t2, _null = null,
error = new A.Uri_parseIPv6Address_error(host),
- parseHex = new A.Uri_parseIPv6Address_parseHex(error, host);
- if (host.length < 2)
+ parseHex = new A.Uri_parseIPv6Address_parseHex(error, host),
+ t1 = host.length;
+ if (t1 < 2)
error.call$2("address is too short", _null);
parts = A._setArrayType([], type$.JSArray_int);
for (i = start, partStart = i, wildcardSeen = false, seenDot = false; i < end; ++i) {
- char = B.JSString_methods.codeUnitAt$1(host, i);
+ if (!(i >= 0 && i < t1))
+ return A.ioore(host, i);
+ char = host.charCodeAt(i);
if (char === 58) {
if (i === start) {
++i;
- if (B.JSString_methods.codeUnitAt$1(host, i) !== 58)
+ if (!(i < t1))
+ return A.ioore(host, i);
+ if (host.charCodeAt(i) !== 58)
error.call$2("invalid start colon.", i);
partStart = i;
}
@@ -5037,30 +5233,24 @@
return windows ? A._Uri__makeWindowsFileUrl(path, false) : A._Uri__makeFileUri(path, false);
},
_Uri__checkNonWindowsPathReservedCharacters(segments, argumentError) {
- var t1, _i, segment, t2, t3;
+ var t1, _i, segment;
for (t1 = segments.length, _i = 0; _i < t1; ++_i) {
segment = segments[_i];
- t2 = J.getInterceptor$asx(segment);
- t3 = t2.get$length(segment);
- if (0 > t3)
- A.throwExpression(A.RangeError$range(0, 0, t2.get$length(segment), null, null));
- if (A.stringContainsUnchecked(segment, "/", 0)) {
+ if (J.contains$1$asx(segment, "/")) {
t1 = A.UnsupportedError$("Illegal path character " + A.S(segment));
throw A.wrapException(t1);
}
}
},
_Uri__checkWindowsPathReservedCharacters(segments, argumentError, firstSegment) {
- var t1, t2, t3, t4, t5, _null = null;
- for (t1 = A.SubListIterable$(segments, firstSegment, _null, A._arrayInstanceType(segments)._precomputed1), t2 = t1.$ti, t1 = new A.ListIterator(t1, t1.get$length(t1), t2._eval$1("ListIterator<ListIterable.E>")), t2 = t2._eval$1("ListIterable.E"); t1.moveNext$0();) {
+ var t1, t2, t3;
+ for (t1 = A.SubListIterable$(segments, firstSegment, null, A._arrayInstanceType(segments)._precomputed1), t2 = t1.$ti, t1 = new A.ListIterator(t1, t1.get$length(t1), t2._eval$1("ListIterator<ListIterable.E>")), t2 = t2._eval$1("ListIterable.E"); t1.moveNext$0();) {
t3 = t1.__internal$_current;
if (t3 == null)
t3 = t2._as(t3);
- t4 = A.RegExp_RegExp('["*/:<>?\\\\|]', false);
- t5 = t3.length;
- if (A.stringContainsUnchecked(t3, t4, 0))
+ if (B.JSString_methods.contains$1(t3, A.RegExp_RegExp('["*/:<>?\\\\|]', false)))
if (argumentError)
- throw A.wrapException(A.ArgumentError$("Illegal character in path", _null));
+ throw A.wrapException(A.ArgumentError$("Illegal character in path", null));
else
throw A.wrapException(A.UnsupportedError$("Illegal character in path: " + t3));
}
@@ -5094,16 +5284,36 @@
path = B.JSString_methods.replaceRange$3(path, 0, 7, _s1_);
else {
path = B.JSString_methods.substring$1(path, 4);
- if (path.length < 3 || B.JSString_methods._codeUnitAt$1(path, 1) !== 58 || B.JSString_methods._codeUnitAt$1(path, 2) !== 92)
- throw A.wrapException(A.ArgumentError$("Windows paths with \\\\?\\ prefix must be absolute", _null));
+ t1 = path.length;
+ if (t1 >= 3) {
+ if (1 >= t1)
+ return A.ioore(path, 1);
+ if (path.charCodeAt(1) === 58) {
+ if (2 >= t1)
+ return A.ioore(path, 2);
+ t1 = path.charCodeAt(2) !== 92;
+ } else
+ t1 = true;
+ } else
+ t1 = true;
+ if (t1)
+ throw A.wrapException(A.ArgumentError$value(path, "path", "Windows paths with \\\\?\\ prefix must be absolute"));
}
else
path = A.stringReplaceAllUnchecked(path, "/", _s1_);
t1 = path.length;
- if (t1 > 1 && B.JSString_methods._codeUnitAt$1(path, 1) === 58) {
- A._Uri__checkWindowsDriveLetter(B.JSString_methods._codeUnitAt$1(path, 0), true);
- if (t1 === 2 || B.JSString_methods._codeUnitAt$1(path, 2) !== 92)
- throw A.wrapException(A.ArgumentError$("Windows paths with drive letter must be absolute", _null));
+ if (t1 > 1 && path.charCodeAt(1) === 58) {
+ if (0 >= t1)
+ return A.ioore(path, 0);
+ A._Uri__checkWindowsDriveLetter(path.charCodeAt(0), true);
+ if (t1 !== 2) {
+ if (2 >= t1)
+ return A.ioore(path, 2);
+ t1 = path.charCodeAt(2) !== 92;
+ } else
+ t1 = true;
+ if (t1)
+ throw A.wrapException(A.ArgumentError$value(path, "path", "Windows paths with drive letter must be absolute"));
pathSegments = A._setArrayType(path.split(_s1_), type$.JSArray_String);
A._Uri__checkWindowsPathReservedCharacters(pathSegments, true, 1);
return A._Uri__Uri(_null, _null, pathSegments, _s4_);
@@ -5138,22 +5348,29 @@
return null;
if (start === end)
return "";
- if (B.JSString_methods.codeUnitAt$1(host, start) === 91) {
- t1 = end - 1;
- if (B.JSString_methods.codeUnitAt$1(host, t1) !== 93)
+ t1 = host.length;
+ if (!(start >= 0 && start < t1))
+ return A.ioore(host, start);
+ if (host.charCodeAt(start) === 91) {
+ t2 = end - 1;
+ if (!(t2 >= 0 && t2 < t1))
+ return A.ioore(host, t2);
+ if (host.charCodeAt(t2) !== 93)
A._Uri__fail(host, start, "Missing end `]` to match `[` in host");
- t2 = start + 1;
- index = A._Uri__checkZoneID(host, t2, t1);
- if (index < t1) {
+ t1 = start + 1;
+ index = A._Uri__checkZoneID(host, t1, t2);
+ if (index < t2) {
zoneIDstart = index + 1;
- zoneID = A._Uri__normalizeZoneID(host, B.JSString_methods.startsWith$2(host, "25", zoneIDstart) ? index + 3 : zoneIDstart, t1, "%25");
+ zoneID = A._Uri__normalizeZoneID(host, B.JSString_methods.startsWith$2(host, "25", zoneIDstart) ? index + 3 : zoneIDstart, t2, "%25");
} else
zoneID = "";
- A.Uri_parseIPv6Address(host, t2, index);
+ A.Uri_parseIPv6Address(host, t1, index);
return B.JSString_methods.substring$2(host, start, index).toLowerCase() + zoneID + "]";
}
- for (i = start; i < end; ++i)
- if (B.JSString_methods.codeUnitAt$1(host, i) === 58) {
+ for (i = start; i < end; ++i) {
+ if (!(i < t1))
+ return A.ioore(host, i);
+ if (host.charCodeAt(i) === 58) {
index = B.JSString_methods.indexOf$2(host, "%", start);
index = index >= start && index < end ? index : end;
if (index < end) {
@@ -5164,6 +5381,7 @@
A.Uri_parseIPv6Address(host, start, index);
return "[" + B.JSString_methods.substring$2(host, start, index) + zoneID + "]";
}
+ }
return A._Uri__normalizeRegName(host, start, end);
},
_Uri__checkZoneID(host, start, end) {
@@ -5171,37 +5389,39 @@
return index >= start && index < end ? index : end;
},
_Uri__normalizeZoneID(host, start, end, prefix) {
- var index, sectionStart, isNormalized, char, replacement, t1, t2, tail, sourceLength, slice,
+ var t1, index, sectionStart, isNormalized, char, replacement, t2, t3, tail, sourceLength, slice,
buffer = prefix !== "" ? new A.StringBuffer(prefix) : null;
- for (index = start, sectionStart = index, isNormalized = true; index < end;) {
- char = B.JSString_methods.codeUnitAt$1(host, index);
+ for (t1 = host.length, index = start, sectionStart = index, isNormalized = true; index < end;) {
+ if (!(index >= 0 && index < t1))
+ return A.ioore(host, index);
+ char = host.charCodeAt(index);
if (char === 37) {
replacement = A._Uri__normalizeEscape(host, index, true);
- t1 = replacement == null;
- if (t1 && isNormalized) {
+ t2 = replacement == null;
+ if (t2 && isNormalized) {
index += 3;
continue;
}
if (buffer == null)
buffer = new A.StringBuffer("");
- t2 = buffer._contents += B.JSString_methods.substring$2(host, sectionStart, index);
- if (t1)
+ t3 = buffer._contents += B.JSString_methods.substring$2(host, sectionStart, index);
+ if (t2)
replacement = B.JSString_methods.substring$2(host, index, index + 3);
else if (replacement === "%")
A._Uri__fail(host, index, "ZoneID should not contain % anymore");
- buffer._contents = t2 + replacement;
+ buffer._contents = t3 + replacement;
index += 3;
sectionStart = index;
isNormalized = true;
} else {
if (char < 127) {
- t1 = char >>> 4;
- if (!(t1 < 8))
- return A.ioore(B.List_nxB, t1);
- t1 = (B.List_nxB[t1] & 1 << (char & 15)) !== 0;
+ t2 = char >>> 4;
+ if (!(t2 < 8))
+ return A.ioore(B.List_M1A, t2);
+ t2 = (B.List_M1A[t2] & 1 << (char & 15)) !== 0;
} else
- t1 = false;
- if (t1) {
+ t2 = false;
+ if (t2) {
if (isNormalized && 65 <= char && 90 >= char) {
if (buffer == null)
buffer = new A.StringBuffer("");
@@ -5214,7 +5434,10 @@
++index;
} else {
if ((char & 64512) === 55296 && index + 1 < end) {
- tail = B.JSString_methods.codeUnitAt$1(host, index + 1);
+ t2 = index + 1;
+ if (!(t2 < t1))
+ return A.ioore(host, t2);
+ tail = host.charCodeAt(t2);
if ((tail & 64512) === 56320) {
char = (char & 1023) << 10 | tail & 1023 | 65536;
sourceLength = 2;
@@ -5225,11 +5448,11 @@
slice = B.JSString_methods.substring$2(host, sectionStart, index);
if (buffer == null) {
buffer = new A.StringBuffer("");
- t1 = buffer;
+ t2 = buffer;
} else
- t1 = buffer;
- t1._contents += slice;
- t1._contents += A._Uri__escapeChar(char);
+ t2 = buffer;
+ t2._contents += slice;
+ t2._contents += A._Uri__escapeChar(char);
index += sourceLength;
sectionStart = index;
}
@@ -5243,21 +5466,23 @@
return t1.charCodeAt(0) == 0 ? t1 : t1;
},
_Uri__normalizeRegName(host, start, end) {
- var index, sectionStart, buffer, isNormalized, char, replacement, t1, slice, t2, sourceLength, tail;
- for (index = start, sectionStart = index, buffer = null, isNormalized = true; index < end;) {
- char = B.JSString_methods.codeUnitAt$1(host, index);
+ var t1, index, sectionStart, buffer, isNormalized, char, replacement, t2, slice, t3, sourceLength, tail;
+ for (t1 = host.length, index = start, sectionStart = index, buffer = null, isNormalized = true; index < end;) {
+ if (!(index >= 0 && index < t1))
+ return A.ioore(host, index);
+ char = host.charCodeAt(index);
if (char === 37) {
replacement = A._Uri__normalizeEscape(host, index, true);
- t1 = replacement == null;
- if (t1 && isNormalized) {
+ t2 = replacement == null;
+ if (t2 && isNormalized) {
index += 3;
continue;
}
if (buffer == null)
buffer = new A.StringBuffer("");
slice = B.JSString_methods.substring$2(host, sectionStart, index);
- t2 = buffer._contents += !isNormalized ? slice.toLowerCase() : slice;
- if (t1) {
+ t3 = buffer._contents += !isNormalized ? slice.toLowerCase() : slice;
+ if (t2) {
replacement = B.JSString_methods.substring$2(host, index, index + 3);
sourceLength = 3;
} else if (replacement === "%") {
@@ -5265,19 +5490,19 @@
sourceLength = 1;
} else
sourceLength = 3;
- buffer._contents = t2 + replacement;
+ buffer._contents = t3 + replacement;
index += sourceLength;
sectionStart = index;
isNormalized = true;
} else {
if (char < 127) {
- t1 = char >>> 4;
- if (!(t1 < 8))
- return A.ioore(B.List_qNA, t1);
- t1 = (B.List_qNA[t1] & 1 << (char & 15)) !== 0;
+ t2 = char >>> 4;
+ if (!(t2 < 8))
+ return A.ioore(B.List_ejq, t2);
+ t2 = (B.List_ejq[t2] & 1 << (char & 15)) !== 0;
} else
- t1 = false;
- if (t1) {
+ t2 = false;
+ if (t2) {
if (isNormalized && 65 <= char && 90 >= char) {
if (buffer == null)
buffer = new A.StringBuffer("");
@@ -5290,17 +5515,20 @@
++index;
} else {
if (char <= 93) {
- t1 = char >>> 4;
- if (!(t1 < 8))
- return A.ioore(B.List_2Vk, t1);
- t1 = (B.List_2Vk[t1] & 1 << (char & 15)) !== 0;
+ t2 = char >>> 4;
+ if (!(t2 < 8))
+ return A.ioore(B.List_YmH, t2);
+ t2 = (B.List_YmH[t2] & 1 << (char & 15)) !== 0;
} else
- t1 = false;
- if (t1)
+ t2 = false;
+ if (t2)
A._Uri__fail(host, index, "Invalid character");
else {
if ((char & 64512) === 55296 && index + 1 < end) {
- tail = B.JSString_methods.codeUnitAt$1(host, index + 1);
+ t2 = index + 1;
+ if (!(t2 < t1))
+ return A.ioore(host, t2);
+ tail = host.charCodeAt(t2);
if ((tail & 64512) === 56320) {
char = (char & 1023) << 10 | tail & 1023 | 65536;
sourceLength = 2;
@@ -5313,11 +5541,11 @@
slice = slice.toLowerCase();
if (buffer == null) {
buffer = new A.StringBuffer("");
- t1 = buffer;
+ t2 = buffer;
} else
- t1 = buffer;
- t1._contents += slice;
- t1._contents += A._Uri__escapeChar(char);
+ t2 = buffer;
+ t2._contents += slice;
+ t2._contents += A._Uri__escapeChar(char);
index += sourceLength;
sectionStart = index;
}
@@ -5334,21 +5562,26 @@
return t1.charCodeAt(0) == 0 ? t1 : t1;
},
_Uri__makeScheme(scheme, start, end) {
- var i, containsUpperCase, codeUnit, t1;
+ var t1, i, containsUpperCase, codeUnit, t2;
if (start === end)
return "";
- if (!A._Uri__isAlphabeticCharacter(B.JSString_methods._codeUnitAt$1(scheme, start)))
+ t1 = scheme.length;
+ if (!(start < t1))
+ return A.ioore(scheme, start);
+ if (!A._Uri__isAlphabeticCharacter(scheme.charCodeAt(start)))
A._Uri__fail(scheme, start, "Scheme not starting with alphabetic character");
for (i = start, containsUpperCase = false; i < end; ++i) {
- codeUnit = B.JSString_methods._codeUnitAt$1(scheme, i);
+ if (!(i < t1))
+ return A.ioore(scheme, i);
+ codeUnit = scheme.charCodeAt(i);
if (codeUnit < 128) {
- t1 = codeUnit >>> 4;
- if (!(t1 < 8))
- return A.ioore(B.List_JYB, t1);
- t1 = (B.List_JYB[t1] & 1 << (codeUnit & 15)) !== 0;
+ t2 = codeUnit >>> 4;
+ if (!(t2 < 8))
+ return A.ioore(B.List_MMm, t2);
+ t2 = (B.List_MMm[t2] & 1 << (codeUnit & 15)) !== 0;
} else
- t1 = false;
- if (!t1)
+ t2 = false;
+ if (!t2)
A._Uri__fail(scheme, i, "Illegal scheme character");
if (65 <= codeUnit && codeUnit <= 90)
containsUpperCase = true;
@@ -5370,7 +5603,7 @@
_Uri__makeUserInfo(userInfo, start, end) {
if (userInfo == null)
return "";
- return A._Uri__normalizeOrSubstring(userInfo, start, end, B.List_gRj, false);
+ return A._Uri__normalizeOrSubstring(userInfo, start, end, B.List_OL3, false, false);
},
_Uri__makePath(path, start, end, pathSegments, scheme, hasAuthority) {
var t1, result,
@@ -5384,7 +5617,7 @@
} else if (pathSegments != null)
throw A.wrapException(A.ArgumentError$("Both path and pathSegments specified", null));
else
- result = A._Uri__normalizeOrSubstring(path, start, end, B.List_qg4, true);
+ result = A._Uri__normalizeOrSubstring(path, start, end, B.List_XRg, true, true);
if (result.length === 0) {
if (isFile)
return "/";
@@ -5394,27 +5627,33 @@
},
_Uri__normalizePath(path, scheme, hasAuthority) {
var t1 = scheme.length === 0;
- if (t1 && !hasAuthority && !B.JSString_methods.startsWith$1(path, "/"))
+ if (t1 && !hasAuthority && !B.JSString_methods.startsWith$1(path, "/") && !B.JSString_methods.startsWith$1(path, "\\"))
return A._Uri__normalizeRelativePath(path, !t1 || hasAuthority);
return A._Uri__removeDotSegments(path);
},
_Uri__makeQuery(query, start, end, queryParameters) {
if (query != null)
- return A._Uri__normalizeOrSubstring(query, start, end, B.List_CVk, true);
+ return A._Uri__normalizeOrSubstring(query, start, end, B.List_oFp, true, false);
return null;
},
_Uri__makeFragment(fragment, start, end) {
if (fragment == null)
return null;
- return A._Uri__normalizeOrSubstring(fragment, start, end, B.List_CVk, true);
+ return A._Uri__normalizeOrSubstring(fragment, start, end, B.List_oFp, true, false);
},
_Uri__normalizeEscape(source, index, lowerCase) {
- var firstDigit, secondDigit, firstDigitValue, secondDigitValue, value,
- t1 = index + 2;
- if (t1 >= source.length)
+ var t3, firstDigit, secondDigit, firstDigitValue, secondDigitValue, value,
+ t1 = index + 2,
+ t2 = source.length;
+ if (t1 >= t2)
return "%";
- firstDigit = B.JSString_methods.codeUnitAt$1(source, index + 1);
- secondDigit = B.JSString_methods.codeUnitAt$1(source, t1);
+ t3 = index + 1;
+ if (!(t3 >= 0 && t3 < t2))
+ return A.ioore(source, t3);
+ firstDigit = source.charCodeAt(t3);
+ if (!(t1 >= 0))
+ return A.ioore(source, t1);
+ secondDigit = source.charCodeAt(t1);
firstDigitValue = A.hexDigitValue(firstDigit);
secondDigitValue = A.hexDigitValue(secondDigit);
if (firstDigitValue < 0 || secondDigitValue < 0)
@@ -5423,8 +5662,8 @@
if (value < 127) {
t1 = B.JSInt_methods._shrOtherPositive$1(value, 4);
if (!(t1 < 8))
- return A.ioore(B.List_nxB, t1);
- t1 = (B.List_nxB[t1] & 1 << (value & 15)) !== 0;
+ return A.ioore(B.List_M1A, t1);
+ t1 = (B.List_M1A[t1] & 1 << (value & 15)) !== 0;
} else
t1 = false;
if (t1)
@@ -5434,13 +5673,16 @@
return null;
},
_Uri__escapeChar(char) {
- var codeUnits, flag, encodedBytes, t1, index, byte, t2, t3,
+ var codeUnits, t1, flag, encodedBytes, index, byte, t2, t3,
_s16_ = "0123456789ABCDEF";
if (char < 128) {
codeUnits = new Uint8Array(3);
codeUnits[0] = 37;
- codeUnits[1] = B.JSString_methods._codeUnitAt$1(_s16_, char >>> 4);
- codeUnits[2] = B.JSString_methods._codeUnitAt$1(_s16_, char & 15);
+ t1 = char >>> 4;
+ if (!(t1 < 16))
+ return A.ioore(_s16_, t1);
+ codeUnits[1] = _s16_.charCodeAt(t1);
+ codeUnits[2] = _s16_.charCodeAt(char & 15);
} else {
if (char > 2047)
if (char > 65535) {
@@ -5462,36 +5704,39 @@
return A.ioore(codeUnits, index);
codeUnits[index] = 37;
t2 = index + 1;
- t3 = B.JSString_methods._codeUnitAt$1(_s16_, byte >>> 4);
+ t3 = byte >>> 4;
+ if (!(t3 < 16))
+ return A.ioore(_s16_, t3);
if (!(t2 < t1))
return A.ioore(codeUnits, t2);
- codeUnits[t2] = t3;
+ codeUnits[t2] = _s16_.charCodeAt(t3);
t3 = index + 2;
- t2 = B.JSString_methods._codeUnitAt$1(_s16_, byte & 15);
if (!(t3 < t1))
return A.ioore(codeUnits, t3);
- codeUnits[t3] = t2;
+ codeUnits[t3] = _s16_.charCodeAt(byte & 15);
index += 3;
}
}
return A.String_String$fromCharCodes(codeUnits, 0, null);
},
- _Uri__normalizeOrSubstring(component, start, end, charTable, escapeDelimiters) {
- var t1 = A._Uri__normalize(component, start, end, charTable, escapeDelimiters);
+ _Uri__normalizeOrSubstring(component, start, end, charTable, escapeDelimiters, replaceBackslash) {
+ var t1 = A._Uri__normalize(component, start, end, charTable, escapeDelimiters, replaceBackslash);
return t1 == null ? B.JSString_methods.substring$2(component, start, end) : t1;
},
- _Uri__normalize(component, start, end, charTable, escapeDelimiters) {
- var t1, index, sectionStart, buffer, char, t2, replacement, sourceLength, tail, t3, _null = null;
- for (t1 = !escapeDelimiters, index = start, sectionStart = index, buffer = _null; index < end;) {
- char = B.JSString_methods.codeUnitAt$1(component, index);
+ _Uri__normalize(component, start, end, charTable, escapeDelimiters, replaceBackslash) {
+ var t1, t2, index, sectionStart, buffer, char, t3, replacement, sourceLength, tail, t4, _null = null;
+ for (t1 = !escapeDelimiters, t2 = component.length, index = start, sectionStart = index, buffer = _null; index < end;) {
+ if (!(index >= 0 && index < t2))
+ return A.ioore(component, index);
+ char = component.charCodeAt(index);
if (char < 127) {
- t2 = char >>> 4;
- if (!(t2 < 8))
- return A.ioore(charTable, t2);
- t2 = (charTable[t2] & 1 << (char & 15)) !== 0;
+ t3 = char >>> 4;
+ if (!(t3 < 8))
+ return A.ioore(charTable, t3);
+ t3 = (charTable[t3] & 1 << (char & 15)) !== 0;
} else
- t2 = false;
- if (t2)
+ t3 = false;
+ if (t3)
++index;
else {
if (char === 37) {
@@ -5505,26 +5750,31 @@
sourceLength = 1;
} else
sourceLength = 3;
+ } else if (char === 92 && replaceBackslash) {
+ replacement = "/";
+ sourceLength = 1;
} else {
if (t1)
if (char <= 93) {
- t2 = char >>> 4;
- if (!(t2 < 8))
- return A.ioore(B.List_2Vk, t2);
- t2 = (B.List_2Vk[t2] & 1 << (char & 15)) !== 0;
+ t3 = char >>> 4;
+ if (!(t3 < 8))
+ return A.ioore(B.List_YmH, t3);
+ t3 = (B.List_YmH[t3] & 1 << (char & 15)) !== 0;
} else
- t2 = false;
+ t3 = false;
else
- t2 = false;
- if (t2) {
+ t3 = false;
+ if (t3) {
A._Uri__fail(component, index, "Invalid character");
sourceLength = _null;
replacement = sourceLength;
} else {
if ((char & 64512) === 55296) {
- t2 = index + 1;
- if (t2 < end) {
- tail = B.JSString_methods.codeUnitAt$1(component, t2);
+ t3 = index + 1;
+ if (t3 < end) {
+ if (!(t3 < t2))
+ return A.ioore(component, t3);
+ tail = component.charCodeAt(t3);
if ((tail & 64512) === 56320) {
char = (char & 1023) << 10 | tail & 1023 | 65536;
sourceLength = 2;
@@ -5539,11 +5789,11 @@
}
if (buffer == null) {
buffer = new A.StringBuffer("");
- t2 = buffer;
+ t3 = buffer;
} else
- t2 = buffer;
- t3 = t2._contents += B.JSString_methods.substring$2(component, sectionStart, index);
- t2._contents = t3 + A.S(replacement);
+ t3 = buffer;
+ t4 = t3._contents += B.JSString_methods.substring$2(component, sectionStart, index);
+ t3._contents = t4 + A.S(replacement);
if (typeof sourceLength !== "number")
return A.iae(sourceLength);
index += sourceLength;
@@ -5638,16 +5888,16 @@
_Uri__escapeScheme(path) {
var i, char, t2,
t1 = path.length;
- if (t1 >= 2 && A._Uri__isAlphabeticCharacter(B.JSString_methods._codeUnitAt$1(path, 0)))
+ if (t1 >= 2 && A._Uri__isAlphabeticCharacter(path.charCodeAt(0)))
for (i = 1; i < t1; ++i) {
- char = B.JSString_methods._codeUnitAt$1(path, i);
+ char = path.charCodeAt(i);
if (char === 58)
return B.JSString_methods.substring$2(path, 0, i) + "%3A" + B.JSString_methods.substring$1(path, i + 1);
if (char <= 127) {
t2 = char >>> 4;
if (!(t2 < 8))
- return A.ioore(B.List_JYB, t2);
- t2 = (B.List_JYB[t2] & 1 << (char & 15)) === 0;
+ return A.ioore(B.List_MMm, t2);
+ t2 = (B.List_MMm[t2] & 1 << (char & 15)) === 0;
} else
t2 = true;
if (t2)
@@ -5685,9 +5935,12 @@
return t1.charCodeAt(0) == 0 ? t1 : t1;
},
_Uri__hexCharPairToByte(s, pos) {
- var byte, i, charCode;
- for (byte = 0, i = 0; i < 2; ++i) {
- charCode = B.JSString_methods._codeUnitAt$1(s, pos + i);
+ var t1, byte, i, t2, charCode;
+ for (t1 = s.length, byte = 0, i = 0; i < 2; ++i) {
+ t2 = pos + i;
+ if (!(t2 < t1))
+ return A.ioore(s, t2);
+ charCode = s.charCodeAt(t2);
if (48 <= charCode && charCode <= 57)
byte = byte * 16 + charCode - 48;
else {
@@ -5701,22 +5954,25 @@
return byte;
},
_Uri__uriDecode(text, start, end, encoding, plusToSpace) {
- var simple, codeUnit, t1, bytes,
+ var simple, codeUnit, t2, bytes,
+ t1 = text.length,
i = start;
while (true) {
if (!(i < end)) {
simple = true;
break;
}
- codeUnit = B.JSString_methods._codeUnitAt$1(text, i);
+ if (!(i < t1))
+ return A.ioore(text, i);
+ codeUnit = text.charCodeAt(i);
if (codeUnit <= 127)
if (codeUnit !== 37)
- t1 = plusToSpace && codeUnit === 43;
+ t2 = plusToSpace && codeUnit === 43;
else
- t1 = true;
+ t2 = true;
else
- t1 = true;
- if (t1) {
+ t2 = true;
+ if (t2) {
simple = false;
break;
}
@@ -5733,8 +5989,10 @@
bytes = new A.CodeUnits(B.JSString_methods.substring$2(text, start, end));
} else {
bytes = A._setArrayType([], type$.JSArray_int);
- for (t1 = text.length, i = start; i < end; ++i) {
- codeUnit = B.JSString_methods._codeUnitAt$1(text, i);
+ for (i = start; i < end; ++i) {
+ if (!(i < t1))
+ return A.ioore(text, i);
+ codeUnit = text.charCodeAt(i);
if (codeUnit > 127)
throw A.wrapException(A.ArgumentError$("Illegal percent encoding in URI", null));
if (codeUnit === 37) {
@@ -5763,15 +6021,15 @@
slashIndex = A.UriData__validateMimeType("");
if (slashIndex < 0)
throw A.wrapException(A.ArgumentError$value("", "mimeType", "Invalid MIME type"));
- t1 = buffer._contents += A._Uri__uriEncode(B.List_qFt, B.JSString_methods.substring$2("", 0, slashIndex), B.C_Utf8Codec, false);
+ t1 = buffer._contents += A._Uri__uriEncode(B.List_yzX, B.JSString_methods.substring$2("", 0, slashIndex), B.C_Utf8Codec, false);
buffer._contents = t1 + "/";
- buffer._contents += A._Uri__uriEncode(B.List_qFt, B.JSString_methods.substring$1("", slashIndex + 1), B.C_Utf8Codec, false);
+ buffer._contents += A._Uri__uriEncode(B.List_yzX, B.JSString_methods.substring$1("", slashIndex + 1), B.C_Utf8Codec, false);
}
},
UriData__validateMimeType(mimeType) {
var t1, slashIndex, i;
for (t1 = mimeType.length, slashIndex = -1, i = 0; i < t1; ++i) {
- if (B.JSString_methods._codeUnitAt$1(mimeType, i) !== 47)
+ if (mimeType.charCodeAt(i) !== 47)
continue;
if (slashIndex < 0) {
slashIndex = i;
@@ -5786,7 +6044,7 @@
_s17_ = "Invalid MIME type",
indices = A._setArrayType([start - 1], type$.JSArray_int);
for (t1 = text.length, i = start, slashIndex = -1, char = null; i < t1; ++i) {
- char = B.JSString_methods._codeUnitAt$1(text, i);
+ char = text.charCodeAt(i);
if (char === 44 || char === 59)
break;
if (char === 47) {
@@ -5803,7 +6061,9 @@
B.JSArray_methods.add$1(indices, i);
++i;
for (equalsIndex = -1; i < t1; ++i) {
- char = B.JSString_methods._codeUnitAt$1(text, i);
+ if (!(i >= 0))
+ return A.ioore(text, i);
+ char = text.charCodeAt(i);
if (char === 61) {
if (equalsIndex < 0)
equalsIndex = i;
@@ -5824,183 +6084,198 @@
if ((indices.length & 1) === 1)
text = B.C_Base64Codec.normalize$3(0, text, t2, t1);
else {
- data = A._Uri__normalize(text, t2, t1, B.List_CVk, true);
+ data = A._Uri__normalize(text, t2, t1, B.List_oFp, true, false);
if (data != null)
text = B.JSString_methods.replaceRange$3(text, t2, t1, data);
}
return new A.UriData(text, indices, sourceUri);
},
UriData__uriEncodeBytes(canonicalTable, bytes, buffer) {
- var t1, byteOr, i, byte, t2, t3,
+ var t1, byteOr, i, byte, t2,
_s16_ = "0123456789ABCDEF";
- for (t1 = J.getInterceptor$asx(bytes), byteOr = 0, i = 0; i < t1.get$length(bytes); ++i) {
- byte = t1.$index(bytes, i);
+ for (t1 = bytes.length, byteOr = 0, i = 0; i < t1; ++i) {
+ byte = bytes[i];
byteOr |= byte;
if (byte < 128) {
- t2 = B.JSInt_methods._shrOtherPositive$1(byte, 4);
+ t2 = byte >>> 4;
if (!(t2 < 8))
return A.ioore(canonicalTable, t2);
t2 = (canonicalTable[t2] & 1 << (byte & 15)) !== 0;
} else
t2 = false;
- t3 = buffer._contents;
if (t2)
- buffer._contents = t3 + A.Primitives_stringFromCharCode(byte);
+ buffer._contents += A.Primitives_stringFromCharCode(byte);
else {
- t2 = t3 + A.Primitives_stringFromCharCode(37);
- buffer._contents = t2;
- t2 += A.Primitives_stringFromCharCode(B.JSString_methods._codeUnitAt$1(_s16_, B.JSInt_methods._shrOtherPositive$1(byte, 4)));
- buffer._contents = t2;
- buffer._contents = t2 + A.Primitives_stringFromCharCode(B.JSString_methods._codeUnitAt$1(_s16_, byte & 15));
+ buffer._contents += A.Primitives_stringFromCharCode(37);
+ t2 = byte >>> 4;
+ if (!(t2 < 16))
+ return A.ioore(_s16_, t2);
+ buffer._contents += A.Primitives_stringFromCharCode(_s16_.charCodeAt(t2));
+ buffer._contents += A.Primitives_stringFromCharCode(_s16_.charCodeAt(byte & 15));
}
}
- if ((byteOr & 4294967040) >>> 0 !== 0)
- for (i = 0; i < t1.get$length(bytes); ++i) {
- byte = t1.$index(bytes, i);
- if (byte < 0 || byte > 255)
+ if ((byteOr & 4294967040) !== 0)
+ for (i = 0; i < t1; ++i) {
+ byte = bytes[i];
+ if (byte > 255)
throw A.wrapException(A.ArgumentError$value(byte, "non-byte value", null));
}
},
_createTables() {
- var _i, t1, t2, t3, t4, b,
+ var _i, t1, t2, t3, t4, t5,
_s77_ = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~!$&'()*+,;=",
- _s1_ = ".", _s1_0 = ":", _s1_1 = "/", _s1_2 = "?", _s1_3 = "#",
+ _s1_ = ".", _s1_0 = ":", _s1_1 = "/", _s1_2 = "\\", _s1_3 = "?", _s1_4 = "#", _s2_ = "/\\",
tables = A._setArrayType(new Array(22), type$.JSArray_Uint8List);
for (_i = 0; _i < 22; ++_i)
tables[_i] = new Uint8Array(96);
t1 = new A._createTables_build(tables);
t2 = new A._createTables_setChars();
t3 = new A._createTables_setRange();
- t4 = type$.Uint8List._as(t1.call$2(0, 225));
- t2.call$3(t4, _s77_, 1);
- t2.call$3(t4, _s1_, 14);
- t2.call$3(t4, _s1_0, 34);
- t2.call$3(t4, _s1_1, 3);
- t2.call$3(t4, _s1_2, 172);
- t2.call$3(t4, _s1_3, 205);
- b = t1.call$2(14, 225);
- t2.call$3(b, _s77_, 1);
- t2.call$3(b, _s1_, 15);
- t2.call$3(b, _s1_0, 34);
- t2.call$3(b, _s1_1, 234);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(15, 225);
- t2.call$3(b, _s77_, 1);
- t2.call$3(b, "%", 225);
- t2.call$3(b, _s1_0, 34);
- t2.call$3(b, _s1_1, 9);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(1, 225);
- t2.call$3(b, _s77_, 1);
- t2.call$3(b, _s1_0, 34);
- t2.call$3(b, _s1_1, 10);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(2, 235);
- t2.call$3(b, _s77_, 139);
- t2.call$3(b, _s1_1, 131);
- t2.call$3(b, _s1_, 146);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(3, 235);
- t2.call$3(b, _s77_, 11);
- t2.call$3(b, _s1_1, 68);
- t2.call$3(b, _s1_, 18);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(4, 229);
- t2.call$3(b, _s77_, 5);
- t3.call$3(b, "AZ", 229);
- t2.call$3(b, _s1_0, 102);
- t2.call$3(b, "@", 68);
- t2.call$3(b, "[", 232);
- t2.call$3(b, _s1_1, 138);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(5, 229);
- t2.call$3(b, _s77_, 5);
- t3.call$3(b, "AZ", 229);
- t2.call$3(b, _s1_0, 102);
- t2.call$3(b, "@", 68);
- t2.call$3(b, _s1_1, 138);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(6, 231);
- t3.call$3(b, "19", 7);
- t2.call$3(b, "@", 68);
- t2.call$3(b, _s1_1, 138);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(7, 231);
- t3.call$3(b, "09", 7);
- t2.call$3(b, "@", 68);
- t2.call$3(b, _s1_1, 138);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- t2.call$3(t1.call$2(8, 8), "]", 5);
- b = t1.call$2(9, 235);
- t2.call$3(b, _s77_, 11);
- t2.call$3(b, _s1_, 16);
- t2.call$3(b, _s1_1, 234);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(16, 235);
- t2.call$3(b, _s77_, 11);
- t2.call$3(b, _s1_, 17);
- t2.call$3(b, _s1_1, 234);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(17, 235);
- t2.call$3(b, _s77_, 11);
- t2.call$3(b, _s1_1, 9);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(10, 235);
- t2.call$3(b, _s77_, 11);
- t2.call$3(b, _s1_, 18);
- t2.call$3(b, _s1_1, 234);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(18, 235);
- t2.call$3(b, _s77_, 11);
- t2.call$3(b, _s1_, 19);
- t2.call$3(b, _s1_1, 234);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(19, 235);
- t2.call$3(b, _s77_, 11);
- t2.call$3(b, _s1_1, 234);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(11, 235);
- t2.call$3(b, _s77_, 11);
- t2.call$3(b, _s1_1, 10);
- t2.call$3(b, _s1_2, 172);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(12, 236);
- t2.call$3(b, _s77_, 12);
- t2.call$3(b, _s1_2, 12);
- t2.call$3(b, _s1_3, 205);
- b = t1.call$2(13, 237);
- t2.call$3(b, _s77_, 13);
- t2.call$3(b, _s1_2, 13);
- t3.call$3(t1.call$2(20, 245), "az", 21);
- b = t1.call$2(21, 245);
- t3.call$3(b, "az", 21);
- t3.call$3(b, "09", 21);
- t2.call$3(b, "+-.", 21);
+ t4 = type$.Uint8List;
+ t5 = t4._as(t1.call$2(0, 225));
+ t2.call$3(t5, _s77_, 1);
+ t2.call$3(t5, _s1_, 14);
+ t2.call$3(t5, _s1_0, 34);
+ t2.call$3(t5, _s1_1, 3);
+ t2.call$3(t5, _s1_2, 227);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(14, 225));
+ t2.call$3(t5, _s77_, 1);
+ t2.call$3(t5, _s1_, 15);
+ t2.call$3(t5, _s1_0, 34);
+ t2.call$3(t5, _s2_, 234);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(15, 225));
+ t2.call$3(t5, _s77_, 1);
+ t2.call$3(t5, "%", 225);
+ t2.call$3(t5, _s1_0, 34);
+ t2.call$3(t5, _s1_1, 9);
+ t2.call$3(t5, _s1_2, 233);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(1, 225));
+ t2.call$3(t5, _s77_, 1);
+ t2.call$3(t5, _s1_0, 34);
+ t2.call$3(t5, _s1_1, 10);
+ t2.call$3(t5, _s1_2, 234);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(2, 235));
+ t2.call$3(t5, _s77_, 139);
+ t2.call$3(t5, _s1_1, 131);
+ t2.call$3(t5, _s1_2, 131);
+ t2.call$3(t5, _s1_, 146);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(3, 235));
+ t2.call$3(t5, _s77_, 11);
+ t2.call$3(t5, _s1_1, 68);
+ t2.call$3(t5, _s1_2, 68);
+ t2.call$3(t5, _s1_, 18);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(4, 229));
+ t2.call$3(t5, _s77_, 5);
+ t3.call$3(t5, "AZ", 229);
+ t2.call$3(t5, _s1_0, 102);
+ t2.call$3(t5, "@", 68);
+ t2.call$3(t5, "[", 232);
+ t2.call$3(t5, _s1_1, 138);
+ t2.call$3(t5, _s1_2, 138);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(5, 229));
+ t2.call$3(t5, _s77_, 5);
+ t3.call$3(t5, "AZ", 229);
+ t2.call$3(t5, _s1_0, 102);
+ t2.call$3(t5, "@", 68);
+ t2.call$3(t5, _s1_1, 138);
+ t2.call$3(t5, _s1_2, 138);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(6, 231));
+ t3.call$3(t5, "19", 7);
+ t2.call$3(t5, "@", 68);
+ t2.call$3(t5, _s1_1, 138);
+ t2.call$3(t5, _s1_2, 138);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(7, 231));
+ t3.call$3(t5, "09", 7);
+ t2.call$3(t5, "@", 68);
+ t2.call$3(t5, _s1_1, 138);
+ t2.call$3(t5, _s1_2, 138);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t2.call$3(t4._as(t1.call$2(8, 8)), "]", 5);
+ t5 = t4._as(t1.call$2(9, 235));
+ t2.call$3(t5, _s77_, 11);
+ t2.call$3(t5, _s1_, 16);
+ t2.call$3(t5, _s2_, 234);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(16, 235));
+ t2.call$3(t5, _s77_, 11);
+ t2.call$3(t5, _s1_, 17);
+ t2.call$3(t5, _s2_, 234);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(17, 235));
+ t2.call$3(t5, _s77_, 11);
+ t2.call$3(t5, _s1_1, 9);
+ t2.call$3(t5, _s1_2, 233);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(10, 235));
+ t2.call$3(t5, _s77_, 11);
+ t2.call$3(t5, _s1_, 18);
+ t2.call$3(t5, _s1_1, 10);
+ t2.call$3(t5, _s1_2, 234);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(18, 235));
+ t2.call$3(t5, _s77_, 11);
+ t2.call$3(t5, _s1_, 19);
+ t2.call$3(t5, _s2_, 234);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(19, 235));
+ t2.call$3(t5, _s77_, 11);
+ t2.call$3(t5, _s2_, 234);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(11, 235));
+ t2.call$3(t5, _s77_, 11);
+ t2.call$3(t5, _s1_1, 10);
+ t2.call$3(t5, _s1_2, 234);
+ t2.call$3(t5, _s1_3, 172);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(12, 236));
+ t2.call$3(t5, _s77_, 12);
+ t2.call$3(t5, _s1_3, 12);
+ t2.call$3(t5, _s1_4, 205);
+ t5 = t4._as(t1.call$2(13, 237));
+ t2.call$3(t5, _s77_, 13);
+ t2.call$3(t5, _s1_3, 13);
+ t3.call$3(t4._as(t1.call$2(20, 245)), "az", 21);
+ t1 = t4._as(t1.call$2(21, 245));
+ t3.call$3(t1, "az", 21);
+ t3.call$3(t1, "09", 21);
+ t2.call$3(t1, "+-.", 21);
return tables;
},
_scan(uri, start, end, state, indices) {
- var i, table, char, transition,
+ var t1, i, table, char, transition,
tables = $.$get$_scannerTables();
- for (i = start; i < end; ++i) {
+ for (t1 = uri.length, i = start; i < end; ++i) {
if (!(state >= 0 && state < tables.length))
return A.ioore(tables, state);
table = tables[state];
- char = B.JSString_methods._codeUnitAt$1(uri, i) ^ 96;
+ if (!(i < t1))
+ return A.ioore(uri, i);
+ char = uri.charCodeAt(i) ^ 96;
transition = table[char > 95 ? 31 : char];
state = transition & 31;
B.JSArray_methods.$indexSet(indices, transition >>> 5, i);
@@ -6013,9 +6288,11 @@
return -1;
},
_skipPackageNameChars(source, start, end) {
- var i, dots, char;
- for (i = start, dots = 0; i < end; ++i) {
- char = B.JSString_methods.codeUnitAt$1(source, i);
+ var t1, i, dots, char;
+ for (t1 = source.length, i = start, dots = 0; i < end; ++i) {
+ if (!(i >= 0 && i < t1))
+ return A.ioore(source, i);
+ char = source.charCodeAt(i);
if (char === 47)
return dots !== 0 ? i : -1;
if (char === 37 || char === 58)
@@ -6025,11 +6302,13 @@
return -1;
},
_caseInsensitiveCompareStart(prefix, string, start) {
- var t1, result, i, prefixChar, stringChar, delta, lowerChar;
- for (t1 = prefix.length, result = 0, i = 0; i < t1; ++i) {
- prefixChar = B.JSString_methods._codeUnitAt$1(prefix, i);
- stringChar = B.JSString_methods._codeUnitAt$1(string, start + i);
- delta = prefixChar ^ stringChar;
+ var t1, t2, result, i, t3, stringChar, delta, lowerChar;
+ for (t1 = prefix.length, t2 = string.length, result = 0, i = 0; i < t1; ++i) {
+ t3 = start + i;
+ if (!(t3 < t2))
+ return A.ioore(string, t3);
+ stringChar = string.charCodeAt(t3);
+ delta = prefix.charCodeAt(i) ^ stringChar;
if (delta !== 0) {
if (delta === 32) {
lowerChar = stringChar | delta;
@@ -6048,7 +6327,7 @@
this.sb = t1;
},
DateTime: function DateTime(t0, t1) {
- this._value = t0;
+ this._core$_value = t0;
this.isUtc = t1;
},
Duration: function Duration(t0) {
@@ -6061,8 +6340,6 @@
},
TypeError: function TypeError() {
},
- NullThrownError: function NullThrownError() {
- },
ArgumentError: function ArgumentError(t0, t1, t2, t3) {
var _ = this;
_._hasValue = t0;
@@ -6110,9 +6387,6 @@
},
StackOverflowError: function StackOverflowError() {
},
- CyclicInitializationError: function CyclicInitializationError(t0) {
- this.variableName = t0;
- },
_Exception: function _Exception(t0) {
this.message = t0;
},
@@ -6123,8 +6397,6 @@
},
Iterable: function Iterable() {
},
- Iterator: function Iterator() {
- },
Null: function Null() {
},
Object: function Object() {
@@ -6424,10 +6696,38 @@
},
__StyleSheetList_JavaScriptObject_ListMixin_ImmutableListMixin: function __StyleSheetList_JavaScriptObject_ListMixin_ImmutableListMixin() {
},
- _convertDataTree(data) {
- var t1 = new A._convertDataTree__convert(new A._IdentityHashMap(type$._IdentityHashMap_dynamic_dynamic)).call$1(data);
- t1.toString;
- return t1;
+ _convertDartFunctionFast(f) {
+ var ret,
+ existing = f.$dart_jsFunction;
+ if (existing != null)
+ return existing;
+ ret = function(_call, f) {
+ return function() {
+ return _call(f, Array.prototype.slice.apply(arguments));
+ };
+ }(A._callDartFunctionFast, f);
+ ret[$.$get$DART_CLOSURE_PROPERTY_NAME()] = f;
+ f.$dart_jsFunction = ret;
+ return ret;
+ },
+ _callDartFunctionFast(callback, $arguments) {
+ type$.List_dynamic._as($arguments);
+ type$.Function._as(callback);
+ return A.Primitives_applyFunction(callback, $arguments, null);
+ },
+ allowInterop(f, $F) {
+ if (typeof f == "function")
+ return f;
+ else
+ return $F._as(A._convertDartFunctionFast(f));
+ },
+ _noJsifyRequired(o) {
+ return o == null || A._isBool(o) || typeof o == "number" || typeof o == "string" || type$.Int8List._is(o) || type$.Uint8List._is(o) || type$.Uint8ClampedList._is(o) || type$.Int16List._is(o) || type$.Uint16List._is(o) || type$.Int32List._is(o) || type$.Uint32List._is(o) || type$.Float32List._is(o) || type$.Float64List._is(o) || type$.ByteBuffer._is(o) || type$.ByteData._is(o);
+ },
+ jsify(object) {
+ if (A._noJsifyRequired(object))
+ return object;
+ return new A.jsify__convert(new A._IdentityHashMap(type$._IdentityHashMap_of_nullable_Object_and_nullable_Object)).call$1(object);
},
getProperty(o, $name, $T) {
return $T._as(o[$name]);
@@ -6462,10 +6762,15 @@
jsPromise.then(A.convertDartClosureToJS(new A.promiseToFuture_closure(completer, $T), 1), A.convertDartClosureToJS(new A.promiseToFuture_closure0(completer), 1));
return t1;
},
- dartify(o) {
- return new A.dartify_convert(new A._IdentityHashMap(type$._IdentityHashMap_dynamic_dynamic)).call$1(o);
+ _noDartifyRequired(o) {
+ return o == null || typeof o === "boolean" || typeof o === "number" || typeof o === "string" || o instanceof Int8Array || o instanceof Uint8Array || o instanceof Uint8ClampedArray || o instanceof Int16Array || o instanceof Uint16Array || o instanceof Int32Array || o instanceof Uint32Array || o instanceof Float32Array || o instanceof Float64Array || o instanceof ArrayBuffer || o instanceof DataView;
},
- _convertDataTree__convert: function _convertDataTree__convert(t0) {
+ dartify(o) {
+ if (A._noDartifyRequired(o))
+ return o;
+ return new A.dartify_convert(new A._IdentityHashMap(type$._IdentityHashMap_of_nullable_Object_and_nullable_Object)).call$1(o);
+ },
+ jsify__convert: function jsify__convert(t0) {
this._convertedObjects = t0;
},
promiseToFuture_closure: function promiseToFuture_closure(t0, t1) {
@@ -6538,10 +6843,7 @@
this.$this = t0;
},
Context_Context(style) {
- var current = style == null ? A.current() : ".";
- if (style == null)
- style = $.$get$Style_platform();
- return new A.Context(type$.InternalStyle._as(style), current);
+ return new A.Context(style, ".");
},
_parseUri(uri) {
return uri;
@@ -6582,7 +6884,7 @@
InternalStyle: function InternalStyle() {
},
ParsedPath_ParsedPath$parse(path, style) {
- var t1, parts, separators, start, i,
+ var t1, parts, separators, t2, start, i,
root = style.getRoot$1(path);
style.isRootRelative$1(path);
if (root != null)
@@ -6591,7 +6893,13 @@
parts = A._setArrayType([], t1);
separators = A._setArrayType([], t1);
t1 = path.length;
- if (t1 !== 0 && style.isSeparator$1(B.JSString_methods._codeUnitAt$1(path, 0))) {
+ if (t1 !== 0) {
+ if (0 >= t1)
+ return A.ioore(path, 0);
+ t2 = style.isSeparator$1(path.charCodeAt(0));
+ } else
+ t2 = false;
+ if (t2) {
if (0 >= t1)
return A.ioore(path, 0);
B.JSArray_methods.add$1(separators, path[0]);
@@ -6601,7 +6909,7 @@
start = 0;
}
for (i = start; i < t1; ++i)
- if (style.isSeparator$1(B.JSString_methods._codeUnitAt$1(path, i))) {
+ if (style.isSeparator$1(path.charCodeAt(i))) {
B.JSArray_methods.add$1(parts, B.JSString_methods.substring$2(path, start, i));
B.JSArray_methods.add$1(separators, path[i]);
start = i + 1;
@@ -6660,28 +6968,24 @@
},
Chain_Chain$parse(chain) {
var t1, t2,
- _s51_ = string$.______;
+ _s51_ = string$.x3d_____;
if (chain.length === 0)
return new A.Chain(A.List_List$unmodifiable(A._setArrayType([], type$.JSArray_Trace), type$.Trace));
t1 = $.$get$vmChainGap();
if (B.JSString_methods.contains$1(chain, t1)) {
t1 = B.JSString_methods.split$1(chain, t1);
t2 = A._arrayInstanceType(t1);
- return new A.Chain(A.List_List$unmodifiable(new A.MappedIterable(new A.WhereIterable(t1, t2._eval$1("bool(1)")._as(new A.Chain_Chain$parse_closure()), t2._eval$1("WhereIterable<1>")), t2._eval$1("Trace(1)")._as(new A.Chain_Chain$parse_closure0()), t2._eval$1("MappedIterable<1,Trace>")), type$.Trace));
+ return new A.Chain(A.List_List$unmodifiable(new A.MappedIterable(new A.WhereIterable(t1, t2._eval$1("bool(1)")._as(new A.Chain_Chain$parse_closure()), t2._eval$1("WhereIterable<1>")), t2._eval$1("Trace(1)")._as(A.trace_Trace___parseVM_tearOff$closure()), t2._eval$1("MappedIterable<1,Trace>")), type$.Trace));
}
if (!B.JSString_methods.contains$1(chain, _s51_))
return new A.Chain(A.List_List$unmodifiable(A._setArrayType([A.Trace_Trace$parse(chain)], type$.JSArray_Trace), type$.Trace));
- return new A.Chain(A.List_List$unmodifiable(new A.MappedListIterable(A._setArrayType(chain.split(_s51_), type$.JSArray_String), type$.Trace_Function_String._as(new A.Chain_Chain$parse_closure1()), type$.MappedListIterable_String_Trace), type$.Trace));
+ return new A.Chain(A.List_List$unmodifiable(new A.MappedListIterable(A._setArrayType(chain.split(_s51_), type$.JSArray_String), type$.Trace_Function_String._as(A.trace_Trace___parseFriendly_tearOff$closure()), type$.MappedListIterable_String_Trace), type$.Trace));
},
Chain: function Chain(t0) {
this.traces = t0;
},
Chain_Chain$parse_closure: function Chain_Chain$parse_closure() {
},
- Chain_Chain$parse_closure0: function Chain_Chain$parse_closure0() {
- },
- Chain_Chain$parse_closure1: function Chain_Chain$parse_closure1() {
- },
Chain_toTrace_closure: function Chain_toTrace_closure() {
},
Chain_toString_closure0: function Chain_toString_closure0() {
@@ -6694,18 +6998,30 @@
Chain_toString__closure: function Chain_toString__closure(t0) {
this.longest = t0;
},
+ Frame___parseVM_tearOff(frame) {
+ return A.Frame_Frame$parseVM(A._asString(frame));
+ },
Frame_Frame$parseVM(frame) {
return A.Frame__catchFormatException(frame, new A.Frame_Frame$parseVM_closure(frame));
},
+ Frame___parseV8_tearOff(frame) {
+ return A.Frame_Frame$parseV8(A._asString(frame));
+ },
Frame_Frame$parseV8(frame) {
return A.Frame__catchFormatException(frame, new A.Frame_Frame$parseV8_closure(frame));
},
Frame_Frame$_parseFirefoxEval(frame) {
return A.Frame__catchFormatException(frame, new A.Frame_Frame$_parseFirefoxEval_closure(frame));
},
+ Frame___parseFirefox_tearOff(frame) {
+ return A.Frame_Frame$parseFirefox(A._asString(frame));
+ },
Frame_Frame$parseFirefox(frame) {
return A.Frame__catchFormatException(frame, new A.Frame_Frame$parseFirefox_closure(frame));
},
+ Frame___parseFriendly_tearOff(frame) {
+ return A.Frame_Frame$parseFriendly(A._asString(frame));
+ },
Frame_Frame$parseFriendly(frame) {
return A.Frame__catchFormatException(frame, new A.Frame_Frame$parseFriendly_closure(frame));
},
@@ -6790,7 +7106,7 @@
t1 = A.Trace$parseFirefox(trace);
return t1;
}
- if (B.JSString_methods.contains$1(trace, string$.______)) {
+ if (B.JSString_methods.contains$1(trace, string$.x3d_____)) {
t1 = A.Chain_Chain$parse(trace).toTrace$0();
return t1;
}
@@ -6809,6 +7125,9 @@
throw exception;
}
},
+ Trace___parseVM_tearOff(trace) {
+ return A.Trace$parseVM(A._asString(trace));
+ },
Trace$parseVM(trace) {
var t1 = A.List_List$unmodifiable(A.Trace__parseVM(trace), type$.Frame);
return new A.Trace(t1, new A._StringStackTrace(trace));
@@ -6816,14 +7135,14 @@
Trace__parseVM(trace) {
var $frames,
t1 = B.JSString_methods.trim$0(trace),
- t2 = type$.Pattern._as($.$get$vmChainGap()),
+ t2 = $.$get$vmChainGap(),
t3 = type$.WhereIterable_String,
lines = new A.WhereIterable(A._setArrayType(A.stringReplaceAllUnchecked(t1, t2, "").split("\n"), type$.JSArray_String), type$.bool_Function_String._as(new A.Trace__parseVM_closure()), t3);
if (!lines.get$iterator(lines).moveNext$0())
return A._setArrayType([], type$.JSArray_Frame);
t1 = A.TakeIterable_TakeIterable(lines, lines.get$length(lines) - 1, t3._eval$1("Iterable.E"));
t2 = A._instanceType(t1);
- t2 = A.MappedIterable_MappedIterable(t1, t2._eval$1("Frame(Iterable.E)")._as(new A.Trace__parseVM_closure0()), t2._eval$1("Iterable.E"), type$.Frame);
+ t2 = A.MappedIterable_MappedIterable(t1, t2._eval$1("Frame(Iterable.E)")._as(A.frame_Frame___parseVM_tearOff$closure()), t2._eval$1("Iterable.E"), type$.Frame);
$frames = A.List_List$of(t2, true, A._instanceType(t2)._eval$1("Iterable.E"));
if (!J.endsWith$1$s(lines.get$last(lines), ".da"))
B.JSArray_methods.add$1($frames, A.Frame_Frame$parseVM(lines.get$last(lines)));
@@ -6835,19 +7154,22 @@
t1 = t1.super$Iterable$skipWhile(0, t1.$ti._eval$1("bool(ListIterable.E)")._as(new A.Trace$parseV8_closure()));
t2 = type$.Frame;
t3 = t1.$ti;
- t2 = A.List_List$unmodifiable(A.MappedIterable_MappedIterable(t1, t3._eval$1("Frame(Iterable.E)")._as(new A.Trace$parseV8_closure0()), t3._eval$1("Iterable.E"), t2), t2);
+ t2 = A.List_List$unmodifiable(A.MappedIterable_MappedIterable(t1, t3._eval$1("Frame(Iterable.E)")._as(A.frame_Frame___parseV8_tearOff$closure()), t3._eval$1("Iterable.E"), t2), t2);
return new A.Trace(t2, new A._StringStackTrace(trace));
},
Trace$parseJSCore(trace) {
- var t1 = A.List_List$unmodifiable(new A.MappedIterable(new A.WhereIterable(A._setArrayType(trace.split("\n"), type$.JSArray_String), type$.bool_Function_String._as(new A.Trace$parseJSCore_closure()), type$.WhereIterable_String), type$.Frame_Function_String._as(new A.Trace$parseJSCore_closure0()), type$.MappedIterable_String_Frame), type$.Frame);
+ var t1 = A.List_List$unmodifiable(new A.MappedIterable(new A.WhereIterable(A._setArrayType(trace.split("\n"), type$.JSArray_String), type$.bool_Function_String._as(new A.Trace$parseJSCore_closure()), type$.WhereIterable_String), type$.Frame_Function_String._as(A.frame_Frame___parseV8_tearOff$closure()), type$.MappedIterable_String_Frame), type$.Frame);
return new A.Trace(t1, new A._StringStackTrace(trace));
},
Trace$parseFirefox(trace) {
- var t1 = A.List_List$unmodifiable(new A.MappedIterable(new A.WhereIterable(A._setArrayType(B.JSString_methods.trim$0(trace).split("\n"), type$.JSArray_String), type$.bool_Function_String._as(new A.Trace$parseFirefox_closure()), type$.WhereIterable_String), type$.Frame_Function_String._as(new A.Trace$parseFirefox_closure0()), type$.MappedIterable_String_Frame), type$.Frame);
+ var t1 = A.List_List$unmodifiable(new A.MappedIterable(new A.WhereIterable(A._setArrayType(B.JSString_methods.trim$0(trace).split("\n"), type$.JSArray_String), type$.bool_Function_String._as(new A.Trace$parseFirefox_closure()), type$.WhereIterable_String), type$.Frame_Function_String._as(A.frame_Frame___parseFirefox_tearOff$closure()), type$.MappedIterable_String_Frame), type$.Frame);
return new A.Trace(t1, new A._StringStackTrace(trace));
},
+ Trace___parseFriendly_tearOff(trace) {
+ return A.Trace$parseFriendly(A._asString(trace));
+ },
Trace$parseFriendly(trace) {
- var t1 = trace.length === 0 ? A._setArrayType([], type$.JSArray_Frame) : new A.MappedIterable(new A.WhereIterable(A._setArrayType(B.JSString_methods.trim$0(trace).split("\n"), type$.JSArray_String), type$.bool_Function_String._as(new A.Trace$parseFriendly_closure()), type$.WhereIterable_String), type$.Frame_Function_String._as(new A.Trace$parseFriendly_closure0()), type$.MappedIterable_String_Frame);
+ var t1 = trace.length === 0 ? A._setArrayType([], type$.JSArray_Frame) : new A.MappedIterable(new A.WhereIterable(A._setArrayType(B.JSString_methods.trim$0(trace).split("\n"), type$.JSArray_String), type$.bool_Function_String._as(new A.Trace$parseFriendly_closure()), type$.WhereIterable_String), type$.Frame_Function_String._as(A.frame_Frame___parseFriendly_tearOff$closure()), type$.MappedIterable_String_Frame);
t1 = A.List_List$unmodifiable(t1, type$.Frame);
return new A.Trace(t1, new A._StringStackTrace(trace));
},
@@ -6864,24 +7186,14 @@
},
Trace__parseVM_closure: function Trace__parseVM_closure() {
},
- Trace__parseVM_closure0: function Trace__parseVM_closure0() {
- },
Trace$parseV8_closure: function Trace$parseV8_closure() {
},
- Trace$parseV8_closure0: function Trace$parseV8_closure0() {
- },
Trace$parseJSCore_closure: function Trace$parseJSCore_closure() {
},
- Trace$parseJSCore_closure0: function Trace$parseJSCore_closure0() {
- },
Trace$parseFirefox_closure: function Trace$parseFirefox_closure() {
},
- Trace$parseFirefox_closure0: function Trace$parseFirefox_closure0() {
- },
Trace$parseFriendly_closure: function Trace$parseFriendly_closure() {
},
- Trace$parseFriendly_closure0: function Trace$parseFriendly_closure0() {
- },
Trace_terse_closure: function Trace_terse_closure() {
},
Trace_foldFrames_closure: function Trace_foldFrames_closure(t0) {
@@ -7002,13 +7314,17 @@
},
StreamChannelMixin: function StreamChannelMixin() {
},
- WindowExtension_get_location(_this) {
- return type$.JavaScriptObject._as(_this.location);
- },
EventTargetExtension_addEventListener(_this, type, listener) {
var t1 = A._setArrayType([type, listener], type$.JSArray_Object);
A.callMethod(_this, "addEventListener", t1, type$.dynamic);
},
+ EventTargetExtension_removeEventListener(_this, type, listener) {
+ var t1 = A._setArrayType([type, listener], type$.JSArray_Object);
+ A.callMethod(_this, "removeEventListener", t1, type$.dynamic);
+ },
+ MessagePortExtension_get_postMessage(_this) {
+ return new A.MessagePortExtension_get_postMessage_closure(_this);
+ },
_callConstructor(constructorName, args) {
var $constructor = self.window[constructorName];
if ($constructor == null)
@@ -7019,43 +7335,8 @@
A.EventTargetExtension_addEventListener(target, type, listener);
return new A.Subscription(type, target, listener);
},
- Window0: function Window0() {
- },
- Document0: function Document0() {
- },
- HTMLDocument: function HTMLDocument() {
- },
- Navigator0: function Navigator0() {
- },
- Element0: function Element0() {
- },
- HTMLElement: function HTMLElement() {
- },
- HTMLBodyElement: function HTMLBodyElement() {
- },
- Node0: function Node0() {
- },
- EventTarget0: function EventTarget0() {
- },
- Event0: function Event0() {
- },
- MessageEvent0: function MessageEvent0() {
- },
- Location0: function Location0() {
- },
- MessagePort0: function MessagePort0() {
- },
- CSSStyleDeclaration: function CSSStyleDeclaration() {
- },
- HTMLScriptElement: function HTMLScriptElement() {
- },
- DomTokenList0: function DomTokenList0() {
- },
- HTMLIFrameElement: function HTMLIFrameElement() {
- },
- WebSocket0: function WebSocket0() {
- },
- MessageChannel0: function MessageChannel0() {
+ MessagePortExtension_get_postMessage_closure: function MessagePortExtension_get_postMessage_closure(t0) {
+ this._this = t0;
},
Subscription: function Subscription(t0, t1, t2) {
this.type = t0;
@@ -7063,9 +7344,6 @@
this.listener = t2;
},
main() {
- var t1 = self.testRunner;
- if (t1 != null)
- t1.waitUntilDone();
if (J.$eq$($.$get$_currentUrl().get$queryParameters().$index(0, "debug"), "true"))
type$.JavaScriptObject._as(type$.nullable_JavaScriptObject._as(self.document.body).classList).add("debug");
A.runZonedGuarded(new A.main_closure(), new A.main_closure0(), type$.Null);
@@ -7090,41 +7368,21 @@
return A._MultiChannel$(t1, t2);
},
_connectToIframe(url, id) {
- var controller, readyCompleter, subscriptions, domSubscriptions,
+ var controller, windowSubscription,
t1 = self.document,
- t2 = type$.JSArray_Object,
- t3 = A._setArrayType(["iframe"], t2),
- t4 = type$.dynamic,
- t5 = type$.JavaScriptObject,
- iframe = t5._as(A.callMethod(t1, "createElement", t3, t4));
+ t2 = A._setArrayType(["iframe"], type$.JSArray_Object),
+ t3 = type$.dynamic,
+ t4 = type$.JavaScriptObject,
+ iframe = t4._as(A.callMethod(t1, "createElement", t2, t3));
$._iframes.$indexSet(0, id, iframe);
+ controller = A.StreamChannelController$(true, t3);
+ windowSubscription = A._Cell$named("windowSubscription");
+ windowSubscription._value = A.Subscription$(self.window, "message", A.allowInterop(new A._connectToIframe_closure(iframe, windowSubscription, id, controller), type$.void_Function_JavaScriptObject));
iframe.src = url;
- t5._as(type$.nullable_JavaScriptObject._as(self.document.body).appendChild(iframe));
- t2 = A._callConstructor("MessageChannel", A._setArrayType([], t2));
- t2.toString;
- t5._as(t2);
- controller = A.StreamChannelController$(true, t4);
- readyCompleter = new A._AsyncCompleter(new A._Future($.Zone__current, type$._Future_dynamic), type$._AsyncCompleter_dynamic);
- subscriptions = A._setArrayType([], type$.JSArray_StreamSubscription_void);
- domSubscriptions = A._setArrayType([], type$.JSArray_Subscription);
- $._subscriptions.$indexSet(0, id, subscriptions);
- $._domSubscriptions.$indexSet(0, id, domSubscriptions);
- t4 = type$.void_Function_JavaScriptObject;
- B.JSArray_methods.add$1(domSubscriptions, A.Subscription$(self.window, "message", A.allowInterop(new A._connectToIframe_closure(iframe, t2, readyCompleter, controller), t4)));
- t5._as(t2.port1).start();
- B.JSArray_methods.add$1(domSubscriptions, A.Subscription$(t5._as(t2.port1), "message", A.allowInterop(new A._connectToIframe_closure0(controller), t4)));
- t4 = controller.__StreamChannelController__local_F;
- t4 === $ && A.throwLateFieldNI("_local");
- t4 = t4.__GuaranteeChannel__streamController_F;
- t4 === $ && A.throwLateFieldNI("_streamController");
- B.JSArray_methods.add$1(subscriptions, new A._ControllerStream(t4, A._instanceType(t4)._eval$1("_ControllerStream<1>")).listen$1(new A._connectToIframe_closure1(readyCompleter, t2)));
- t2 = controller.__StreamChannelController__foreign_F;
- t2 === $ && A.throwLateFieldNI("_foreign");
- return t2;
- },
- TestRunner: function TestRunner() {
- },
- _JSApi: function _JSApi() {
+ t4._as(type$.nullable_JavaScriptObject._as(self.document.body).appendChild(iframe));
+ t4 = controller.__StreamChannelController__foreign_F;
+ t4 === $ && A.throwLateFieldNI("_foreign");
+ return t4;
},
main_closure: function main_closure() {
},
@@ -7154,16 +7412,24 @@
_connectToIframe_closure: function _connectToIframe_closure(t0, t1, t2, t3) {
var _ = this;
_.iframe = t0;
- _.channel = t1;
- _.readyCompleter = t2;
+ _.windowSubscription = t1;
+ _.id = t2;
_.controller = t3;
},
- _connectToIframe_closure0: function _connectToIframe_closure0(t0) {
+ _connectToIframe__closure2: function _connectToIframe__closure2(t0) {
this.controller = t0;
},
- _connectToIframe_closure1: function _connectToIframe_closure1(t0, t1) {
- this.readyCompleter = t0;
- this.channel = t1;
+ _connectToIframe__closure: function _connectToIframe__closure(t0) {
+ this._0_0 = t0;
+ },
+ _connectToIframe__closure3: function _connectToIframe__closure3(t0) {
+ this.controller = t0;
+ },
+ _connectToIframe__closure0: function _connectToIframe__closure0(t0) {
+ this._0_0 = t0;
+ },
+ _connectToIframe__closure1: function _connectToIframe__closure1(t0) {
+ this._0_0 = t0;
},
max(a, b, $T) {
A.checkTypeBound($T, type$.num, "T", "max");
@@ -7178,8 +7444,6 @@
console.log(string);
return;
}
- if (typeof window == "object")
- return;
if (typeof print == "function") {
print(string);
return;
@@ -7187,62 +7451,52 @@
throw "Unable to print message: " + String(string);
},
_convertNativeToDart_Value(value) {
- var values, i;
+ var proto, t1, values, i;
if (value == null)
return value;
if (typeof value == "string" || typeof value == "number" || A._isBool(value))
return value;
- if (A.isJavaScriptSimpleObject(value))
+ proto = Object.getPrototypeOf(value);
+ t1 = proto === Object.prototype;
+ t1.toString;
+ if (!t1) {
+ t1 = proto === null;
+ t1.toString;
+ } else
+ t1 = true;
+ if (t1)
return A.convertNativeToDart_Dictionary(value);
- if (Array.isArray(value)) {
+ t1 = Array.isArray(value);
+ t1.toString;
+ if (t1) {
values = [];
- for (i = 0; i < value.length; ++i)
+ i = 0;
+ while (true) {
+ t1 = value.length;
+ t1.toString;
+ if (!(i < t1))
+ break;
values.push(A._convertNativeToDart_Value(value[i]));
+ ++i;
+ }
return values;
}
return value;
},
convertNativeToDart_Dictionary(object) {
- var dict, keys, t1, _i, key;
+ var dict, keys, t1, _i, key, t2;
if (object == null)
return null;
dict = A.LinkedHashMap_LinkedHashMap$_empty(type$.String, type$.dynamic);
keys = Object.getOwnPropertyNames(object);
for (t1 = keys.length, _i = 0; _i < keys.length; keys.length === t1 || (0, A.throwConcurrentModificationError)(keys), ++_i) {
key = keys[_i];
- dict.$indexSet(0, key, A._convertNativeToDart_Value(object[key]));
+ t2 = key;
+ t2.toString;
+ dict.$indexSet(0, t2, A._convertNativeToDart_Value(object[key]));
}
return dict;
},
- isJavaScriptSimpleObject(value) {
- var proto = Object.getPrototypeOf(value);
- return proto === Object.prototype || proto === null;
- },
- _convertDartFunctionFast(f) {
- var ret,
- existing = f.$dart_jsFunction;
- if (existing != null)
- return existing;
- ret = function(_call, f) {
- return function() {
- return _call(f, Array.prototype.slice.apply(arguments));
- };
- }(A._callDartFunctionFast, f);
- ret[$.$get$DART_CLOSURE_PROPERTY_NAME()] = f;
- f.$dart_jsFunction = ret;
- return ret;
- },
- _callDartFunctionFast(callback, $arguments) {
- type$.List_dynamic._as($arguments);
- type$.Function._as(callback);
- return A.Primitives_applyFunction(callback, $arguments, null);
- },
- allowInterop(f, $F) {
- if (typeof f == "function")
- return f;
- else
- return $F._as(A._convertDartFunctionFast(f));
- },
current() {
var exception, t1, path, lastIndex, uri = null;
try {
@@ -7262,7 +7516,7 @@
return t1;
}
$._currentUriBase = uri;
- if ($.$get$Style_platform() == $.$get$Style_url())
+ if ($.$get$Style_platform() === $.$get$Style_url())
t1 = $._current = uri.resolve$1(".").toString$0(0);
else {
path = uri.toFilePath$0();
@@ -7280,17 +7534,25 @@
return t1;
},
isDriveLetter(path, index) {
- var t1 = path.length,
+ var t3,
+ t1 = path.length,
t2 = index + 2;
if (t1 < t2)
return false;
- if (!A.isAlphabetic(B.JSString_methods.codeUnitAt$1(path, index)))
+ if (!(index >= 0 && index < t1))
+ return A.ioore(path, index);
+ if (!A.isAlphabetic(path.charCodeAt(index)))
return false;
- if (B.JSString_methods.codeUnitAt$1(path, index + 1) !== 58)
+ t3 = index + 1;
+ if (!(t3 < t1))
+ return A.ioore(path, t3);
+ if (path.charCodeAt(t3) !== 58)
return false;
if (t1 === t2)
return true;
- return B.JSString_methods.codeUnitAt$1(path, t2) === 47;
+ if (!(t2 >= 0 && t2 < t1))
+ return A.ioore(path, t2);
+ return path.charCodeAt(t2) === 47;
}
},
J = {
@@ -7411,7 +7673,7 @@
JSString__skipLeadingWhitespace(string, index) {
var t1, codeUnit;
for (t1 = string.length; index < t1;) {
- codeUnit = B.JSString_methods._codeUnitAt$1(string, index);
+ codeUnit = string.charCodeAt(index);
if (codeUnit !== 32 && codeUnit !== 13 && !J.JSString__isWhitespace(codeUnit))
break;
++index;
@@ -7419,10 +7681,12 @@
return index;
},
JSString__skipTrailingWhitespace(string, index) {
- var index0, codeUnit;
- for (; index > 0; index = index0) {
+ var t1, index0, codeUnit;
+ for (t1 = string.length; index > 0; index = index0) {
index0 = index - 1;
- codeUnit = B.JSString_methods.codeUnitAt$1(string, index0);
+ if (!(index0 < t1))
+ return A.ioore(string, index0);
+ codeUnit = string.charCodeAt(index0);
if (codeUnit !== 32 && codeUnit !== 13 && !J.JSString__isWhitespace(codeUnit))
break;
}
@@ -7440,7 +7704,7 @@
return J.JSNull.prototype;
if (typeof receiver == "boolean")
return J.JSBool.prototype;
- if (receiver.constructor == Array)
+ if (Array.isArray(receiver))
return J.JSArray.prototype;
if (typeof receiver != "object") {
if (typeof receiver == "function")
@@ -7456,7 +7720,7 @@
return J.JSString.prototype;
if (receiver == null)
return receiver;
- if (receiver.constructor == Array)
+ if (Array.isArray(receiver))
return J.JSArray.prototype;
if (typeof receiver != "object") {
if (typeof receiver == "function")
@@ -7470,7 +7734,7 @@
getInterceptor$ax(receiver) {
if (receiver == null)
return receiver;
- if (receiver.constructor == Array)
+ if (Array.isArray(receiver))
return J.JSArray.prototype;
if (typeof receiver != "object") {
if (typeof receiver == "function")
@@ -7515,6 +7779,9 @@
get$isEmpty$asx(receiver) {
return J.getInterceptor$asx(receiver).get$isEmpty(receiver);
},
+ get$isNotEmpty$asx(receiver) {
+ return J.getInterceptor$asx(receiver).get$isNotEmpty(receiver);
+ },
get$iterator$ax(receiver) {
return J.getInterceptor$ax(receiver).get$iterator(receiver);
},
@@ -7527,6 +7794,9 @@
get$parent$z(receiver) {
return J.getInterceptor$z(receiver).get$parent(receiver);
},
+ get$runtimeType$(receiver) {
+ return J.getInterceptor$(receiver).get$runtimeType(receiver);
+ },
$eq$(receiver, a0) {
if (receiver == null)
return a0 == null;
@@ -7536,7 +7806,7 @@
},
$index$asx(receiver, a0) {
if (typeof a0 === "number")
- if (receiver.constructor == Array || typeof receiver == "string" || A.isJsIndexable(receiver, receiver[init.dispatchPropertyName]))
+ if (Array.isArray(receiver) || typeof receiver == "string" || A.isJsIndexable(receiver, receiver[init.dispatchPropertyName]))
if (a0 >>> 0 === a0 && a0 < receiver.length)
return receiver[a0];
return J.getInterceptor$asx(receiver).$index(receiver, a0);
@@ -7550,9 +7820,21 @@
allMatches$2$s(receiver, a0, a1) {
return J.getInterceptor$s(receiver).allMatches$2(receiver, a0, a1);
},
+ cancel$0$z(receiver) {
+ return J.getInterceptor$z(receiver).cancel$0(receiver);
+ },
+ cast$1$0$ax(receiver, $T1) {
+ return J.getInterceptor$ax(receiver).cast$1$0(receiver, $T1);
+ },
codeUnitAt$1$s(receiver, a0) {
return J.getInterceptor$s(receiver).codeUnitAt$1(receiver, a0);
},
+ contains$1$asx(receiver, a0) {
+ return J.getInterceptor$asx(receiver).contains$1(receiver, a0);
+ },
+ containsKey$1$x(receiver, a0) {
+ return J.getInterceptor$x(receiver).containsKey$1(receiver, a0);
+ },
elementAt$1$ax(receiver, a0) {
return J.getInterceptor$ax(receiver).elementAt$1(receiver, a0);
},
@@ -7571,6 +7853,12 @@
noSuchMethod$1$(receiver, a0) {
return J.getInterceptor$(receiver).noSuchMethod$1(receiver, a0);
},
+ skip$1$ax(receiver, a0) {
+ return J.getInterceptor$ax(receiver).skip$1(receiver, a0);
+ },
+ toList$0$ax(receiver) {
+ return J.getInterceptor$ax(receiver).toList$0(receiver);
+ },
toString$0$(receiver) {
return J.getInterceptor$(receiver).toString$0(receiver);
},
@@ -7628,8 +7916,10 @@
return "Instance of '" + A.Primitives_objectTypeName(receiver) + "'";
},
noSuchMethod$1(receiver, invocation) {
- type$.Invocation._as(invocation);
- throw A.wrapException(A.NoSuchMethodError$(receiver, invocation.get$memberName(), invocation.get$positionalArguments(), invocation.get$namedArguments()));
+ throw A.wrapException(A.NoSuchMethodError_NoSuchMethodError$withInvocation(receiver, type$.Invocation._as(invocation)));
+ },
+ get$runtimeType(receiver) {
+ return A.createRuntimeType(A._instanceTypeFromConstructor(this));
}
};
J.JSBool.prototype = {
@@ -7639,6 +7929,10 @@
get$hashCode(receiver) {
return receiver ? 519018 : 218159;
},
+ get$runtimeType(receiver) {
+ return A.createRuntimeType(type$.bool);
+ },
+ $isTrustedGetRuntimeType: 1,
$isbool: 1
};
J.JSNull.prototype = {
@@ -7651,6 +7945,7 @@
get$hashCode(receiver) {
return 0;
},
+ $isTrustedGetRuntimeType: 1,
$isNull: 1
};
J.JavaScriptObject.prototype = {};
@@ -7674,6 +7969,9 @@
$isFunction: 1
};
J.JSArray.prototype = {
+ cast$1$0(receiver, $R) {
+ return new A.CastList(receiver, A._arrayInstanceType(receiver)._eval$1("@<1>")._bind$1($R)._eval$1("CastList<1,2>"));
+ },
add$1(receiver, value) {
A._arrayInstanceType(receiver)._precomputed1._as(value);
if (!!receiver.fixed$length)
@@ -7700,14 +7998,15 @@
receiver.splice(index, 0, value);
},
insertAll$2(receiver, index, iterable) {
- var t1, insertionLength, end;
+ var insertionLength, end;
A._arrayInstanceType(receiver)._eval$1("Iterable<1>")._as(iterable);
if (!!receiver.fixed$length)
A.throwExpression(A.UnsupportedError$("insertAll"));
- t1 = receiver.length;
- A.RangeError_checkValueInInterval(index, 0, t1, "index");
- insertionLength = iterable.length;
- receiver.length = t1 + insertionLength;
+ A.RangeError_checkValueInInterval(index, 0, receiver.length, "index");
+ if (!type$.EfficientLengthIterable_dynamic._is(iterable))
+ iterable = J.toList$0$ax(iterable);
+ insertionLength = J.get$length$asx(iterable);
+ receiver.length = receiver.length + insertionLength;
end = index + insertionLength;
this.setRange$4(receiver, end, receiver.length, receiver, index);
this.setRange$3(receiver, index, end, iterable);
@@ -7761,6 +8060,9 @@
join$0($receiver) {
return this.join$1($receiver, "");
},
+ skip$1(receiver, n) {
+ return A.SubListIterable$(receiver, n, null, A._arrayInstanceType(receiver)._precomputed1);
+ },
fold$1$2(receiver, initialValue, combine, $T) {
var $length, value, i;
$T._as(initialValue);
@@ -7790,7 +8092,7 @@
throw A.wrapException(A.IterableElementError_noElement());
},
setRange$4(receiver, start, end, iterable, skipCount) {
- var $length, otherList, t1, i;
+ var $length, otherList, otherStart, t1, i;
A._arrayInstanceType(receiver)._eval$1("Iterable<1>")._as(iterable);
if (!!receiver.immutable$list)
A.throwExpression(A.UnsupportedError$("setRange"));
@@ -7799,20 +8101,33 @@
if ($length === 0)
return;
A.RangeError_checkNotNegative(skipCount, "skipCount");
- otherList = iterable;
+ if (type$.List_dynamic._is(iterable)) {
+ otherList = iterable;
+ otherStart = skipCount;
+ } else {
+ otherList = J.skip$1$ax(iterable, skipCount).toList$1$growable(0, false);
+ otherStart = 0;
+ }
t1 = J.getInterceptor$asx(otherList);
- if (skipCount + $length > t1.get$length(otherList))
+ if (otherStart + $length > t1.get$length(otherList))
throw A.wrapException(A.IterableElementError_tooFew());
- if (skipCount < start)
+ if (otherStart < start)
for (i = $length - 1; i >= 0; --i)
- receiver[start + i] = t1.$index(otherList, skipCount + i);
+ receiver[start + i] = t1.$index(otherList, otherStart + i);
else
for (i = 0; i < $length; ++i)
- receiver[start + i] = t1.$index(otherList, skipCount + i);
+ receiver[start + i] = t1.$index(otherList, otherStart + i);
},
setRange$3($receiver, start, end, iterable) {
return this.setRange$4($receiver, start, end, iterable, 0);
},
+ contains$1(receiver, other) {
+ var i;
+ for (i = 0; i < receiver.length; ++i)
+ if (J.$eq$(receiver[i], other))
+ return true;
+ return false;
+ },
get$isEmpty(receiver) {
return receiver.length === 0;
},
@@ -7820,7 +8135,14 @@
return receiver.length !== 0;
},
toString$0(receiver) {
- return A.IterableBase_iterableToFullString(receiver, "[", "]");
+ return A.Iterable_iterableToFullString(receiver, "[", "]");
+ },
+ toList$1$growable(receiver, growable) {
+ var t1 = A._setArrayType(receiver.slice(0), A._arrayInstanceType(receiver));
+ return t1;
+ },
+ toList$0($receiver) {
+ return this.toList$1$growable($receiver, true);
},
get$iterator(receiver) {
return new J.ArrayIterator(receiver, receiver.length, A._arrayInstanceType(receiver)._eval$1("ArrayIterator<1>"));
@@ -7838,7 +8160,6 @@
return receiver[index];
},
$indexSet(receiver, index, value) {
- A._asInt(index);
A._arrayInstanceType(receiver)._precomputed1._as(value);
if (!!receiver.immutable$list)
A.throwExpression(A.UnsupportedError$("indexed set"));
@@ -7860,8 +8181,10 @@
var t2, _this = this,
t1 = _this._iterable,
$length = t1.length;
- if (_this.__interceptors$_length !== $length)
- throw A.wrapException(A.throwConcurrentModificationError(t1));
+ if (_this.__interceptors$_length !== $length) {
+ t1 = A.throwConcurrentModificationError(t1);
+ throw A.wrapException(t1);
+ }
t2 = _this._index;
if (t2 >= $length) {
_this.set$_current(null);
@@ -7877,6 +8200,16 @@
$isIterator: 1
};
J.JSNumber.prototype = {
+ toInt$0(receiver) {
+ var t1;
+ if (receiver >= -2147483648 && receiver <= 2147483647)
+ return receiver | 0;
+ if (isFinite(receiver)) {
+ t1 = receiver < 0 ? Math.ceil(receiver) : Math.floor(receiver);
+ return t1 + 0;
+ }
+ throw A.wrapException(A.UnsupportedError$("" + receiver + ".toInt()"));
+ },
toString$0(receiver) {
if (receiver === 0 && 1 / receiver < 0)
return "-0.0";
@@ -7940,11 +8273,25 @@
_shrBothPositive$1(receiver, other) {
return other > 31 ? 0 : receiver >>> other;
},
+ get$runtimeType(receiver) {
+ return A.createRuntimeType(type$.num);
+ },
$isdouble: 1,
$isnum: 1
};
- J.JSInt.prototype = {$isint: 1};
- J.JSNumNotInt.prototype = {};
+ J.JSInt.prototype = {
+ get$runtimeType(receiver) {
+ return A.createRuntimeType(type$.int);
+ },
+ $isTrustedGetRuntimeType: 1,
+ $isint: 1
+ };
+ J.JSNumNotInt.prototype = {
+ get$runtimeType(receiver) {
+ return A.createRuntimeType(type$.double);
+ },
+ $isTrustedGetRuntimeType: 1
+ };
J.JSString.prototype = {
codeUnitAt$1(receiver, index) {
if (index < 0)
@@ -7953,11 +8300,6 @@
A.throwExpression(A.diagnoseIndexError(receiver, index));
return receiver.charCodeAt(index);
},
- _codeUnitAt$1(receiver, index) {
- if (index >= receiver.length)
- throw A.wrapException(A.diagnoseIndexError(receiver, index));
- return receiver.charCodeAt(index);
- },
allMatches$2(receiver, string, start) {
var t1 = string.length;
if (start > t1)
@@ -7968,15 +8310,20 @@
return this.allMatches$2($receiver, string, 0);
},
matchAsPrefix$2(receiver, string, start) {
- var t1, i, _null = null;
+ var t1, t2, i, t3, _null = null;
if (start < 0 || start > string.length)
throw A.wrapException(A.RangeError$range(start, 0, string.length, _null, _null));
t1 = receiver.length;
- if (start + t1 > string.length)
+ t2 = string.length;
+ if (start + t1 > t2)
return _null;
- for (i = 0; i < t1; ++i)
- if (this.codeUnitAt$1(string, start + i) !== this._codeUnitAt$1(receiver, i))
+ for (i = 0; i < t1; ++i) {
+ t3 = start + i;
+ if (!(t3 >= 0 && t3 < t2))
+ return A.ioore(string, t3);
+ if (string.charCodeAt(t3) !== receiver.charCodeAt(i))
return _null;
+ }
return new A.StringMatch(start, receiver);
},
$add(receiver, other) {
@@ -7990,12 +8337,10 @@
return other === this.substring$1(receiver, t1 - otherLength);
},
replaceFirst$2(receiver, from, to) {
- type$.Pattern._as(from);
A.RangeError_checkValueInInterval(0, 0, receiver.length, "startIndex");
return A.stringReplaceFirstUnchecked(receiver, from, to, 0);
},
split$1(receiver, pattern) {
- type$.Pattern._as(pattern);
if (typeof pattern == "string")
return A._setArrayType(receiver.split(pattern), type$.JSArray_String);
else if (pattern instanceof A.JSSyntaxRegExp && pattern.get$_nativeAnchoredVersion().exec("").length - 2 === 0)
@@ -8026,7 +8371,6 @@
},
startsWith$2(receiver, pattern, index) {
var endIndex;
- type$.Pattern._as(pattern);
if (index < 0 || index > receiver.length)
throw A.wrapException(A.RangeError$range(index, 0, receiver.length, null, null));
if (typeof pattern == "string") {
@@ -8052,14 +8396,18 @@
endIndex = result.length;
if (endIndex === 0)
return result;
- if (this._codeUnitAt$1(result, 0) === 133) {
+ if (0 >= endIndex)
+ return A.ioore(result, 0);
+ if (result.charCodeAt(0) === 133) {
startIndex = J.JSString__skipLeadingWhitespace(result, 1);
if (startIndex === endIndex)
return "";
} else
startIndex = 0;
t1 = endIndex - 1;
- endIndex0 = this.codeUnitAt$1(result, t1) === 133 ? J.JSString__skipTrailingWhitespace(result, t1) : endIndex;
+ if (!(t1 >= 0))
+ return A.ioore(result, t1);
+ endIndex0 = result.charCodeAt(t1) === 133 ? J.JSString__skipTrailingWhitespace(result, t1) : endIndex;
if (startIndex === 0 && endIndex0 === endIndex)
return result;
return result.substring(startIndex, endIndex0);
@@ -8119,16 +8467,8 @@
lastIndexOf$1($receiver, pattern) {
return this.lastIndexOf$2($receiver, pattern, null);
},
- contains$2(receiver, other, startIndex) {
- var t1;
- type$.Pattern._as(other);
- t1 = receiver.length;
- if (startIndex > t1)
- throw A.wrapException(A.RangeError$range(startIndex, 0, t1, null, null));
- return A.stringContainsUnchecked(receiver, other, startIndex);
- },
- contains$1($receiver, other) {
- return this.contains$2($receiver, other, 0);
+ contains$1(receiver, other) {
+ return A.stringContainsUnchecked(receiver, other, 0);
},
toString$0(receiver) {
return receiver;
@@ -8144,6 +8484,9 @@
hash ^= hash >> 11;
return hash + ((hash & 16383) << 15) & 536870911;
},
+ get$runtimeType(receiver) {
+ return A.createRuntimeType(type$.String);
+ },
get$length(receiver) {
return receiver.length;
},
@@ -8153,6 +8496,7 @@
throw A.wrapException(A.diagnoseIndexError(receiver, index));
return receiver[index];
},
+ $isTrustedGetRuntimeType: 1,
$isPattern: 1,
$isString: 1
};
@@ -8232,6 +8576,66 @@
},
$isStreamSubscription: 1
};
+ A._CastIterableBase.prototype = {
+ get$iterator(_) {
+ var t1 = A._instanceType(this);
+ return new A.CastIterator(J.get$iterator$ax(this.get$_source()), t1._eval$1("@<1>")._bind$1(t1._rest[1])._eval$1("CastIterator<1,2>"));
+ },
+ get$length(_) {
+ return J.get$length$asx(this.get$_source());
+ },
+ get$isEmpty(_) {
+ return J.get$isEmpty$asx(this.get$_source());
+ },
+ get$isNotEmpty(_) {
+ return J.get$isNotEmpty$asx(this.get$_source());
+ },
+ skip$1(_, count) {
+ var t1 = A._instanceType(this);
+ return A.CastIterable_CastIterable(J.skip$1$ax(this.get$_source(), count), t1._precomputed1, t1._rest[1]);
+ },
+ elementAt$1(_, index) {
+ return A._instanceType(this)._rest[1]._as(J.elementAt$1$ax(this.get$_source(), index));
+ },
+ toString$0(_) {
+ return J.toString$0$(this.get$_source());
+ }
+ };
+ A.CastIterator.prototype = {
+ moveNext$0() {
+ return this._source.moveNext$0();
+ },
+ get$current(_) {
+ var t1 = this._source;
+ return this.$ti._rest[1]._as(t1.get$current(t1));
+ },
+ $isIterator: 1
+ };
+ A.CastIterable.prototype = {
+ get$_source() {
+ return this._source;
+ }
+ };
+ A._EfficientLengthCastIterable.prototype = {$isEfficientLengthIterable: 1};
+ A._CastListBase.prototype = {
+ $index(_, index) {
+ return this.$ti._rest[1]._as(J.$index$asx(this._source, A._asInt(index)));
+ },
+ $indexSet(_, index, value) {
+ var t1 = this.$ti;
+ J.$indexSet$ax(this._source, index, t1._precomputed1._as(t1._rest[1]._as(value)));
+ },
+ $isEfficientLengthIterable: 1,
+ $isList: 1
+ };
+ A.CastList.prototype = {
+ cast$1$0(_, $R) {
+ return new A.CastList(this._source, this.$ti._eval$1("@<1>")._bind$1($R)._eval$1("CastList<1,2>"));
+ },
+ get$_source() {
+ return this._source;
+ }
+ };
A.LateError.prototype = {
toString$0(_) {
return "LateInitializationError: " + this._message;
@@ -8242,14 +8646,19 @@
return this._string.length;
},
$index(_, i) {
- return B.JSString_methods.codeUnitAt$1(this._string, A._asInt(i));
+ var t1;
+ A._asInt(i);
+ t1 = this._string;
+ if (!(i >= 0 && i < t1.length))
+ return A.ioore(t1, i);
+ return t1.charCodeAt(i);
}
};
A.nullFuture_closure.prototype = {
call$0() {
return A.Future_Future$value(null, type$.Null);
},
- $signature: 44
+ $signature: 61
};
A.SentinelValue.prototype = {};
A.EfficientLengthIterable.prototype = {};
@@ -8303,12 +8712,15 @@
throw A.wrapException(A.ConcurrentModificationError$(_this));
}
return value;
+ },
+ skip$1(_, count) {
+ return A.SubListIterable$(this, count, null, A._instanceType(this)._eval$1("ListIterable.E"));
}
};
A.SubListIterable.prototype = {
SubListIterable$3(_iterable, _start, _endOrLength, $E) {
var endOrLength,
- t1 = this.__internal$_start;
+ t1 = this._start;
A.RangeError_checkNotNegative(t1, "start");
endOrLength = this._endOrLength;
if (endOrLength != null) {
@@ -8326,7 +8738,7 @@
},
get$_startIndex() {
var $length = J.get$length$asx(this.__internal$_iterable),
- t1 = this.__internal$_start;
+ t1 = this._start;
if (t1 > $length)
return $length;
return t1;
@@ -8334,7 +8746,7 @@
get$length(_) {
var endOrLength,
$length = J.get$length$asx(this.__internal$_iterable),
- t1 = this.__internal$_start;
+ t1 = this._start;
if (t1 >= $length)
return 0;
endOrLength = this._endOrLength;
@@ -8348,8 +8760,39 @@
var _this = this,
realIndex = _this.get$_startIndex() + index;
if (index < 0 || realIndex >= _this.get$_endIndex())
- throw A.wrapException(A.IndexError$(index, _this, "index", null, null));
+ throw A.wrapException(A.IndexError$withLength(index, _this.get$length(_this), _this, "index"));
return J.elementAt$1$ax(_this.__internal$_iterable, realIndex);
+ },
+ skip$1(_, count) {
+ var newStart, endOrLength, _this = this;
+ A.RangeError_checkNotNegative(count, "count");
+ newStart = _this._start + count;
+ endOrLength = _this._endOrLength;
+ if (endOrLength != null && newStart >= endOrLength)
+ return new A.EmptyIterable(_this.$ti._eval$1("EmptyIterable<1>"));
+ return A.SubListIterable$(_this.__internal$_iterable, newStart, endOrLength, _this.$ti._precomputed1);
+ },
+ toList$1$growable(_, growable) {
+ var $length, result, i, _this = this,
+ start = _this._start,
+ t1 = _this.__internal$_iterable,
+ t2 = J.getInterceptor$asx(t1),
+ end = t2.get$length(t1),
+ endOrLength = _this._endOrLength;
+ if (endOrLength != null && endOrLength < end)
+ end = endOrLength;
+ $length = end - start;
+ if ($length <= 0) {
+ t1 = J.JSArray_JSArray$fixed(0, _this.$ti._precomputed1);
+ return t1;
+ }
+ result = A.List_List$filled($length, t2.elementAt$1(t1, start), false, _this.$ti._precomputed1);
+ for (i = 1; i < $length; ++i) {
+ B.JSArray_methods.$indexSet(result, i, t2.elementAt$1(t1, start + i));
+ if (t2.get$length(t1) < end)
+ throw A.wrapException(A.ConcurrentModificationError$(_this));
+ }
+ return result;
}
};
A.ListIterator.prototype = {
@@ -8385,6 +8828,12 @@
},
get$length(_) {
return J.get$length$asx(this.__internal$_iterable);
+ },
+ get$isEmpty(_) {
+ return J.get$isEmpty$asx(this.__internal$_iterable);
+ },
+ elementAt$1(_, index) {
+ return this._f.call$1(J.elementAt$1$ax(this.__internal$_iterable, index));
}
};
A.EfficientLengthMappedIterable.prototype = {$isEfficientLengthIterable: 1};
@@ -8405,7 +8854,8 @@
},
set$__internal$_current(_current) {
this.__internal$_current = this.$ti._eval$1("2?")._as(_current);
- }
+ },
+ $isIterator: 1
};
A.MappedListIterable.prototype = {
get$length(_) {
@@ -8435,7 +8885,8 @@
get$current(_) {
var t1 = this._iterator;
return t1.get$current(t1);
- }
+ },
+ $isIterator: 1
};
A.ExpandIterable.prototype = {
get$iterator(_) {
@@ -8502,8 +8953,47 @@
}
t1 = this._iterator;
return t1.get$current(t1);
+ },
+ $isIterator: 1
+ };
+ A.SkipIterable.prototype = {
+ skip$1(_, count) {
+ A.ArgumentError_checkNotNull(count, "count", type$.int);
+ A.RangeError_checkNotNegative(count, "count");
+ return new A.SkipIterable(this.__internal$_iterable, this._skipCount + count, A._instanceType(this)._eval$1("SkipIterable<1>"));
+ },
+ get$iterator(_) {
+ return new A.SkipIterator(J.get$iterator$ax(this.__internal$_iterable), this._skipCount, A._instanceType(this)._eval$1("SkipIterator<1>"));
}
};
+ A.EfficientLengthSkipIterable.prototype = {
+ get$length(_) {
+ var $length = J.get$length$asx(this.__internal$_iterable) - this._skipCount;
+ if ($length >= 0)
+ return $length;
+ return 0;
+ },
+ skip$1(_, count) {
+ A.ArgumentError_checkNotNull(count, "count", type$.int);
+ A.RangeError_checkNotNegative(count, "count");
+ return new A.EfficientLengthSkipIterable(this.__internal$_iterable, this._skipCount + count, this.$ti);
+ },
+ $isEfficientLengthIterable: 1
+ };
+ A.SkipIterator.prototype = {
+ moveNext$0() {
+ var t1, i;
+ for (t1 = this._iterator, i = 0; i < this._skipCount; ++i)
+ t1.moveNext$0();
+ this._skipCount = 0;
+ return t1.moveNext$0();
+ },
+ get$current(_) {
+ var t1 = this._iterator;
+ return t1.get$current(t1);
+ },
+ $isIterator: 1
+ };
A.SkipWhileIterable.prototype = {
get$iterator(_) {
return new A.SkipWhileIterator(J.get$iterator$ax(this.__internal$_iterable), this._f, this.$ti._eval$1("SkipWhileIterator<1>"));
@@ -8523,6 +9013,29 @@
get$current(_) {
var t1 = this._iterator;
return t1.get$current(t1);
+ },
+ $isIterator: 1
+ };
+ A.EmptyIterable.prototype = {
+ get$iterator(_) {
+ return B.C_EmptyIterator;
+ },
+ get$isEmpty(_) {
+ return true;
+ },
+ get$length(_) {
+ return 0;
+ },
+ elementAt$1(_, index) {
+ throw A.wrapException(A.RangeError$range(index, 0, 0, "index", null));
+ },
+ map$1$1(_, toElement, $T) {
+ this.$ti._bind$1($T)._eval$1("1(2)")._as(toElement);
+ return new A.EmptyIterable($T._eval$1("EmptyIterable<0>"));
+ },
+ skip$1(_, count) {
+ A.RangeError_checkNotNegative(count, "count");
+ return this;
}
};
A.EmptyIterator.prototype = {
@@ -8556,7 +9069,6 @@
A.FixedLengthListMixin.prototype = {};
A.UnmodifiableListMixin.prototype = {
$indexSet(_, index, value) {
- A._asInt(index);
A._instanceType(this)._eval$1("UnmodifiableListMixin.E")._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot modify an unmodifiable list"));
}
@@ -8577,20 +9089,21 @@
var hash = this._hashCode;
if (hash != null)
return hash;
- hash = 664597 * J.get$hashCode$(this._name) & 536870911;
+ hash = 664597 * B.JSString_methods.get$hashCode(this._name) & 536870911;
this._hashCode = hash;
return hash;
},
toString$0(_) {
- return 'Symbol("' + A.S(this._name) + '")';
+ return 'Symbol("' + this._name + '")';
},
$eq(_, other) {
if (other == null)
return false;
- return other instanceof A.Symbol && this._name == other._name;
+ return other instanceof A.Symbol && this._name === other._name;
},
$isSymbol0: 1
};
+ A.__CastListBase__CastIterableBase_ListMixin.prototype = {};
A.ConstantMapView.prototype = {};
A.ConstantMap.prototype = {
get$isEmpty(_) {
@@ -8599,61 +9112,94 @@
toString$0(_) {
return A.MapBase_mapToString(this);
},
- $indexSet(_, key, val) {
+ $indexSet(_, key, value) {
var t1 = A._instanceType(this);
t1._precomputed1._as(key);
- t1._rest[1]._as(val);
+ t1._rest[1]._as(value);
A.ConstantMap__throwUnmodifiable();
},
$isMap: 1
};
A.ConstantStringMap.prototype = {
get$length(_) {
- return this._length;
+ return this._values.length;
+ },
+ get$__js_helper$_keys() {
+ var keys = this.$keys;
+ if (keys == null) {
+ keys = Object.keys(this._jsIndex);
+ this.$keys = keys;
+ }
+ return keys;
},
containsKey$1(_, key) {
if (typeof key != "string")
return false;
if ("__proto__" === key)
return false;
- return this._jsObject.hasOwnProperty(key);
+ return this._jsIndex.hasOwnProperty(key);
},
$index(_, key) {
if (!this.containsKey$1(0, key))
return null;
- return this._jsObject[A._asString(key)];
+ return this._values[this._jsIndex[key]];
},
forEach$1(_, f) {
- var keys, t2, t3, i, t4,
- t1 = this.$ti;
- t1._eval$1("~(1,2)")._as(f);
- keys = this.__js_helper$_keys;
- for (t2 = keys.length, t3 = this._jsObject, t1 = t1._rest[1], i = 0; i < t2; ++i) {
- t4 = A._asString(keys[i]);
- f.call$2(t4, t1._as(t3[t4]));
- }
+ var keys, values, t1, i;
+ this.$ti._eval$1("~(1,2)")._as(f);
+ keys = this.get$__js_helper$_keys();
+ values = this._values;
+ for (t1 = keys.length, i = 0; i < t1; ++i)
+ f.call$2(keys[i], values[i]);
},
get$keys(_) {
- return new A._ConstantMapKeyIterable(this, this.$ti._eval$1("_ConstantMapKeyIterable<1>"));
+ return new A._KeysOrValues(this.get$__js_helper$_keys(), this.$ti._eval$1("_KeysOrValues<1>"));
}
};
- A._ConstantMapKeyIterable.prototype = {
- get$iterator(_) {
- var t1 = this._map.__js_helper$_keys;
- return new J.ArrayIterator(t1, t1.length, A._arrayInstanceType(t1)._eval$1("ArrayIterator<1>"));
- },
+ A._KeysOrValues.prototype = {
get$length(_) {
- return this._map.__js_helper$_keys.length;
+ return this._elements.length;
+ },
+ get$isEmpty(_) {
+ return 0 === this._elements.length;
+ },
+ get$isNotEmpty(_) {
+ return 0 !== this._elements.length;
+ },
+ get$iterator(_) {
+ var t1 = this._elements;
+ return new A._KeysOrValuesOrElementsIterator(t1, t1.length, this.$ti._eval$1("_KeysOrValuesOrElementsIterator<1>"));
}
};
+ A._KeysOrValuesOrElementsIterator.prototype = {
+ get$current(_) {
+ var t1 = this.__js_helper$_current;
+ return t1 == null ? this.$ti._precomputed1._as(t1) : t1;
+ },
+ moveNext$0() {
+ var _this = this,
+ t1 = _this.__js_helper$_index;
+ if (t1 >= _this._length) {
+ _this.set$__js_helper$_current(null);
+ return false;
+ }
+ _this.set$__js_helper$_current(_this._elements[t1]);
+ ++_this.__js_helper$_index;
+ return true;
+ },
+ set$__js_helper$_current(_current) {
+ this.__js_helper$_current = this.$ti._eval$1("1?")._as(_current);
+ },
+ $isIterator: 1
+ };
A.Instantiation.prototype = {
$eq(_, other) {
if (other == null)
return false;
- return other instanceof A.Instantiation && this._genericClosure.$eq(0, other._genericClosure) && A.getRuntimeType(this) === A.getRuntimeType(other);
+ return other instanceof A.Instantiation1 && this._genericClosure.$eq(0, other._genericClosure) && A.getRuntimeTypeOfClosure(this) === A.getRuntimeTypeOfClosure(other);
},
get$hashCode(_) {
- return A.Object_hash(this._genericClosure, A.getRuntimeType(this), B.C_SentinelValue, B.C_SentinelValue);
+ return A.Object_hash(this._genericClosure, A.getRuntimeTypeOfClosure(this), B.C_SentinelValue, B.C_SentinelValue);
},
toString$0(_) {
var t1 = B.JSArray_methods.join$1([A.createRuntimeType(this.$ti._precomputed1)], ", ");
@@ -8726,7 +9272,7 @@
B.JSArray_methods.add$1(this.$arguments, argument);
++t1.argumentCount;
},
- $signature: 5
+ $signature: 3
};
A.TypeErrorDecoder.prototype = {
matchTypeError$1(message) {
@@ -8786,7 +9332,6 @@
},
$isException: 1
};
- A.ExceptionAndStackTrace.prototype = {};
A._StackTrace.prototype = {
toString$0(_) {
var trace,
@@ -8841,6 +9386,11 @@
return "Closure '" + this.$_name + "' of " + ("Instance of '" + A.Primitives_objectTypeName(this._receiver) + "'");
}
};
+ A._CyclicInitializationError.prototype = {
+ toString$0(_) {
+ return "Reading static variable '" + this.variableName + "' during its initialization";
+ }
+ };
A.RuntimeError.prototype = {
toString$0(_) {
return "RuntimeError: " + this.message;
@@ -8918,7 +9468,7 @@
return bucket[index].hashMapCellValue;
},
$indexSet(_, key, value) {
- var strings, nums, _this = this,
+ var strings, nums, rest, hash, bucket, index, _this = this,
t1 = A._instanceType(_this);
t1._precomputed1._as(key);
t1._rest[1]._as(value);
@@ -8928,27 +9478,21 @@
} else if (typeof key == "number" && (key & 0x3fffffff) === key) {
nums = _this._nums;
_this._addHashTableEntry$3(nums == null ? _this._nums = _this._newHashTable$0() : nums, key, value);
- } else
- _this.internalSet$2(key, value);
- },
- internalSet$2(key, value) {
- var rest, hash, bucket, index, _this = this,
- t1 = A._instanceType(_this);
- t1._precomputed1._as(key);
- t1._rest[1]._as(value);
- rest = _this.__js_helper$_rest;
- if (rest == null)
- rest = _this.__js_helper$_rest = _this._newHashTable$0();
- hash = _this.internalComputeHashCode$1(key);
- bucket = rest[hash];
- if (bucket == null)
- rest[hash] = [_this._newLinkedCell$2(key, value)];
- else {
- index = _this.internalFindBucketIndex$2(bucket, key);
- if (index >= 0)
- bucket[index].hashMapCellValue = value;
- else
- bucket.push(_this._newLinkedCell$2(key, value));
+ } else {
+ rest = _this.__js_helper$_rest;
+ if (rest == null)
+ rest = _this.__js_helper$_rest = _this._newHashTable$0();
+ hash = _this.internalComputeHashCode$1(key);
+ bucket = rest[hash];
+ if (bucket == null)
+ rest[hash] = [_this._newLinkedCell$2(key, value)];
+ else {
+ index = _this.internalFindBucketIndex$2(bucket, key);
+ if (index >= 0)
+ bucket[index].hashMapCellValue = value;
+ else
+ bucket.push(_this._newLinkedCell$2(key, value));
+ }
}
},
putIfAbsent$2(_, key, ifAbsent) {
@@ -9066,7 +9610,7 @@
_this._modified$0();
},
internalComputeHashCode$1(key) {
- return J.get$hashCode$(key) & 0x3fffffff;
+ return J.get$hashCode$(key) & 1073741823;
},
internalFindBucketIndex$2(bucket, key) {
var $length, i;
@@ -9113,6 +9657,9 @@
t2 = new A.LinkedHashMapKeyIterator(t1, t1._modifications, this.$ti._eval$1("LinkedHashMapKeyIterator<1>"));
t2._cell = t1._first;
return t2;
+ },
+ contains$1(_, element) {
+ return this._map.containsKey$1(0, element);
}
};
A.LinkedHashMapKeyIterator.prototype = {
@@ -9143,19 +9690,19 @@
call$1(o) {
return this.getTag(o);
},
- $signature: 14
+ $signature: 15
};
A.initHooks_closure0.prototype = {
call$2(o, tag) {
return this.getUnknownTag(o, tag);
},
- $signature: 42
+ $signature: 36
};
A.initHooks_closure1.prototype = {
call$1(tag) {
return this.prototypeForTag(A._asString(tag));
},
- $signature: 50
+ $signature: 37
};
A.JSSyntaxRegExp.prototype = {
toString$0(_) {
@@ -9223,7 +9770,8 @@
throw A.wrapException(A.RangeError$range(start, 0, string.length, null, null));
return this._execAnchored$2(string, start);
},
- $isPattern: 1
+ $isPattern: 1,
+ $isRegExp: 1
};
A._MatchImplementation.prototype = {
get$start(_) {
@@ -9246,7 +9794,7 @@
};
A._AllMatchesIterable.prototype = {
get$iterator(_) {
- return new A._AllMatchesIterator(this._re, this.__js_helper$_string, this._start);
+ return new A._AllMatchesIterator(this._re, this.__js_helper$_string, this.__js_helper$_start);
}
};
A._AllMatchesIterator.prototype = {
@@ -9272,9 +9820,13 @@
t1 = _this._nextIndex;
t3 = t1 + 1;
if (t3 < t2) {
- t1 = B.JSString_methods.codeUnitAt$1(string, t1);
+ if (!(t1 >= 0 && t1 < t2))
+ return A.ioore(string, t1);
+ t1 = string.charCodeAt(t1);
if (t1 >= 55296 && t1 <= 56319) {
- t1 = B.JSString_methods.codeUnitAt$1(string, t3);
+ if (!(t3 >= 0))
+ return A.ioore(string, t3);
+ t1 = string.charCodeAt(t3);
t1 = t1 >= 56320 && t1 <= 57343;
} else
t1 = false;
@@ -9343,13 +9895,41 @@
};
A._Cell.prototype = {
_readLocal$0() {
- var t1 = this.__late_helper$_value;
+ var t1 = this._value;
if (t1 === this)
throw A.wrapException(new A.LateError("Local '" + this.__late_helper$_name + "' has not been initialized."));
return t1;
}
};
+ A._InitializedCell.prototype = {
+ _readFinal$0() {
+ var result, _this = this,
+ t1 = _this._value;
+ if (t1 === _this) {
+ result = _this._initializer.call$0();
+ if (_this._value !== _this)
+ throw A.wrapException(new A.LateError("Local '" + _this.__late_helper$_name + string$.x27_has_));
+ _this._value = result;
+ t1 = result;
+ }
+ return t1;
+ }
+ };
+ A.NativeByteBuffer.prototype = {
+ get$runtimeType(receiver) {
+ return B.Type_ByteBuffer_RkP;
+ },
+ $isTrustedGetRuntimeType: 1,
+ $isByteBuffer: 1
+ };
A.NativeTypedData.prototype = {};
+ A.NativeByteData.prototype = {
+ get$runtimeType(receiver) {
+ return B.Type_ByteData_zNC;
+ },
+ $isTrustedGetRuntimeType: 1,
+ $isByteData: 1
+ };
A.NativeTypedArray.prototype = {
get$length(receiver) {
return receiver.length;
@@ -9363,7 +9943,6 @@
return receiver[index];
},
$indexSet(receiver, index, value) {
- A._asInt(index);
A._asDouble(value);
A._checkValidIndex(index, receiver, receiver.length);
receiver[index] = value;
@@ -9374,7 +9953,6 @@
};
A.NativeTypedArrayOfInt.prototype = {
$indexSet(receiver, index, value) {
- A._asInt(index);
A._asInt(value);
A._checkValidIndex(index, receiver, receiver.length);
receiver[index] = value;
@@ -9383,42 +9961,84 @@
$isIterable: 1,
$isList: 1
};
+ A.NativeFloat32List.prototype = {
+ get$runtimeType(receiver) {
+ return B.Type_Float32List_LB7;
+ },
+ $isTrustedGetRuntimeType: 1,
+ $isFloat32List: 1
+ };
+ A.NativeFloat64List.prototype = {
+ get$runtimeType(receiver) {
+ return B.Type_Float64List_LB7;
+ },
+ $isTrustedGetRuntimeType: 1,
+ $isFloat64List: 1
+ };
A.NativeInt16List.prototype = {
+ get$runtimeType(receiver) {
+ return B.Type_Int16List_uXf;
+ },
$index(receiver, index) {
A._asInt(index);
A._checkValidIndex(index, receiver, receiver.length);
return receiver[index];
- }
+ },
+ $isTrustedGetRuntimeType: 1,
+ $isInt16List: 1
};
A.NativeInt32List.prototype = {
+ get$runtimeType(receiver) {
+ return B.Type_Int32List_O50;
+ },
$index(receiver, index) {
A._asInt(index);
A._checkValidIndex(index, receiver, receiver.length);
return receiver[index];
- }
+ },
+ $isTrustedGetRuntimeType: 1,
+ $isInt32List: 1
};
A.NativeInt8List.prototype = {
+ get$runtimeType(receiver) {
+ return B.Type_Int8List_ekJ;
+ },
$index(receiver, index) {
A._asInt(index);
A._checkValidIndex(index, receiver, receiver.length);
return receiver[index];
- }
+ },
+ $isTrustedGetRuntimeType: 1,
+ $isInt8List: 1
};
A.NativeUint16List.prototype = {
+ get$runtimeType(receiver) {
+ return B.Type_Uint16List_2bx;
+ },
$index(receiver, index) {
A._asInt(index);
A._checkValidIndex(index, receiver, receiver.length);
return receiver[index];
- }
+ },
+ $isTrustedGetRuntimeType: 1,
+ $isUint16List: 1
};
A.NativeUint32List.prototype = {
+ get$runtimeType(receiver) {
+ return B.Type_Uint32List_2bx;
+ },
$index(receiver, index) {
A._asInt(index);
A._checkValidIndex(index, receiver, receiver.length);
return receiver[index];
- }
+ },
+ $isTrustedGetRuntimeType: 1,
+ $isUint32List: 1
};
A.NativeUint8ClampedList.prototype = {
+ get$runtimeType(receiver) {
+ return B.Type_Uint8ClampedList_Jik;
+ },
get$length(receiver) {
return receiver.length;
},
@@ -9426,9 +10046,14 @@
A._asInt(index);
A._checkValidIndex(index, receiver, receiver.length);
return receiver[index];
- }
+ },
+ $isTrustedGetRuntimeType: 1,
+ $isUint8ClampedList: 1
};
A.NativeUint8List.prototype = {
+ get$runtimeType(receiver) {
+ return B.Type_Uint8List_WLA;
+ },
get$length(receiver) {
return receiver.length;
},
@@ -9440,6 +10065,7 @@
sublist$2(receiver, start, end) {
return new Uint8Array(receiver.subarray(start, A._checkValidRange(start, end, receiver.length)));
},
+ $isTrustedGetRuntimeType: 1,
$isNativeUint8List: 1,
$isUint8List: 1
};
@@ -9474,7 +10100,7 @@
t1.storedCallback = null;
f.call$0();
},
- $signature: 8
+ $signature: 10
};
A._AsyncRun__initializeScheduleImmediate_closure.prototype = {
call$1(callback) {
@@ -9484,7 +10110,7 @@
t2 = this.span;
t1.firstChild ? t1.removeChild(t2) : t1.appendChild(t2);
},
- $signature: 48
+ $signature: 30
};
A._AsyncRun__scheduleImmediateJsOverride_internalCallback.prototype = {
call$0() {
@@ -9536,50 +10162,6 @@
},
$signature: 2
};
- A._AsyncAwaitCompleter.prototype = {
- complete$1(_, value) {
- var t2, _this = this,
- t1 = _this.$ti;
- t1._eval$1("1/?")._as(value);
- if (value == null)
- t1._precomputed1._as(value);
- if (!_this.isSync)
- _this._future._asyncComplete$1(value);
- else {
- t2 = _this._future;
- if (t1._eval$1("Future<1>")._is(value))
- t2._chainFuture$1(value);
- else
- t2._completeWithValue$1(t1._precomputed1._as(value));
- }
- },
- completeError$2(e, st) {
- var t1 = this._future;
- if (this.isSync)
- t1._completeError$2(e, st);
- else
- t1._asyncCompleteError$2(e, st);
- },
- $isCompleter: 1
- };
- A._awaitOnObject_closure.prototype = {
- call$1(result) {
- return this.bodyFunction.call$2(0, result);
- },
- $signature: 3
- };
- A._awaitOnObject_closure0.prototype = {
- call$2(error, stackTrace) {
- this.bodyFunction.call$2(1, new A.ExceptionAndStackTrace(error, type$.StackTrace._as(stackTrace)));
- },
- $signature: 65
- };
- A._wrapJsFunctionForAsync_closure.prototype = {
- call$2(errorCode, result) {
- this.$protected(A._asInt(errorCode), result);
- },
- $signature: 40
- };
A.AsyncError.prototype = {
toString$0(_) {
return A.S(this.error);
@@ -9674,6 +10256,10 @@
}
};
A._Future.prototype = {
+ _setChained$1(source) {
+ this._async$_state = this._async$_state & 1 | 4;
+ this._resultOrListeners = source;
+ },
then$1$2$onError(f, onError, $R) {
var currentZone, result, t2,
t1 = this.$ti;
@@ -9695,14 +10281,6 @@
then$1$1(f, $R) {
return this.then$1$2$onError(f, null, $R);
},
- _thenAwait$1$2(f, onError, $E) {
- var result,
- t1 = this.$ti;
- t1._bind$1($E)._eval$1("1/(2)")._as(f);
- result = new A._Future($.Zone__current, $E._eval$1("_Future<0>"));
- this._addListener$1(new A._FutureListener(result, 3, f, onError, t1._eval$1("@<1>")._bind$1($E)._eval$1("_FutureListener<1,2>")));
- return result;
- },
whenComplete$1(action) {
var t1, t2, result;
type$.dynamic_Function._as(action);
@@ -9798,7 +10376,7 @@
t1._eval$1("1/")._as(value);
if (t1._eval$1("Future<1>")._is(value))
if (t1._is(value))
- A._Future__chainCoreFuture(value, _this);
+ A._Future__chainCoreFutureSync(value, _this);
else
_this._chainForeignFuture$1(value);
else {
@@ -9832,7 +10410,7 @@
this._chainFuture$1(value);
return;
}
- this._asyncCompleteWithValue$1(t1._precomputed1._as(value));
+ this._asyncCompleteWithValue$1(value);
},
_asyncCompleteWithValue$1(value) {
var _this = this;
@@ -9841,18 +10419,13 @@
_this._zone.scheduleMicrotask$1(new A._Future__asyncCompleteWithValue_closure(_this, value));
},
_chainFuture$1(value) {
- var _this = this,
- t1 = _this.$ti;
+ var t1 = this.$ti;
t1._eval$1("Future<1>")._as(value);
if (t1._is(value)) {
- if ((value._async$_state & 16) !== 0) {
- _this._async$_state ^= 2;
- _this._zone.scheduleMicrotask$1(new A._Future__chainFuture_closure(_this, value));
- } else
- A._Future__chainCoreFuture(value, _this);
+ A._Future__chainCoreFutureAsync(value, this);
return;
}
- _this._chainForeignFuture$1(value);
+ this._chainForeignFuture$1(value);
},
_asyncCompleteError$2(error, stackTrace) {
type$.StackTrace._as(stackTrace);
@@ -9886,13 +10459,13 @@
t1._completeError$2(error, stackTrace);
}
},
- $signature: 8
+ $signature: 10
};
A._Future__chainForeignFuture_closure0.prototype = {
call$2(error, stackTrace) {
this.$this._completeError$2(type$.Object._as(error), type$.StackTrace._as(stackTrace));
},
- $signature: 37
+ $signature: 26
};
A._Future__chainForeignFuture_closure1.prototype = {
call$0() {
@@ -9900,15 +10473,15 @@
},
$signature: 0
};
- A._Future__asyncCompleteWithValue_closure.prototype = {
+ A._Future__chainCoreFutureAsync_closure.prototype = {
call$0() {
- this.$this._completeWithValue$1(this.value);
+ A._Future__chainCoreFutureSync(this._box_0.source, this.target);
},
$signature: 0
};
- A._Future__chainFuture_closure.prototype = {
+ A._Future__asyncCompleteWithValue_closure.prototype = {
call$0() {
- A._Future__chainCoreFuture(this.value, this.$this);
+ this.$this._completeWithValue$1(this.value);
},
$signature: 0
};
@@ -9944,7 +10517,7 @@
}
return;
}
- if (type$.Future_dynamic._is(completeResult)) {
+ if (completeResult instanceof A._Future) {
originalSource = _this._box_1.source;
t1 = _this._box_0;
t1.listenerValueOrError = completeResult.then$1$1(new A._Future__propagateToListeners_handleWhenCompleteCallback_closure(originalSource), type$.dynamic);
@@ -9957,7 +10530,7 @@
call$1(_) {
return this.originalSource;
},
- $signature: 34
+ $signature: 28
};
A._Future__propagateToListeners_handleValueCallback.prototype = {
call$0() {
@@ -10021,7 +10594,7 @@
call$1(_) {
return this.streamConsumer.close$0(0);
},
- $signature: 32
+ $signature: 29
};
A.Stream_length_closure.prototype = {
call$1(_) {
@@ -10038,7 +10611,6 @@
},
$signature: 0
};
- A.StreamTransformerBase.prototype = {$isStreamTransformer: 1};
A._StreamController.prototype = {
get$_pendingEvents() {
var t1, _this = this;
@@ -10175,7 +10747,7 @@
if (result == null)
try {
cancelResult = onCancel.call$0();
- if (type$.Future_void._is(cancelResult))
+ if (cancelResult instanceof A._Future)
result = cancelResult;
} catch (exception) {
e = A.unwrapException(exception);
@@ -10615,7 +11187,6 @@
},
$isStreamSubscription: 1
};
- A._StreamIterator.prototype = {};
A._EmptyStream.prototype = {
listen$4$cancelOnError$onDone$onError(onData, cancelOnError, onDone, onError) {
var t1 = this.$ti;
@@ -10903,11 +11474,7 @@
};
A._rootHandleError_closure.prototype = {
call$0() {
- var t1 = this.error,
- t2 = this.stackTrace;
- A.checkNotNullable(t1, "error", type$.Object);
- A.checkNotNullable(t2, "stackTrace", type$.StackTrace);
- A.Error__throw(t1, t2);
+ A.Error_throwWithStackTrace(this.error, this.stackTrace);
},
$signature: 0
};
@@ -11130,7 +11697,7 @@
t2._processUncaughtError$3(zone, type$.Object._as(e), t1._as(s));
}
},
- $signature: 31
+ $signature: 34
};
A._HashMap.prototype = {
get$length(_) {
@@ -11325,9 +11892,15 @@
get$isEmpty(_) {
return this._collection$_map._collection$_length === 0;
},
+ get$isNotEmpty(_) {
+ return this._collection$_map._collection$_length !== 0;
+ },
get$iterator(_) {
var t1 = this._collection$_map;
return new A._HashMapKeyIterator(t1, t1._computeKeys$0(), this.$ti._eval$1("_HashMapKeyIterator<1>"));
+ },
+ contains$1(_, element) {
+ return this._collection$_map.containsKey$1(0, element);
}
};
A._HashMapKeyIterator.prototype = {
@@ -11366,6 +11939,12 @@
get$length(_) {
return this._collection$_length;
},
+ get$isEmpty(_) {
+ return this._collection$_length === 0;
+ },
+ get$isNotEmpty(_) {
+ return this._collection$_length !== 0;
+ },
contains$1(_, object) {
var nums;
if ((object & 1073741823) === object) {
@@ -11412,20 +11991,17 @@
return true;
},
remove$1(_, object) {
- var _this = this;
- if (typeof object == "string" && object !== "__proto__")
- return _this._collection$_removeHashTableEntry$2(_this._collection$_strings, object);
- else if (typeof object == "number" && (object & 1073741823) === object)
- return _this._collection$_removeHashTableEntry$2(_this._collection$_nums, object);
+ if ((object & 1073741823) === object)
+ return this._collection$_removeHashTableEntry$2(this._collection$_nums, object);
else
- return _this._remove$1(0, object);
+ return this._remove$1(0, object);
},
_remove$1(_, object) {
var hash, bucket, index, cell,
rest = this._collection$_rest;
if (rest == null)
return false;
- hash = J.get$hashCode$(object) & 1073741823;
+ hash = B.JSInt_methods.get$hashCode(object) & 1073741823;
bucket = rest[hash];
index = this._findBucketIndex$2(bucket, object);
if (index < 0)
@@ -11524,34 +12100,73 @@
},
$isIterator: 1
};
- A.IterableBase.prototype = {};
- A.ListBase.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isList: 1};
- A.ListMixin.prototype = {
+ A.ListBase.prototype = {
get$iterator(receiver) {
- return new A.ListIterator(receiver, this.get$length(receiver), A.instanceType(receiver)._eval$1("ListIterator<ListMixin.E>"));
+ return new A.ListIterator(receiver, this.get$length(receiver), A.instanceType(receiver)._eval$1("ListIterator<ListBase.E>"));
},
elementAt$1(receiver, index) {
return this.$index(receiver, index);
},
+ get$isEmpty(receiver) {
+ return this.get$length(receiver) === 0;
+ },
get$isNotEmpty(receiver) {
- return this.get$length(receiver) !== 0;
+ return !this.get$isEmpty(receiver);
+ },
+ get$first(receiver) {
+ if (this.get$length(receiver) === 0)
+ throw A.wrapException(A.IterableElementError_noElement());
+ return this.$index(receiver, 0);
},
map$1$1(receiver, f, $T) {
var t1 = A.instanceType(receiver);
- return new A.MappedListIterable(receiver, t1._bind$1($T)._eval$1("1(ListMixin.E)")._as(f), t1._eval$1("@<ListMixin.E>")._bind$1($T)._eval$1("MappedListIterable<1,2>"));
+ return new A.MappedListIterable(receiver, t1._bind$1($T)._eval$1("1(ListBase.E)")._as(f), t1._eval$1("@<ListBase.E>")._bind$1($T)._eval$1("MappedListIterable<1,2>"));
+ },
+ skip$1(receiver, count) {
+ return A.SubListIterable$(receiver, count, null, A.instanceType(receiver)._eval$1("ListBase.E"));
+ },
+ cast$1$0(receiver, $R) {
+ return new A.CastList(receiver, A.instanceType(receiver)._eval$1("@<ListBase.E>")._bind$1($R)._eval$1("CastList<1,2>"));
},
fillRange$3(receiver, start, end, fill) {
var i;
- A.instanceType(receiver)._eval$1("ListMixin.E?")._as(fill);
+ A.instanceType(receiver)._eval$1("ListBase.E?")._as(fill);
A.RangeError_checkValidRange(start, end, this.get$length(receiver));
for (i = start; i < end; ++i)
this.$indexSet(receiver, i, fill);
},
toString$0(receiver) {
- return A.IterableBase_iterableToFullString(receiver, "[", "]");
- }
+ return A.Iterable_iterableToFullString(receiver, "[", "]");
+ },
+ $isEfficientLengthIterable: 1,
+ $isIterable: 1,
+ $isList: 1
};
- A.MapBase.prototype = {};
+ A.MapBase.prototype = {
+ forEach$1(receiver, action) {
+ var t2, key, t3,
+ t1 = A.instanceType(receiver);
+ t1._eval$1("~(MapBase.K,MapBase.V)")._as(action);
+ for (t2 = J.get$iterator$ax(this.get$keys(receiver)), t1 = t1._eval$1("MapBase.V"); t2.moveNext$0();) {
+ key = t2.get$current(t2);
+ t3 = this.$index(receiver, key);
+ action.call$2(key, t3 == null ? t1._as(t3) : t3);
+ }
+ },
+ containsKey$1(receiver, key) {
+ return J.contains$1$asx(this.get$keys(receiver), key);
+ },
+ get$length(receiver) {
+ return J.get$length$asx(this.get$keys(receiver));
+ },
+ get$isEmpty(receiver) {
+ return J.get$isEmpty$asx(this.get$keys(receiver));
+ },
+ toString$0(receiver) {
+ return A.MapBase_mapToString(receiver);
+ },
+ $isMap: 1
+ };
A.MapBase_mapToString_closure.prototype = {
call$2(k, v) {
var t2,
@@ -11564,29 +12179,7 @@
t1._contents = t2 + ": ";
t1._contents += A.S(v);
},
- $signature: 21
- };
- A.MapMixin.prototype = {
- forEach$1(receiver, action) {
- var t2, key, t3,
- t1 = A.instanceType(receiver);
- t1._eval$1("~(MapMixin.K,MapMixin.V)")._as(action);
- for (t2 = J.get$iterator$ax(this.get$keys(receiver)), t1 = t1._eval$1("MapMixin.V"); t2.moveNext$0();) {
- key = t2.get$current(t2);
- t3 = this.$index(receiver, key);
- action.call$2(key, t3 == null ? t1._as(t3) : t3);
- }
- },
- get$length(receiver) {
- return J.get$length$asx(this.get$keys(receiver));
- },
- get$isEmpty(receiver) {
- return J.get$isEmpty$asx(this.get$keys(receiver));
- },
- toString$0(receiver) {
- return A.MapBase_mapToString(receiver);
- },
- $isMap: 1
+ $signature: 16
};
A._UnmodifiableMapMixin.prototype = {
$indexSet(_, key, value) {
@@ -11604,6 +12197,9 @@
var t1 = A._instanceType(this);
J.$indexSet$ax(this._collection$_map, t1._precomputed1._as(key), t1._rest[1]._as(value));
},
+ containsKey$1(_, key) {
+ return J.containsKey$1$x(this._collection$_map, key);
+ },
forEach$1(_, action) {
J.forEach$1$x(this._collection$_map, A._instanceType(this)._eval$1("~(1,2)")._as(action));
},
@@ -11622,19 +12218,42 @@
$isMap: 1
};
A.UnmodifiableMapView.prototype = {};
- A.SetMixin.prototype = {
+ A.SetBase.prototype = {
+ get$isEmpty(_) {
+ return this._collection$_length === 0;
+ },
+ get$isNotEmpty(_) {
+ return this._collection$_length !== 0;
+ },
map$1$1(_, f, $T) {
var t1 = this.$ti;
return new A.EfficientLengthMappedIterable(this, t1._bind$1($T)._eval$1("1(2)")._as(f), t1._eval$1("@<1>")._bind$1($T)._eval$1("EfficientLengthMappedIterable<1,2>"));
},
toString$0(_) {
- return A.IterableBase_iterableToFullString(this, "{", "}");
- }
+ return A.Iterable_iterableToFullString(this, "{", "}");
+ },
+ skip$1(_, n) {
+ return A.SkipIterable_SkipIterable(this, n, this.$ti._precomputed1);
+ },
+ elementAt$1(_, index) {
+ var iterator, skipCount, t1, _this = this;
+ A.RangeError_checkNotNegative(index, "index");
+ iterator = A._LinkedHashSetIterator$(_this, _this._collection$_modifications, _this.$ti._precomputed1);
+ for (skipCount = index; iterator.moveNext$0();) {
+ if (skipCount === 0) {
+ t1 = iterator._collection$_current;
+ return t1 == null ? iterator.$ti._precomputed1._as(t1) : t1;
+ }
+ --skipCount;
+ }
+ throw A.wrapException(A.IndexError$withLength(index, index - skipCount, _this, "index"));
+ },
+ $isEfficientLengthIterable: 1,
+ $isIterable: 1,
+ $isSet: 1
};
- A._SetBase.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isSet: 1};
- A._ListBase_Object_ListMixin.prototype = {};
+ A._SetBase.prototype = {};
A._UnmodifiableMapView_MapView__UnmodifiableMapMixin.prototype = {};
- A.__SetBase_Object_SetMixin.prototype = {};
A._JsonMap.prototype = {
$index(_, key) {
var result,
@@ -11756,6 +12375,9 @@
t1 = new J.ArrayIterator(t1, t1.length, A._arrayInstanceType(t1)._eval$1("ArrayIterator<1>"));
}
return t1;
+ },
+ contains$1(_, key) {
+ return this._convert$_parent.containsKey$1(0, key);
}
};
A.Utf8Decoder__decoder_closure.prototype = {
@@ -11768,7 +12390,7 @@
}
return null;
},
- $signature: 19
+ $signature: 4
};
A.Utf8Decoder__decoderNonfatal_closure.prototype = {
call$0() {
@@ -11780,7 +12402,7 @@
}
return null;
},
- $signature: 19
+ $signature: 4
};
A.AsciiCodec.prototype = {
encode$1(source) {
@@ -11789,12 +12411,15 @@
};
A._UnicodeSubsetEncoder.prototype = {
convert$1(string) {
- var $length, result, t1, i, codeUnit;
+ var stringLength, $length, result, t1, i, codeUnit;
A._asString(string);
- $length = A.RangeError_checkValidRange(0, null, string.length) - 0;
+ stringLength = string.length;
+ $length = A.RangeError_checkValidRange(0, null, stringLength) - 0;
result = new Uint8Array($length);
for (t1 = ~this._subsetMask, i = 0; i < $length; ++i) {
- codeUnit = B.JSString_methods._codeUnitAt$1(string, i);
+ if (!(i < stringLength))
+ return A.ioore(string, i);
+ codeUnit = string.charCodeAt(i);
if ((codeUnit & t1) !== 0)
throw A.wrapException(A.ArgumentError$value(string, "string", "Contains invalid characters."));
if (!(i < $length))
@@ -11807,18 +12432,27 @@
A.AsciiEncoder.prototype = {};
A.Base64Codec.prototype = {
normalize$3(_, source, start, end) {
- var inverseAlphabet, t1, i, sliceStart, buffer, firstPadding, firstPaddingSourceIndex, paddingCount, i0, char, i1, digit1, digit2, char0, value, t2, t3, endLength, $length,
- _s31_ = "Invalid base64 encoding length ";
- end = A.RangeError_checkValidRange(start, end, source.length);
+ var inverseAlphabet, t2, i, sliceStart, buffer, firstPadding, firstPaddingSourceIndex, paddingCount, i0, char, i1, digit1, t3, digit2, char0, value, endLength, $length,
+ _s64_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
+ _s31_ = "Invalid base64 encoding length ",
+ t1 = source.length;
+ end = A.RangeError_checkValidRange(start, end, t1);
inverseAlphabet = $.$get$_Base64Decoder__inverseAlphabet();
- for (t1 = inverseAlphabet.length, i = start, sliceStart = i, buffer = null, firstPadding = -1, firstPaddingSourceIndex = -1, paddingCount = 0; i < end; i = i0) {
+ for (t2 = inverseAlphabet.length, i = start, sliceStart = i, buffer = null, firstPadding = -1, firstPaddingSourceIndex = -1, paddingCount = 0; i < end; i = i0) {
i0 = i + 1;
- char = B.JSString_methods._codeUnitAt$1(source, i);
+ if (!(i < t1))
+ return A.ioore(source, i);
+ char = source.charCodeAt(i);
if (char === 37) {
i1 = i0 + 2;
if (i1 <= end) {
- digit1 = A.hexDigitValue(B.JSString_methods._codeUnitAt$1(source, i0));
- digit2 = A.hexDigitValue(B.JSString_methods._codeUnitAt$1(source, i0 + 1));
+ if (!(i0 < t1))
+ return A.ioore(source, i0);
+ digit1 = A.hexDigitValue(source.charCodeAt(i0));
+ t3 = i0 + 1;
+ if (!(t3 < t1))
+ return A.ioore(source, t3);
+ digit2 = A.hexDigitValue(source.charCodeAt(t3));
char0 = digit1 * 16 + digit2 - (digit2 & 256);
if (char0 === 37)
char0 = -1;
@@ -11828,21 +12462,23 @@
} else
char0 = char;
if (0 <= char0 && char0 <= 127) {
- if (!(char0 >= 0 && char0 < t1))
+ if (!(char0 >= 0 && char0 < t2))
return A.ioore(inverseAlphabet, char0);
value = inverseAlphabet[char0];
if (value >= 0) {
- char0 = B.JSString_methods.codeUnitAt$1("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", value);
+ if (!(value < 64))
+ return A.ioore(_s64_, value);
+ char0 = _s64_.charCodeAt(value);
if (char0 === char)
continue;
char = char0;
} else {
if (value === -1) {
if (firstPadding < 0) {
- t2 = buffer == null ? null : buffer._contents.length;
- if (t2 == null)
- t2 = 0;
- firstPadding = t2 + (i - sliceStart);
+ t3 = buffer == null ? null : buffer._contents.length;
+ if (t3 == null)
+ t3 = 0;
+ firstPadding = t3 + (i - sliceStart);
firstPaddingSourceIndex = i;
}
++paddingCount;
@@ -11854,11 +12490,11 @@
if (value !== -2) {
if (buffer == null) {
buffer = new A.StringBuffer("");
- t2 = buffer;
+ t3 = buffer;
} else
- t2 = buffer;
- t3 = t2._contents += B.JSString_methods.substring$2(source, sliceStart, i);
- t2._contents = t3 + A.Primitives_stringFromCharCode(char);
+ t3 = buffer;
+ t3._contents += B.JSString_methods.substring$2(source, sliceStart, i);
+ t3._contents += A.Primitives_stringFromCharCode(char);
sliceStart = i0;
continue;
}
@@ -11899,7 +12535,7 @@
A.Base64Encoder.prototype = {};
A.Codec.prototype = {};
A._FusedCodec.prototype = {};
- A.Converter.prototype = {};
+ A.Converter.prototype = {$isStreamTransformer: 1};
A.Encoding.prototype = {};
A.JsonUnsupportedObjectError.prototype = {
toString$0(_) {
@@ -11914,15 +12550,11 @@
};
A.JsonCodec.prototype = {
decode$2$reviver(_, source, reviver) {
- var t1;
- type$.nullable_nullable_Object_Function_2_nullable_Object_and_nullable_Object._as(reviver);
- t1 = A._parseJson(source, this.get$decoder()._reviver);
+ var t1 = A._parseJson(source, this.get$decoder()._reviver);
return t1;
},
encode$2$toEncodable(value, toEncodable) {
- var t1;
- type$.nullable_nullable_Object_Function_dynamic._as(toEncodable);
- t1 = A._JsonStringStringifier_stringify(value, this.get$encoder()._toEncodable, null);
+ var t1 = A._JsonStringStringifier_stringify(value, this.get$encoder()._toEncodable, null);
return t1;
},
get$encoder() {
@@ -11939,19 +12571,19 @@
var offset, i, charCode, t1, t2, _this = this,
$length = s.length;
for (offset = 0, i = 0; i < $length; ++i) {
- charCode = B.JSString_methods._codeUnitAt$1(s, i);
+ charCode = s.charCodeAt(i);
if (charCode > 92) {
if (charCode >= 55296) {
t1 = charCode & 64512;
if (t1 === 55296) {
t2 = i + 1;
- t2 = !(t2 < $length && (B.JSString_methods._codeUnitAt$1(s, t2) & 64512) === 56320);
+ t2 = !(t2 < $length && (s.charCodeAt(t2) & 64512) === 56320);
} else
t2 = false;
if (!t2)
if (t1 === 56320) {
t1 = i - 1;
- t1 = !(t1 >= 0 && (B.JSString_methods.codeUnitAt$1(s, t1) & 64512) === 55296);
+ t1 = !(t1 >= 0 && (s.charCodeAt(t1) & 64512) === 55296);
} else
t1 = false;
else
@@ -12138,7 +12770,7 @@
B.JSArray_methods.$indexSet(t1, t2.i++, key);
B.JSArray_methods.$indexSet(t1, t2.i++, value);
},
- $signature: 21
+ $signature: 16
};
A._JsonStringStringifier.prototype = {
get$_partialResult() {
@@ -12158,23 +12790,22 @@
this._sink.writeCharCode$1(charCode);
}
};
- A.Utf8Codec.prototype = {
- get$encoder() {
- return B.C_Utf8Encoder;
- }
- };
+ A.Utf8Codec.prototype = {};
A.Utf8Encoder.prototype = {
convert$1(string) {
- var end, $length, t1, encoder;
+ var stringLength, end, $length, t1, encoder, t2;
A._asString(string);
- end = A.RangeError_checkValidRange(0, null, string.length);
+ stringLength = string.length;
+ end = A.RangeError_checkValidRange(0, null, stringLength);
$length = end - 0;
if ($length === 0)
return new Uint8Array(0);
t1 = new Uint8Array($length * 3);
encoder = new A._Utf8Encoder(t1);
if (encoder._fillBuffer$3(string, 0, end) !== end) {
- B.JSString_methods.codeUnitAt$1(string, end - 1);
+ t2 = end - 1;
+ if (!(t2 >= 0 && t2 < stringLength))
+ return A.ioore(string, t2);
encoder._writeReplacementCharacter$0();
}
return B.NativeUint8List_methods.sublist$2(t1, 0, encoder._bufferIndex);
@@ -12229,56 +12860,67 @@
}
},
_fillBuffer$3(str, start, end) {
- var t1, t2, stringIndex, codeUnit, t3, stringIndex0, t4, _this = this;
- if (start !== end && (B.JSString_methods.codeUnitAt$1(str, end - 1) & 64512) === 55296)
+ var t1, t2, t3, stringIndex, codeUnit, t4, t5, _this = this;
+ if (start !== end) {
+ t1 = end - 1;
+ if (!(t1 >= 0 && t1 < str.length))
+ return A.ioore(str, t1);
+ t1 = (str.charCodeAt(t1) & 64512) === 55296;
+ } else
+ t1 = false;
+ if (t1)
--end;
- for (t1 = _this._buffer, t2 = t1.length, stringIndex = start; stringIndex < end; ++stringIndex) {
- codeUnit = B.JSString_methods._codeUnitAt$1(str, stringIndex);
+ for (t1 = _this._buffer, t2 = t1.length, t3 = str.length, stringIndex = start; stringIndex < end; ++stringIndex) {
+ if (!(stringIndex < t3))
+ return A.ioore(str, stringIndex);
+ codeUnit = str.charCodeAt(stringIndex);
if (codeUnit <= 127) {
- t3 = _this._bufferIndex;
- if (t3 >= t2)
+ t4 = _this._bufferIndex;
+ if (t4 >= t2)
break;
- _this._bufferIndex = t3 + 1;
- t1[t3] = codeUnit;
+ _this._bufferIndex = t4 + 1;
+ t1[t4] = codeUnit;
} else {
- t3 = codeUnit & 64512;
- if (t3 === 55296) {
+ t4 = codeUnit & 64512;
+ if (t4 === 55296) {
if (_this._bufferIndex + 4 > t2)
break;
- stringIndex0 = stringIndex + 1;
- if (_this._writeSurrogate$2(codeUnit, B.JSString_methods._codeUnitAt$1(str, stringIndex0)))
- stringIndex = stringIndex0;
- } else if (t3 === 56320) {
+ t4 = stringIndex + 1;
+ if (!(t4 < t3))
+ return A.ioore(str, t4);
+ if (_this._writeSurrogate$2(codeUnit, str.charCodeAt(t4)))
+ stringIndex = t4;
+ } else if (t4 === 56320) {
if (_this._bufferIndex + 3 > t2)
break;
_this._writeReplacementCharacter$0();
} else if (codeUnit <= 2047) {
- t3 = _this._bufferIndex;
- t4 = t3 + 1;
- if (t4 >= t2)
+ t4 = _this._bufferIndex;
+ t5 = t4 + 1;
+ if (t5 >= t2)
break;
- _this._bufferIndex = t4;
- if (!(t3 < t2))
- return A.ioore(t1, t3);
- t1[t3] = codeUnit >>> 6 | 192;
- _this._bufferIndex = t4 + 1;
- t1[t4] = codeUnit & 63 | 128;
- } else {
- t3 = _this._bufferIndex;
- if (t3 + 2 >= t2)
- break;
- t4 = _this._bufferIndex = t3 + 1;
- if (!(t3 < t2))
- return A.ioore(t1, t3);
- t1[t3] = codeUnit >>> 12 | 224;
- t3 = _this._bufferIndex = t4 + 1;
+ _this._bufferIndex = t5;
if (!(t4 < t2))
return A.ioore(t1, t4);
- t1[t4] = codeUnit >>> 6 & 63 | 128;
- _this._bufferIndex = t3 + 1;
- if (!(t3 < t2))
- return A.ioore(t1, t3);
- t1[t3] = codeUnit & 63 | 128;
+ t1[t4] = codeUnit >>> 6 | 192;
+ _this._bufferIndex = t5 + 1;
+ t1[t5] = codeUnit & 63 | 128;
+ } else {
+ t4 = _this._bufferIndex;
+ if (t4 + 2 >= t2)
+ break;
+ t5 = _this._bufferIndex = t4 + 1;
+ if (!(t4 < t2))
+ return A.ioore(t1, t4);
+ t1[t4] = codeUnit >>> 12 | 224;
+ t4 = _this._bufferIndex = t5 + 1;
+ if (!(t5 < t2))
+ return A.ioore(t1, t5);
+ t1[t5] = codeUnit >>> 6 & 63 | 128;
+ _this._bufferIndex = t4 + 1;
+ if (!(t4 < t2))
+ return A.ioore(t1, t4);
+ t1[t4] = codeUnit & 63 | 128;
}
}
}
@@ -12333,7 +12975,10 @@
return _this.decodeGeneral$4(bytes, start, end, single);
},
decodeGeneral$4(bytes, start, end, single) {
- var byte, t2, type, t3, i0, markEnd, i1, m, _this = this, _65533 = 65533,
+ var byte, t2, type, t3, i0, markEnd, i1, m, _this = this,
+ _s256_ = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHIHHHJEEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBKCCCCCCCCCCCCDCLONNNMEEEEEEEEEEE",
+ _s144_ = " \x000:XECCCCCN:lDb \x000:XECCCCCNvlDb \x000:XECCCCCN:lDb AAAAA\x00\x00\x00\x00\x00AAAAA00000AAAAA:::::AAAAAGG000AAAAA00KKKAAAAAG::::AAAAA:IIIIAAAAA000\x800AAAAA\x00\x00\x00\x00 AAAAA",
+ _65533 = 65533,
state = _this._state,
char = _this._charOrIndex,
buffer = new A.StringBuffer(""),
@@ -12345,9 +12990,14 @@
$label0$0:
for (t2 = _this.allowMalformed; true;) {
for (; true; i = i0) {
- type = B.JSString_methods._codeUnitAt$1("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHIHHHJEEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBKCCCCCCCCCCCCDCLONNNMEEEEEEEEEEE", byte) & 31;
+ if (!(byte >= 0 && byte < 256))
+ return A.ioore(_s256_, byte);
+ type = _s256_.charCodeAt(byte) & 31;
char = state <= 32 ? byte & 61694 >>> type : (byte & 63 | char << 6) >>> 0;
- state = B.JSString_methods._codeUnitAt$1(" \x000:XECCCCCN:lDb \x000:XECCCCCNvlDb \x000:XECCCCCN:lDb AAAAA\x00\x00\x00\x00\x00AAAAA00000AAAAA:::::AAAAAGG000AAAAA00KKKAAAAAG::::AAAAA:IIIIAAAAA000\x800AAAAA\x00\x00\x00\x00 AAAAA", state + type);
+ t3 = state + type;
+ if (!(t3 >= 0 && t3 < 144))
+ return A.ioore(_s144_, t3);
+ state = _s144_.charCodeAt(t3);
if (state === 0) {
buffer._contents += A.Primitives_stringFromCharCode(char);
if (i === end)
@@ -12445,16 +13095,16 @@
t1._contents += A.Error_safeToString(value);
t2.comma = ", ";
},
- $signature: 29
+ $signature: 39
};
A.DateTime.prototype = {
$eq(_, other) {
if (other == null)
return false;
- return other instanceof A.DateTime && this._value === other._value && true;
+ return other instanceof A.DateTime && this._core$_value === other._core$_value && true;
},
get$hashCode(_) {
- var t1 = this._value;
+ var t1 = this._core$_value;
return (t1 ^ B.JSInt_methods._shrOtherPositive$1(t1, 30)) & 1073741823;
},
toString$0(_) {
@@ -12488,7 +13138,7 @@
minutesPadding = minutes < 10 ? "0" : "";
seconds = B.JSInt_methods._tdivFast$1(microseconds, 1000000);
secondsPadding = seconds < 10 ? "0" : "";
- return "" + Math.abs(hours) + ":" + minutesPadding + minutes + ":" + secondsPadding + seconds + "." + B.JSString_methods.padLeft$2(B.JSInt_methods.toString$0(microseconds % 1000000), 6, "0");
+ return "" + hours + ":" + minutesPadding + minutes + ":" + secondsPadding + seconds + "." + B.JSString_methods.padLeft$2(B.JSInt_methods.toString$0(microseconds % 1000000), 6, "0");
}
};
A.Error.prototype = {
@@ -12505,11 +13155,6 @@
}
};
A.TypeError.prototype = {};
- A.NullThrownError.prototype = {
- toString$0(_) {
- return "Throw of null.";
- }
- };
A.ArgumentError.prototype = {
get$_errorName() {
return "Invalid argument" + (!this._hasValue ? "(s)" : "");
@@ -12526,10 +13171,16 @@
prefix = _this.get$_errorName() + nameString + messageString;
if (!_this._hasValue)
return prefix;
- return prefix + _this.get$_errorExplanation() + ": " + A.Error_safeToString(_this.invalidValue);
+ return prefix + _this.get$_errorExplanation() + ": " + A.Error_safeToString(_this.get$invalidValue());
+ },
+ get$invalidValue() {
+ return this.invalidValue;
}
};
A.RangeError.prototype = {
+ get$invalidValue() {
+ return A._asNumQ(this.invalidValue);
+ },
get$_errorName() {
return "RangeError";
},
@@ -12549,6 +13200,9 @@
}
};
A.IndexError.prototype = {
+ get$invalidValue() {
+ return A._asInt(this.invalidValue);
+ },
get$_errorName() {
return "RangeError";
},
@@ -12623,11 +13277,6 @@
},
$isError: 1
};
- A.CyclicInitializationError.prototype = {
- toString$0(_) {
- return "Reading static variable '" + this.variableName + "' during its initialization";
- }
- };
A._Exception.prototype = {
toString$0(_) {
return "Exception: " + this.message;
@@ -12636,7 +13285,7 @@
};
A.FormatException.prototype = {
toString$0(_) {
- var t1, lineNum, lineStart, previousCharWasCR, i, char, lineEnd, end, start, prefix, postfix,
+ var t1, lineEnd, lineNum, lineStart, previousCharWasCR, i, char, end, start, prefix, postfix,
message = this.message,
report = "" !== message ? "FormatException: " + message : "FormatException",
offset = this.offset,
@@ -12653,8 +13302,10 @@
source = B.JSString_methods.substring$2(source, 0, 75) + "...";
return report + "\n" + source;
}
- for (lineNum = 1, lineStart = 0, previousCharWasCR = false, i = 0; i < offset; ++i) {
- char = B.JSString_methods._codeUnitAt$1(source, i);
+ for (lineEnd = source.length, lineNum = 1, lineStart = 0, previousCharWasCR = false, i = 0; i < offset; ++i) {
+ if (!(i < lineEnd))
+ return A.ioore(source, i);
+ char = source.charCodeAt(i);
if (char === 10) {
if (lineStart !== i || !previousCharWasCR)
++lineNum;
@@ -12667,9 +13318,10 @@
}
}
report = lineNum > 1 ? report + (" (at line " + lineNum + ", character " + (offset - lineStart + 1) + ")\n") : report + (" (at character " + (offset + 1) + ")\n");
- lineEnd = source.length;
for (i = offset; i < lineEnd; ++i) {
- char = B.JSString_methods.codeUnitAt$1(source, i);
+ if (!(i >= 0))
+ return A.ioore(source, i);
+ char = source.charCodeAt(i);
if (char === 10 || char === 13) {
lineEnd = i;
break;
@@ -12706,10 +13358,19 @@
$isException: 1
};
A.Iterable.prototype = {
+ cast$1$0(_, $R) {
+ return A.CastIterable_CastIterable(this, A._instanceType(this)._eval$1("Iterable.E"), $R);
+ },
map$1$1(_, toElement, $T) {
var t1 = A._instanceType(this);
return A.MappedIterable_MappedIterable(this, t1._bind$1($T)._eval$1("1(Iterable.E)")._as(toElement), t1._eval$1("Iterable.E"), $T);
},
+ toList$1$growable(_, growable) {
+ return A.List_List$of(this, growable, A._instanceType(this)._eval$1("Iterable.E"));
+ },
+ toList$0($receiver) {
+ return this.toList$1$growable($receiver, true);
+ },
get$length(_) {
var count,
it = this.get$iterator(this);
@@ -12720,6 +13381,12 @@
get$isEmpty(_) {
return !this.get$iterator(this).moveNext$0();
},
+ get$isNotEmpty(_) {
+ return !this.get$isEmpty(this);
+ },
+ skip$1(_, count) {
+ return A.SkipIterable_SkipIterable(this, count, A._instanceType(this)._eval$1("Iterable.E"));
+ },
skipWhile$1(_, test) {
var t1 = A._instanceType(this);
return new A.SkipWhileIterable(this, t1._eval$1("bool(Iterable.E)")._as(test), t1._eval$1("SkipWhileIterable<Iterable.E>"));
@@ -12741,21 +13408,20 @@
return result;
},
elementAt$1(_, index) {
- var t1, elementIndex, element;
+ var iterator, skipCount;
A.RangeError_checkNotNegative(index, "index");
- for (t1 = this.get$iterator(this), elementIndex = 0; t1.moveNext$0();) {
- element = t1.get$current(t1);
- if (index === elementIndex)
- return element;
- ++elementIndex;
+ iterator = this.get$iterator(this);
+ for (skipCount = index; iterator.moveNext$0();) {
+ if (skipCount === 0)
+ return iterator.get$current(iterator);
+ --skipCount;
}
- throw A.wrapException(A.IndexError$(index, this, "index", null, elementIndex));
+ throw A.wrapException(A.IndexError$withLength(index, index - skipCount, this, "index"));
},
toString$0(_) {
- return A.IterableBase_iterableToShortString(this, "(", ")");
+ return A.Iterable_iterableToShortString(this, "(", ")");
}
};
- A.Iterator.prototype = {};
A.Null.prototype = {
get$hashCode(_) {
return A.Object.prototype.get$hashCode.call(this, this);
@@ -12775,8 +13441,10 @@
return "Instance of '" + A.Primitives_objectTypeName(this) + "'";
},
noSuchMethod$1(_, invocation) {
- type$.Invocation._as(invocation);
- throw A.wrapException(A.NoSuchMethodError$(this, invocation.get$memberName(), invocation.get$positionalArguments(), invocation.get$namedArguments()));
+ throw A.wrapException(A.NoSuchMethodError_NoSuchMethodError$withInvocation(this, type$.Invocation._as(invocation)));
+ },
+ get$runtimeType(_) {
+ return A.getRuntimeTypeOfDartObject(this);
},
toString() {
return this.toString$0(this);
@@ -12821,7 +13489,7 @@
}
return map;
},
- $signature: 27
+ $signature: 40
};
A.Uri__parseIPv4Address_error.prototype = {
call$2(msg, position) {
@@ -12833,7 +13501,7 @@
call$2(msg, position) {
throw A.wrapException(A.FormatException$("Illegal IPv6 address, " + msg, this.host, position));
},
- $signature: 25
+ $signature: 45
};
A.Uri_parseIPv6Address_parseHex.prototype = {
call$2(start, end) {
@@ -12845,7 +13513,7 @@
this.error.call$2("each part must be in the range of `0x0..0xFFFF`", start);
return value;
},
- $signature: 26
+ $signature: 60
};
A._Uri.prototype = {
get$_text() {
@@ -12881,11 +13549,18 @@
return value;
},
get$pathSegments() {
- var pathToSplit, result, _this = this,
+ var pathToSplit, t1, result, _this = this,
value = _this.___Uri_pathSegments_FI;
if (value === $) {
pathToSplit = _this.path;
- if (pathToSplit.length !== 0 && B.JSString_methods._codeUnitAt$1(pathToSplit, 0) === 47)
+ t1 = pathToSplit.length;
+ if (t1 !== 0) {
+ if (0 >= t1)
+ return A.ioore(pathToSplit, 0);
+ t1 = pathToSplit.charCodeAt(0) === 47;
+ } else
+ t1 = false;
+ if (t1)
pathToSplit = B.JSString_methods.substring$1(pathToSplit, 1);
result = pathToSplit.length === 0 ? B.List_empty : A.List_List$unmodifiable(new A.MappedListIterable(A._setArrayType(pathToSplit.split("/"), type$.JSArray_String), type$.dynamic_Function_String._as(A.core_Uri_decodeComponent$closure()), type$.MappedListIterable_String_dynamic), type$.String);
_this.___Uri_pathSegments_FI !== $ && A.throwLateFieldADI("pathSegments");
@@ -12947,12 +13622,13 @@
return A._caseInsensitiveCompareStart(scheme, thisScheme, 0) >= 0;
},
_mergePaths$2(base, reference) {
- var backCount, refStart, baseEnd, newEnd, delta, t1;
+ var backCount, refStart, baseEnd, t1, newEnd, delta, t2, t3;
for (backCount = 0, refStart = 0; B.JSString_methods.startsWith$2(reference, "../", refStart);) {
refStart += 3;
++backCount;
}
baseEnd = B.JSString_methods.lastIndexOf$1(base, "/");
+ t1 = base.length;
while (true) {
if (!(baseEnd > 0 && backCount > 0))
break;
@@ -12960,15 +13636,24 @@
if (newEnd < 0)
break;
delta = baseEnd - newEnd;
- t1 = delta !== 2;
- if (!t1 || delta === 3)
- if (B.JSString_methods.codeUnitAt$1(base, newEnd + 1) === 46)
- t1 = !t1 || B.JSString_methods.codeUnitAt$1(base, newEnd + 2) === 46;
+ t2 = delta !== 2;
+ if (!t2 || delta === 3) {
+ t3 = newEnd + 1;
+ if (!(t3 < t1))
+ return A.ioore(base, t3);
+ if (base.charCodeAt(t3) === 46)
+ if (t2) {
+ t2 = newEnd + 2;
+ if (!(t2 < t1))
+ return A.ioore(base, t2);
+ t2 = base.charCodeAt(t2) === 46;
+ } else
+ t2 = true;
else
- t1 = false;
- else
- t1 = false;
- if (t1)
+ t2 = false;
+ } else
+ t2 = false;
+ if (t2)
break;
--backCount;
baseEnd = newEnd;
@@ -13061,7 +13746,7 @@
if ((t1 == null ? "" : t1) !== "")
throw A.wrapException(A.UnsupportedError$(string$.Cannotff));
t1 = $.$get$_Uri__isWindowsCached();
- if (A.boolConversionCheck(t1))
+ if (t1)
t1 = A._Uri__toWindowsFilePath(_this);
else {
if (_this._host != null && _this.get$host(_this) !== "")
@@ -13139,9 +13824,9 @@
};
A._Uri__makePath_closure.prototype = {
call$1(s) {
- return A._Uri__uriEncode(B.List_qg40, A._asString(s), B.C_Utf8Codec, false);
+ return A._Uri__uriEncode(B.List_XRg0, A._asString(s), B.C_Utf8Codec, false);
},
- $signature: 23
+ $signature: 17
};
A.UriData.prototype = {
get$uri() {
@@ -13156,11 +13841,11 @@
queryIndex = B.JSString_methods.indexOf$2(t2, "?", t1);
end = t2.length;
if (queryIndex >= 0) {
- query = A._Uri__normalizeOrSubstring(t2, queryIndex + 1, end, B.List_CVk, false);
+ query = A._Uri__normalizeOrSubstring(t2, queryIndex + 1, end, B.List_oFp, false, false);
end = queryIndex;
} else
query = _null;
- t1 = _this._uriCache = new A._DataUri("data", "", _null, _null, A._Uri__normalizeOrSubstring(t2, t1, end, B.List_qg4, false), query, _null);
+ t1 = _this._uriCache = new A._DataUri("data", "", _null, _null, A._Uri__normalizeOrSubstring(t2, t1, end, B.List_XRg, false, false), query, _null);
}
return t1;
},
@@ -13182,31 +13867,38 @@
B.NativeUint8List_methods.fillRange$3(t1, 0, 96, defaultTransition);
return t1;
},
- $signature: 28
+ $signature: 25
};
A._createTables_setChars.prototype = {
call$3(target, chars, transition) {
var t1, i, t2;
for (t1 = chars.length, i = 0; i < t1; ++i) {
- t2 = B.JSString_methods._codeUnitAt$1(chars, i) ^ 96;
+ t2 = chars.charCodeAt(i) ^ 96;
if (!(t2 < 96))
return A.ioore(target, t2);
target[t2] = transition;
}
},
- $signature: 22
+ $signature: 18
};
A._createTables_setRange.prototype = {
call$3(target, range, transition) {
- var i, n, t1;
- for (i = B.JSString_methods._codeUnitAt$1(range, 0), n = B.JSString_methods._codeUnitAt$1(range, 1); i <= n; ++i) {
+ var i, n,
+ t1 = range.length;
+ if (0 >= t1)
+ return A.ioore(range, 0);
+ i = range.charCodeAt(0);
+ if (1 >= t1)
+ return A.ioore(range, 1);
+ n = range.charCodeAt(1);
+ for (; i <= n; ++i) {
t1 = (i ^ 96) >>> 0;
if (!(t1 < 96))
return A.ioore(target, t1);
target[t1] = transition;
}
},
- $signature: 22
+ $signature: 18
};
A._SimpleUri.prototype = {
get$hasAuthority() {
@@ -13278,7 +13970,7 @@
return t1 < t2.length ? B.JSString_methods.substring$1(t2, t1 + 1) : "";
},
get$pathSegments() {
- var parts, i,
+ var parts, t2, i,
start = this._pathStart,
end = this._queryStart,
t1 = this._uri;
@@ -13287,11 +13979,14 @@
if (start === end)
return B.List_empty;
parts = A._setArrayType([], type$.JSArray_String);
- for (i = start; i < end; ++i)
- if (B.JSString_methods.codeUnitAt$1(t1, i) === 47) {
+ for (t2 = t1.length, i = start; i < end; ++i) {
+ if (!(i >= 0 && i < t2))
+ return A.ioore(t1, i);
+ if (t1.charCodeAt(i) === 47) {
B.JSArray_methods.add$1(parts, B.JSString_methods.substring$2(t1, start, i));
start = i + 1;
}
+ }
B.JSArray_methods.add$1(parts, B.JSString_methods.substring$2(t1, start, end));
return A.List_List$unmodifiable(parts, type$.String);
},
@@ -13391,9 +14086,11 @@
++backCount;
refStart = refStart0;
}
- for (insert = ""; baseEnd > baseStart0;) {
+ for (t3 = baseUri.length, insert = ""; baseEnd > baseStart0;) {
--baseEnd;
- if (B.JSString_methods.codeUnitAt$1(baseUri, baseEnd) === 47) {
+ if (!(baseEnd >= 0 && baseEnd < t3))
+ return A.ioore(baseUri, baseEnd);
+ if (baseUri.charCodeAt(baseEnd) === 47) {
if (backCount === 0) {
insert = "/";
break;
@@ -13427,7 +14124,7 @@
throw A.wrapException(A.UnsupportedError$(string$.Cannotff));
}
t3 = $.$get$_Uri__isWindowsCached();
- if (A.boolConversionCheck(t3))
+ if (t3)
t1 = A._Uri__toWindowsFilePath(_this);
else {
if (_this._hostStart < _this._portStart)
@@ -13474,12 +14171,16 @@
};
A.AnchorElement.prototype = {
toString$0(receiver) {
- return String(receiver);
+ var t1 = String(receiver);
+ t1.toString;
+ return t1;
}
};
A.AreaElement.prototype = {
toString$0(receiver) {
- return String(receiver);
+ var t1 = String(receiver);
+ t1.toString;
+ return t1;
}
};
A.Blob.prototype = {};
@@ -13496,7 +14197,9 @@
A.CssRule.prototype = {$isCssRule: 1};
A.CssStyleDeclaration.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
}
};
A.CssStyleDeclarationBase.prototype = {};
@@ -13517,26 +14220,37 @@
return receiver.length;
},
$index(receiver, index) {
- return receiver[A._asInt(index)];
+ var t1 = receiver[A._asInt(index)];
+ t1.toString;
+ return t1;
}
};
A.DomException.prototype = {
toString$0(receiver) {
- return String(receiver);
+ var t1 = String(receiver);
+ t1.toString;
+ return t1;
}
};
A.DomRectList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.Rectangle_num._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -13612,16 +14326,23 @@
};
A.DomStringList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
A._asString(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -13637,28 +14358,39 @@
};
A.DomTokenList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
}
};
A.Element.prototype = {
toString$0(receiver) {
- return receiver.localName;
+ var t1 = receiver.localName;
+ t1.toString;
+ return t1;
}
};
A.EventTarget.prototype = {};
A.File.prototype = {$isFile: 1};
A.FileList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.File._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -13685,21 +14417,30 @@
A.Gamepad.prototype = {$isGamepad: 1};
A.History.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
}
};
A.HtmlCollection.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.Node._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -13715,7 +14456,9 @@
};
A.Location.prototype = {
toString$0(receiver) {
- return String(receiver);
+ var t1 = String(receiver);
+ t1.toString;
+ return t1;
}
};
A.MediaList.prototype = {
@@ -13724,18 +14467,25 @@
}
};
A.MidiInputMap.prototype = {
+ containsKey$1(receiver, key) {
+ return A.convertNativeToDart_Dictionary(receiver.get(key)) != null;
+ },
$index(receiver, key) {
return A.convertNativeToDart_Dictionary(receiver.get(A._asString(key)));
},
forEach$1(receiver, f) {
- var entries, entry;
+ var entries, entry, t1;
type$.void_Function_String_dynamic._as(f);
entries = receiver.entries();
for (; true;) {
entry = entries.next();
- if (entry.done)
+ t1 = entry.done;
+ t1.toString;
+ if (t1)
return;
- f.call$2(entry.value[0], A.convertNativeToDart_Dictionary(entry.value[1]));
+ t1 = entry.value[0];
+ t1.toString;
+ f.call$2(t1, A.convertNativeToDart_Dictionary(entry.value[1]));
}
},
get$keys(receiver) {
@@ -13744,10 +14494,14 @@
return keys;
},
get$length(receiver) {
- return receiver.size;
+ var t1 = receiver.size;
+ t1.toString;
+ return t1;
},
get$isEmpty(receiver) {
- return receiver.size === 0;
+ var t1 = receiver.size;
+ t1.toString;
+ return t1 === 0;
},
$indexSet(receiver, key, value) {
throw A.wrapException(A.UnsupportedError$("Not supported"));
@@ -13758,21 +14512,28 @@
call$2(k, v) {
return B.JSArray_methods.add$1(this.keys, k);
},
- $signature: 5
+ $signature: 3
};
A.MidiOutputMap.prototype = {
+ containsKey$1(receiver, key) {
+ return A.convertNativeToDart_Dictionary(receiver.get(key)) != null;
+ },
$index(receiver, key) {
return A.convertNativeToDart_Dictionary(receiver.get(A._asString(key)));
},
forEach$1(receiver, f) {
- var entries, entry;
+ var entries, entry, t1;
type$.void_Function_String_dynamic._as(f);
entries = receiver.entries();
for (; true;) {
entry = entries.next();
- if (entry.done)
+ t1 = entry.done;
+ t1.toString;
+ if (t1)
return;
- f.call$2(entry.value[0], A.convertNativeToDart_Dictionary(entry.value[1]));
+ t1 = entry.value[0];
+ t1.toString;
+ f.call$2(t1, A.convertNativeToDart_Dictionary(entry.value[1]));
}
},
get$keys(receiver) {
@@ -13781,10 +14542,14 @@
return keys;
},
get$length(receiver) {
- return receiver.size;
+ var t1 = receiver.size;
+ t1.toString;
+ return t1;
},
get$isEmpty(receiver) {
- return receiver.size === 0;
+ var t1 = receiver.size;
+ t1.toString;
+ return t1 === 0;
},
$indexSet(receiver, key, value) {
throw A.wrapException(A.UnsupportedError$("Not supported"));
@@ -13795,21 +14560,28 @@
call$2(k, v) {
return B.JSArray_methods.add$1(this.keys, k);
},
- $signature: 5
+ $signature: 3
};
A.MimeType.prototype = {$isMimeType: 1};
A.MimeTypeArray.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.MimeType._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -13832,16 +14604,23 @@
};
A.NodeList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.Node._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -13863,16 +14642,23 @@
};
A.PluginArray.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.Plugin._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -13887,18 +14673,25 @@
$isList: 1
};
A.RtcStatsReport.prototype = {
+ containsKey$1(receiver, key) {
+ return A.convertNativeToDart_Dictionary(receiver.get(key)) != null;
+ },
$index(receiver, key) {
return A.convertNativeToDart_Dictionary(receiver.get(A._asString(key)));
},
forEach$1(receiver, f) {
- var entries, entry;
+ var entries, entry, t1;
type$.void_Function_String_dynamic._as(f);
entries = receiver.entries();
for (; true;) {
entry = entries.next();
- if (entry.done)
+ t1 = entry.done;
+ t1.toString;
+ if (t1)
return;
- f.call$2(entry.value[0], A.convertNativeToDart_Dictionary(entry.value[1]));
+ t1 = entry.value[0];
+ t1.toString;
+ f.call$2(t1, A.convertNativeToDart_Dictionary(entry.value[1]));
}
},
get$keys(receiver) {
@@ -13907,10 +14700,14 @@
return keys;
},
get$length(receiver) {
- return receiver.size;
+ var t1 = receiver.size;
+ t1.toString;
+ return t1;
},
get$isEmpty(receiver) {
- return receiver.size === 0;
+ var t1 = receiver.size;
+ t1.toString;
+ return t1 === 0;
},
$indexSet(receiver, key, value) {
throw A.wrapException(A.UnsupportedError$("Not supported"));
@@ -13921,7 +14718,7 @@
call$2(k, v) {
return B.JSArray_methods.add$1(this.keys, k);
},
- $signature: 5
+ $signature: 3
};
A.SelectElement.prototype = {
get$length(receiver) {
@@ -13931,16 +14728,23 @@
A.SourceBuffer.prototype = {$isSourceBuffer: 1};
A.SourceBufferList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.SourceBuffer._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -13957,16 +14761,23 @@
A.SpeechGrammar.prototype = {$isSpeechGrammar: 1};
A.SpeechGrammarList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.SpeechGrammar._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -13987,6 +14798,9 @@
$isSpeechRecognitionResult: 1
};
A.Storage.prototype = {
+ containsKey$1(receiver, key) {
+ return receiver.getItem(key) != null;
+ },
$index(receiver, key) {
return receiver.getItem(A._asString(key));
},
@@ -14011,7 +14825,9 @@
return keys;
},
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
get$isEmpty(receiver) {
return receiver.key(0) == null;
@@ -14022,23 +14838,30 @@
call$2(k, v) {
return B.JSArray_methods.add$1(this.keys, k);
},
- $signature: 30
+ $signature: 27
};
A.StyleSheet.prototype = {$isStyleSheet: 1};
A.TextTrack.prototype = {$isTextTrack: 1};
A.TextTrackCue.prototype = {$isTextTrackCue: 1};
A.TextTrackCueList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.TextTrackCue._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14054,16 +14877,23 @@
};
A.TextTrackList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.TextTrack._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14079,22 +14909,31 @@
};
A.TimeRanges.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
}
};
A.Touch.prototype = {$isTouch: 1};
A.TouchList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.Touch._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14115,7 +14954,9 @@
};
A.Url.prototype = {
toString$0(receiver) {
- return String(receiver);
+ var t1 = String(receiver);
+ t1.toString;
+ return t1;
}
};
A.VideoTrackList.prototype = {
@@ -14125,16 +14966,23 @@
};
A._CssRuleList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.CssRule._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14225,16 +15073,21 @@
};
A._GamepadList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
return receiver[index];
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.nullable_Gamepad._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14250,16 +15103,23 @@
};
A._NamedNodeMap.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.Node._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14275,16 +15135,23 @@
};
A._SpeechRecognitionResultList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.SpeechRecognitionResult._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14300,16 +15167,23 @@
};
A._StyleSheetList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1, t2;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver[index];
+ t1 = receiver.length;
+ t2 = index >>> 0 !== index || index >= t1;
+ t2.toString;
+ if (t2)
+ throw A.wrapException(A.IndexError$withLength(index, t1, receiver, null));
+ t1 = receiver[index];
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.StyleSheet._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14390,13 +15264,15 @@
A.__SpeechRecognitionResultList_JavaScriptObject_ListMixin_ImmutableListMixin.prototype = {};
A.__StyleSheetList_JavaScriptObject_ListMixin.prototype = {};
A.__StyleSheetList_JavaScriptObject_ListMixin_ImmutableListMixin.prototype = {};
- A._convertDataTree__convert.prototype = {
+ A.jsify__convert.prototype = {
call$1(o) {
- var convertedMap, t2, key, convertedList,
- t1 = this._convertedObjects;
+ var t1, convertedMap, t2, key, convertedList;
+ if (A._noJsifyRequired(o))
+ return o;
+ t1 = this._convertedObjects;
if (t1.containsKey$1(0, o))
return t1.$index(0, o);
- if (type$.Map_dynamic_dynamic._is(o)) {
+ if (type$.Map_of_nullable_Object_and_nullable_Object._is(o)) {
convertedMap = {};
t1.$indexSet(0, o, convertedMap);
for (t1 = J.getInterceptor$x(o), t2 = J.get$iterator$ax(t1.get$keys(o)); t2.moveNext$0();) {
@@ -14404,7 +15280,7 @@
convertedMap[key] = this.call$1(t1.$index(o, key));
}
return convertedMap;
- } else if (type$.Iterable_dynamic._is(o)) {
+ } else if (type$.Iterable_nullable_Object._is(o)) {
convertedList = [];
t1.$indexSet(0, o, convertedList);
B.JSArray_methods.addAll$1(convertedList, J.map$1$1$ax(o, this, type$.dynamic));
@@ -14412,13 +15288,13 @@
} else
return o;
},
- $signature: 20
+ $signature: 19
};
A.promiseToFuture_closure.prototype = {
call$1(r) {
return this.completer.complete$1(0, this.T._eval$1("0/?")._as(r));
},
- $signature: 3
+ $signature: 5
};
A.promiseToFuture_closure0.prototype = {
call$1(e) {
@@ -14426,22 +15302,32 @@
return this.completer.completeError$1(new A.NullRejectionException(e === undefined));
return this.completer.completeError$1(e);
},
- $signature: 3
+ $signature: 5
};
A.dartify_convert.prototype = {
call$1(o) {
- var proto, t2, dartObject, originalKeys, dartKeys, i, jsKey, dartKey, l, $length,
- t1 = this._convertedObjects;
+ var t1, millisSinceEpoch, proto, t2, dartObject, originalKeys, dartKeys, i, jsKey, dartKey, l, $length;
+ if (A._noDartifyRequired(o))
+ return o;
+ t1 = this._convertedObjects;
+ o.toString;
if (t1.containsKey$1(0, o))
return t1.$index(0, o);
- if (o == null || A._isBool(o) || typeof o == "number" || typeof o == "string")
- return o;
- if (o instanceof Date)
- return A.DateTime$fromMillisecondsSinceEpoch(o.getTime(), true);
+ if (o instanceof Date) {
+ millisSinceEpoch = o.getTime();
+ if (Math.abs(millisSinceEpoch) <= 864e13)
+ t1 = false;
+ else
+ t1 = true;
+ if (t1)
+ A.throwExpression(A.ArgumentError$("DateTime is outside valid range: " + millisSinceEpoch, null));
+ A.checkNotNullable(true, "isUtc", type$.bool);
+ return new A.DateTime(millisSinceEpoch, true);
+ }
if (o instanceof RegExp)
throw A.wrapException(A.ArgumentError$("structured clone of RegExp", null));
if (typeof Promise != "undefined" && o instanceof Promise)
- return A.promiseToFuture(o, type$.dynamic);
+ return A.promiseToFuture(o, type$.nullable_Object);
proto = Object.getPrototypeOf(o);
if (proto === Object.prototype || proto === null) {
t2 = type$.nullable_Object;
@@ -14472,7 +15358,7 @@
}
return o;
},
- $signature: 20
+ $signature: 19
};
A.NullRejectionException.prototype = {
toString$0(_) {
@@ -14483,16 +15369,24 @@
A.Length.prototype = {$isLength: 1};
A.LengthList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver.getItem(index);
+ t1 = receiver.length;
+ t1.toString;
+ t1 = index >>> 0 !== index || index >= t1;
+ t1.toString;
+ if (t1)
+ throw A.wrapException(A.IndexError$withLength(index, this.get$length(receiver), receiver, null));
+ t1 = receiver.getItem(index);
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.Length._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14506,16 +15400,24 @@
A.Number.prototype = {$isNumber: 1};
A.NumberList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver.getItem(index);
+ t1 = receiver.length;
+ t1.toString;
+ t1 = index >>> 0 !== index || index >= t1;
+ t1.toString;
+ if (t1)
+ throw A.wrapException(A.IndexError$withLength(index, this.get$length(receiver), receiver, null));
+ t1 = receiver.getItem(index);
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.Number._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14533,16 +15435,24 @@
};
A.StringList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver.getItem(index);
+ t1 = receiver.length;
+ t1.toString;
+ t1 = index >>> 0 !== index || index >= t1;
+ t1.toString;
+ if (t1)
+ throw A.wrapException(A.IndexError$withLength(index, this.get$length(receiver), receiver, null));
+ t1 = receiver.getItem(index);
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
A._asString(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14556,16 +15466,24 @@
A.Transform.prototype = {$isTransform: 1};
A.TransformList.prototype = {
get$length(receiver) {
- return receiver.length;
+ var t1 = receiver.length;
+ t1.toString;
+ return t1;
},
$index(receiver, index) {
+ var t1;
A._asInt(index);
- if (index >>> 0 !== index || index >= receiver.length)
- throw A.wrapException(A.IndexError$(index, receiver, null, null, null));
- return receiver.getItem(index);
+ t1 = receiver.length;
+ t1.toString;
+ t1 = index >>> 0 !== index || index >= t1;
+ t1.toString;
+ if (t1)
+ throw A.wrapException(A.IndexError$withLength(index, this.get$length(receiver), receiver, null));
+ t1 = receiver.getItem(index);
+ t1.toString;
+ return t1;
},
$indexSet(receiver, index, value) {
- A._asInt(index);
type$.Transform._as(value);
throw A.wrapException(A.UnsupportedError$("Cannot assign element of immutable List."));
},
@@ -14590,18 +15508,25 @@
}
};
A.AudioParamMap.prototype = {
+ containsKey$1(receiver, key) {
+ return A.convertNativeToDart_Dictionary(receiver.get(key)) != null;
+ },
$index(receiver, key) {
return A.convertNativeToDart_Dictionary(receiver.get(A._asString(key)));
},
forEach$1(receiver, f) {
- var entries, entry;
+ var entries, entry, t1;
type$.void_Function_String_dynamic._as(f);
entries = receiver.entries();
for (; true;) {
entry = entries.next();
- if (entry.done)
+ t1 = entry.done;
+ t1.toString;
+ if (t1)
return;
- f.call$2(entry.value[0], A.convertNativeToDart_Dictionary(entry.value[1]));
+ t1 = entry.value[0];
+ t1.toString;
+ f.call$2(t1, A.convertNativeToDart_Dictionary(entry.value[1]));
}
},
get$keys(receiver) {
@@ -14610,10 +15535,14 @@
return keys;
},
get$length(receiver) {
- return receiver.size;
+ var t1 = receiver.size;
+ t1.toString;
+ return t1;
},
get$isEmpty(receiver) {
- return receiver.size === 0;
+ var t1 = receiver.size;
+ t1.toString;
+ return t1 === 0;
},
$indexSet(receiver, key, value) {
throw A.wrapException(A.UnsupportedError$("Not supported"));
@@ -14624,7 +15553,7 @@
call$2(k, v) {
return B.JSArray_methods.add$1(this.keys, k);
},
- $signature: 5
+ $signature: 3
};
A.AudioTrackList.prototype = {
get$length(receiver) {
@@ -14666,26 +15595,26 @@
$signature: 2
};
A.Context.prototype = {
- absolute$7(_, part1, part2, part3, part4, part5, part6, part7) {
+ absolute$15(_, part1, part2, part3, part4, part5, part6, part7, part8, part9, part10, part11, part12, part13, part14, part15) {
var t1;
- A._validateArgList("absolute", A._setArrayType([part1, part2, part3, part4, part5, part6, part7], type$.JSArray_nullable_String));
+ A._validateArgList("absolute", A._setArrayType([part1, part2, part3, part4, part5, part6, part7, part8, part9, part10, part11, part12, part13, part14, part15], type$.JSArray_nullable_String));
t1 = this.style;
t1 = t1.rootLength$1(part1) > 0 && !t1.isRootRelative$1(part1);
if (t1)
return part1;
t1 = this._context$_current;
- return this.join$8(0, t1 == null ? A.current() : t1, part1, part2, part3, part4, part5, part6, part7);
+ return this.join$16(0, t1 == null ? A.current() : t1, part1, part2, part3, part4, part5, part6, part7, part8, part9, part10, part11, part12, part13, part14, part15);
},
absolute$1($receiver, part1) {
- return this.absolute$7($receiver, part1, null, null, null, null, null, null);
+ return this.absolute$15($receiver, part1, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
},
- join$8(_, part1, part2, part3, part4, part5, part6, part7, part8) {
- var parts = A._setArrayType([part1, part2, part3, part4, part5, part6, part7, part8], type$.JSArray_nullable_String);
+ join$16(_, part1, part2, part3, part4, part5, part6, part7, part8, part9, part10, part11, part12, part13, part14, part15, part16) {
+ var parts = A._setArrayType([part1, part2, part3, part4, part5, part6, part7, part8, part9, part10, part11, part12, part13, part14, part15, part16], type$.JSArray_nullable_String);
A._validateArgList("join", parts);
return this.joinAll$1(new A.WhereTypeIterable(parts, type$.WhereTypeIterable_String));
},
join$2($receiver, part1, part2) {
- return this.join$8($receiver, part1, part2, null, null, null, null, null, null);
+ return this.join$16($receiver, part1, part2, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
},
joinAll$1(parts) {
var t1, t2, t3, needsSeparator, isAbsoluteAndNotRootRelative, t4, t5, parsed, path, t6;
@@ -14740,14 +15669,17 @@
return parsed.toString$0(0);
},
_needsNormalization$1(path) {
- var i, start, previous, t2, t3, previousPrevious, codeUnit, t4,
+ var t2, i, start, previous, t3, previousPrevious, codeUnit, t4,
t1 = this.style,
root = t1.rootLength$1(path);
if (root !== 0) {
if (t1 === $.$get$Style_windows())
- for (i = 0; i < root; ++i)
- if (B.JSString_methods._codeUnitAt$1(path, i) === 47)
+ for (t2 = path.length, i = 0; i < root; ++i) {
+ if (!(i < t2))
+ return A.ioore(path, i);
+ if (path.charCodeAt(i) === 47)
return true;
+ }
start = root;
previous = 47;
} else {
@@ -14755,7 +15687,9 @@
previous = null;
}
for (t2 = new A.CodeUnits(path)._string, t3 = t2.length, i = start, previousPrevious = null; i < t3; ++i, previousPrevious = previous, previous = codeUnit) {
- codeUnit = B.JSString_methods.codeUnitAt$1(t2, i);
+ if (!(i >= 0))
+ return A.ioore(t2, i);
+ codeUnit = t2.charCodeAt(i);
if (t1.isSeparator$1(codeUnit)) {
if (t1 === $.$get$Style_windows() && codeUnit === 47)
return true;
@@ -14915,7 +15849,7 @@
A._asStringQ(arg);
return arg == null ? "null" : '"' + arg + '"';
},
- $signature: 33
+ $signature: 31
};
A.InternalStyle.prototype = {
getRoot$1(path) {
@@ -14932,12 +15866,15 @@
return t1;
},
relativePathToUri$1(path) {
- var segments, _null = null,
+ var segments, t2, _null = null,
t1 = path.length;
if (t1 === 0)
return A._Uri__Uri(_null, _null, _null, _null);
segments = A.Context_Context(this).split$1(0, path);
- if (this.isSeparator$1(B.JSString_methods.codeUnitAt$1(path, t1 - 1)))
+ t2 = t1 - 1;
+ if (!(t2 >= 0))
+ return A.ioore(path, t2);
+ if (this.isSeparator$1(path.charCodeAt(t2)))
B.JSArray_methods.add$1(segments, "");
return A._Uri__Uri(_null, _null, segments, _null);
},
@@ -15049,11 +15986,27 @@
return codeUnit === 47;
},
needsSeparator$1(path) {
- var t1 = path.length;
- return t1 !== 0 && B.JSString_methods.codeUnitAt$1(path, t1 - 1) !== 47;
+ var t2,
+ t1 = path.length;
+ if (t1 !== 0) {
+ t2 = t1 - 1;
+ if (!(t2 >= 0))
+ return A.ioore(path, t2);
+ t2 = path.charCodeAt(t2) !== 47;
+ t1 = t2;
+ } else
+ t1 = false;
+ return t1;
},
rootLength$2$withDrive(path, withDrive) {
- if (path.length !== 0 && B.JSString_methods._codeUnitAt$1(path, 0) === 47)
+ var t1 = path.length;
+ if (t1 !== 0) {
+ if (0 >= t1)
+ return A.ioore(path, 0);
+ t1 = path.charCodeAt(0) === 47;
+ } else
+ t1 = false;
+ if (t1)
return 1;
return 0;
},
@@ -15095,10 +16048,14 @@
return codeUnit === 47;
},
needsSeparator$1(path) {
- var t1 = path.length;
+ var t2,
+ t1 = path.length;
if (t1 === 0)
return false;
- if (B.JSString_methods.codeUnitAt$1(path, t1 - 1) !== 47)
+ t2 = t1 - 1;
+ if (!(t2 >= 0))
+ return A.ioore(path, t2);
+ if (path.charCodeAt(t2) !== 47)
return true;
return B.JSString_methods.endsWith$1(path, "://") && this.rootLength$1(path) === t1;
},
@@ -15107,10 +16064,12 @@
t1 = path.length;
if (t1 === 0)
return 0;
- if (B.JSString_methods._codeUnitAt$1(path, 0) === 47)
+ if (0 >= t1)
+ return A.ioore(path, 0);
+ if (path.charCodeAt(0) === 47)
return 1;
for (i = 0; i < t1; ++i) {
- codeUnit = B.JSString_methods._codeUnitAt$1(path, i);
+ codeUnit = path.charCodeAt(i);
if (codeUnit === 47)
return 0;
if (codeUnit === 58) {
@@ -15135,7 +16094,14 @@
return this.rootLength$2$withDrive(path, false);
},
isRootRelative$1(path) {
- return path.length !== 0 && B.JSString_methods._codeUnitAt$1(path, 0) === 47;
+ var t1 = path.length;
+ if (t1 !== 0) {
+ if (0 >= t1)
+ return A.ioore(path, 0);
+ t1 = path.charCodeAt(0) === 47;
+ } else
+ t1 = false;
+ return t1;
},
pathFromUri$1(uri) {
return uri.toString$0(0);
@@ -15161,22 +16127,33 @@
return codeUnit === 47 || codeUnit === 92;
},
needsSeparator$1(path) {
- var t1 = path.length;
+ var t2,
+ t1 = path.length;
if (t1 === 0)
return false;
- t1 = B.JSString_methods.codeUnitAt$1(path, t1 - 1);
- return !(t1 === 47 || t1 === 92);
+ t2 = t1 - 1;
+ if (!(t2 >= 0))
+ return A.ioore(path, t2);
+ t2 = path.charCodeAt(t2);
+ return !(t2 === 47 || t2 === 92);
},
rootLength$2$withDrive(path, withDrive) {
var t2, index,
t1 = path.length;
if (t1 === 0)
return 0;
- t2 = B.JSString_methods._codeUnitAt$1(path, 0);
- if (t2 === 47)
+ if (0 >= t1)
+ return A.ioore(path, 0);
+ if (path.charCodeAt(0) === 47)
return 1;
- if (t2 === 92) {
- if (t1 < 2 || B.JSString_methods._codeUnitAt$1(path, 1) !== 92)
+ if (path.charCodeAt(0) === 92) {
+ if (t1 >= 2) {
+ if (1 >= t1)
+ return A.ioore(path, 1);
+ t2 = path.charCodeAt(1) !== 92;
+ } else
+ t2 = true;
+ if (t2)
return 1;
index = B.JSString_methods.indexOf$2(path, "\\", 2);
if (index > 0) {
@@ -15188,11 +16165,11 @@
}
if (t1 < 3)
return 0;
- if (!A.isAlphabetic(t2))
+ if (!A.isAlphabetic(path.charCodeAt(0)))
return 0;
- if (B.JSString_methods._codeUnitAt$1(path, 1) !== 58)
+ if (path.charCodeAt(1) !== 58)
return 0;
- t1 = B.JSString_methods._codeUnitAt$1(path, 2);
+ t1 = path.charCodeAt(2);
if (!(t1 === 47 || t1 === 92))
return 0;
return 3;
@@ -15252,15 +16229,19 @@
return upperCase1 >= 97 && upperCase1 <= 122;
},
pathsEqual$2(path1, path2) {
- var t1, i;
+ var t1, t2, i;
if (path1 === path2)
return true;
t1 = path1.length;
- if (t1 !== path2.length)
+ t2 = path2.length;
+ if (t1 !== t2)
return false;
- for (i = 0; i < t1; ++i)
- if (!this.codeUnitsEqual$2(B.JSString_methods._codeUnitAt$1(path1, i), B.JSString_methods._codeUnitAt$1(path2, i)))
+ for (i = 0; i < t1; ++i) {
+ if (!(i < t2))
+ return A.ioore(path2, i);
+ if (!this.codeUnitsEqual$2(path1.charCodeAt(i), path2.charCodeAt(i)))
return false;
+ }
return true;
},
get$name() {
@@ -15285,7 +16266,7 @@
toString$0(_) {
var t1 = this.traces,
t2 = A._arrayInstanceType(t1);
- return new A.MappedListIterable(t1, t2._eval$1("String(1)")._as(new A.Chain_toString_closure(new A.MappedListIterable(t1, t2._eval$1("int(1)")._as(new A.Chain_toString_closure0()), t2._eval$1("MappedListIterable<1,int>")).fold$1$2(0, 0, B.CONSTANT, type$.int))), t2._eval$1("MappedListIterable<1,String>")).join$1(0, string$.______);
+ return new A.MappedListIterable(t1, t2._eval$1("String(1)")._as(new A.Chain_toString_closure(new A.MappedListIterable(t1, t2._eval$1("int(1)")._as(new A.Chain_toString_closure0()), t2._eval$1("MappedListIterable<1,int>")).fold$1$2(0, 0, B.CONSTANT, type$.int))), t2._eval$1("MappedListIterable<1,String>")).join$1(0, string$.x3d_____);
},
$isStackTrace: 1
};
@@ -15295,23 +16276,11 @@
},
$signature: 1
};
- A.Chain_Chain$parse_closure0.prototype = {
- call$1(trace) {
- return A.Trace$parseVM(A._asString(trace));
- },
- $signature: 18
- };
- A.Chain_Chain$parse_closure1.prototype = {
- call$1(trace) {
- return A.Trace$parseFriendly(A._asString(trace));
- },
- $signature: 18
- };
A.Chain_toTrace_closure.prototype = {
call$1(trace) {
return type$.Trace._as(trace).get$frames();
},
- $signature: 35
+ $signature: 32
};
A.Chain_toString_closure0.prototype = {
call$1(trace) {
@@ -15319,14 +16288,14 @@
t2 = A._arrayInstanceType(t1);
return new A.MappedListIterable(t1, t2._eval$1("int(1)")._as(new A.Chain_toString__closure0()), t2._eval$1("MappedListIterable<1,int>")).fold$1$2(0, 0, B.CONSTANT, type$.int);
},
- $signature: 36
+ $signature: 33
};
A.Chain_toString__closure0.prototype = {
call$1(frame) {
type$.Frame._as(frame);
return frame.get$location(frame).length;
},
- $signature: 17
+ $signature: 20
};
A.Chain_toString_closure.prototype = {
call$1(trace) {
@@ -15334,14 +16303,14 @@
t2 = A._arrayInstanceType(t1);
return new A.MappedListIterable(t1, t2._eval$1("String(1)")._as(new A.Chain_toString__closure(this.longest)), t2._eval$1("MappedListIterable<1,String>")).join$0(0);
},
- $signature: 38
+ $signature: 35
};
A.Chain_toString__closure.prototype = {
call$1(frame) {
type$.Frame._as(frame);
return B.JSString_methods.padRight$1(frame.get$location(frame), this.longest) + " " + A.S(frame.get$member()) + "\n";
},
- $signature: 16
+ $signature: 21
};
A.Frame.prototype = {
get$isCore() {
@@ -15399,7 +16368,7 @@
return A.ioore(t1, 1);
t2 = t1[1];
t2.toString;
- t3 = type$.Pattern._as($.$get$_asyncBody());
+ t3 = $.$get$_asyncBody();
t2 = A.stringReplaceAllUnchecked(t2, t3, "<async>");
member = A.stringReplaceAllUnchecked(t2, "<anonymous closure>", "<fn>");
if (2 >= t1.length)
@@ -15488,7 +16457,7 @@
columnMatch = t1[3];
return new A.Frame(uri, line, columnMatch != null ? A.int_parse(columnMatch, _null) : _null, member);
},
- $signature: 41
+ $signature: 38
};
A.Frame_Frame$_parseFirefoxEval_closure.prototype = {
call$0() {
@@ -15595,7 +16564,7 @@
}
if (uri.get$scheme() === "") {
t2 = $.$get$context();
- uri = t2.toUri$1(t2.absolute$7(0, t2.style.pathFromUri$1(A._parseUri(uri)), _null, _null, _null, _null, _null, _null));
+ uri = t2.toUri$1(t2.absolute$15(0, t2.style.pathFromUri$1(A._parseUri(uri)), _null, _null, _null, _null, _null, _null, _null, _null, _null, _null, _null, _null, _null, _null));
}
if (2 >= t1.length)
return A.ioore(t1, 2);
@@ -15651,7 +16620,7 @@
call$0() {
return this.$this.get$_lazy_trace$_trace().get$terse();
},
- $signature: 15
+ $signature: 22
};
A.Trace.prototype = {
get$terse() {
@@ -15693,7 +16662,7 @@
call$0() {
return A.Trace_Trace$parse(this.trace.toString$0(0));
},
- $signature: 15
+ $signature: 22
};
A.Trace__parseVM_closure.prototype = {
call$1(line) {
@@ -15701,36 +16670,18 @@
},
$signature: 1
};
- A.Trace__parseVM_closure0.prototype = {
- call$1(line) {
- return A.Frame_Frame$parseVM(A._asString(line));
- },
- $signature: 4
- };
A.Trace$parseV8_closure.prototype = {
call$1(line) {
return !B.JSString_methods.startsWith$1(A._asString(line), $.$get$_v8TraceLine());
},
$signature: 1
};
- A.Trace$parseV8_closure0.prototype = {
- call$1(line) {
- return A.Frame_Frame$parseV8(A._asString(line));
- },
- $signature: 4
- };
A.Trace$parseJSCore_closure.prototype = {
call$1(line) {
return A._asString(line) !== "\tat ";
},
$signature: 1
};
- A.Trace$parseJSCore_closure0.prototype = {
- call$1(line) {
- return A.Frame_Frame$parseV8(A._asString(line));
- },
- $signature: 4
- };
A.Trace$parseFirefox_closure.prototype = {
call$1(line) {
A._asString(line);
@@ -15738,29 +16689,17 @@
},
$signature: 1
};
- A.Trace$parseFirefox_closure0.prototype = {
- call$1(line) {
- return A.Frame_Frame$parseFirefox(A._asString(line));
- },
- $signature: 4
- };
A.Trace$parseFriendly_closure.prototype = {
call$1(line) {
return !B.JSString_methods.startsWith$1(A._asString(line), "=====");
},
$signature: 1
};
- A.Trace$parseFriendly_closure0.prototype = {
- call$1(line) {
- return A.Frame_Frame$parseFriendly(A._asString(line));
- },
- $signature: 4
- };
A.Trace_terse_closure.prototype = {
call$1(_) {
return false;
},
- $signature: 13
+ $signature: 23
};
A.Trace_foldFrames_closure.prototype = {
call$1(frame) {
@@ -15777,7 +16716,7 @@
return false;
return frame.get$line(frame) == null;
},
- $signature: 13
+ $signature: 23
};
A.Trace_foldFrames_closure0.prototype = {
call$1(frame) {
@@ -15786,17 +16725,17 @@
if (frame instanceof A.UnparsedFrame || !A.boolConversionCheck(this._box_0.predicate.call$1(frame)))
return frame;
t1 = frame.get$library();
- t2 = type$.Pattern._as($.$get$_terseRegExp());
+ t2 = $.$get$_terseRegExp();
return new A.Frame(A.Uri_parse(A.stringReplaceAllUnchecked(t1, t2, "")), null, null, frame.get$member());
},
- $signature: 45
+ $signature: 62
};
A.Trace_toString_closure0.prototype = {
call$1(frame) {
type$.Frame._as(frame);
return frame.get$location(frame).length;
},
- $signature: 17
+ $signature: 20
};
A.Trace_toString_closure.prototype = {
call$1(frame) {
@@ -15805,7 +16744,7 @@
return frame.toString$0(0) + "\n";
return B.JSString_methods.padRight$1(frame.get$location(frame), this.longest) + " " + A.S(frame.get$member()) + "\n";
},
- $signature: 16
+ $signature: 21
};
A.UnparsedFrame.prototype = {
toString$0(_) {
@@ -15983,7 +16922,7 @@
t1._addStreamCompleter = null;
t1.set$_addStreamSubscription(null);
},
- $signature: 8
+ $signature: 10
};
A._MultiChannel.prototype = {
_MultiChannel$1(inner, $T) {
@@ -16020,13 +16959,13 @@
if (_this._pendingIds.remove$1(0, id)) {
t2 = _this._controllers.$index(0, id);
t2.toString;
- controller.__late_helper$_value = t2;
+ controller._value = t2;
} else {
t2 = _this._controllers;
if (t2.containsKey$1(0, id) || _this._closedIds.contains$1(0, id))
throw A.wrapException(A.ArgumentError$("A virtual channel with id " + id + " already exists.", null));
else {
- controller.__late_helper$_value = A.StreamChannelController$(true, _this.$ti._precomputed1);
+ controller._value = A.StreamChannelController$(true, _this.$ti._precomputed1);
t2.$indexSet(0, id, controller._readLocal$0());
}
}
@@ -16072,8 +17011,10 @@
t1.close$0(0);
_this._innerStreamSubscription._source.cancel$0(0);
_this._multi_channel$_inner = null;
- for (t1 = _this._controllers, t2 = A.List_List$from(t1.get$values(t1), true, type$.dynamic), t3 = t2.length, _i = 0; _i < t3; ++_i) {
- t4 = t2[_i].get$local().__GuaranteeChannel__sink_F;
+ for (t1 = _this._controllers, t2 = t1.get$values(t1), t2 = A.List_List$of(t2, false, A._instanceType(t2)._eval$1("Iterable.E")), t3 = t2.length, _i = 0; _i < t3; ++_i) {
+ t4 = t2[_i].__StreamChannelController__local_F;
+ t4 === $ && A.throwLateFieldNI("_local");
+ t4 = t4.__GuaranteeChannel__sink_F;
t4 === $ && A.throwLateFieldNI("_sink");
t4.close$0(0);
}
@@ -16104,7 +17045,7 @@
var t1, id, t2, t3, controller, t4;
type$.List_dynamic._as(message);
t1 = J.getInterceptor$asx(message);
- id = A._asInt(t1.$index(message, 0));
+ id = B.JSNumber_methods.toInt$0(A._asNum(t1.$index(message, 0)));
t2 = this.$this;
if (t2._closedIds.contains$1(0, id))
return;
@@ -16124,7 +17065,7 @@
t1.close$0(0);
}
},
- $signature: 46
+ $signature: 42
};
A._MultiChannel__closure.prototype = {
call$0() {
@@ -16156,11 +17097,6 @@
};
A.VirtualChannel.prototype = {$isMultiChannel: 1};
A.StreamChannelController.prototype = {
- get$local() {
- var t1 = this.__StreamChannelController__local_F;
- t1 === $ && A.throwLateFieldNI("_local");
- return t1;
- },
set$__StreamChannelController__local_F(__StreamChannelController__local_F) {
this.__StreamChannelController__local_F = this.$ti._eval$1("StreamChannel<1>")._as(__StreamChannelController__local_F);
},
@@ -16169,54 +17105,46 @@
}
};
A.StreamChannelMixin.prototype = {$isStreamChannel: 1};
- A.Window0.prototype = {};
- A.Document0.prototype = {};
- A.HTMLDocument.prototype = {};
- A.Navigator0.prototype = {};
- A.Element0.prototype = {};
- A.HTMLElement.prototype = {};
- A.HTMLBodyElement.prototype = {};
- A.Node0.prototype = {};
- A.EventTarget0.prototype = {};
- A.Event0.prototype = {};
- A.MessageEvent0.prototype = {};
- A.Location0.prototype = {};
- A.MessagePort0.prototype = {};
- A.CSSStyleDeclaration.prototype = {};
- A.HTMLScriptElement.prototype = {};
- A.DomTokenList0.prototype = {};
- A.HTMLIFrameElement.prototype = {};
- A.WebSocket0.prototype = {};
- A.MessageChannel0.prototype = {};
+ A.MessagePortExtension_get_postMessage_closure.prototype = {
+ call$1(message) {
+ var t2,
+ t1 = A._setArrayType([], type$.JSArray_Object);
+ if (message != null) {
+ t2 = A.jsify(message);
+ t1.push(t2 == null ? type$.Object._as(t2) : t2);
+ }
+ return A.callMethod(this._this, "postMessage", t1, type$.void);
+ },
+ $signature: 8
+ };
A.Subscription.prototype = {};
- A.TestRunner.prototype = {};
- A._JSApi.prototype = {};
A.main_closure.prototype = {
call$0() {
- var serverChannel = A._connectToServer(),
+ var play,
+ serverChannel = A._connectToServer(),
t1 = serverChannel._mainController.__StreamChannelController__foreign_F;
t1 === $ && A.throwLateFieldNI("_foreign");
t1 = t1.__GuaranteeChannel__streamController_F;
t1 === $ && A.throwLateFieldNI("_streamController");
new A._ControllerStream(t1, A._instanceType(t1)._eval$1("_ControllerStream<1>")).listen$1(new A.main__closure(serverChannel));
A.Timer_Timer$periodic(new A.Duration(1000000), new A.main__closure0(serverChannel));
- t1 = type$.nullable_JavaScriptObject._as(self.document.querySelector("#play"));
- t1.toString;
- A.EventTargetExtension_addEventListener(t1, "click", A.allowInterop(new A.main__closure1(serverChannel), type$.void_Function_JavaScriptObject));
+ play = type$.nullable_JavaScriptObject._as(self.document.querySelector("#play"));
+ play.toString;
+ A.EventTargetExtension_addEventListener(play, "click", A.allowInterop(new A.main__closure1(serverChannel), type$.void_Function_JavaScriptObject));
t1 = type$.void_Function;
- self.dartTest = type$.JavaScriptObject._as({resume: A.allowInterop(new A.main__closure2(serverChannel), t1), restartCurrent: A.allowInterop(new A.main__closure3(serverChannel), t1)});
+ self.dartTest = {resume: A.allowInterop(new A.main__closure2(serverChannel), t1), restartCurrent: A.allowInterop(new A.main__closure3(serverChannel), t1)};
},
$signature: 2
};
A.main__closure.prototype = {
call$1(message) {
- var suiteChannel, t2, t3, t4,
+ var suiteChannel, t2, t3,
_s7_ = "command",
_s2_ = "id",
t1 = J.getInterceptor$asx(message);
if (J.$eq$(t1.$index(message, _s7_), "loadSuite")) {
- suiteChannel = this.serverChannel.virtualChannel$1(A._asInt(t1.$index(message, "channel")));
- t1 = suiteChannel.$ti._eval$1("StreamChannel<1>")._as(A._connectToIframe(A._asString(t1.$index(message, "url")), A._asInt(t1.$index(message, _s2_))));
+ suiteChannel = this.serverChannel.virtualChannel$1(B.JSNumber_methods.toInt$0(A._asNum(t1.$index(message, "channel"))));
+ t1 = suiteChannel.$ti._eval$1("StreamChannel<1>")._as(A._connectToIframe(A._asString(t1.$index(message, "url")), B.JSNumber_methods.toInt$0(A._asNum(t1.$index(message, _s2_)))));
t2 = t1.__GuaranteeChannel__sink_F;
t2 === $ && A.throwLateFieldNI("_sink");
suiteChannel.stream.pipe$1(t2);
@@ -16233,23 +17161,14 @@
if (t3._as(t2.parentNode) != null)
type$.JavaScriptObject._as(t3._as(t2.parentNode).removeChild(t2));
t2 = $._subscriptions.remove$1(0, t1.$index(message, _s2_));
- t2.toString;
- t2 = J.get$iterator$ax(t2);
- for (; t2.moveNext$0();)
- t2.get$current(t2).cancel$0(0);
+ if (t2 != null)
+ J.cancel$0$z(t2);
t1 = $._domSubscriptions.remove$1(0, t1.$index(message, _s2_));
- t1.toString;
- t1 = J.get$iterator$ax(t1);
- t2 = type$.JSArray_Object;
- for (; t1.moveNext$0();) {
- t3 = t1.get$current(t1);
- t4 = t3.target;
- t3 = A._setArrayType([t3.type, t3.listener], t2);
- t4.removeEventListener.apply(t4, t3);
- }
+ if (t1 != null)
+ A.EventTargetExtension_removeEventListener(t1.target, t1.type, t1.listener);
}
},
- $signature: 3
+ $signature: 5
};
A.main__closure0.prototype = {
call$1(_) {
@@ -16262,7 +17181,7 @@
t2 = type$.String;
return t1.add$1(0, A.LinkedHashMap_LinkedHashMap$_literal(["command", "ping"], t2, t2));
},
- $signature: 47
+ $signature: 43
};
A.main__closure1.prototype = {
call$1(_) {
@@ -16322,7 +17241,7 @@
else
toZone.call$1(line);
},
- $signature: 10
+ $signature: 11
};
A._connectToServer_closure.prototype = {
call$1(message) {
@@ -16338,37 +17257,132 @@
};
A._connectToServer_closure0.prototype = {
call$1(message) {
- return A.callMethod(this.webSocket, "send", [B.C_JsonCodec.encode$2$toEncodable(message, null)], type$.void);
+ return this.webSocket.send(B.C_JsonCodec.encode$2$toEncodable(message, null));
},
- $signature: 3
+ $signature: 5
};
A._connectToIframe_closure.prototype = {
call$1($event) {
- var t2, t3, _this = this,
+ var $location, t2, t3, _0_0, _0_6, _0_11, _0_15, port, t4, t5, data, _this = this, _null = null, _s6_ = "_local",
+ _s17_ = "_streamController",
t1 = type$.JavaScriptObject;
t1._as($event);
if (A._asString($event.origin) !== A._asString(t1._as(self.window.location).origin))
return;
+ $location = $event.source.location;
+ if ($location == null)
+ return;
t2 = _this.iframe;
- if (!J.$eq$(J.$index$asx(A.dartify($event.data), "href"), A._asStringQ(t2.src)))
+ if (!J.$eq$($location.href, A._asStringQ(t2.src)))
return;
$event.stopPropagation();
- if (J.$eq$(J.$index$asx(A.dartify($event.data), "ready"), true)) {
- t3 = _this.channel;
- t1._as(t3.port2).start();
- type$.Object._as(t2.contentWindow).postMessage("port", A._asString(t1._as(self.window.location).origin), A._setArrayType([t1._as(t3.port2)], type$.JSArray_JavaScriptObject));
- _this.readyCompleter.complete$0(0);
- } else if (J.$eq$(J.$index$asx(A.dartify($event.data), "exception"), true)) {
- t1 = _this.controller.__StreamChannelController__local_F;
- t1 === $ && A.throwLateFieldNI("_local");
- t1 = t1.__GuaranteeChannel__sink_F;
- t1 === $ && A.throwLateFieldNI("_sink");
- t1.add$1(0, J.$index$asx(A.dartify($event.data), "data"));
+ t3 = _this.windowSubscription._readLocal$0();
+ A.EventTargetExtension_removeEventListener(t3.target, t3.type, t3.listener);
+ $label0$0: {
+ _0_0 = A.dartify($event.data);
+ _0_6 = A._InitializedCell$named("#0#6", new A._connectToIframe__closure(_0_0));
+ _0_11 = A._InitializedCell$named("#0#11", new A._connectToIframe__closure0(_0_0));
+ _0_15 = A._InitializedCell$named("#0#15", new A._connectToIframe__closure1(_0_0));
+ if ("port" === _0_0) {
+ t1 = J.cast$1$0$ax(type$.List_dynamic._as($event.ports), t1);
+ port = t1.get$first(t1);
+ t1 = _this.id;
+ t2 = _this.controller;
+ $._domSubscriptions.$indexSet(0, t1, A.Subscription$(port, "message", A.allowInterop(new A._connectToIframe__closure2(t2), type$.void_Function_JavaScriptObject)));
+ port.start();
+ t2 = t2.__StreamChannelController__local_F;
+ t2 === $ && A.throwLateFieldNI(_s6_);
+ t2 = t2.__GuaranteeChannel__streamController_F;
+ t2 === $ && A.throwLateFieldNI(_s17_);
+ $._subscriptions.$indexSet(0, t1, new A._ControllerStream(t2, A._instanceType(t2)._eval$1("_ControllerStream<1>")).listen$1(A.MessagePortExtension_get_postMessage(port)));
+ break $label0$0;
+ }
+ t3 = type$.Map_dynamic_dynamic._is(_0_0);
+ if (t3) {
+ if (_0_6._readFinal$0() == null)
+ t4 = J.containsKey$1$x(_0_0, "ready");
+ else
+ t4 = true;
+ t4 = t4 && true === _0_6._readFinal$0();
+ } else
+ t4 = false;
+ if (t4) {
+ t3 = A._callConstructor("MessageChannel", A._setArrayType([], type$.JSArray_Object));
+ t3.toString;
+ t1._as(t3);
+ t4 = _this.id;
+ t5 = _this.controller;
+ $._domSubscriptions.$indexSet(0, t4, A.Subscription$(t1._as(t3.port1), "message", A.allowInterop(new A._connectToIframe__closure3(t5), type$.void_Function_JavaScriptObject)));
+ t5 = t5.__StreamChannelController__local_F;
+ t5 === $ && A.throwLateFieldNI(_s6_);
+ t5 = t5.__GuaranteeChannel__streamController_F;
+ t5 === $ && A.throwLateFieldNI(_s17_);
+ $._subscriptions.$indexSet(0, t4, new A._ControllerStream(t5, A._instanceType(t5)._eval$1("_ControllerStream<1>")).listen$1(A.MessagePortExtension_get_postMessage(t1._as(t3.port1))));
+ t1._as(t3.port2).start();
+ t1._as(t3.port1).start();
+ type$.Object._as(t2.contentWindow).postMessage("port", A._asString(t1._as(self.window.location).origin), A._setArrayType([t1._as(t3.port2)], type$.JSArray_JavaScriptObject));
+ break $label0$0;
+ }
+ if (t3) {
+ if (_0_11._readFinal$0() == null)
+ t1 = J.containsKey$1$x(_0_0, "exception");
+ else
+ t1 = true;
+ if (t1)
+ if (true === _0_11._readFinal$0()) {
+ if (_0_15._readFinal$0() == null)
+ t1 = J.containsKey$1$x(_0_0, "data");
+ else
+ t1 = true;
+ if (t1) {
+ data = _0_15._readFinal$0();
+ t1 = true;
+ } else {
+ data = _null;
+ t1 = false;
+ }
+ } else {
+ data = _null;
+ t1 = false;
+ }
+ else {
+ data = _null;
+ t1 = false;
+ }
+ } else {
+ data = _null;
+ t1 = false;
+ }
+ if (t1) {
+ t1 = _this.controller.__StreamChannelController__local_F;
+ t1 === $ && A.throwLateFieldNI(_s6_);
+ t1 = t1.__GuaranteeChannel__sink_F;
+ t1 === $ && A.throwLateFieldNI("_sink");
+ t1.add$1(0, data);
+ }
}
},
$signature: 7
};
- A._connectToIframe_closure0.prototype = {
+ A._connectToIframe__closure2.prototype = {
+ call$1($event) {
+ var t1;
+ type$.JavaScriptObject._as($event);
+ t1 = this.controller.__StreamChannelController__local_F;
+ t1 === $ && A.throwLateFieldNI("_local");
+ t1 = t1.__GuaranteeChannel__sink_F;
+ t1 === $ && A.throwLateFieldNI("_sink");
+ t1.add$1(0, A.dartify($event.data));
+ },
+ $signature: 7
+ };
+ A._connectToIframe__closure.prototype = {
+ call$0() {
+ return J.$index$asx(type$.Map_dynamic_dynamic._as(this._0_0), "ready");
+ },
+ $signature: 4
+ };
+ A._connectToIframe__closure3.prototype = {
call$1($event) {
var t1;
type$.JavaScriptObject._as($event);
@@ -16380,38 +17394,17 @@
},
$signature: 7
};
- A._connectToIframe_closure1.prototype = {
- call$1(message) {
- var $async$goto = 0,
- $async$completer = A._makeAsyncAwaitCompleter(type$.void),
- $async$self = this, t1, t2, t3;
- var $async$call$1 = A._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
- if ($async$errorCode === 1)
- return A._asyncRethrow($async$result, $async$completer);
- while (true)
- switch ($async$goto) {
- case 0:
- // Function start
- $async$goto = 2;
- return A._asyncAwait($async$self.readyCompleter.future, $async$call$1);
- case 2:
- // returning from await.
- t1 = type$.JavaScriptObject._as($async$self.channel.port1);
- t2 = A._setArrayType([], type$.JSArray_Object);
- if (message != null) {
- if (!type$.Map_dynamic_dynamic._is(message) && !type$.Iterable_dynamic._is(message))
- A.throwExpression(A.ArgumentError$("object must be a Map or Iterable", null));
- t3 = A._convertDataTree(message);
- t2.push(t3);
- }
- A.callMethod(t1, "postMessage", t2, type$.void);
- // implicit return
- return A._asyncReturn(null, $async$completer);
- }
- });
- return A._asyncStartSync($async$call$1, $async$completer);
+ A._connectToIframe__closure0.prototype = {
+ call$0() {
+ return J.$index$asx(type$.Map_dynamic_dynamic._as(this._0_0), "exception");
},
- $signature: 49
+ $signature: 4
+ };
+ A._connectToIframe__closure1.prototype = {
+ call$0() {
+ return J.$index$asx(type$.Map_dynamic_dynamic._as(this._0_0), "data");
+ },
+ $signature: 4
};
(function aliases() {
var _ = J.Interceptor.prototype;
@@ -16431,106 +17424,114 @@
_instance_2_u = hunkHelpers._instance_2u,
_instance_1_i = hunkHelpers._instance_1i,
_instance_0_u = hunkHelpers._instance_0u;
- _instance_1_u(A.CastStreamSubscription.prototype, "get$__internal$_onData", "__internal$_onData$1", 12);
- _static_1(A, "async__AsyncRun__scheduleImmediateJsOverride$closure", "_AsyncRun__scheduleImmediateJsOverride", 9);
- _static_1(A, "async__AsyncRun__scheduleImmediateWithSetImmediate$closure", "_AsyncRun__scheduleImmediateWithSetImmediate", 9);
- _static_1(A, "async__AsyncRun__scheduleImmediateWithTimer$closure", "_AsyncRun__scheduleImmediateWithTimer", 9);
+ _instance_1_u(A.CastStreamSubscription.prototype, "get$__internal$_onData", "__internal$_onData$1", 8);
+ _static_1(A, "async__AsyncRun__scheduleImmediateJsOverride$closure", "_AsyncRun__scheduleImmediateJsOverride", 13);
+ _static_1(A, "async__AsyncRun__scheduleImmediateWithSetImmediate$closure", "_AsyncRun__scheduleImmediateWithSetImmediate", 13);
+ _static_1(A, "async__AsyncRun__scheduleImmediateWithTimer$closure", "_AsyncRun__scheduleImmediateWithTimer", 13);
_static_0(A, "async___startMicrotaskLoop$closure", "_startMicrotaskLoop", 0);
- _static_1(A, "async___nullDataHandler$closure", "_nullDataHandler", 3);
- _static_2(A, "async___nullErrorHandler$closure", "_nullErrorHandler", 10);
+ _static_1(A, "async___nullDataHandler$closure", "_nullDataHandler", 5);
+ _static_2(A, "async___nullErrorHandler$closure", "_nullErrorHandler", 11);
_static_0(A, "async___nullDoneHandler$closure", "_nullDoneHandler", 0);
- _static(A, "async___rootHandleUncaughtError$closure", 5, null, ["call$5"], ["_rootHandleUncaughtError"], 51, 0);
+ _static(A, "async___rootHandleUncaughtError$closure", 5, null, ["call$5"], ["_rootHandleUncaughtError"], 46, 0);
_static(A, "async___rootRun$closure", 4, null, ["call$1$4", "call$4"], ["_rootRun", function($self, $parent, zone, f) {
return A._rootRun($self, $parent, zone, f, type$.dynamic);
- }], 52, 1);
+ }], 47, 1);
_static(A, "async___rootRunUnary$closure", 5, null, ["call$2$5", "call$5"], ["_rootRunUnary", function($self, $parent, zone, f, arg) {
return A._rootRunUnary($self, $parent, zone, f, arg, type$.dynamic, type$.dynamic);
- }], 53, 1);
+ }], 48, 1);
_static(A, "async___rootRunBinary$closure", 6, null, ["call$3$6", "call$6"], ["_rootRunBinary", function($self, $parent, zone, f, arg1, arg2) {
return A._rootRunBinary($self, $parent, zone, f, arg1, arg2, type$.dynamic, type$.dynamic, type$.dynamic);
- }], 54, 1);
+ }], 49, 1);
_static(A, "async___rootRegisterCallback$closure", 4, null, ["call$1$4", "call$4"], ["_rootRegisterCallback", function($self, $parent, zone, f) {
return A._rootRegisterCallback($self, $parent, zone, f, type$.dynamic);
- }], 55, 0);
+ }], 50, 0);
_static(A, "async___rootRegisterUnaryCallback$closure", 4, null, ["call$2$4", "call$4"], ["_rootRegisterUnaryCallback", function($self, $parent, zone, f) {
return A._rootRegisterUnaryCallback($self, $parent, zone, f, type$.dynamic, type$.dynamic);
- }], 56, 0);
+ }], 51, 0);
_static(A, "async___rootRegisterBinaryCallback$closure", 4, null, ["call$3$4", "call$4"], ["_rootRegisterBinaryCallback", function($self, $parent, zone, f) {
return A._rootRegisterBinaryCallback($self, $parent, zone, f, type$.dynamic, type$.dynamic, type$.dynamic);
- }], 57, 0);
- _static(A, "async___rootErrorCallback$closure", 5, null, ["call$5"], ["_rootErrorCallback"], 58, 0);
- _static(A, "async___rootScheduleMicrotask$closure", 4, null, ["call$4"], ["_rootScheduleMicrotask"], 59, 0);
- _static(A, "async___rootCreateTimer$closure", 5, null, ["call$5"], ["_rootCreateTimer"], 60, 0);
- _static(A, "async___rootCreatePeriodicTimer$closure", 5, null, ["call$5"], ["_rootCreatePeriodicTimer"], 61, 0);
- _static(A, "async___rootPrint$closure", 4, null, ["call$4"], ["_rootPrint"], 62, 0);
- _static_1(A, "async___printToZone$closure", "_printToZone", 63);
- _static(A, "async___rootFork$closure", 5, null, ["call$5"], ["_rootFork"], 64, 0);
+ }], 52, 0);
+ _static(A, "async___rootErrorCallback$closure", 5, null, ["call$5"], ["_rootErrorCallback"], 53, 0);
+ _static(A, "async___rootScheduleMicrotask$closure", 4, null, ["call$4"], ["_rootScheduleMicrotask"], 54, 0);
+ _static(A, "async___rootCreateTimer$closure", 5, null, ["call$5"], ["_rootCreateTimer"], 55, 0);
+ _static(A, "async___rootCreatePeriodicTimer$closure", 5, null, ["call$5"], ["_rootCreatePeriodicTimer"], 56, 0);
+ _static(A, "async___rootPrint$closure", 4, null, ["call$4"], ["_rootPrint"], 57, 0);
+ _static_1(A, "async___printToZone$closure", "_printToZone", 58);
+ _static(A, "async___rootFork$closure", 5, null, ["call$5"], ["_rootFork"], 59, 0);
_instance(A._SyncCompleter.prototype, "get$complete", 1, 0, function() {
return [null];
- }, ["call$1", "call$0"], ["complete$1", "complete$0"], 39, 0, 0);
- _instance_2_u(A._Future.prototype, "get$_completeError", "_completeError$2", 10);
+ }, ["call$1", "call$0"], ["complete$1", "complete$0"], 44, 0, 0);
+ _instance_2_u(A._Future.prototype, "get$_completeError", "_completeError$2", 11);
var _;
- _instance_1_i(_ = A._StreamController.prototype, "get$add", "add$1", 12);
+ _instance_1_i(_ = A._StreamController.prototype, "get$add", "add$1", 8);
_instance(_, "get$addError", 0, 1, function() {
return [null];
- }, ["call$2", "call$1"], ["addError$2", "addError$1"], 11, 0, 0);
- _instance_1_i(A._StreamSinkWrapper.prototype, "get$add", "add$1", 12);
+ }, ["call$2", "call$1"], ["addError$2", "addError$1"], 12, 0, 0);
+ _instance_1_i(A._StreamSinkWrapper.prototype, "get$add", "add$1", 8);
_instance_0_u(A._DoneStreamSubscription.prototype, "get$_sendDone", "_sendDone$0", 0);
- _static_1(A, "convert___defaultToEncodable$closure", "_defaultToEncodable", 14);
- _static_1(A, "core_Uri_decodeComponent$closure", "Uri_decodeComponent", 23);
+ _static_1(A, "convert___defaultToEncodable$closure", "_defaultToEncodable", 15);
+ _static_1(A, "core_Uri_decodeComponent$closure", "Uri_decodeComponent", 17);
+ _static_1(A, "frame_Frame___parseVM_tearOff$closure", "Frame___parseVM_tearOff", 9);
+ _static_1(A, "frame_Frame___parseV8_tearOff$closure", "Frame___parseV8_tearOff", 9);
+ _static_1(A, "frame_Frame___parseFirefox_tearOff$closure", "Frame___parseFirefox_tearOff", 9);
+ _static_1(A, "frame_Frame___parseFriendly_tearOff$closure", "Frame___parseFriendly_tearOff", 9);
+ _static_1(A, "trace_Trace___parseVM_tearOff$closure", "Trace___parseVM_tearOff", 14);
+ _static_1(A, "trace_Trace___parseFriendly_tearOff$closure", "Trace___parseFriendly_tearOff", 14);
_instance(_ = A._GuaranteeSink.prototype, "get$addError", 0, 1, function() {
return [null];
- }, ["call$2", "call$1"], ["addError$2", "addError$1"], 11, 0, 0);
+ }, ["call$2", "call$1"], ["addError$2", "addError$1"], 12, 0, 0);
_instance(_, "get$_addError", 0, 1, function() {
return [null];
- }, ["call$2", "call$1"], ["_addError$2", "_addError$1"], 11, 0, 0);
+ }, ["call$2", "call$1"], ["_addError$2", "_addError$1"], 12, 0, 0);
_instance_0_u(A._MultiChannel.prototype, "get$_closeInnerChannel", "_closeInnerChannel$0", 0);
_static(A, "math__max$closure", 2, null, ["call$1$2", "call$2"], ["max", function(a, b) {
return A.max(a, b, type$.num);
- }], 43, 0);
+ }], 41, 0);
})();
(function inheritance() {
var _mixin = hunkHelpers.mixin,
_inherit = hunkHelpers.inherit,
_inheritMany = hunkHelpers.inheritMany;
_inherit(A.Object, null);
- _inheritMany(A.Object, [A.JS_CONST, J.Interceptor, J.ArrayIterator, A.Stream, A.CastStreamSubscription, A.Error, A._ListBase_Object_ListMixin, A.Closure, A.SentinelValue, A.Iterable, A.ListIterator, A.Iterator, A.ExpandIterator, A.EmptyIterator, A.WhereTypeIterator, A.FixedLengthListMixin, A.UnmodifiableListMixin, A.Symbol, A.MapView, A.ConstantMap, A.JSInvocationMirror, A.TypeErrorDecoder, A.NullThrownFromJavaScriptException, A.ExceptionAndStackTrace, A._StackTrace, A._Required, A.MapMixin, A.LinkedHashMapCell, A.LinkedHashMapKeyIterator, A.JSSyntaxRegExp, A._MatchImplementation, A._AllMatchesIterator, A.StringMatch, A._StringAllMatchesIterator, A._Cell, A.Rti, A._FunctionParameters, A._Type, A._TimerImpl, A._AsyncAwaitCompleter, A.AsyncError, A._Completer, A._FutureListener, A._Future, A._AsyncCallbackEntry, A.StreamTransformerBase, A._StreamController, A._SyncStreamControllerDispatch, A._BufferingStreamSubscription, A._StreamSinkWrapper, A._DelayedEvent, A._DelayedDone, A._PendingEvents, A._DoneStreamSubscription, A._StreamIterator, A._ZoneFunction, A._ZoneSpecification, A._ZoneDelegate, A._Zone, A._HashMapKeyIterator, A.__SetBase_Object_SetMixin, A._LinkedHashSetCell, A._LinkedHashSetIterator, A.ListMixin, A._UnmodifiableMapMixin, A.SetMixin, A.Codec, A._JsonStringifier, A._Utf8Encoder, A._Utf8Decoder, A.DateTime, A.Duration, A.OutOfMemoryError, A.StackOverflowError, A._Exception, A.FormatException, A.Null, A._StringStackTrace, A.StringBuffer, A._Uri, A.UriData, A._SimpleUri, A.CssStyleDeclarationBase, A.ImmutableListMixin, A.FixedSizeListIterator, A.NullRejectionException, A.NullStreamSink, A.Context, A.Style, A.ParsedPath, A.PathException, A.Chain, A.Frame, A.LazyTrace, A.Trace, A.UnparsedFrame, A.StreamChannelMixin, A._GuaranteeSink, A.StreamChannelController, A.Subscription]);
- _inheritMany(J.Interceptor, [J.JSBool, J.JSNull, J.JavaScriptObject, J.JSArray, J.JSNumber, J.JSString, A.NativeTypedData]);
- _inheritMany(J.JavaScriptObject, [J.LegacyJavaScriptObject, A.EventTarget, A.AccessibleNodeList, A.Blob, A.CssTransformComponent, A.CssRule, A._CssStyleDeclaration_JavaScriptObject_CssStyleDeclarationBase, A.CssStyleValue, A.DataTransferItemList, A.DomException, A._DomRectList_JavaScriptObject_ListMixin, A.DomRectReadOnly, A._DomStringList_JavaScriptObject_ListMixin, A.DomTokenList, A._FileList_JavaScriptObject_ListMixin, A.Gamepad, A.History, A._HtmlCollection_JavaScriptObject_ListMixin, A.Location, A.MediaList, A._MidiInputMap_JavaScriptObject_MapMixin, A._MidiOutputMap_JavaScriptObject_MapMixin, A.MimeType, A._MimeTypeArray_JavaScriptObject_ListMixin, A._NodeList_JavaScriptObject_ListMixin, A.Plugin, A._PluginArray_JavaScriptObject_ListMixin, A._RtcStatsReport_JavaScriptObject_MapMixin, A.SpeechGrammar, A._SpeechGrammarList_JavaScriptObject_ListMixin, A.SpeechRecognitionResult, A._Storage_JavaScriptObject_MapMixin, A.StyleSheet, A._TextTrackCueList_JavaScriptObject_ListMixin, A.TimeRanges, A.Touch, A._TouchList_JavaScriptObject_ListMixin, A.TrackDefaultList, A.Url, A.__CssRuleList_JavaScriptObject_ListMixin, A.__GamepadList_JavaScriptObject_ListMixin, A.__NamedNodeMap_JavaScriptObject_ListMixin, A.__SpeechRecognitionResultList_JavaScriptObject_ListMixin, A.__StyleSheetList_JavaScriptObject_ListMixin, A.Length, A._LengthList_JavaScriptObject_ListMixin, A.Number, A._NumberList_JavaScriptObject_ListMixin, A.PointList, A._StringList_JavaScriptObject_ListMixin, A.Transform, A._TransformList_JavaScriptObject_ListMixin, A.AudioBuffer, A._AudioParamMap_JavaScriptObject_MapMixin]);
- _inheritMany(J.LegacyJavaScriptObject, [J.PlainJavaScriptObject, J.UnknownJavaScriptObject, J.JavaScriptFunction, A.EventTarget0, A.Navigator0, A.Event0, A.Location0, A.CSSStyleDeclaration, A.DomTokenList0, A.MessageChannel0, A.TestRunner, A._JSApi]);
+ _inheritMany(A.Object, [A.JS_CONST, J.Interceptor, J.ArrayIterator, A.Stream, A.CastStreamSubscription, A.Iterable, A.CastIterator, A.Error, A.ListBase, A.Closure, A.SentinelValue, A.ListIterator, A.MappedIterator, A.WhereIterator, A.ExpandIterator, A.TakeIterator, A.SkipIterator, A.SkipWhileIterator, A.EmptyIterator, A.WhereTypeIterator, A.FixedLengthListMixin, A.UnmodifiableListMixin, A.Symbol, A.MapView, A.ConstantMap, A._KeysOrValuesOrElementsIterator, A.JSInvocationMirror, A.TypeErrorDecoder, A.NullThrownFromJavaScriptException, A._StackTrace, A._Required, A.MapBase, A.LinkedHashMapCell, A.LinkedHashMapKeyIterator, A.JSSyntaxRegExp, A._MatchImplementation, A._AllMatchesIterator, A.StringMatch, A._StringAllMatchesIterator, A._Cell, A._InitializedCell, A.Rti, A._FunctionParameters, A._Type, A._TimerImpl, A.AsyncError, A._Completer, A._FutureListener, A._Future, A._AsyncCallbackEntry, A._StreamController, A._SyncStreamControllerDispatch, A._BufferingStreamSubscription, A._StreamSinkWrapper, A._DelayedEvent, A._DelayedDone, A._PendingEvents, A._DoneStreamSubscription, A._ZoneFunction, A._ZoneSpecification, A._ZoneDelegate, A._Zone, A._HashMapKeyIterator, A.SetBase, A._LinkedHashSetCell, A._LinkedHashSetIterator, A._UnmodifiableMapMixin, A.Codec, A.Converter, A._JsonStringifier, A._Utf8Encoder, A._Utf8Decoder, A.DateTime, A.Duration, A.OutOfMemoryError, A.StackOverflowError, A._Exception, A.FormatException, A.Null, A._StringStackTrace, A.StringBuffer, A._Uri, A.UriData, A._SimpleUri, A.CssStyleDeclarationBase, A.ImmutableListMixin, A.FixedSizeListIterator, A.NullRejectionException, A.NullStreamSink, A.Context, A.Style, A.ParsedPath, A.PathException, A.Chain, A.Frame, A.LazyTrace, A.Trace, A.UnparsedFrame, A.StreamChannelMixin, A._GuaranteeSink, A.StreamChannelController, A.Subscription]);
+ _inheritMany(J.Interceptor, [J.JSBool, J.JSNull, J.JavaScriptObject, J.JSNumber, J.JSString]);
+ _inheritMany(J.JavaScriptObject, [J.LegacyJavaScriptObject, J.JSArray, A.NativeByteBuffer, A.NativeTypedData, A.EventTarget, A.AccessibleNodeList, A.Blob, A.CssTransformComponent, A.CssRule, A._CssStyleDeclaration_JavaScriptObject_CssStyleDeclarationBase, A.CssStyleValue, A.DataTransferItemList, A.DomException, A._DomRectList_JavaScriptObject_ListMixin, A.DomRectReadOnly, A._DomStringList_JavaScriptObject_ListMixin, A.DomTokenList, A._FileList_JavaScriptObject_ListMixin, A.Gamepad, A.History, A._HtmlCollection_JavaScriptObject_ListMixin, A.Location, A.MediaList, A._MidiInputMap_JavaScriptObject_MapMixin, A._MidiOutputMap_JavaScriptObject_MapMixin, A.MimeType, A._MimeTypeArray_JavaScriptObject_ListMixin, A._NodeList_JavaScriptObject_ListMixin, A.Plugin, A._PluginArray_JavaScriptObject_ListMixin, A._RtcStatsReport_JavaScriptObject_MapMixin, A.SpeechGrammar, A._SpeechGrammarList_JavaScriptObject_ListMixin, A.SpeechRecognitionResult, A._Storage_JavaScriptObject_MapMixin, A.StyleSheet, A._TextTrackCueList_JavaScriptObject_ListMixin, A.TimeRanges, A.Touch, A._TouchList_JavaScriptObject_ListMixin, A.TrackDefaultList, A.Url, A.__CssRuleList_JavaScriptObject_ListMixin, A.__GamepadList_JavaScriptObject_ListMixin, A.__NamedNodeMap_JavaScriptObject_ListMixin, A.__SpeechRecognitionResultList_JavaScriptObject_ListMixin, A.__StyleSheetList_JavaScriptObject_ListMixin, A.Length, A._LengthList_JavaScriptObject_ListMixin, A.Number, A._NumberList_JavaScriptObject_ListMixin, A.PointList, A._StringList_JavaScriptObject_ListMixin, A.Transform, A._TransformList_JavaScriptObject_ListMixin, A.AudioBuffer, A._AudioParamMap_JavaScriptObject_MapMixin]);
+ _inheritMany(J.LegacyJavaScriptObject, [J.PlainJavaScriptObject, J.UnknownJavaScriptObject, J.JavaScriptFunction]);
_inherit(J.JSUnmodifiableArray, J.JSArray);
_inheritMany(J.JSNumber, [J.JSInt, J.JSNumNotInt]);
_inheritMany(A.Stream, [A.CastStream, A._StreamImpl, A._EmptyStream]);
- _inheritMany(A.Error, [A.LateError, A.TypeError, A.JsNoSuchMethodError, A.UnknownJsTypeError, A.RuntimeError, A.AssertionError, A._Error, A.JsonUnsupportedObjectError, A.NullThrownError, A.ArgumentError, A.NoSuchMethodError, A.UnsupportedError, A.UnimplementedError, A.StateError, A.ConcurrentModificationError, A.CyclicInitializationError]);
- _inherit(A.ListBase, A._ListBase_Object_ListMixin);
+ _inheritMany(A.Iterable, [A._CastIterableBase, A.EfficientLengthIterable, A.MappedIterable, A.WhereIterable, A.ExpandIterable, A.TakeIterable, A.SkipIterable, A.SkipWhileIterable, A.WhereTypeIterable, A._KeysOrValues, A._AllMatchesIterable, A._StringAllMatchesIterable]);
+ _inheritMany(A._CastIterableBase, [A.CastIterable, A.__CastListBase__CastIterableBase_ListMixin]);
+ _inherit(A._EfficientLengthCastIterable, A.CastIterable);
+ _inherit(A._CastListBase, A.__CastListBase__CastIterableBase_ListMixin);
+ _inherit(A.CastList, A._CastListBase);
+ _inheritMany(A.Error, [A.LateError, A.TypeError, A.JsNoSuchMethodError, A.UnknownJsTypeError, A._CyclicInitializationError, A.RuntimeError, A.AssertionError, A._Error, A.JsonUnsupportedObjectError, A.ArgumentError, A.NoSuchMethodError, A.UnsupportedError, A.UnimplementedError, A.StateError, A.ConcurrentModificationError]);
_inherit(A.UnmodifiableListBase, A.ListBase);
_inherit(A.CodeUnits, A.UnmodifiableListBase);
- _inheritMany(A.Closure, [A.Closure0Args, A.Instantiation, A.Closure2Args, A.TearOffClosure, A.JsLinkedHashMap_values_closure, A.initHooks_closure, A.initHooks_closure1, A._AsyncRun__initializeScheduleImmediate_internalCallback, A._AsyncRun__initializeScheduleImmediate_closure, A._awaitOnObject_closure, A._Future__chainForeignFuture_closure, A._Future__propagateToListeners_handleWhenCompleteCallback_closure, A.Stream_pipe_closure, A.Stream_length_closure, A._CustomZone_bindUnaryCallback_closure, A._CustomZone_bindUnaryCallbackGuarded_closure, A._RootZone_bindUnaryCallback_closure, A._RootZone_bindUnaryCallbackGuarded_closure, A.runZonedGuarded_closure, A._Uri__makePath_closure, A._createTables_setChars, A._createTables_setRange, A._convertDataTree__convert, A.promiseToFuture_closure, A.promiseToFuture_closure0, A.dartify_convert, A.Context_joinAll_closure, A.Context_split_closure, A._validateArgList_closure, A.WindowsStyle_absolutePathToUri_closure, A.Chain_Chain$parse_closure, A.Chain_Chain$parse_closure0, A.Chain_Chain$parse_closure1, A.Chain_toTrace_closure, A.Chain_toString_closure0, A.Chain_toString__closure0, A.Chain_toString_closure, A.Chain_toString__closure, A.Trace__parseVM_closure, A.Trace__parseVM_closure0, A.Trace$parseV8_closure, A.Trace$parseV8_closure0, A.Trace$parseJSCore_closure, A.Trace$parseJSCore_closure0, A.Trace$parseFirefox_closure, A.Trace$parseFirefox_closure0, A.Trace$parseFriendly_closure, A.Trace$parseFriendly_closure0, A.Trace_terse_closure, A.Trace_foldFrames_closure, A.Trace_foldFrames_closure0, A.Trace_toString_closure0, A.Trace_toString_closure, A._GuaranteeSink_addStream_closure, A._MultiChannel_closure, A._MultiChannel_closure1, A._MultiChannel_virtualChannel_closure, A.main__closure, A.main__closure0, A.main__closure1, A._connectToServer_closure, A._connectToServer_closure0, A._connectToIframe_closure, A._connectToIframe_closure0, A._connectToIframe_closure1]);
- _inheritMany(A.Closure0Args, [A.nullFuture_closure, A._AsyncRun__scheduleImmediateJsOverride_internalCallback, A._AsyncRun__scheduleImmediateWithSetImmediate_internalCallback, A._TimerImpl_internalCallback, A._TimerImpl$periodic_closure, A._Future__addListener_closure, A._Future__prependListeners_closure, A._Future__chainForeignFuture_closure1, A._Future__asyncCompleteWithValue_closure, A._Future__chainFuture_closure, A._Future__asyncCompleteError_closure, A._Future__propagateToListeners_handleWhenCompleteCallback, A._Future__propagateToListeners_handleValueCallback, A._Future__propagateToListeners_handleError, A.Stream_length_closure0, A._StreamController__subscribe_closure, A._StreamController__recordCancel_complete, A._AddStreamState_cancel_closure, A._BufferingStreamSubscription__sendError_sendError, A._BufferingStreamSubscription__sendDone_sendDone, A._PendingEvents_schedule_closure, A._CustomZone_bindCallback_closure, A._CustomZone_bindCallbackGuarded_closure, A._rootHandleError_closure, A._RootZone_bindCallback_closure, A._RootZone_bindCallbackGuarded_closure, A.Utf8Decoder__decoder_closure, A.Utf8Decoder__decoderNonfatal_closure, A.NullStreamSink_addStream_closure, A.Frame_Frame$parseVM_closure, A.Frame_Frame$parseV8_closure, A.Frame_Frame$_parseFirefoxEval_closure, A.Frame_Frame$parseFirefox_closure, A.Frame_Frame$parseFriendly_closure, A.LazyTrace_terse_closure, A.Trace_Trace$from_closure, A.GuaranteeChannel_closure, A.GuaranteeChannel__closure, A._MultiChannel_closure0, A._MultiChannel__closure, A._MultiChannel_virtualChannel_closure0, A.main_closure, A.main__closure2, A.main__closure3]);
- _inheritMany(A.Iterable, [A.EfficientLengthIterable, A.MappedIterable, A.WhereIterable, A.ExpandIterable, A.TakeIterable, A.SkipWhileIterable, A.WhereTypeIterable, A._ConstantMapKeyIterable, A.IterableBase, A._StringAllMatchesIterable]);
- _inheritMany(A.EfficientLengthIterable, [A.ListIterable, A.LinkedHashMapKeyIterable, A._HashMapKeyIterable]);
+ _inheritMany(A.Closure, [A.Closure0Args, A.Instantiation, A.Closure2Args, A.TearOffClosure, A.JsLinkedHashMap_values_closure, A.initHooks_closure, A.initHooks_closure1, A._AsyncRun__initializeScheduleImmediate_internalCallback, A._AsyncRun__initializeScheduleImmediate_closure, A._Future__chainForeignFuture_closure, A._Future__propagateToListeners_handleWhenCompleteCallback_closure, A.Stream_pipe_closure, A.Stream_length_closure, A._CustomZone_bindUnaryCallback_closure, A._CustomZone_bindUnaryCallbackGuarded_closure, A._RootZone_bindUnaryCallback_closure, A._RootZone_bindUnaryCallbackGuarded_closure, A.runZonedGuarded_closure, A._Uri__makePath_closure, A._createTables_setChars, A._createTables_setRange, A.jsify__convert, A.promiseToFuture_closure, A.promiseToFuture_closure0, A.dartify_convert, A.Context_joinAll_closure, A.Context_split_closure, A._validateArgList_closure, A.WindowsStyle_absolutePathToUri_closure, A.Chain_Chain$parse_closure, A.Chain_toTrace_closure, A.Chain_toString_closure0, A.Chain_toString__closure0, A.Chain_toString_closure, A.Chain_toString__closure, A.Trace__parseVM_closure, A.Trace$parseV8_closure, A.Trace$parseJSCore_closure, A.Trace$parseFirefox_closure, A.Trace$parseFriendly_closure, A.Trace_terse_closure, A.Trace_foldFrames_closure, A.Trace_foldFrames_closure0, A.Trace_toString_closure0, A.Trace_toString_closure, A._GuaranteeSink_addStream_closure, A._MultiChannel_closure, A._MultiChannel_closure1, A._MultiChannel_virtualChannel_closure, A.MessagePortExtension_get_postMessage_closure, A.main__closure, A.main__closure0, A.main__closure1, A._connectToServer_closure, A._connectToServer_closure0, A._connectToIframe_closure, A._connectToIframe__closure2, A._connectToIframe__closure3]);
+ _inheritMany(A.Closure0Args, [A.nullFuture_closure, A._AsyncRun__scheduleImmediateJsOverride_internalCallback, A._AsyncRun__scheduleImmediateWithSetImmediate_internalCallback, A._TimerImpl_internalCallback, A._TimerImpl$periodic_closure, A._Future__addListener_closure, A._Future__prependListeners_closure, A._Future__chainForeignFuture_closure1, A._Future__chainCoreFutureAsync_closure, A._Future__asyncCompleteWithValue_closure, A._Future__asyncCompleteError_closure, A._Future__propagateToListeners_handleWhenCompleteCallback, A._Future__propagateToListeners_handleValueCallback, A._Future__propagateToListeners_handleError, A.Stream_length_closure0, A._StreamController__subscribe_closure, A._StreamController__recordCancel_complete, A._AddStreamState_cancel_closure, A._BufferingStreamSubscription__sendError_sendError, A._BufferingStreamSubscription__sendDone_sendDone, A._PendingEvents_schedule_closure, A._CustomZone_bindCallback_closure, A._CustomZone_bindCallbackGuarded_closure, A._rootHandleError_closure, A._RootZone_bindCallback_closure, A._RootZone_bindCallbackGuarded_closure, A.Utf8Decoder__decoder_closure, A.Utf8Decoder__decoderNonfatal_closure, A.NullStreamSink_addStream_closure, A.Frame_Frame$parseVM_closure, A.Frame_Frame$parseV8_closure, A.Frame_Frame$_parseFirefoxEval_closure, A.Frame_Frame$parseFirefox_closure, A.Frame_Frame$parseFriendly_closure, A.LazyTrace_terse_closure, A.Trace_Trace$from_closure, A.GuaranteeChannel_closure, A.GuaranteeChannel__closure, A._MultiChannel_closure0, A._MultiChannel__closure, A._MultiChannel_virtualChannel_closure0, A.main_closure, A.main__closure2, A.main__closure3, A._connectToIframe__closure, A._connectToIframe__closure0, A._connectToIframe__closure1]);
+ _inheritMany(A.EfficientLengthIterable, [A.ListIterable, A.EmptyIterable, A.LinkedHashMapKeyIterable, A._HashMapKeyIterable]);
_inheritMany(A.ListIterable, [A.SubListIterable, A.MappedListIterable, A.ReversedListIterable, A._JsonMapKeyIterable]);
_inherit(A.EfficientLengthMappedIterable, A.MappedIterable);
- _inheritMany(A.Iterator, [A.MappedIterator, A.WhereIterator, A.TakeIterator, A.SkipWhileIterator]);
_inherit(A.EfficientLengthTakeIterable, A.TakeIterable);
+ _inherit(A.EfficientLengthSkipIterable, A.SkipIterable);
_inherit(A._UnmodifiableMapView_MapView__UnmodifiableMapMixin, A.MapView);
_inherit(A.UnmodifiableMapView, A._UnmodifiableMapView_MapView__UnmodifiableMapMixin);
_inherit(A.ConstantMapView, A.UnmodifiableMapView);
_inherit(A.ConstantStringMap, A.ConstantMap);
_inherit(A.Instantiation1, A.Instantiation);
- _inheritMany(A.Closure2Args, [A.Primitives_functionNoSuchMethod_closure, A.initHooks_closure0, A._awaitOnObject_closure0, A._wrapJsFunctionForAsync_closure, A._Future__chainForeignFuture_closure0, A.MapBase_mapToString_closure, A._JsonStringifier_writeMap_closure, A.NoSuchMethodError_toString_closure, A.Uri_splitQueryString_closure, A.Uri__parseIPv4Address_error, A.Uri_parseIPv6Address_error, A.Uri_parseIPv6Address_parseHex, A._createTables_build, A.MidiInputMap_keys_closure, A.MidiOutputMap_keys_closure, A.RtcStatsReport_keys_closure, A.Storage_keys_closure, A.AudioParamMap_keys_closure, A.Frame_Frame$parseV8_closure_parseLocation, A.main_closure0]);
+ _inheritMany(A.Closure2Args, [A.Primitives_functionNoSuchMethod_closure, A.initHooks_closure0, A._Future__chainForeignFuture_closure0, A.MapBase_mapToString_closure, A._JsonStringifier_writeMap_closure, A.NoSuchMethodError_toString_closure, A.Uri_splitQueryString_closure, A.Uri__parseIPv4Address_error, A.Uri_parseIPv6Address_error, A.Uri_parseIPv6Address_parseHex, A._createTables_build, A.MidiInputMap_keys_closure, A.MidiOutputMap_keys_closure, A.RtcStatsReport_keys_closure, A.Storage_keys_closure, A.AudioParamMap_keys_closure, A.Frame_Frame$parseV8_closure_parseLocation, A.main_closure0]);
_inherit(A.NullError, A.TypeError);
_inheritMany(A.TearOffClosure, [A.StaticClosure, A.BoundClosure]);
_inherit(A._AssertionError, A.AssertionError);
- _inherit(A.MapBase, A.MapMixin);
_inheritMany(A.MapBase, [A.JsLinkedHashMap, A._HashMap, A._JsonMap]);
- _inherit(A._AllMatchesIterable, A.IterableBase);
- _inherit(A.NativeTypedArray, A.NativeTypedData);
+ _inheritMany(A.NativeTypedData, [A.NativeByteData, A.NativeTypedArray]);
_inheritMany(A.NativeTypedArray, [A._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin, A._NativeTypedArrayOfInt_NativeTypedArray_ListMixin]);
_inherit(A._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin, A._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin);
_inherit(A.NativeTypedArrayOfDouble, A._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin);
_inherit(A._NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin, A._NativeTypedArrayOfInt_NativeTypedArray_ListMixin);
_inherit(A.NativeTypedArrayOfInt, A._NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin);
+ _inheritMany(A.NativeTypedArrayOfDouble, [A.NativeFloat32List, A.NativeFloat64List]);
_inheritMany(A.NativeTypedArrayOfInt, [A.NativeInt16List, A.NativeInt32List, A.NativeInt8List, A.NativeUint16List, A.NativeUint32List, A.NativeUint8ClampedList, A.NativeUint8List]);
_inherit(A._TypeError, A._Error);
_inheritMany(A._Completer, [A._AsyncCompleter, A._SyncCompleter]);
@@ -16540,11 +17541,10 @@
_inheritMany(A._DelayedEvent, [A._DelayedData, A._DelayedError]);
_inheritMany(A._Zone, [A._CustomZone, A._RootZone]);
_inherit(A._IdentityHashMap, A._HashMap);
- _inherit(A._SetBase, A.__SetBase_Object_SetMixin);
+ _inherit(A._SetBase, A.SetBase);
_inherit(A._LinkedHashSet, A._SetBase);
_inheritMany(A.Codec, [A.Encoding, A.Base64Codec, A._FusedCodec, A.JsonCodec]);
_inheritMany(A.Encoding, [A.AsciiCodec, A.Utf8Codec]);
- _inherit(A.Converter, A.StreamTransformerBase);
_inheritMany(A.Converter, [A._UnicodeSubsetEncoder, A.Base64Encoder, A.JsonEncoder, A.JsonDecoder, A.Utf8Encoder, A.Utf8Decoder]);
_inherit(A.AsciiEncoder, A._UnicodeSubsetEncoder);
_inherit(A.JsonCyclicError, A.JsonUnsupportedObjectError);
@@ -16611,83 +17611,77 @@
_inherit(A.InternalStyle, A.Style);
_inheritMany(A.InternalStyle, [A.PosixStyle, A.UrlStyle, A.WindowsStyle]);
_inheritMany(A.StreamChannelMixin, [A.GuaranteeChannel, A._MultiChannel, A.VirtualChannel]);
- _inheritMany(A.EventTarget0, [A.Window0, A.Node0, A.MessagePort0, A.WebSocket0]);
- _inheritMany(A.Node0, [A.Document0, A.Element0]);
- _inherit(A.HTMLDocument, A.Document0);
- _inherit(A.HTMLElement, A.Element0);
- _inheritMany(A.HTMLElement, [A.HTMLBodyElement, A.HTMLScriptElement, A.HTMLIFrameElement]);
- _inherit(A.MessageEvent0, A.Event0);
_mixin(A.UnmodifiableListBase, A.UnmodifiableListMixin);
- _mixin(A._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin, A.ListMixin);
+ _mixin(A.__CastListBase__CastIterableBase_ListMixin, A.ListBase);
+ _mixin(A._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin, A.ListBase);
_mixin(A._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin, A.FixedLengthListMixin);
- _mixin(A._NativeTypedArrayOfInt_NativeTypedArray_ListMixin, A.ListMixin);
+ _mixin(A._NativeTypedArrayOfInt_NativeTypedArray_ListMixin, A.ListBase);
_mixin(A._NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin, A.FixedLengthListMixin);
_mixin(A._SyncStreamController, A._SyncStreamControllerDispatch);
- _mixin(A._ListBase_Object_ListMixin, A.ListMixin);
_mixin(A._UnmodifiableMapView_MapView__UnmodifiableMapMixin, A._UnmodifiableMapMixin);
- _mixin(A.__SetBase_Object_SetMixin, A.SetMixin);
_mixin(A._CssStyleDeclaration_JavaScriptObject_CssStyleDeclarationBase, A.CssStyleDeclarationBase);
- _mixin(A._DomRectList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._DomRectList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._DomRectList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._DomStringList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._DomStringList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._DomStringList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._FileList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._FileList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._FileList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._HtmlCollection_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._HtmlCollection_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._HtmlCollection_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._MidiInputMap_JavaScriptObject_MapMixin, A.MapMixin);
- _mixin(A._MidiOutputMap_JavaScriptObject_MapMixin, A.MapMixin);
- _mixin(A._MimeTypeArray_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._MidiInputMap_JavaScriptObject_MapMixin, A.MapBase);
+ _mixin(A._MidiOutputMap_JavaScriptObject_MapMixin, A.MapBase);
+ _mixin(A._MimeTypeArray_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._MimeTypeArray_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._NodeList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._NodeList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._NodeList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._PluginArray_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._PluginArray_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._PluginArray_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._RtcStatsReport_JavaScriptObject_MapMixin, A.MapMixin);
- _mixin(A._SourceBufferList_EventTarget_ListMixin, A.ListMixin);
+ _mixin(A._RtcStatsReport_JavaScriptObject_MapMixin, A.MapBase);
+ _mixin(A._SourceBufferList_EventTarget_ListMixin, A.ListBase);
_mixin(A._SourceBufferList_EventTarget_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._SpeechGrammarList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._SpeechGrammarList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._SpeechGrammarList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._Storage_JavaScriptObject_MapMixin, A.MapMixin);
- _mixin(A._TextTrackCueList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._Storage_JavaScriptObject_MapMixin, A.MapBase);
+ _mixin(A._TextTrackCueList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._TextTrackCueList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._TextTrackList_EventTarget_ListMixin, A.ListMixin);
+ _mixin(A._TextTrackList_EventTarget_ListMixin, A.ListBase);
_mixin(A._TextTrackList_EventTarget_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._TouchList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._TouchList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._TouchList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A.__CssRuleList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A.__CssRuleList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A.__CssRuleList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A.__GamepadList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A.__GamepadList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A.__GamepadList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A.__NamedNodeMap_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A.__NamedNodeMap_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A.__NamedNodeMap_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A.__SpeechRecognitionResultList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A.__SpeechRecognitionResultList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A.__SpeechRecognitionResultList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A.__StyleSheetList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A.__StyleSheetList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A.__StyleSheetList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._LengthList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._LengthList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._LengthList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._NumberList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._NumberList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._NumberList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._StringList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._StringList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._StringList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._TransformList_JavaScriptObject_ListMixin, A.ListMixin);
+ _mixin(A._TransformList_JavaScriptObject_ListMixin, A.ListBase);
_mixin(A._TransformList_JavaScriptObject_ListMixin_ImmutableListMixin, A.ImmutableListMixin);
- _mixin(A._AudioParamMap_JavaScriptObject_MapMixin, A.MapMixin);
+ _mixin(A._AudioParamMap_JavaScriptObject_MapMixin, A.MapBase);
})();
var init = {
typeUniverse: {eC: new Map(), tR: {}, eT: {}, tPV: {}, sEA: []},
mangledGlobalNames: {int: "int", double: "double", num: "num", String: "String", bool: "bool", Null: "Null", List: "List"},
mangledNames: {},
- types: ["~()", "bool(String)", "Null()", "~(@)", "Frame(String)", "~(String,@)", "Frame()", "~(JavaScriptObject)", "Null(@)", "~(~())", "~(Object,StackTrace)", "~(Object[StackTrace?])", "~(Object?)", "bool(Frame)", "@(@)", "Trace()", "String(Frame)", "int(Frame)", "Trace(String)", "@()", "Object?(Object?)", "~(Object?,Object?)", "~(Uint8List,String,int)", "String(String)", "~(String,int)", "~(String,int?)", "int(int,int)", "Map<String,String>(Map<String,String>,String)", "Uint8List(@,@)", "~(Symbol0,@)", "~(String,String)", "~(Zone,ZoneDelegate,Zone,Object,StackTrace)", "Future<@>(@)", "String(String?)", "_Future<@>(@)", "List<Frame>(Trace)", "int(Trace)", "Null(Object,StackTrace)", "String(Trace)", "~([Object?])", "~(int,@)", "Frame(String,String)", "@(@,String)", "0^(0^,0^)<num>", "Future<Null>()", "Frame(Frame)", "~(List<@>)", "~(Timer)", "Null(~())", "Future<~>(@)", "@(String)", "~(Zone?,ZoneDelegate?,Zone,Object,StackTrace)", "0^(Zone?,ZoneDelegate?,Zone,0^())<Object?>", "0^(Zone?,ZoneDelegate?,Zone,0^(1^),1^)<Object?Object?>", "0^(Zone?,ZoneDelegate?,Zone,0^(1^,2^),1^,2^)<Object?Object?Object?>", "0^()(Zone,ZoneDelegate,Zone,0^())<Object?>", "0^(1^)(Zone,ZoneDelegate,Zone,0^(1^))<Object?Object?>", "0^(1^,2^)(Zone,ZoneDelegate,Zone,0^(1^,2^))<Object?Object?Object?>", "AsyncError?(Zone,ZoneDelegate,Zone,Object,StackTrace?)", "~(Zone?,ZoneDelegate?,Zone,~())", "Timer(Zone,ZoneDelegate,Zone,Duration,~())", "Timer(Zone,ZoneDelegate,Zone,Duration,~(Timer))", "~(Zone,ZoneDelegate,Zone,String)", "~(String)", "Zone(Zone?,ZoneDelegate?,Zone,ZoneSpecification?,Map<Object?,Object?>?)", "Null(@,StackTrace)"],
+ types: ["~()", "bool(String)", "Null()", "~(String,@)", "@()", "~(@)", "Frame()", "~(JavaScriptObject)", "~(Object?)", "Frame(String)", "Null(@)", "~(Object,StackTrace)", "~(Object[StackTrace?])", "~(~())", "Trace(String)", "@(@)", "~(Object?,Object?)", "String(String)", "~(Uint8List,String,int)", "Object?(Object?)", "int(Frame)", "String(Frame)", "Trace()", "bool(Frame)", "~(String,int)", "Uint8List(@,@)", "Null(Object,StackTrace)", "~(String,String)", "_Future<@>(@)", "Future<@>(@)", "Null(~())", "String(String?)", "List<Frame>(Trace)", "int(Trace)", "~(Zone,ZoneDelegate,Zone,Object,StackTrace)", "String(Trace)", "@(@,String)", "@(String)", "Frame(String,String)", "~(Symbol0,@)", "Map<String,String>(Map<String,String>,String)", "0^(0^,0^)<num>", "~(List<@>)", "~(Timer)", "~([Object?])", "~(String,int?)", "~(Zone?,ZoneDelegate?,Zone,Object,StackTrace)", "0^(Zone?,ZoneDelegate?,Zone,0^())<Object?>", "0^(Zone?,ZoneDelegate?,Zone,0^(1^),1^)<Object?,Object?>", "0^(Zone?,ZoneDelegate?,Zone,0^(1^,2^),1^,2^)<Object?,Object?,Object?>", "0^()(Zone,ZoneDelegate,Zone,0^())<Object?>", "0^(1^)(Zone,ZoneDelegate,Zone,0^(1^))<Object?,Object?>", "0^(1^,2^)(Zone,ZoneDelegate,Zone,0^(1^,2^))<Object?,Object?,Object?>", "AsyncError?(Zone,ZoneDelegate,Zone,Object,StackTrace?)", "~(Zone?,ZoneDelegate?,Zone,~())", "Timer(Zone,ZoneDelegate,Zone,Duration,~())", "Timer(Zone,ZoneDelegate,Zone,Duration,~(Timer))", "~(Zone,ZoneDelegate,Zone,String)", "~(String)", "Zone(Zone?,ZoneDelegate?,Zone,ZoneSpecification?,Map<Object?,Object?>?)", "int(int,int)", "Future<Null>()", "Frame(Frame)"],
interceptorsByTag: null,
leafTags: null,
arrayRti: Symbol("$ti")
};
- A._Universe_addRules(init.typeUniverse, JSON.parse('{"PlainJavaScriptObject":"LegacyJavaScriptObject","UnknownJavaScriptObject":"LegacyJavaScriptObject","JavaScriptFunction":"LegacyJavaScriptObject","Window0":"LegacyJavaScriptObject","Document0":"LegacyJavaScriptObject","HTMLDocument":"LegacyJavaScriptObject","Navigator0":"LegacyJavaScriptObject","Element0":"LegacyJavaScriptObject","HTMLElement":"LegacyJavaScriptObject","HTMLBodyElement":"LegacyJavaScriptObject","Node0":"LegacyJavaScriptObject","EventTarget0":"LegacyJavaScriptObject","Event0":"LegacyJavaScriptObject","MessageEvent0":"LegacyJavaScriptObject","Location0":"LegacyJavaScriptObject","MessagePort0":"LegacyJavaScriptObject","CSSStyleDeclaration":"LegacyJavaScriptObject","HTMLScriptElement":"LegacyJavaScriptObject","DomTokenList0":"LegacyJavaScriptObject","HTMLIFrameElement":"LegacyJavaScriptObject","WebSocket0":"LegacyJavaScriptObject","MessageChannel0":"LegacyJavaScriptObject","TestRunner":"LegacyJavaScriptObject","_JSApi":"LegacyJavaScriptObject","AbortPaymentEvent":"JavaScriptObject","ExtendableEvent":"JavaScriptObject","Event":"JavaScriptObject","AudioContext":"BaseAudioContext","AbsoluteOrientationSensor":"EventTarget","OrientationSensor":"EventTarget","Sensor":"EventTarget","MathMLElement":"Element","AudioElement":"HtmlElement","MediaElement":"HtmlElement","HtmlDocument":"Node","Document":"Node","VttCue":"TextTrackCue","CDataSection":"CharacterData","Text":"CharacterData","HtmlFormControlsCollection":"HtmlCollection","CssCharsetRule":"CssRule","CssMatrixComponent":"CssTransformComponent","CssStyleSheet":"StyleSheet","CssurlImageValue":"CssStyleValue","CssImageValue":"CssStyleValue","CssResourceValue":"CssStyleValue","NativeFloat32List":"NativeTypedArrayOfDouble","JSBool":{"bool":[]},"JSNull":{"Null":[]},"LegacyJavaScriptObject":{"JavaScriptObject":[]},"JSArray":{"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"JSUnmodifiableArray":{"JSArray":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"ArrayIterator":{"Iterator":["1"]},"JSNumber":{"double":[],"num":[]},"JSInt":{"double":[],"int":[],"num":[]},"JSNumNotInt":{"double":[],"num":[]},"JSString":{"String":[],"Pattern":[]},"CastStream":{"Stream":["2"],"Stream.T":"2"},"CastStreamSubscription":{"StreamSubscription":["2"]},"LateError":{"Error":[]},"CodeUnits":{"ListMixin":["int"],"UnmodifiableListMixin":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"ListMixin.E":"int","UnmodifiableListMixin.E":"int"},"EfficientLengthIterable":{"Iterable":["1"]},"ListIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"SubListIterable":{"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListIterable.E":"1","Iterable.E":"1"},"ListIterator":{"Iterator":["1"]},"MappedIterable":{"Iterable":["2"],"Iterable.E":"2"},"EfficientLengthMappedIterable":{"MappedIterable":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"Iterable.E":"2"},"MappedIterator":{"Iterator":["2"]},"MappedListIterable":{"ListIterable":["2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"ListIterable.E":"2","Iterable.E":"2"},"WhereIterable":{"Iterable":["1"],"Iterable.E":"1"},"WhereIterator":{"Iterator":["1"]},"ExpandIterable":{"Iterable":["2"],"Iterable.E":"2"},"ExpandIterator":{"Iterator":["2"]},"TakeIterable":{"Iterable":["1"],"Iterable.E":"1"},"EfficientLengthTakeIterable":{"TakeIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"TakeIterator":{"Iterator":["1"]},"SkipWhileIterable":{"Iterable":["1"],"Iterable.E":"1"},"SkipWhileIterator":{"Iterator":["1"]},"EmptyIterator":{"Iterator":["1"]},"WhereTypeIterable":{"Iterable":["1"],"Iterable.E":"1"},"WhereTypeIterator":{"Iterator":["1"]},"UnmodifiableListBase":{"ListMixin":["1"],"UnmodifiableListMixin":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"ReversedListIterable":{"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListIterable.E":"1","Iterable.E":"1"},"Symbol":{"Symbol0":[]},"ConstantMapView":{"UnmodifiableMapView":["1","2"],"_UnmodifiableMapView_MapView__UnmodifiableMapMixin":["1","2"],"MapView":["1","2"],"_UnmodifiableMapMixin":["1","2"],"Map":["1","2"]},"ConstantMap":{"Map":["1","2"]},"ConstantStringMap":{"ConstantMap":["1","2"],"Map":["1","2"]},"_ConstantMapKeyIterable":{"Iterable":["1"],"Iterable.E":"1"},"Instantiation":{"Closure":[],"Function":[]},"Instantiation1":{"Closure":[],"Function":[]},"JSInvocationMirror":{"Invocation":[]},"NullError":{"TypeError":[],"Error":[]},"JsNoSuchMethodError":{"Error":[]},"UnknownJsTypeError":{"Error":[]},"NullThrownFromJavaScriptException":{"Exception":[]},"_StackTrace":{"StackTrace":[]},"Closure":{"Function":[]},"Closure0Args":{"Closure":[],"Function":[]},"Closure2Args":{"Closure":[],"Function":[]},"TearOffClosure":{"Closure":[],"Function":[]},"StaticClosure":{"Closure":[],"Function":[]},"BoundClosure":{"Closure":[],"Function":[]},"RuntimeError":{"Error":[]},"_AssertionError":{"Error":[]},"JsLinkedHashMap":{"MapMixin":["1","2"],"LinkedHashMap":["1","2"],"Map":["1","2"],"MapMixin.K":"1","MapMixin.V":"2"},"LinkedHashMapKeyIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"LinkedHashMapKeyIterator":{"Iterator":["1"]},"JSSyntaxRegExp":{"Pattern":[]},"_MatchImplementation":{"RegExpMatch":[],"Match":[]},"_AllMatchesIterable":{"Iterable":["RegExpMatch"],"Iterable.E":"RegExpMatch"},"_AllMatchesIterator":{"Iterator":["RegExpMatch"]},"StringMatch":{"Match":[]},"_StringAllMatchesIterable":{"Iterable":["Match"],"Iterable.E":"Match"},"_StringAllMatchesIterator":{"Iterator":["Match"]},"NativeTypedArray":{"JavaScriptIndexingBehavior":["1"]},"NativeTypedArrayOfDouble":{"ListMixin":["double"],"JavaScriptIndexingBehavior":["double"],"List":["double"],"EfficientLengthIterable":["double"],"Iterable":["double"],"FixedLengthListMixin":["double"],"ListMixin.E":"double"},"NativeTypedArrayOfInt":{"ListMixin":["int"],"JavaScriptIndexingBehavior":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"]},"NativeInt16List":{"ListMixin":["int"],"JavaScriptIndexingBehavior":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"ListMixin.E":"int"},"NativeInt32List":{"ListMixin":["int"],"JavaScriptIndexingBehavior":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"ListMixin.E":"int"},"NativeInt8List":{"ListMixin":["int"],"JavaScriptIndexingBehavior":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"ListMixin.E":"int"},"NativeUint16List":{"ListMixin":["int"],"JavaScriptIndexingBehavior":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"ListMixin.E":"int"},"NativeUint32List":{"ListMixin":["int"],"JavaScriptIndexingBehavior":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"ListMixin.E":"int"},"NativeUint8ClampedList":{"ListMixin":["int"],"JavaScriptIndexingBehavior":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"ListMixin.E":"int"},"NativeUint8List":{"ListMixin":["int"],"Uint8List":[],"JavaScriptIndexingBehavior":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"ListMixin.E":"int"},"_Error":{"Error":[]},"_TypeError":{"TypeError":[],"Error":[]},"AsyncError":{"Error":[]},"_Future":{"Future":["1"]},"_TimerImpl":{"Timer":[]},"_AsyncAwaitCompleter":{"Completer":["1"]},"_Completer":{"Completer":["1"]},"_AsyncCompleter":{"_Completer":["1"],"Completer":["1"]},"_SyncCompleter":{"_Completer":["1"],"Completer":["1"]},"StreamTransformerBase":{"StreamTransformer":["1","2"]},"_StreamController":{"StreamController":["1"],"StreamSink":["1"],"StreamConsumer":["1"],"_StreamControllerLifecycle":["1"],"_EventDispatch":["1"]},"_SyncStreamController":{"_SyncStreamControllerDispatch":["1"],"_StreamController":["1"],"StreamController":["1"],"StreamSink":["1"],"StreamConsumer":["1"],"_StreamControllerLifecycle":["1"],"_EventDispatch":["1"]},"_ControllerStream":{"_StreamImpl":["1"],"Stream":["1"],"Stream.T":"1"},"_ControllerSubscription":{"_BufferingStreamSubscription":["1"],"StreamSubscription":["1"],"_EventDispatch":["1"],"_BufferingStreamSubscription.T":"1"},"_StreamSinkWrapper":{"StreamSink":["1"],"StreamConsumer":["1"]},"_BufferingStreamSubscription":{"StreamSubscription":["1"],"_EventDispatch":["1"],"_BufferingStreamSubscription.T":"1"},"_StreamImpl":{"Stream":["1"]},"_DelayedData":{"_DelayedEvent":["1"]},"_DelayedError":{"_DelayedEvent":["@"]},"_DelayedDone":{"_DelayedEvent":["@"]},"_DoneStreamSubscription":{"StreamSubscription":["1"]},"_EmptyStream":{"Stream":["1"],"Stream.T":"1"},"_ZoneSpecification":{"ZoneSpecification":[]},"_ZoneDelegate":{"ZoneDelegate":[]},"_Zone":{"Zone":[]},"_CustomZone":{"_Zone":[],"Zone":[]},"_RootZone":{"_Zone":[],"Zone":[]},"_HashMap":{"MapMixin":["1","2"],"Map":["1","2"],"MapMixin.K":"1","MapMixin.V":"2"},"_IdentityHashMap":{"_HashMap":["1","2"],"MapMixin":["1","2"],"Map":["1","2"],"MapMixin.K":"1","MapMixin.V":"2"},"_HashMapKeyIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"_HashMapKeyIterator":{"Iterator":["1"]},"_LinkedHashSet":{"SetMixin":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_LinkedHashSetIterator":{"Iterator":["1"]},"IterableBase":{"Iterable":["1"]},"ListBase":{"ListMixin":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"MapBase":{"MapMixin":["1","2"],"Map":["1","2"]},"MapMixin":{"Map":["1","2"]},"MapView":{"Map":["1","2"]},"UnmodifiableMapView":{"_UnmodifiableMapView_MapView__UnmodifiableMapMixin":["1","2"],"MapView":["1","2"],"_UnmodifiableMapMixin":["1","2"],"Map":["1","2"]},"_SetBase":{"SetMixin":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_JsonMap":{"MapMixin":["String","@"],"Map":["String","@"],"MapMixin.K":"String","MapMixin.V":"@"},"_JsonMapKeyIterable":{"ListIterable":["String"],"EfficientLengthIterable":["String"],"Iterable":["String"],"ListIterable.E":"String","Iterable.E":"String"},"AsciiCodec":{"Codec":["String","List<int>"],"Codec.S":"String"},"_UnicodeSubsetEncoder":{"Converter":["String","List<int>"],"StreamTransformer":["String","List<int>"]},"AsciiEncoder":{"Converter":["String","List<int>"],"StreamTransformer":["String","List<int>"]},"Base64Codec":{"Codec":["List<int>","String"],"Codec.S":"List<int>"},"Base64Encoder":{"Converter":["List<int>","String"],"StreamTransformer":["List<int>","String"]},"_FusedCodec":{"Codec":["1","3"],"Codec.S":"1"},"Converter":{"StreamTransformer":["1","2"]},"Encoding":{"Codec":["String","List<int>"]},"JsonUnsupportedObjectError":{"Error":[]},"JsonCyclicError":{"Error":[]},"JsonCodec":{"Codec":["Object?","String"],"Codec.S":"Object?"},"JsonEncoder":{"Converter":["Object?","String"],"StreamTransformer":["Object?","String"]},"JsonDecoder":{"Converter":["String","Object?"],"StreamTransformer":["String","Object?"]},"Utf8Codec":{"Codec":["String","List<int>"],"Codec.S":"String"},"Utf8Encoder":{"Converter":["String","List<int>"],"StreamTransformer":["String","List<int>"]},"Utf8Decoder":{"Converter":["List<int>","String"],"StreamTransformer":["List<int>","String"]},"double":{"num":[]},"int":{"num":[]},"List":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"RegExpMatch":{"Match":[]},"String":{"Pattern":[]},"AssertionError":{"Error":[]},"TypeError":{"Error":[]},"NullThrownError":{"Error":[]},"ArgumentError":{"Error":[]},"RangeError":{"Error":[]},"IndexError":{"Error":[]},"NoSuchMethodError":{"Error":[]},"UnsupportedError":{"Error":[]},"UnimplementedError":{"Error":[]},"StateError":{"Error":[]},"ConcurrentModificationError":{"Error":[]},"OutOfMemoryError":{"Error":[]},"StackOverflowError":{"Error":[]},"CyclicInitializationError":{"Error":[]},"_Exception":{"Exception":[]},"FormatException":{"Exception":[]},"_StringStackTrace":{"StackTrace":[]},"StringBuffer":{"StringSink":[]},"_Uri":{"Uri":[]},"_SimpleUri":{"Uri":[]},"_DataUri":{"Uri":[]},"CssRule":{"JavaScriptObject":[]},"File":{"JavaScriptObject":[]},"Gamepad":{"JavaScriptObject":[]},"MimeType":{"JavaScriptObject":[]},"Node":{"JavaScriptObject":[]},"Plugin":{"JavaScriptObject":[]},"SourceBuffer":{"JavaScriptObject":[]},"SpeechGrammar":{"JavaScriptObject":[]},"SpeechRecognitionResult":{"JavaScriptObject":[]},"StyleSheet":{"JavaScriptObject":[]},"TextTrack":{"JavaScriptObject":[]},"TextTrackCue":{"JavaScriptObject":[]},"Touch":{"JavaScriptObject":[]},"HtmlElement":{"Node":[],"JavaScriptObject":[]},"AccessibleNodeList":{"JavaScriptObject":[]},"AnchorElement":{"Node":[],"JavaScriptObject":[]},"AreaElement":{"Node":[],"JavaScriptObject":[]},"Blob":{"JavaScriptObject":[]},"CharacterData":{"Node":[],"JavaScriptObject":[]},"CssPerspective":{"JavaScriptObject":[]},"CssStyleDeclaration":{"JavaScriptObject":[]},"CssStyleValue":{"JavaScriptObject":[]},"CssTransformComponent":{"JavaScriptObject":[]},"CssTransformValue":{"JavaScriptObject":[]},"CssUnparsedValue":{"JavaScriptObject":[]},"DataTransferItemList":{"JavaScriptObject":[]},"DomException":{"JavaScriptObject":[]},"DomRectList":{"ListMixin":["Rectangle<num>"],"ImmutableListMixin":["Rectangle<num>"],"List":["Rectangle<num>"],"JavaScriptIndexingBehavior":["Rectangle<num>"],"JavaScriptObject":[],"EfficientLengthIterable":["Rectangle<num>"],"Iterable":["Rectangle<num>"],"ImmutableListMixin.E":"Rectangle<num>","ListMixin.E":"Rectangle<num>"},"DomRectReadOnly":{"JavaScriptObject":[],"Rectangle":["num"]},"DomStringList":{"ListMixin":["String"],"ImmutableListMixin":["String"],"List":["String"],"JavaScriptIndexingBehavior":["String"],"JavaScriptObject":[],"EfficientLengthIterable":["String"],"Iterable":["String"],"ImmutableListMixin.E":"String","ListMixin.E":"String"},"DomTokenList":{"JavaScriptObject":[]},"Element":{"Node":[],"JavaScriptObject":[]},"EventTarget":{"JavaScriptObject":[]},"FileList":{"ListMixin":["File"],"ImmutableListMixin":["File"],"List":["File"],"JavaScriptIndexingBehavior":["File"],"JavaScriptObject":[],"EfficientLengthIterable":["File"],"Iterable":["File"],"ImmutableListMixin.E":"File","ListMixin.E":"File"},"FileWriter":{"JavaScriptObject":[]},"FormElement":{"Node":[],"JavaScriptObject":[]},"History":{"JavaScriptObject":[]},"HtmlCollection":{"ListMixin":["Node"],"ImmutableListMixin":["Node"],"List":["Node"],"JavaScriptIndexingBehavior":["Node"],"JavaScriptObject":[],"EfficientLengthIterable":["Node"],"Iterable":["Node"],"ImmutableListMixin.E":"Node","ListMixin.E":"Node"},"Location":{"JavaScriptObject":[]},"MediaList":{"JavaScriptObject":[]},"MidiInputMap":{"JavaScriptObject":[],"MapMixin":["String","@"],"Map":["String","@"],"MapMixin.K":"String","MapMixin.V":"@"},"MidiOutputMap":{"JavaScriptObject":[],"MapMixin":["String","@"],"Map":["String","@"],"MapMixin.K":"String","MapMixin.V":"@"},"MimeTypeArray":{"ListMixin":["MimeType"],"ImmutableListMixin":["MimeType"],"List":["MimeType"],"JavaScriptIndexingBehavior":["MimeType"],"JavaScriptObject":[],"EfficientLengthIterable":["MimeType"],"Iterable":["MimeType"],"ImmutableListMixin.E":"MimeType","ListMixin.E":"MimeType"},"NodeList":{"ListMixin":["Node"],"ImmutableListMixin":["Node"],"List":["Node"],"JavaScriptIndexingBehavior":["Node"],"JavaScriptObject":[],"EfficientLengthIterable":["Node"],"Iterable":["Node"],"ImmutableListMixin.E":"Node","ListMixin.E":"Node"},"PluginArray":{"ListMixin":["Plugin"],"ImmutableListMixin":["Plugin"],"List":["Plugin"],"JavaScriptIndexingBehavior":["Plugin"],"JavaScriptObject":[],"EfficientLengthIterable":["Plugin"],"Iterable":["Plugin"],"ImmutableListMixin.E":"Plugin","ListMixin.E":"Plugin"},"RtcStatsReport":{"JavaScriptObject":[],"MapMixin":["String","@"],"Map":["String","@"],"MapMixin.K":"String","MapMixin.V":"@"},"SelectElement":{"Node":[],"JavaScriptObject":[]},"SourceBufferList":{"ListMixin":["SourceBuffer"],"ImmutableListMixin":["SourceBuffer"],"List":["SourceBuffer"],"JavaScriptIndexingBehavior":["SourceBuffer"],"JavaScriptObject":[],"EfficientLengthIterable":["SourceBuffer"],"Iterable":["SourceBuffer"],"ImmutableListMixin.E":"SourceBuffer","ListMixin.E":"SourceBuffer"},"SpeechGrammarList":{"ListMixin":["SpeechGrammar"],"ImmutableListMixin":["SpeechGrammar"],"List":["SpeechGrammar"],"JavaScriptIndexingBehavior":["SpeechGrammar"],"JavaScriptObject":[],"EfficientLengthIterable":["SpeechGrammar"],"Iterable":["SpeechGrammar"],"ImmutableListMixin.E":"SpeechGrammar","ListMixin.E":"SpeechGrammar"},"Storage":{"JavaScriptObject":[],"MapMixin":["String","String"],"Map":["String","String"],"MapMixin.K":"String","MapMixin.V":"String"},"TextTrackCueList":{"ListMixin":["TextTrackCue"],"ImmutableListMixin":["TextTrackCue"],"List":["TextTrackCue"],"JavaScriptIndexingBehavior":["TextTrackCue"],"JavaScriptObject":[],"EfficientLengthIterable":["TextTrackCue"],"Iterable":["TextTrackCue"],"ImmutableListMixin.E":"TextTrackCue","ListMixin.E":"TextTrackCue"},"TextTrackList":{"ListMixin":["TextTrack"],"ImmutableListMixin":["TextTrack"],"List":["TextTrack"],"JavaScriptIndexingBehavior":["TextTrack"],"JavaScriptObject":[],"EfficientLengthIterable":["TextTrack"],"Iterable":["TextTrack"],"ImmutableListMixin.E":"TextTrack","ListMixin.E":"TextTrack"},"TimeRanges":{"JavaScriptObject":[]},"TouchList":{"ListMixin":["Touch"],"ImmutableListMixin":["Touch"],"List":["Touch"],"JavaScriptIndexingBehavior":["Touch"],"JavaScriptObject":[],"EfficientLengthIterable":["Touch"],"Iterable":["Touch"],"ImmutableListMixin.E":"Touch","ListMixin.E":"Touch"},"TrackDefaultList":{"JavaScriptObject":[]},"Url":{"JavaScriptObject":[]},"VideoTrackList":{"JavaScriptObject":[]},"_CssRuleList":{"ListMixin":["CssRule"],"ImmutableListMixin":["CssRule"],"List":["CssRule"],"JavaScriptIndexingBehavior":["CssRule"],"JavaScriptObject":[],"EfficientLengthIterable":["CssRule"],"Iterable":["CssRule"],"ImmutableListMixin.E":"CssRule","ListMixin.E":"CssRule"},"_DomRect":{"JavaScriptObject":[],"Rectangle":["num"]},"_GamepadList":{"ListMixin":["Gamepad?"],"ImmutableListMixin":["Gamepad?"],"List":["Gamepad?"],"JavaScriptIndexingBehavior":["Gamepad?"],"JavaScriptObject":[],"EfficientLengthIterable":["Gamepad?"],"Iterable":["Gamepad?"],"ImmutableListMixin.E":"Gamepad?","ListMixin.E":"Gamepad?"},"_NamedNodeMap":{"ListMixin":["Node"],"ImmutableListMixin":["Node"],"List":["Node"],"JavaScriptIndexingBehavior":["Node"],"JavaScriptObject":[],"EfficientLengthIterable":["Node"],"Iterable":["Node"],"ImmutableListMixin.E":"Node","ListMixin.E":"Node"},"_SpeechRecognitionResultList":{"ListMixin":["SpeechRecognitionResult"],"ImmutableListMixin":["SpeechRecognitionResult"],"List":["SpeechRecognitionResult"],"JavaScriptIndexingBehavior":["SpeechRecognitionResult"],"JavaScriptObject":[],"EfficientLengthIterable":["SpeechRecognitionResult"],"Iterable":["SpeechRecognitionResult"],"ImmutableListMixin.E":"SpeechRecognitionResult","ListMixin.E":"SpeechRecognitionResult"},"_StyleSheetList":{"ListMixin":["StyleSheet"],"ImmutableListMixin":["StyleSheet"],"List":["StyleSheet"],"JavaScriptIndexingBehavior":["StyleSheet"],"JavaScriptObject":[],"EfficientLengthIterable":["StyleSheet"],"Iterable":["StyleSheet"],"ImmutableListMixin.E":"StyleSheet","ListMixin.E":"StyleSheet"},"FixedSizeListIterator":{"Iterator":["1"]},"NullRejectionException":{"Exception":[]},"Length":{"JavaScriptObject":[]},"Number":{"JavaScriptObject":[]},"Transform":{"JavaScriptObject":[]},"LengthList":{"ListMixin":["Length"],"ImmutableListMixin":["Length"],"List":["Length"],"JavaScriptObject":[],"EfficientLengthIterable":["Length"],"Iterable":["Length"],"ImmutableListMixin.E":"Length","ListMixin.E":"Length"},"NumberList":{"ListMixin":["Number"],"ImmutableListMixin":["Number"],"List":["Number"],"JavaScriptObject":[],"EfficientLengthIterable":["Number"],"Iterable":["Number"],"ImmutableListMixin.E":"Number","ListMixin.E":"Number"},"PointList":{"JavaScriptObject":[]},"StringList":{"ListMixin":["String"],"ImmutableListMixin":["String"],"List":["String"],"JavaScriptObject":[],"EfficientLengthIterable":["String"],"Iterable":["String"],"ImmutableListMixin.E":"String","ListMixin.E":"String"},"TransformList":{"ListMixin":["Transform"],"ImmutableListMixin":["Transform"],"List":["Transform"],"JavaScriptObject":[],"EfficientLengthIterable":["Transform"],"Iterable":["Transform"],"ImmutableListMixin.E":"Transform","ListMixin.E":"Transform"},"AudioBuffer":{"JavaScriptObject":[]},"AudioParamMap":{"JavaScriptObject":[],"MapMixin":["String","@"],"Map":["String","@"],"MapMixin.K":"String","MapMixin.V":"@"},"AudioTrackList":{"JavaScriptObject":[]},"BaseAudioContext":{"JavaScriptObject":[]},"OfflineAudioContext":{"JavaScriptObject":[]},"NullStreamSink":{"StreamSink":["1"],"StreamConsumer":["1"]},"PathException":{"Exception":[]},"PosixStyle":{"InternalStyle":[]},"UrlStyle":{"InternalStyle":[]},"WindowsStyle":{"InternalStyle":[]},"Chain":{"StackTrace":[]},"LazyTrace":{"Trace":[],"StackTrace":[]},"Trace":{"StackTrace":[]},"UnparsedFrame":{"Frame":[]},"GuaranteeChannel":{"StreamChannelMixin":["1"],"StreamChannel":["1"]},"_GuaranteeSink":{"StreamSink":["1"],"StreamConsumer":["1"]},"_MultiChannel":{"StreamChannelMixin":["1"],"MultiChannel":["1"],"StreamChannel":["1"]},"VirtualChannel":{"StreamChannelMixin":["1"],"MultiChannel":["1"],"StreamChannel":["1"]},"StreamChannelMixin":{"StreamChannel":["1"]},"Uint8List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]}}'));
- A._Universe_addErasedTypes(init.typeUniverse, JSON.parse('{"EfficientLengthIterable":1,"UnmodifiableListBase":1,"NativeTypedArray":1,"StreamTransformerBase":2,"IterableBase":1,"ListBase":1,"MapBase":2,"_SetBase":1,"_ListBase_Object_ListMixin":1,"__SetBase_Object_SetMixin":1}'));
+ A._Universe_addRules(init.typeUniverse, JSON.parse('{"PlainJavaScriptObject":"LegacyJavaScriptObject","UnknownJavaScriptObject":"LegacyJavaScriptObject","JavaScriptFunction":"LegacyJavaScriptObject","AbortPaymentEvent":"JavaScriptObject","ExtendableEvent":"JavaScriptObject","Event":"JavaScriptObject","AudioContext":"BaseAudioContext","AbsoluteOrientationSensor":"EventTarget","OrientationSensor":"EventTarget","Sensor":"EventTarget","MathMLElement":"Element","AudioElement":"HtmlElement","MediaElement":"HtmlElement","HtmlDocument":"Node","Document":"Node","VttCue":"TextTrackCue","CDataSection":"CharacterData","Text":"CharacterData","HtmlFormControlsCollection":"HtmlCollection","CssCharsetRule":"CssRule","CssMatrixComponent":"CssTransformComponent","CssStyleSheet":"StyleSheet","CssurlImageValue":"CssStyleValue","CssImageValue":"CssStyleValue","CssResourceValue":"CssStyleValue","JSBool":{"bool":[],"TrustedGetRuntimeType":[]},"JSNull":{"Null":[],"TrustedGetRuntimeType":[]},"LegacyJavaScriptObject":{"JavaScriptObject":[]},"JSArray":{"List":["1"],"JavaScriptObject":[],"EfficientLengthIterable":["1"],"Iterable":["1"]},"JSUnmodifiableArray":{"JSArray":["1"],"List":["1"],"JavaScriptObject":[],"EfficientLengthIterable":["1"],"Iterable":["1"]},"ArrayIterator":{"Iterator":["1"]},"JSNumber":{"double":[],"num":[]},"JSInt":{"double":[],"int":[],"num":[],"TrustedGetRuntimeType":[]},"JSNumNotInt":{"double":[],"num":[],"TrustedGetRuntimeType":[]},"JSString":{"String":[],"Pattern":[],"TrustedGetRuntimeType":[]},"CastStream":{"Stream":["2"],"Stream.T":"2"},"CastStreamSubscription":{"StreamSubscription":["2"]},"_CastIterableBase":{"Iterable":["2"]},"CastIterator":{"Iterator":["2"]},"CastIterable":{"_CastIterableBase":["1","2"],"Iterable":["2"],"Iterable.E":"2"},"_EfficientLengthCastIterable":{"CastIterable":["1","2"],"_CastIterableBase":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"Iterable.E":"2"},"_CastListBase":{"ListBase":["2"],"List":["2"],"_CastIterableBase":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"]},"CastList":{"_CastListBase":["1","2"],"ListBase":["2"],"List":["2"],"_CastIterableBase":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"ListBase.E":"2","Iterable.E":"2"},"LateError":{"Error":[]},"CodeUnits":{"ListBase":["int"],"UnmodifiableListMixin":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"ListBase.E":"int","UnmodifiableListMixin.E":"int"},"EfficientLengthIterable":{"Iterable":["1"]},"ListIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"SubListIterable":{"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListIterable.E":"1","Iterable.E":"1"},"ListIterator":{"Iterator":["1"]},"MappedIterable":{"Iterable":["2"],"Iterable.E":"2"},"EfficientLengthMappedIterable":{"MappedIterable":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"Iterable.E":"2"},"MappedIterator":{"Iterator":["2"]},"MappedListIterable":{"ListIterable":["2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"ListIterable.E":"2","Iterable.E":"2"},"WhereIterable":{"Iterable":["1"],"Iterable.E":"1"},"WhereIterator":{"Iterator":["1"]},"ExpandIterable":{"Iterable":["2"],"Iterable.E":"2"},"ExpandIterator":{"Iterator":["2"]},"TakeIterable":{"Iterable":["1"],"Iterable.E":"1"},"EfficientLengthTakeIterable":{"TakeIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"TakeIterator":{"Iterator":["1"]},"SkipIterable":{"Iterable":["1"],"Iterable.E":"1"},"EfficientLengthSkipIterable":{"SkipIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"SkipIterator":{"Iterator":["1"]},"SkipWhileIterable":{"Iterable":["1"],"Iterable.E":"1"},"SkipWhileIterator":{"Iterator":["1"]},"EmptyIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"EmptyIterator":{"Iterator":["1"]},"WhereTypeIterable":{"Iterable":["1"],"Iterable.E":"1"},"WhereTypeIterator":{"Iterator":["1"]},"UnmodifiableListBase":{"ListBase":["1"],"UnmodifiableListMixin":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"ReversedListIterable":{"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListIterable.E":"1","Iterable.E":"1"},"Symbol":{"Symbol0":[]},"ConstantMapView":{"UnmodifiableMapView":["1","2"],"_UnmodifiableMapView_MapView__UnmodifiableMapMixin":["1","2"],"MapView":["1","2"],"_UnmodifiableMapMixin":["1","2"],"Map":["1","2"]},"ConstantMap":{"Map":["1","2"]},"ConstantStringMap":{"ConstantMap":["1","2"],"Map":["1","2"]},"_KeysOrValues":{"Iterable":["1"],"Iterable.E":"1"},"_KeysOrValuesOrElementsIterator":{"Iterator":["1"]},"Instantiation":{"Closure":[],"Function":[]},"Instantiation1":{"Closure":[],"Function":[]},"JSInvocationMirror":{"Invocation":[]},"NullError":{"TypeError":[],"Error":[]},"JsNoSuchMethodError":{"Error":[]},"UnknownJsTypeError":{"Error":[]},"NullThrownFromJavaScriptException":{"Exception":[]},"_StackTrace":{"StackTrace":[]},"Closure":{"Function":[]},"Closure0Args":{"Closure":[],"Function":[]},"Closure2Args":{"Closure":[],"Function":[]},"TearOffClosure":{"Closure":[],"Function":[]},"StaticClosure":{"Closure":[],"Function":[]},"BoundClosure":{"Closure":[],"Function":[]},"_CyclicInitializationError":{"Error":[]},"RuntimeError":{"Error":[]},"_AssertionError":{"Error":[]},"JsLinkedHashMap":{"MapBase":["1","2"],"LinkedHashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"LinkedHashMapKeyIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"LinkedHashMapKeyIterator":{"Iterator":["1"]},"JSSyntaxRegExp":{"RegExp":[],"Pattern":[]},"_MatchImplementation":{"RegExpMatch":[],"Match":[]},"_AllMatchesIterable":{"Iterable":["RegExpMatch"],"Iterable.E":"RegExpMatch"},"_AllMatchesIterator":{"Iterator":["RegExpMatch"]},"StringMatch":{"Match":[]},"_StringAllMatchesIterable":{"Iterable":["Match"],"Iterable.E":"Match"},"_StringAllMatchesIterator":{"Iterator":["Match"]},"NativeByteBuffer":{"JavaScriptObject":[],"ByteBuffer":[],"TrustedGetRuntimeType":[]},"NativeTypedData":{"JavaScriptObject":[]},"NativeByteData":{"JavaScriptObject":[],"ByteData":[],"TrustedGetRuntimeType":[]},"NativeTypedArray":{"JavaScriptIndexingBehavior":["1"],"JavaScriptObject":[]},"NativeTypedArrayOfDouble":{"ListBase":["double"],"JavaScriptIndexingBehavior":["double"],"List":["double"],"JavaScriptObject":[],"EfficientLengthIterable":["double"],"Iterable":["double"],"FixedLengthListMixin":["double"]},"NativeTypedArrayOfInt":{"ListBase":["int"],"JavaScriptIndexingBehavior":["int"],"List":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"]},"NativeFloat32List":{"ListBase":["double"],"Float32List":[],"JavaScriptIndexingBehavior":["double"],"List":["double"],"JavaScriptObject":[],"EfficientLengthIterable":["double"],"Iterable":["double"],"FixedLengthListMixin":["double"],"TrustedGetRuntimeType":[],"ListBase.E":"double"},"NativeFloat64List":{"ListBase":["double"],"Float64List":[],"JavaScriptIndexingBehavior":["double"],"List":["double"],"JavaScriptObject":[],"EfficientLengthIterable":["double"],"Iterable":["double"],"FixedLengthListMixin":["double"],"TrustedGetRuntimeType":[],"ListBase.E":"double"},"NativeInt16List":{"ListBase":["int"],"Int16List":[],"JavaScriptIndexingBehavior":["int"],"List":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int"},"NativeInt32List":{"ListBase":["int"],"Int32List":[],"JavaScriptIndexingBehavior":["int"],"List":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int"},"NativeInt8List":{"ListBase":["int"],"Int8List":[],"JavaScriptIndexingBehavior":["int"],"List":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int"},"NativeUint16List":{"ListBase":["int"],"Uint16List":[],"JavaScriptIndexingBehavior":["int"],"List":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int"},"NativeUint32List":{"ListBase":["int"],"Uint32List":[],"JavaScriptIndexingBehavior":["int"],"List":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int"},"NativeUint8ClampedList":{"ListBase":["int"],"Uint8ClampedList":[],"JavaScriptIndexingBehavior":["int"],"List":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int"},"NativeUint8List":{"ListBase":["int"],"Uint8List":[],"JavaScriptIndexingBehavior":["int"],"List":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int"},"_Error":{"Error":[]},"_TypeError":{"TypeError":[],"Error":[]},"AsyncError":{"Error":[]},"_Future":{"Future":["1"]},"_TimerImpl":{"Timer":[]},"_Completer":{"Completer":["1"]},"_AsyncCompleter":{"_Completer":["1"],"Completer":["1"]},"_SyncCompleter":{"_Completer":["1"],"Completer":["1"]},"_StreamController":{"StreamController":["1"],"StreamSink":["1"],"StreamConsumer":["1"],"_StreamControllerLifecycle":["1"],"_EventDispatch":["1"]},"_SyncStreamController":{"_SyncStreamControllerDispatch":["1"],"_StreamController":["1"],"StreamController":["1"],"StreamSink":["1"],"StreamConsumer":["1"],"_StreamControllerLifecycle":["1"],"_EventDispatch":["1"]},"_ControllerStream":{"_StreamImpl":["1"],"Stream":["1"],"Stream.T":"1"},"_ControllerSubscription":{"_BufferingStreamSubscription":["1"],"StreamSubscription":["1"],"_EventDispatch":["1"],"_BufferingStreamSubscription.T":"1"},"_StreamSinkWrapper":{"StreamSink":["1"],"StreamConsumer":["1"]},"_BufferingStreamSubscription":{"StreamSubscription":["1"],"_EventDispatch":["1"],"_BufferingStreamSubscription.T":"1"},"_StreamImpl":{"Stream":["1"]},"_DelayedData":{"_DelayedEvent":["1"]},"_DelayedError":{"_DelayedEvent":["@"]},"_DelayedDone":{"_DelayedEvent":["@"]},"_DoneStreamSubscription":{"StreamSubscription":["1"]},"_EmptyStream":{"Stream":["1"],"Stream.T":"1"},"_ZoneSpecification":{"ZoneSpecification":[]},"_ZoneDelegate":{"ZoneDelegate":[]},"_Zone":{"Zone":[]},"_CustomZone":{"_Zone":[],"Zone":[]},"_RootZone":{"_Zone":[],"Zone":[]},"_HashMap":{"MapBase":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"_IdentityHashMap":{"_HashMap":["1","2"],"MapBase":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"_HashMapKeyIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"_HashMapKeyIterator":{"Iterator":["1"]},"_LinkedHashSet":{"SetBase":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_LinkedHashSetIterator":{"Iterator":["1"]},"ListBase":{"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"MapBase":{"Map":["1","2"]},"MapView":{"Map":["1","2"]},"UnmodifiableMapView":{"_UnmodifiableMapView_MapView__UnmodifiableMapMixin":["1","2"],"MapView":["1","2"],"_UnmodifiableMapMixin":["1","2"],"Map":["1","2"]},"SetBase":{"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_SetBase":{"SetBase":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_JsonMap":{"MapBase":["String","@"],"Map":["String","@"],"MapBase.K":"String","MapBase.V":"@"},"_JsonMapKeyIterable":{"ListIterable":["String"],"EfficientLengthIterable":["String"],"Iterable":["String"],"ListIterable.E":"String","Iterable.E":"String"},"AsciiCodec":{"Codec":["String","List<int>"]},"_UnicodeSubsetEncoder":{"Converter":["String","List<int>"],"StreamTransformer":["String","List<int>"]},"AsciiEncoder":{"Converter":["String","List<int>"],"StreamTransformer":["String","List<int>"]},"Base64Codec":{"Codec":["List<int>","String"]},"Base64Encoder":{"Converter":["List<int>","String"],"StreamTransformer":["List<int>","String"]},"_FusedCodec":{"Codec":["1","3"]},"Converter":{"StreamTransformer":["1","2"]},"Encoding":{"Codec":["String","List<int>"]},"JsonUnsupportedObjectError":{"Error":[]},"JsonCyclicError":{"Error":[]},"JsonCodec":{"Codec":["Object?","String"]},"JsonEncoder":{"Converter":["Object?","String"],"StreamTransformer":["Object?","String"]},"JsonDecoder":{"Converter":["String","Object?"],"StreamTransformer":["String","Object?"]},"Utf8Codec":{"Codec":["String","List<int>"]},"Utf8Encoder":{"Converter":["String","List<int>"],"StreamTransformer":["String","List<int>"]},"Utf8Decoder":{"Converter":["List<int>","String"],"StreamTransformer":["List<int>","String"]},"double":{"num":[]},"int":{"num":[]},"List":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"RegExpMatch":{"Match":[]},"String":{"Pattern":[]},"AssertionError":{"Error":[]},"TypeError":{"Error":[]},"ArgumentError":{"Error":[]},"RangeError":{"Error":[]},"IndexError":{"Error":[]},"NoSuchMethodError":{"Error":[]},"UnsupportedError":{"Error":[]},"UnimplementedError":{"Error":[]},"StateError":{"Error":[]},"ConcurrentModificationError":{"Error":[]},"OutOfMemoryError":{"Error":[]},"StackOverflowError":{"Error":[]},"_Exception":{"Exception":[]},"FormatException":{"Exception":[]},"_StringStackTrace":{"StackTrace":[]},"StringBuffer":{"StringSink":[]},"_Uri":{"Uri":[]},"_SimpleUri":{"Uri":[]},"_DataUri":{"Uri":[]},"CssRule":{"JavaScriptObject":[]},"File":{"JavaScriptObject":[]},"Gamepad":{"JavaScriptObject":[]},"MimeType":{"JavaScriptObject":[]},"Node":{"JavaScriptObject":[]},"Plugin":{"JavaScriptObject":[]},"SourceBuffer":{"JavaScriptObject":[]},"SpeechGrammar":{"JavaScriptObject":[]},"SpeechRecognitionResult":{"JavaScriptObject":[]},"StyleSheet":{"JavaScriptObject":[]},"TextTrack":{"JavaScriptObject":[]},"TextTrackCue":{"JavaScriptObject":[]},"Touch":{"JavaScriptObject":[]},"HtmlElement":{"Node":[],"JavaScriptObject":[]},"AccessibleNodeList":{"JavaScriptObject":[]},"AnchorElement":{"Node":[],"JavaScriptObject":[]},"AreaElement":{"Node":[],"JavaScriptObject":[]},"Blob":{"JavaScriptObject":[]},"CharacterData":{"Node":[],"JavaScriptObject":[]},"CssPerspective":{"JavaScriptObject":[]},"CssStyleDeclaration":{"JavaScriptObject":[]},"CssStyleValue":{"JavaScriptObject":[]},"CssTransformComponent":{"JavaScriptObject":[]},"CssTransformValue":{"JavaScriptObject":[]},"CssUnparsedValue":{"JavaScriptObject":[]},"DataTransferItemList":{"JavaScriptObject":[]},"DomException":{"JavaScriptObject":[]},"DomRectList":{"ListBase":["Rectangle<num>"],"ImmutableListMixin":["Rectangle<num>"],"List":["Rectangle<num>"],"JavaScriptIndexingBehavior":["Rectangle<num>"],"JavaScriptObject":[],"EfficientLengthIterable":["Rectangle<num>"],"Iterable":["Rectangle<num>"],"ImmutableListMixin.E":"Rectangle<num>","ListBase.E":"Rectangle<num>"},"DomRectReadOnly":{"JavaScriptObject":[],"Rectangle":["num"]},"DomStringList":{"ListBase":["String"],"ImmutableListMixin":["String"],"List":["String"],"JavaScriptIndexingBehavior":["String"],"JavaScriptObject":[],"EfficientLengthIterable":["String"],"Iterable":["String"],"ImmutableListMixin.E":"String","ListBase.E":"String"},"DomTokenList":{"JavaScriptObject":[]},"Element":{"Node":[],"JavaScriptObject":[]},"EventTarget":{"JavaScriptObject":[]},"FileList":{"ListBase":["File"],"ImmutableListMixin":["File"],"List":["File"],"JavaScriptIndexingBehavior":["File"],"JavaScriptObject":[],"EfficientLengthIterable":["File"],"Iterable":["File"],"ImmutableListMixin.E":"File","ListBase.E":"File"},"FileWriter":{"JavaScriptObject":[]},"FormElement":{"Node":[],"JavaScriptObject":[]},"History":{"JavaScriptObject":[]},"HtmlCollection":{"ListBase":["Node"],"ImmutableListMixin":["Node"],"List":["Node"],"JavaScriptIndexingBehavior":["Node"],"JavaScriptObject":[],"EfficientLengthIterable":["Node"],"Iterable":["Node"],"ImmutableListMixin.E":"Node","ListBase.E":"Node"},"Location":{"JavaScriptObject":[]},"MediaList":{"JavaScriptObject":[]},"MidiInputMap":{"JavaScriptObject":[],"MapBase":["String","@"],"Map":["String","@"],"MapBase.K":"String","MapBase.V":"@"},"MidiOutputMap":{"JavaScriptObject":[],"MapBase":["String","@"],"Map":["String","@"],"MapBase.K":"String","MapBase.V":"@"},"MimeTypeArray":{"ListBase":["MimeType"],"ImmutableListMixin":["MimeType"],"List":["MimeType"],"JavaScriptIndexingBehavior":["MimeType"],"JavaScriptObject":[],"EfficientLengthIterable":["MimeType"],"Iterable":["MimeType"],"ImmutableListMixin.E":"MimeType","ListBase.E":"MimeType"},"NodeList":{"ListBase":["Node"],"ImmutableListMixin":["Node"],"List":["Node"],"JavaScriptIndexingBehavior":["Node"],"JavaScriptObject":[],"EfficientLengthIterable":["Node"],"Iterable":["Node"],"ImmutableListMixin.E":"Node","ListBase.E":"Node"},"PluginArray":{"ListBase":["Plugin"],"ImmutableListMixin":["Plugin"],"List":["Plugin"],"JavaScriptIndexingBehavior":["Plugin"],"JavaScriptObject":[],"EfficientLengthIterable":["Plugin"],"Iterable":["Plugin"],"ImmutableListMixin.E":"Plugin","ListBase.E":"Plugin"},"RtcStatsReport":{"JavaScriptObject":[],"MapBase":["String","@"],"Map":["String","@"],"MapBase.K":"String","MapBase.V":"@"},"SelectElement":{"Node":[],"JavaScriptObject":[]},"SourceBufferList":{"ListBase":["SourceBuffer"],"ImmutableListMixin":["SourceBuffer"],"List":["SourceBuffer"],"JavaScriptIndexingBehavior":["SourceBuffer"],"JavaScriptObject":[],"EfficientLengthIterable":["SourceBuffer"],"Iterable":["SourceBuffer"],"ImmutableListMixin.E":"SourceBuffer","ListBase.E":"SourceBuffer"},"SpeechGrammarList":{"ListBase":["SpeechGrammar"],"ImmutableListMixin":["SpeechGrammar"],"List":["SpeechGrammar"],"JavaScriptIndexingBehavior":["SpeechGrammar"],"JavaScriptObject":[],"EfficientLengthIterable":["SpeechGrammar"],"Iterable":["SpeechGrammar"],"ImmutableListMixin.E":"SpeechGrammar","ListBase.E":"SpeechGrammar"},"Storage":{"JavaScriptObject":[],"MapBase":["String","String"],"Map":["String","String"],"MapBase.K":"String","MapBase.V":"String"},"TextTrackCueList":{"ListBase":["TextTrackCue"],"ImmutableListMixin":["TextTrackCue"],"List":["TextTrackCue"],"JavaScriptIndexingBehavior":["TextTrackCue"],"JavaScriptObject":[],"EfficientLengthIterable":["TextTrackCue"],"Iterable":["TextTrackCue"],"ImmutableListMixin.E":"TextTrackCue","ListBase.E":"TextTrackCue"},"TextTrackList":{"ListBase":["TextTrack"],"ImmutableListMixin":["TextTrack"],"List":["TextTrack"],"JavaScriptIndexingBehavior":["TextTrack"],"JavaScriptObject":[],"EfficientLengthIterable":["TextTrack"],"Iterable":["TextTrack"],"ImmutableListMixin.E":"TextTrack","ListBase.E":"TextTrack"},"TimeRanges":{"JavaScriptObject":[]},"TouchList":{"ListBase":["Touch"],"ImmutableListMixin":["Touch"],"List":["Touch"],"JavaScriptIndexingBehavior":["Touch"],"JavaScriptObject":[],"EfficientLengthIterable":["Touch"],"Iterable":["Touch"],"ImmutableListMixin.E":"Touch","ListBase.E":"Touch"},"TrackDefaultList":{"JavaScriptObject":[]},"Url":{"JavaScriptObject":[]},"VideoTrackList":{"JavaScriptObject":[]},"_CssRuleList":{"ListBase":["CssRule"],"ImmutableListMixin":["CssRule"],"List":["CssRule"],"JavaScriptIndexingBehavior":["CssRule"],"JavaScriptObject":[],"EfficientLengthIterable":["CssRule"],"Iterable":["CssRule"],"ImmutableListMixin.E":"CssRule","ListBase.E":"CssRule"},"_DomRect":{"JavaScriptObject":[],"Rectangle":["num"]},"_GamepadList":{"ListBase":["Gamepad?"],"ImmutableListMixin":["Gamepad?"],"List":["Gamepad?"],"JavaScriptIndexingBehavior":["Gamepad?"],"JavaScriptObject":[],"EfficientLengthIterable":["Gamepad?"],"Iterable":["Gamepad?"],"ImmutableListMixin.E":"Gamepad?","ListBase.E":"Gamepad?"},"_NamedNodeMap":{"ListBase":["Node"],"ImmutableListMixin":["Node"],"List":["Node"],"JavaScriptIndexingBehavior":["Node"],"JavaScriptObject":[],"EfficientLengthIterable":["Node"],"Iterable":["Node"],"ImmutableListMixin.E":"Node","ListBase.E":"Node"},"_SpeechRecognitionResultList":{"ListBase":["SpeechRecognitionResult"],"ImmutableListMixin":["SpeechRecognitionResult"],"List":["SpeechRecognitionResult"],"JavaScriptIndexingBehavior":["SpeechRecognitionResult"],"JavaScriptObject":[],"EfficientLengthIterable":["SpeechRecognitionResult"],"Iterable":["SpeechRecognitionResult"],"ImmutableListMixin.E":"SpeechRecognitionResult","ListBase.E":"SpeechRecognitionResult"},"_StyleSheetList":{"ListBase":["StyleSheet"],"ImmutableListMixin":["StyleSheet"],"List":["StyleSheet"],"JavaScriptIndexingBehavior":["StyleSheet"],"JavaScriptObject":[],"EfficientLengthIterable":["StyleSheet"],"Iterable":["StyleSheet"],"ImmutableListMixin.E":"StyleSheet","ListBase.E":"StyleSheet"},"FixedSizeListIterator":{"Iterator":["1"]},"NullRejectionException":{"Exception":[]},"Length":{"JavaScriptObject":[]},"Number":{"JavaScriptObject":[]},"Transform":{"JavaScriptObject":[]},"LengthList":{"ListBase":["Length"],"ImmutableListMixin":["Length"],"List":["Length"],"JavaScriptObject":[],"EfficientLengthIterable":["Length"],"Iterable":["Length"],"ImmutableListMixin.E":"Length","ListBase.E":"Length"},"NumberList":{"ListBase":["Number"],"ImmutableListMixin":["Number"],"List":["Number"],"JavaScriptObject":[],"EfficientLengthIterable":["Number"],"Iterable":["Number"],"ImmutableListMixin.E":"Number","ListBase.E":"Number"},"PointList":{"JavaScriptObject":[]},"StringList":{"ListBase":["String"],"ImmutableListMixin":["String"],"List":["String"],"JavaScriptObject":[],"EfficientLengthIterable":["String"],"Iterable":["String"],"ImmutableListMixin.E":"String","ListBase.E":"String"},"TransformList":{"ListBase":["Transform"],"ImmutableListMixin":["Transform"],"List":["Transform"],"JavaScriptObject":[],"EfficientLengthIterable":["Transform"],"Iterable":["Transform"],"ImmutableListMixin.E":"Transform","ListBase.E":"Transform"},"AudioBuffer":{"JavaScriptObject":[]},"AudioParamMap":{"JavaScriptObject":[],"MapBase":["String","@"],"Map":["String","@"],"MapBase.K":"String","MapBase.V":"@"},"AudioTrackList":{"JavaScriptObject":[]},"BaseAudioContext":{"JavaScriptObject":[]},"OfflineAudioContext":{"JavaScriptObject":[]},"NullStreamSink":{"StreamSink":["1"],"StreamConsumer":["1"]},"PathException":{"Exception":[]},"PosixStyle":{"InternalStyle":[]},"UrlStyle":{"InternalStyle":[]},"WindowsStyle":{"InternalStyle":[]},"Chain":{"StackTrace":[]},"LazyTrace":{"Trace":[],"StackTrace":[]},"Trace":{"StackTrace":[]},"UnparsedFrame":{"Frame":[]},"GuaranteeChannel":{"StreamChannelMixin":["1"],"StreamChannel":["1"]},"_GuaranteeSink":{"StreamSink":["1"],"StreamConsumer":["1"]},"_MultiChannel":{"StreamChannelMixin":["1"],"MultiChannel":["1"],"StreamChannel":["1"]},"VirtualChannel":{"StreamChannelMixin":["1"],"MultiChannel":["1"],"StreamChannel":["1"]},"StreamChannelMixin":{"StreamChannel":["1"]},"Int8List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint8List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint8ClampedList":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Int16List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint16List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Int32List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint32List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Float32List":{"List":["double"],"EfficientLengthIterable":["double"],"Iterable":["double"]},"Float64List":{"List":["double"],"EfficientLengthIterable":["double"],"Iterable":["double"]}}'));
+ A._Universe_addErasedTypes(init.typeUniverse, JSON.parse('{"UnmodifiableListBase":1,"__CastListBase__CastIterableBase_ListMixin":2,"NativeTypedArray":1,"_DelayedEvent":1,"_SetBase":1}'));
var string$ = {
- ______: "===== asynchronous gap ===========================\n",
+ x27_has_: "' has been assigned during initialization.",
+ x3d_____: "===== asynchronous gap ===========================\n",
Cannotff: "Cannot extract a file path from a URI with a fragment component",
Cannotfq: "Cannot extract a file path from a URI with a query component",
Cannotn: "Cannot extract a non-Windows file path from a file URI with an authority",
@@ -16698,6 +17692,8 @@
var findType = A.findType;
return {
AsyncError: findType("AsyncError"),
+ ByteBuffer: findType("ByteBuffer"),
+ ByteData: findType("ByteData"),
ConstantMapView_Symbol_dynamic: findType("ConstantMapView<Symbol0,@>"),
CssRule: findType("CssRule"),
Duration: findType("Duration"),
@@ -16705,22 +17701,24 @@
Error: findType("Error"),
Exception: findType("Exception"),
File: findType("File"),
+ Float32List: findType("Float32List"),
+ Float64List: findType("Float64List"),
Frame: findType("Frame"),
Frame_Function_Frame: findType("Frame(Frame)"),
Frame_Function_String: findType("Frame(String)"),
Function: findType("Function"),
Future_dynamic: findType("Future<@>"),
- Future_void: findType("Future<~>"),
- InternalStyle: findType("InternalStyle"),
+ Int16List: findType("Int16List"),
+ Int32List: findType("Int32List"),
+ Int8List: findType("Int8List"),
Invocation: findType("Invocation"),
Iterable_String: findType("Iterable<String>"),
Iterable_dynamic: findType("Iterable<@>"),
+ Iterable_nullable_Object: findType("Iterable<Object?>"),
JSArray_Frame: findType("JSArray<Frame>"),
JSArray_JavaScriptObject: findType("JSArray<JavaScriptObject>"),
JSArray_Object: findType("JSArray<Object>"),
- JSArray_StreamSubscription_void: findType("JSArray<StreamSubscription<~>>"),
JSArray_String: findType("JSArray<String>"),
- JSArray_Subscription: findType("JSArray<Subscription>"),
JSArray_Trace: findType("JSArray<Trace>"),
JSArray_Uint8List: findType("JSArray<Uint8List>"),
JSArray_dynamic: findType("JSArray<@>"),
@@ -16737,6 +17735,7 @@
List_int: findType("List<int>"),
Map_String_String: findType("Map<String,String>"),
Map_dynamic_dynamic: findType("Map<@,@>"),
+ Map_of_nullable_Object_and_nullable_Object: findType("Map<Object?,Object?>"),
MappedIterable_String_Frame: findType("MappedIterable<String,Frame>"),
MappedListIterable_Frame_Frame: findType("MappedListIterable<Frame,Frame>"),
MappedListIterable_String_Trace: findType("MappedListIterable<String,Trace>"),
@@ -16747,8 +17746,8 @@
Null: findType("Null"),
Number: findType("Number"),
Object: findType("Object"),
- Pattern: findType("Pattern"),
Plugin: findType("Plugin"),
+ Record: findType("Record"),
Rectangle_num: findType("Rectangle<num>"),
RegExpMatch: findType("RegExpMatch"),
SourceBuffer: findType("SourceBuffer"),
@@ -16765,7 +17764,11 @@
Trace: findType("Trace"),
Trace_Function_String: findType("Trace(String)"),
Transform: findType("Transform"),
+ TrustedGetRuntimeType: findType("TrustedGetRuntimeType"),
TypeError: findType("TypeError"),
+ Uint16List: findType("Uint16List"),
+ Uint32List: findType("Uint32List"),
+ Uint8ClampedList: findType("Uint8ClampedList"),
Uint8List: findType("Uint8List"),
UnknownJavaScriptObject: findType("UnknownJavaScriptObject"),
UnmodifiableMapView_String_String: findType("UnmodifiableMapView<String,String>"),
@@ -16777,7 +17780,7 @@
_Future_dynamic: findType("_Future<@>"),
_Future_int: findType("_Future<int>"),
_Future_void: findType("_Future<~>"),
- _IdentityHashMap_dynamic_dynamic: findType("_IdentityHashMap<@,@>"),
+ _IdentityHashMap_of_nullable_Object_and_nullable_Object: findType("_IdentityHashMap<Object?,Object?>"),
_StreamControllerAddStreamState_nullable_Object: findType("_StreamControllerAddStreamState<Object?>"),
_SyncCompleter_dynamic: findType("_SyncCompleter<@>"),
_ZoneFunction_of_void_Function_Zone_ZoneDelegate_Zone_Object_StackTrace: findType("_ZoneFunction<~(Zone,ZoneDelegate,Zone,Object,StackTrace)>"),
@@ -16807,8 +17810,6 @@
nullable__DelayedEvent_dynamic: findType("_DelayedEvent<@>?"),
nullable__FutureListener_dynamic_dynamic: findType("_FutureListener<@,@>?"),
nullable__LinkedHashSetCell: findType("_LinkedHashSetCell?"),
- nullable_nullable_Object_Function_2_nullable_Object_and_nullable_Object: findType("Object?(Object?,Object?)?"),
- nullable_nullable_Object_Function_dynamic: findType("Object?(@)?"),
nullable_void_Function: findType("~()?"),
num: findType("num"),
void: findType("~"),
@@ -16971,27 +17972,38 @@
B.Duration_0 = new A.Duration(0);
B.JsonDecoder_null = new A.JsonDecoder(null);
B.JsonEncoder_null = new A.JsonEncoder(null);
- B.List_2Vk = A._setArrayType(makeConstList([0, 0, 32776, 33792, 1, 10240, 0, 0]), type$.JSArray_int);
- B.List_CVk = A._setArrayType(makeConstList([0, 0, 65490, 45055, 65535, 34815, 65534, 18431]), type$.JSArray_int);
- B.List_JYB = A._setArrayType(makeConstList([0, 0, 26624, 1023, 65534, 2047, 65534, 2047]), type$.JSArray_int);
+ B.List_M1A = A._setArrayType(makeConstList([0, 0, 24576, 1023, 65534, 34815, 65534, 18431]), type$.JSArray_int);
+ B.List_MMm = A._setArrayType(makeConstList([0, 0, 26624, 1023, 65534, 2047, 65534, 2047]), type$.JSArray_int);
+ B.List_OL3 = A._setArrayType(makeConstList([0, 0, 32722, 12287, 65534, 34815, 65534, 18431]), type$.JSArray_int);
+ B.List_XRg0 = A._setArrayType(makeConstList([0, 0, 32722, 12287, 65535, 34815, 65534, 18431]), type$.JSArray_int);
+ B.List_XRg = A._setArrayType(makeConstList([0, 0, 65490, 12287, 65535, 34815, 65534, 18431]), type$.JSArray_int);
+ B.List_YmH = A._setArrayType(makeConstList([0, 0, 32776, 33792, 1, 10240, 0, 0]), type$.JSArray_int);
+ B.List_ejq = A._setArrayType(makeConstList([0, 0, 32754, 11263, 65534, 34815, 65534, 18431]), type$.JSArray_int);
B.List_empty = A._setArrayType(makeConstList([]), type$.JSArray_String);
B.List_empty0 = A._setArrayType(makeConstList([]), type$.JSArray_dynamic);
- B.List_gRj = A._setArrayType(makeConstList([0, 0, 32722, 12287, 65534, 34815, 65534, 18431]), type$.JSArray_int);
- B.List_nxB = A._setArrayType(makeConstList([0, 0, 24576, 1023, 65534, 34815, 65534, 18431]), type$.JSArray_int);
- B.List_qFt = A._setArrayType(makeConstList([0, 0, 27858, 1023, 65534, 51199, 65535, 32767]), type$.JSArray_int);
- B.List_qNA = A._setArrayType(makeConstList([0, 0, 32754, 11263, 65534, 34815, 65534, 18431]), type$.JSArray_int);
- B.List_qg40 = A._setArrayType(makeConstList([0, 0, 32722, 12287, 65535, 34815, 65534, 18431]), type$.JSArray_int);
- B.List_qg4 = A._setArrayType(makeConstList([0, 0, 65490, 12287, 65535, 34815, 65534, 18431]), type$.JSArray_int);
- B.Map_empty = new A.ConstantStringMap(0, {}, B.List_empty, A.findType("ConstantStringMap<String,String>"));
- B.List_empty1 = A._setArrayType(makeConstList([]), A.findType("JSArray<Symbol0>"));
- B.Map_empty0 = new A.ConstantStringMap(0, {}, B.List_empty1, A.findType("ConstantStringMap<Symbol0,@>"));
+ B.List_oFp = A._setArrayType(makeConstList([0, 0, 65490, 45055, 65535, 34815, 65534, 18431]), type$.JSArray_int);
+ B.List_yzX = A._setArrayType(makeConstList([0, 0, 27858, 1023, 65534, 51199, 65535, 32767]), type$.JSArray_int);
+ B.Object_empty = {};
+ B.Map_empty = new A.ConstantStringMap(B.Object_empty, [], A.findType("ConstantStringMap<String,String>"));
+ B.Map_empty0 = new A.ConstantStringMap(B.Object_empty, [], A.findType("ConstantStringMap<Symbol0,@>"));
B.Symbol_call = new A.Symbol("call");
+ B.Type_ByteBuffer_RkP = A.typeLiteral("ByteBuffer");
+ B.Type_ByteData_zNC = A.typeLiteral("ByteData");
+ B.Type_Float32List_LB7 = A.typeLiteral("Float32List");
+ B.Type_Float64List_LB7 = A.typeLiteral("Float64List");
+ B.Type_Int16List_uXf = A.typeLiteral("Int16List");
+ B.Type_Int32List_O50 = A.typeLiteral("Int32List");
+ B.Type_Int8List_ekJ = A.typeLiteral("Int8List");
B.Type_Object_xQ6 = A.typeLiteral("Object");
+ B.Type_Uint16List_2bx = A.typeLiteral("Uint16List");
+ B.Type_Uint32List_2bx = A.typeLiteral("Uint32List");
+ B.Type_Uint8ClampedList_Jik = A.typeLiteral("Uint8ClampedList");
+ B.Type_Uint8List_WLA = A.typeLiteral("Uint8List");
B.Utf8Decoder_false = new A.Utf8Decoder(false);
B._StringStackTrace_3uE = new A._StringStackTrace("");
B._ZoneFunction_3bB = new A._ZoneFunction(B.C__RootZone, A.async___rootCreatePeriodicTimer$closure(), A.findType("_ZoneFunction<Timer(Zone,ZoneDelegate,Zone,Duration,~(Timer))>"));
- B._ZoneFunction_7G2 = new A._ZoneFunction(B.C__RootZone, A.async___rootRegisterBinaryCallback$closure(), A.findType("_ZoneFunction<0^(1^,2^)(Zone,ZoneDelegate,Zone,0^(1^,2^))<Object?Object?Object?>>"));
- B._ZoneFunction_Eeh = new A._ZoneFunction(B.C__RootZone, A.async___rootRegisterUnaryCallback$closure(), A.findType("_ZoneFunction<0^(1^)(Zone,ZoneDelegate,Zone,0^(1^))<Object?Object?>>"));
+ B._ZoneFunction_7G2 = new A._ZoneFunction(B.C__RootZone, A.async___rootRegisterBinaryCallback$closure(), A.findType("_ZoneFunction<0^(1^,2^)(Zone,ZoneDelegate,Zone,0^(1^,2^))<Object?,Object?,Object?>>"));
+ B._ZoneFunction_Eeh = new A._ZoneFunction(B.C__RootZone, A.async___rootRegisterUnaryCallback$closure(), A.findType("_ZoneFunction<0^(1^)(Zone,ZoneDelegate,Zone,0^(1^))<Object?,Object?>>"));
B._ZoneFunction_NMc = new A._ZoneFunction(B.C__RootZone, A.async___rootHandleUncaughtError$closure(), type$._ZoneFunction_of_void_Function_Zone_ZoneDelegate_Zone_Object_StackTrace);
B._ZoneFunction__RootZone__rootCreateTimer = new A._ZoneFunction(B.C__RootZone, A.async___rootCreateTimer$closure(), A.findType("_ZoneFunction<Timer(Zone,ZoneDelegate,Zone,Duration,~())>"));
B._ZoneFunction__RootZone__rootErrorCallback = new A._ZoneFunction(B.C__RootZone, A.async___rootErrorCallback$closure(), A.findType("_ZoneFunction<AsyncError?(Zone,ZoneDelegate,Zone,Object,StackTrace?)>"));
@@ -16999,12 +18011,13 @@
B._ZoneFunction__RootZone__rootPrint = new A._ZoneFunction(B.C__RootZone, A.async___rootPrint$closure(), A.findType("_ZoneFunction<~(Zone,ZoneDelegate,Zone,String)>"));
B._ZoneFunction__RootZone__rootRegisterCallback = new A._ZoneFunction(B.C__RootZone, A.async___rootRegisterCallback$closure(), A.findType("_ZoneFunction<0^()(Zone,ZoneDelegate,Zone,0^())<Object?>>"));
B._ZoneFunction__RootZone__rootRun = new A._ZoneFunction(B.C__RootZone, A.async___rootRun$closure(), A.findType("_ZoneFunction<0^(Zone,ZoneDelegate,Zone,0^())<Object?>>"));
- B._ZoneFunction__RootZone__rootRunBinary = new A._ZoneFunction(B.C__RootZone, A.async___rootRunBinary$closure(), A.findType("_ZoneFunction<0^(Zone,ZoneDelegate,Zone,0^(1^,2^),1^,2^)<Object?Object?Object?>>"));
- B._ZoneFunction__RootZone__rootRunUnary = new A._ZoneFunction(B.C__RootZone, A.async___rootRunUnary$closure(), A.findType("_ZoneFunction<0^(Zone,ZoneDelegate,Zone,0^(1^),1^)<Object?Object?>>"));
+ B._ZoneFunction__RootZone__rootRunBinary = new A._ZoneFunction(B.C__RootZone, A.async___rootRunBinary$closure(), A.findType("_ZoneFunction<0^(Zone,ZoneDelegate,Zone,0^(1^,2^),1^,2^)<Object?,Object?,Object?>>"));
+ B._ZoneFunction__RootZone__rootRunUnary = new A._ZoneFunction(B.C__RootZone, A.async___rootRunUnary$closure(), A.findType("_ZoneFunction<0^(Zone,ZoneDelegate,Zone,0^(1^),1^)<Object?,Object?>>"));
B._ZoneFunction__RootZone__rootScheduleMicrotask = new A._ZoneFunction(B.C__RootZone, A.async___rootScheduleMicrotask$closure(), A.findType("_ZoneFunction<~(Zone,ZoneDelegate,Zone,~())>"));
})();
(function staticFields() {
$._JS_INTEROP_INTERCEPTOR_TAG = null;
+ $.toStringVisiting = A._setArrayType([], type$.JSArray_Object);
$.printToZone = null;
$.Primitives__identityHashCodeProperty = null;
$.BoundClosure__receiverFieldNameCache = null;
@@ -17021,12 +18034,13 @@
$._isInCallbackLoop = false;
$.Zone__current = B.C__RootZone;
$._RootZone__rootDelegate = null;
- $._toStringVisiting = A._setArrayType([], type$.JSArray_Object);
+ $.Uri__cachedBaseString = "";
+ $.Uri__cachedBaseUri = null;
$._currentUriBase = null;
$._current = null;
$._iframes = A.LinkedHashMap_LinkedHashMap$_empty(type$.int, type$.JavaScriptObject);
- $._subscriptions = A.LinkedHashMap_LinkedHashMap$_empty(type$.int, A.findType("List<StreamSubscription<~>>"));
- $._domSubscriptions = A.LinkedHashMap_LinkedHashMap$_empty(type$.int, A.findType("List<Subscription>"));
+ $._subscriptions = A.LinkedHashMap_LinkedHashMap$_empty(type$.int, A.findType("StreamSubscription<~>"));
+ $._domSubscriptions = A.LinkedHashMap_LinkedHashMap$_empty(type$.int, A.findType("Subscription"));
})();
(function lazyInitializers() {
var _lazyFinal = hunkHelpers.lazyFinal;
@@ -17090,7 +18104,7 @@
_lazyFinal($, "_hashSeed", "$get$_hashSeed", () => A.objectHashCode(B.Type_Object_xQ6));
_lazyFinal($, "_scannerTables", "$get$_scannerTables", () => A._createTables());
_lazyFinal($, "windows", "$get$windows", () => A.Context_Context($.$get$Style_windows()));
- _lazyFinal($, "context", "$get$context", () => new A.Context(type$.InternalStyle._as($.$get$Style_platform()), null));
+ _lazyFinal($, "context", "$get$context", () => new A.Context($.$get$Style_platform(), null));
_lazyFinal($, "Style_posix", "$get$Style_posix", () => new A.PosixStyle(A.RegExp_RegExp("/", false), A.RegExp_RegExp("[^/]$", false), A.RegExp_RegExp("^/", false)));
_lazyFinal($, "Style_windows", "$get$Style_windows", () => new A.WindowsStyle(A.RegExp_RegExp("[/\\\\]", false), A.RegExp_RegExp("[^/\\\\]$", false), A.RegExp_RegExp("^(\\\\\\\\[^\\\\]+\\\\[^\\\\/]+|[a-zA-Z]:[/\\\\])", false), A.RegExp_RegExp("^[/\\\\](?![/\\\\])", false)));
_lazyFinal($, "Style_url", "$get$Style_url", () => new A.UrlStyle(A.RegExp_RegExp("/", false), A.RegExp_RegExp("(^[a-zA-Z][-+.a-zA-Z\\d]*://|[^/])$", false), A.RegExp_RegExp("[a-zA-Z][-+.a-zA-Z\\d]*://[^/]*", false), A.RegExp_RegExp("^/", false)));
@@ -17113,7 +18127,7 @@
_lazyFinal($, "_firefoxSafariTrace", "$get$_firefoxSafariTrace", () => A.RegExp_RegExp("^(([.0-9A-Za-z_$/<]|\\(.*\\))*@)?[^\\s]*:\\d*$", true));
_lazyFinal($, "_friendlyTrace", "$get$_friendlyTrace", () => A.RegExp_RegExp("^[^\\s<][^\\s]*( \\d+(:\\d+)?)?[ \\t]+[^\\s]+$", true));
_lazyFinal($, "vmChainGap", "$get$vmChainGap", () => A.RegExp_RegExp("^<asynchronous suspension>\\n?$", true));
- _lazyFinal($, "_currentUrl", "$get$_currentUrl", () => A.Uri_parse(A.getProperty(A.WindowExtension_get_location(self.window), "href", type$.String)));
+ _lazyFinal($, "_currentUrl", "$get$_currentUrl", () => A.Uri_parse(A.getProperty(A.getProperty(self.window, "location", type$.JavaScriptObject), "href", type$.String)));
})();
(function nativeSupport() {
!function() {
@@ -17138,8 +18152,8 @@
}
init.dispatchPropertyName = init.getIsolateTag("dispatch_record");
}();
- hunkHelpers.setOrUpdateInterceptorsByTag({ArrayBuffer: J.Interceptor, WebGL: J.Interceptor, AbortPaymentEvent: J.JavaScriptObject, AnimationEffectReadOnly: J.JavaScriptObject, AnimationEffectTiming: J.JavaScriptObject, AnimationEffectTimingReadOnly: J.JavaScriptObject, AnimationEvent: J.JavaScriptObject, AnimationPlaybackEvent: J.JavaScriptObject, AnimationTimeline: J.JavaScriptObject, AnimationWorkletGlobalScope: J.JavaScriptObject, ApplicationCacheErrorEvent: J.JavaScriptObject, AuthenticatorAssertionResponse: J.JavaScriptObject, AuthenticatorAttestationResponse: J.JavaScriptObject, AuthenticatorResponse: J.JavaScriptObject, BackgroundFetchClickEvent: J.JavaScriptObject, BackgroundFetchEvent: J.JavaScriptObject, BackgroundFetchFailEvent: J.JavaScriptObject, BackgroundFetchFetch: J.JavaScriptObject, BackgroundFetchManager: J.JavaScriptObject, BackgroundFetchSettledFetch: J.JavaScriptObject, BackgroundFetchedEvent: J.JavaScriptObject, BarProp: J.JavaScriptObject, BarcodeDetector: J.JavaScriptObject, BeforeInstallPromptEvent: J.JavaScriptObject, BeforeUnloadEvent: J.JavaScriptObject, BlobEvent: J.JavaScriptObject, BluetoothRemoteGATTDescriptor: J.JavaScriptObject, Body: J.JavaScriptObject, BudgetState: J.JavaScriptObject, CacheStorage: J.JavaScriptObject, CanMakePaymentEvent: J.JavaScriptObject, CanvasGradient: J.JavaScriptObject, CanvasPattern: J.JavaScriptObject, CanvasRenderingContext2D: J.JavaScriptObject, Client: J.JavaScriptObject, Clients: J.JavaScriptObject, ClipboardEvent: J.JavaScriptObject, CloseEvent: J.JavaScriptObject, CompositionEvent: J.JavaScriptObject, CookieStore: J.JavaScriptObject, Coordinates: J.JavaScriptObject, Credential: J.JavaScriptObject, CredentialUserData: J.JavaScriptObject, CredentialsContainer: J.JavaScriptObject, Crypto: J.JavaScriptObject, CryptoKey: J.JavaScriptObject, CSS: J.JavaScriptObject, CSSVariableReferenceValue: J.JavaScriptObject, CustomElementRegistry: J.JavaScriptObject, CustomEvent: J.JavaScriptObject, DataTransfer: J.JavaScriptObject, DataTransferItem: J.JavaScriptObject, DeprecatedStorageInfo: J.JavaScriptObject, DeprecatedStorageQuota: J.JavaScriptObject, DeprecationReport: J.JavaScriptObject, DetectedBarcode: J.JavaScriptObject, DetectedFace: J.JavaScriptObject, DetectedText: J.JavaScriptObject, DeviceAcceleration: J.JavaScriptObject, DeviceMotionEvent: J.JavaScriptObject, DeviceOrientationEvent: J.JavaScriptObject, DeviceRotationRate: J.JavaScriptObject, DirectoryEntry: J.JavaScriptObject, webkitFileSystemDirectoryEntry: J.JavaScriptObject, FileSystemDirectoryEntry: J.JavaScriptObject, DirectoryReader: J.JavaScriptObject, WebKitDirectoryReader: J.JavaScriptObject, webkitFileSystemDirectoryReader: J.JavaScriptObject, FileSystemDirectoryReader: J.JavaScriptObject, DocumentOrShadowRoot: J.JavaScriptObject, DocumentTimeline: J.JavaScriptObject, DOMError: J.JavaScriptObject, DOMImplementation: J.JavaScriptObject, Iterator: J.JavaScriptObject, DOMMatrix: J.JavaScriptObject, DOMMatrixReadOnly: J.JavaScriptObject, DOMParser: J.JavaScriptObject, DOMPoint: J.JavaScriptObject, DOMPointReadOnly: J.JavaScriptObject, DOMQuad: J.JavaScriptObject, DOMStringMap: J.JavaScriptObject, Entry: J.JavaScriptObject, webkitFileSystemEntry: J.JavaScriptObject, FileSystemEntry: J.JavaScriptObject, ErrorEvent: J.JavaScriptObject, Event: J.JavaScriptObject, InputEvent: J.JavaScriptObject, SubmitEvent: J.JavaScriptObject, ExtendableEvent: J.JavaScriptObject, ExtendableMessageEvent: J.JavaScriptObject, External: J.JavaScriptObject, FaceDetector: J.JavaScriptObject, FederatedCredential: J.JavaScriptObject, FetchEvent: J.JavaScriptObject, FileEntry: J.JavaScriptObject, webkitFileSystemFileEntry: J.JavaScriptObject, FileSystemFileEntry: J.JavaScriptObject, DOMFileSystem: J.JavaScriptObject, WebKitFileSystem: J.JavaScriptObject, webkitFileSystem: J.JavaScriptObject, FileSystem: J.JavaScriptObject, FocusEvent: J.JavaScriptObject, FontFace: J.JavaScriptObject, FontFaceSetLoadEvent: J.JavaScriptObject, FontFaceSource: J.JavaScriptObject, ForeignFetchEvent: J.JavaScriptObject, FormData: J.JavaScriptObject, GamepadButton: J.JavaScriptObject, GamepadEvent: J.JavaScriptObject, GamepadPose: J.JavaScriptObject, Geolocation: J.JavaScriptObject, Position: J.JavaScriptObject, GeolocationPosition: J.JavaScriptObject, HashChangeEvent: J.JavaScriptObject, Headers: J.JavaScriptObject, HTMLHyperlinkElementUtils: J.JavaScriptObject, IdleDeadline: J.JavaScriptObject, ImageBitmap: J.JavaScriptObject, ImageBitmapRenderingContext: J.JavaScriptObject, ImageCapture: J.JavaScriptObject, ImageData: J.JavaScriptObject, InputDeviceCapabilities: J.JavaScriptObject, InstallEvent: J.JavaScriptObject, IntersectionObserver: J.JavaScriptObject, IntersectionObserverEntry: J.JavaScriptObject, InterventionReport: J.JavaScriptObject, KeyboardEvent: J.JavaScriptObject, KeyframeEffect: J.JavaScriptObject, KeyframeEffectReadOnly: J.JavaScriptObject, MediaCapabilities: J.JavaScriptObject, MediaCapabilitiesInfo: J.JavaScriptObject, MediaDeviceInfo: J.JavaScriptObject, MediaEncryptedEvent: J.JavaScriptObject, MediaError: J.JavaScriptObject, MediaKeyMessageEvent: J.JavaScriptObject, MediaKeyStatusMap: J.JavaScriptObject, MediaKeySystemAccess: J.JavaScriptObject, MediaKeys: J.JavaScriptObject, MediaKeysPolicy: J.JavaScriptObject, MediaMetadata: J.JavaScriptObject, MediaQueryListEvent: J.JavaScriptObject, MediaSession: J.JavaScriptObject, MediaSettingsRange: J.JavaScriptObject, MediaStreamEvent: J.JavaScriptObject, MediaStreamTrackEvent: J.JavaScriptObject, MemoryInfo: J.JavaScriptObject, MessageChannel: J.JavaScriptObject, MessageEvent: J.JavaScriptObject, Metadata: J.JavaScriptObject, MIDIConnectionEvent: J.JavaScriptObject, MIDIMessageEvent: J.JavaScriptObject, MouseEvent: J.JavaScriptObject, DragEvent: J.JavaScriptObject, MutationEvent: J.JavaScriptObject, MutationObserver: J.JavaScriptObject, WebKitMutationObserver: J.JavaScriptObject, MutationRecord: J.JavaScriptObject, NavigationPreloadManager: J.JavaScriptObject, Navigator: J.JavaScriptObject, NavigatorAutomationInformation: J.JavaScriptObject, NavigatorConcurrentHardware: J.JavaScriptObject, NavigatorCookies: J.JavaScriptObject, NavigatorUserMediaError: J.JavaScriptObject, NodeFilter: J.JavaScriptObject, NodeIterator: J.JavaScriptObject, NonDocumentTypeChildNode: J.JavaScriptObject, NonElementParentNode: J.JavaScriptObject, NoncedElement: J.JavaScriptObject, NotificationEvent: J.JavaScriptObject, OffscreenCanvasRenderingContext2D: J.JavaScriptObject, OverconstrainedError: J.JavaScriptObject, PageTransitionEvent: J.JavaScriptObject, PaintRenderingContext2D: J.JavaScriptObject, PaintSize: J.JavaScriptObject, PaintWorkletGlobalScope: J.JavaScriptObject, PasswordCredential: J.JavaScriptObject, Path2D: J.JavaScriptObject, PaymentAddress: J.JavaScriptObject, PaymentInstruments: J.JavaScriptObject, PaymentManager: J.JavaScriptObject, PaymentRequestEvent: J.JavaScriptObject, PaymentRequestUpdateEvent: J.JavaScriptObject, PaymentResponse: J.JavaScriptObject, PerformanceEntry: J.JavaScriptObject, PerformanceLongTaskTiming: J.JavaScriptObject, PerformanceMark: J.JavaScriptObject, PerformanceMeasure: J.JavaScriptObject, PerformanceNavigation: J.JavaScriptObject, PerformanceNavigationTiming: J.JavaScriptObject, PerformanceObserver: J.JavaScriptObject, PerformanceObserverEntryList: J.JavaScriptObject, PerformancePaintTiming: J.JavaScriptObject, PerformanceResourceTiming: J.JavaScriptObject, PerformanceServerTiming: J.JavaScriptObject, PerformanceTiming: J.JavaScriptObject, Permissions: J.JavaScriptObject, PhotoCapabilities: J.JavaScriptObject, PointerEvent: J.JavaScriptObject, PopStateEvent: J.JavaScriptObject, PositionError: J.JavaScriptObject, GeolocationPositionError: J.JavaScriptObject, Presentation: J.JavaScriptObject, PresentationConnectionAvailableEvent: J.JavaScriptObject, PresentationConnectionCloseEvent: J.JavaScriptObject, PresentationReceiver: J.JavaScriptObject, ProgressEvent: J.JavaScriptObject, PromiseRejectionEvent: J.JavaScriptObject, PublicKeyCredential: J.JavaScriptObject, PushEvent: J.JavaScriptObject, PushManager: J.JavaScriptObject, PushMessageData: J.JavaScriptObject, PushSubscription: J.JavaScriptObject, PushSubscriptionOptions: J.JavaScriptObject, Range: J.JavaScriptObject, RelatedApplication: J.JavaScriptObject, ReportBody: J.JavaScriptObject, ReportingObserver: J.JavaScriptObject, ResizeObserver: J.JavaScriptObject, ResizeObserverEntry: J.JavaScriptObject, RTCCertificate: J.JavaScriptObject, RTCDataChannelEvent: J.JavaScriptObject, RTCDTMFToneChangeEvent: J.JavaScriptObject, RTCIceCandidate: J.JavaScriptObject, mozRTCIceCandidate: J.JavaScriptObject, RTCLegacyStatsReport: J.JavaScriptObject, RTCPeerConnectionIceEvent: J.JavaScriptObject, RTCRtpContributingSource: J.JavaScriptObject, RTCRtpReceiver: J.JavaScriptObject, RTCRtpSender: J.JavaScriptObject, RTCSessionDescription: J.JavaScriptObject, mozRTCSessionDescription: J.JavaScriptObject, RTCStatsResponse: J.JavaScriptObject, RTCTrackEvent: J.JavaScriptObject, Screen: J.JavaScriptObject, ScrollState: J.JavaScriptObject, ScrollTimeline: J.JavaScriptObject, SecurityPolicyViolationEvent: J.JavaScriptObject, Selection: J.JavaScriptObject, SensorErrorEvent: J.JavaScriptObject, SharedArrayBuffer: J.JavaScriptObject, SpeechRecognitionAlternative: J.JavaScriptObject, SpeechRecognitionError: J.JavaScriptObject, SpeechRecognitionEvent: J.JavaScriptObject, SpeechSynthesisEvent: J.JavaScriptObject, SpeechSynthesisVoice: J.JavaScriptObject, StaticRange: J.JavaScriptObject, StorageEvent: J.JavaScriptObject, StorageManager: J.JavaScriptObject, StyleMedia: J.JavaScriptObject, StylePropertyMap: J.JavaScriptObject, StylePropertyMapReadonly: J.JavaScriptObject, SyncEvent: J.JavaScriptObject, SyncManager: J.JavaScriptObject, TaskAttributionTiming: J.JavaScriptObject, TextDetector: J.JavaScriptObject, TextEvent: J.JavaScriptObject, TextMetrics: J.JavaScriptObject, TouchEvent: J.JavaScriptObject, TrackDefault: J.JavaScriptObject, TrackEvent: J.JavaScriptObject, TransitionEvent: J.JavaScriptObject, WebKitTransitionEvent: J.JavaScriptObject, TreeWalker: J.JavaScriptObject, TrustedHTML: J.JavaScriptObject, TrustedScriptURL: J.JavaScriptObject, TrustedURL: J.JavaScriptObject, UIEvent: J.JavaScriptObject, UnderlyingSourceBase: J.JavaScriptObject, URLSearchParams: J.JavaScriptObject, VRCoordinateSystem: J.JavaScriptObject, VRDeviceEvent: J.JavaScriptObject, VRDisplayCapabilities: J.JavaScriptObject, VRDisplayEvent: J.JavaScriptObject, VREyeParameters: J.JavaScriptObject, VRFrameData: J.JavaScriptObject, VRFrameOfReference: J.JavaScriptObject, VRPose: J.JavaScriptObject, VRSessionEvent: J.JavaScriptObject, VRStageBounds: J.JavaScriptObject, VRStageBoundsPoint: J.JavaScriptObject, VRStageParameters: J.JavaScriptObject, ValidityState: J.JavaScriptObject, VideoPlaybackQuality: J.JavaScriptObject, VideoTrack: J.JavaScriptObject, VTTRegion: J.JavaScriptObject, WheelEvent: J.JavaScriptObject, WindowClient: J.JavaScriptObject, WorkletAnimation: J.JavaScriptObject, WorkletGlobalScope: J.JavaScriptObject, XPathEvaluator: J.JavaScriptObject, XPathExpression: J.JavaScriptObject, XPathNSResolver: J.JavaScriptObject, XPathResult: J.JavaScriptObject, XMLSerializer: J.JavaScriptObject, XSLTProcessor: J.JavaScriptObject, Bluetooth: J.JavaScriptObject, BluetoothCharacteristicProperties: J.JavaScriptObject, BluetoothRemoteGATTServer: J.JavaScriptObject, BluetoothRemoteGATTService: J.JavaScriptObject, BluetoothUUID: J.JavaScriptObject, BudgetService: J.JavaScriptObject, Cache: J.JavaScriptObject, DOMFileSystemSync: J.JavaScriptObject, DirectoryEntrySync: J.JavaScriptObject, DirectoryReaderSync: J.JavaScriptObject, EntrySync: J.JavaScriptObject, FileEntrySync: J.JavaScriptObject, FileReaderSync: J.JavaScriptObject, FileWriterSync: J.JavaScriptObject, HTMLAllCollection: J.JavaScriptObject, Mojo: J.JavaScriptObject, MojoHandle: J.JavaScriptObject, MojoInterfaceRequestEvent: J.JavaScriptObject, MojoWatcher: J.JavaScriptObject, NFC: J.JavaScriptObject, PagePopupController: J.JavaScriptObject, Report: J.JavaScriptObject, Request: J.JavaScriptObject, ResourceProgressEvent: J.JavaScriptObject, Response: J.JavaScriptObject, SubtleCrypto: J.JavaScriptObject, USBAlternateInterface: J.JavaScriptObject, USBConfiguration: J.JavaScriptObject, USBConnectionEvent: J.JavaScriptObject, USBDevice: J.JavaScriptObject, USBEndpoint: J.JavaScriptObject, USBInTransferResult: J.JavaScriptObject, USBInterface: J.JavaScriptObject, USBIsochronousInTransferPacket: J.JavaScriptObject, USBIsochronousInTransferResult: J.JavaScriptObject, USBIsochronousOutTransferPacket: J.JavaScriptObject, USBIsochronousOutTransferResult: J.JavaScriptObject, USBOutTransferResult: J.JavaScriptObject, WorkerLocation: J.JavaScriptObject, WorkerNavigator: J.JavaScriptObject, Worklet: J.JavaScriptObject, IDBCursor: J.JavaScriptObject, IDBCursorWithValue: J.JavaScriptObject, IDBFactory: J.JavaScriptObject, IDBIndex: J.JavaScriptObject, IDBKeyRange: J.JavaScriptObject, IDBObjectStore: J.JavaScriptObject, IDBObservation: J.JavaScriptObject, IDBObserver: J.JavaScriptObject, IDBObserverChanges: J.JavaScriptObject, IDBVersionChangeEvent: J.JavaScriptObject, SVGAngle: J.JavaScriptObject, SVGAnimatedAngle: J.JavaScriptObject, SVGAnimatedBoolean: J.JavaScriptObject, SVGAnimatedEnumeration: J.JavaScriptObject, SVGAnimatedInteger: J.JavaScriptObject, SVGAnimatedLength: J.JavaScriptObject, SVGAnimatedLengthList: J.JavaScriptObject, SVGAnimatedNumber: J.JavaScriptObject, SVGAnimatedNumberList: J.JavaScriptObject, SVGAnimatedPreserveAspectRatio: J.JavaScriptObject, SVGAnimatedRect: J.JavaScriptObject, SVGAnimatedString: J.JavaScriptObject, SVGAnimatedTransformList: J.JavaScriptObject, SVGMatrix: J.JavaScriptObject, SVGPoint: J.JavaScriptObject, SVGPreserveAspectRatio: J.JavaScriptObject, SVGRect: J.JavaScriptObject, SVGUnitTypes: J.JavaScriptObject, AudioListener: J.JavaScriptObject, AudioParam: J.JavaScriptObject, AudioProcessingEvent: J.JavaScriptObject, AudioTrack: J.JavaScriptObject, AudioWorkletGlobalScope: J.JavaScriptObject, AudioWorkletProcessor: J.JavaScriptObject, OfflineAudioCompletionEvent: J.JavaScriptObject, PeriodicWave: J.JavaScriptObject, WebGLActiveInfo: J.JavaScriptObject, ANGLEInstancedArrays: J.JavaScriptObject, ANGLE_instanced_arrays: J.JavaScriptObject, WebGLBuffer: J.JavaScriptObject, WebGLCanvas: J.JavaScriptObject, WebGLColorBufferFloat: J.JavaScriptObject, WebGLCompressedTextureASTC: J.JavaScriptObject, WebGLCompressedTextureATC: J.JavaScriptObject, WEBGL_compressed_texture_atc: J.JavaScriptObject, WebGLCompressedTextureETC1: J.JavaScriptObject, WEBGL_compressed_texture_etc1: J.JavaScriptObject, WebGLCompressedTextureETC: J.JavaScriptObject, WebGLCompressedTexturePVRTC: J.JavaScriptObject, WEBGL_compressed_texture_pvrtc: J.JavaScriptObject, WebGLCompressedTextureS3TC: J.JavaScriptObject, WEBGL_compressed_texture_s3tc: J.JavaScriptObject, WebGLCompressedTextureS3TCsRGB: J.JavaScriptObject, WebGLContextEvent: J.JavaScriptObject, WebGLDebugRendererInfo: J.JavaScriptObject, WEBGL_debug_renderer_info: J.JavaScriptObject, WebGLDebugShaders: J.JavaScriptObject, WEBGL_debug_shaders: J.JavaScriptObject, WebGLDepthTexture: J.JavaScriptObject, WEBGL_depth_texture: J.JavaScriptObject, WebGLDrawBuffers: J.JavaScriptObject, WEBGL_draw_buffers: J.JavaScriptObject, EXTsRGB: J.JavaScriptObject, EXT_sRGB: J.JavaScriptObject, EXTBlendMinMax: J.JavaScriptObject, EXT_blend_minmax: J.JavaScriptObject, EXTColorBufferFloat: J.JavaScriptObject, EXTColorBufferHalfFloat: J.JavaScriptObject, EXTDisjointTimerQuery: J.JavaScriptObject, EXTDisjointTimerQueryWebGL2: J.JavaScriptObject, EXTFragDepth: J.JavaScriptObject, EXT_frag_depth: J.JavaScriptObject, EXTShaderTextureLOD: J.JavaScriptObject, EXT_shader_texture_lod: J.JavaScriptObject, EXTTextureFilterAnisotropic: J.JavaScriptObject, EXT_texture_filter_anisotropic: J.JavaScriptObject, WebGLFramebuffer: J.JavaScriptObject, WebGLGetBufferSubDataAsync: J.JavaScriptObject, WebGLLoseContext: J.JavaScriptObject, WebGLExtensionLoseContext: J.JavaScriptObject, WEBGL_lose_context: J.JavaScriptObject, OESElementIndexUint: J.JavaScriptObject, OES_element_index_uint: J.JavaScriptObject, OESStandardDerivatives: J.JavaScriptObject, OES_standard_derivatives: J.JavaScriptObject, OESTextureFloat: J.JavaScriptObject, OES_texture_float: J.JavaScriptObject, OESTextureFloatLinear: J.JavaScriptObject, OES_texture_float_linear: J.JavaScriptObject, OESTextureHalfFloat: J.JavaScriptObject, OES_texture_half_float: J.JavaScriptObject, OESTextureHalfFloatLinear: J.JavaScriptObject, OES_texture_half_float_linear: J.JavaScriptObject, OESVertexArrayObject: J.JavaScriptObject, OES_vertex_array_object: J.JavaScriptObject, WebGLProgram: J.JavaScriptObject, WebGLQuery: J.JavaScriptObject, WebGLRenderbuffer: J.JavaScriptObject, WebGLRenderingContext: J.JavaScriptObject, WebGL2RenderingContext: J.JavaScriptObject, WebGLSampler: J.JavaScriptObject, WebGLShader: J.JavaScriptObject, WebGLShaderPrecisionFormat: J.JavaScriptObject, WebGLSync: J.JavaScriptObject, WebGLTexture: J.JavaScriptObject, WebGLTimerQueryEXT: J.JavaScriptObject, WebGLTransformFeedback: J.JavaScriptObject, WebGLUniformLocation: J.JavaScriptObject, WebGLVertexArrayObject: J.JavaScriptObject, WebGLVertexArrayObjectOES: J.JavaScriptObject, WebGL2RenderingContextBase: J.JavaScriptObject, DataView: A.NativeTypedData, ArrayBufferView: A.NativeTypedData, Float32Array: A.NativeTypedArrayOfDouble, Float64Array: A.NativeTypedArrayOfDouble, Int16Array: A.NativeInt16List, Int32Array: A.NativeInt32List, Int8Array: A.NativeInt8List, Uint16Array: A.NativeUint16List, Uint32Array: A.NativeUint32List, Uint8ClampedArray: A.NativeUint8ClampedList, CanvasPixelArray: A.NativeUint8ClampedList, Uint8Array: A.NativeUint8List, HTMLAudioElement: A.HtmlElement, HTMLBRElement: A.HtmlElement, HTMLBaseElement: A.HtmlElement, HTMLBodyElement: A.HtmlElement, HTMLButtonElement: A.HtmlElement, HTMLCanvasElement: A.HtmlElement, HTMLContentElement: A.HtmlElement, HTMLDListElement: A.HtmlElement, HTMLDataElement: A.HtmlElement, HTMLDataListElement: A.HtmlElement, HTMLDetailsElement: A.HtmlElement, HTMLDialogElement: A.HtmlElement, HTMLDivElement: A.HtmlElement, HTMLEmbedElement: A.HtmlElement, HTMLFieldSetElement: A.HtmlElement, HTMLHRElement: A.HtmlElement, HTMLHeadElement: A.HtmlElement, HTMLHeadingElement: A.HtmlElement, HTMLHtmlElement: A.HtmlElement, HTMLIFrameElement: A.HtmlElement, HTMLImageElement: A.HtmlElement, HTMLInputElement: A.HtmlElement, HTMLLIElement: A.HtmlElement, HTMLLabelElement: A.HtmlElement, HTMLLegendElement: A.HtmlElement, HTMLLinkElement: A.HtmlElement, HTMLMapElement: A.HtmlElement, HTMLMediaElement: A.HtmlElement, HTMLMenuElement: A.HtmlElement, HTMLMetaElement: A.HtmlElement, HTMLMeterElement: A.HtmlElement, HTMLModElement: A.HtmlElement, HTMLOListElement: A.HtmlElement, HTMLObjectElement: A.HtmlElement, HTMLOptGroupElement: A.HtmlElement, HTMLOptionElement: A.HtmlElement, HTMLOutputElement: A.HtmlElement, HTMLParagraphElement: A.HtmlElement, HTMLParamElement: A.HtmlElement, HTMLPictureElement: A.HtmlElement, HTMLPreElement: A.HtmlElement, HTMLProgressElement: A.HtmlElement, HTMLQuoteElement: A.HtmlElement, HTMLScriptElement: A.HtmlElement, HTMLShadowElement: A.HtmlElement, HTMLSlotElement: A.HtmlElement, HTMLSourceElement: A.HtmlElement, HTMLSpanElement: A.HtmlElement, HTMLStyleElement: A.HtmlElement, HTMLTableCaptionElement: A.HtmlElement, HTMLTableCellElement: A.HtmlElement, HTMLTableDataCellElement: A.HtmlElement, HTMLTableHeaderCellElement: A.HtmlElement, HTMLTableColElement: A.HtmlElement, HTMLTableElement: A.HtmlElement, HTMLTableRowElement: A.HtmlElement, HTMLTableSectionElement: A.HtmlElement, HTMLTemplateElement: A.HtmlElement, HTMLTextAreaElement: A.HtmlElement, HTMLTimeElement: A.HtmlElement, HTMLTitleElement: A.HtmlElement, HTMLTrackElement: A.HtmlElement, HTMLUListElement: A.HtmlElement, HTMLUnknownElement: A.HtmlElement, HTMLVideoElement: A.HtmlElement, HTMLDirectoryElement: A.HtmlElement, HTMLFontElement: A.HtmlElement, HTMLFrameElement: A.HtmlElement, HTMLFrameSetElement: A.HtmlElement, HTMLMarqueeElement: A.HtmlElement, HTMLElement: A.HtmlElement, AccessibleNodeList: A.AccessibleNodeList, HTMLAnchorElement: A.AnchorElement, HTMLAreaElement: A.AreaElement, Blob: A.Blob, CDATASection: A.CharacterData, CharacterData: A.CharacterData, Comment: A.CharacterData, ProcessingInstruction: A.CharacterData, Text: A.CharacterData, CSSPerspective: A.CssPerspective, CSSCharsetRule: A.CssRule, CSSConditionRule: A.CssRule, CSSFontFaceRule: A.CssRule, CSSGroupingRule: A.CssRule, CSSImportRule: A.CssRule, CSSKeyframeRule: A.CssRule, MozCSSKeyframeRule: A.CssRule, WebKitCSSKeyframeRule: A.CssRule, CSSKeyframesRule: A.CssRule, MozCSSKeyframesRule: A.CssRule, WebKitCSSKeyframesRule: A.CssRule, CSSMediaRule: A.CssRule, CSSNamespaceRule: A.CssRule, CSSPageRule: A.CssRule, CSSRule: A.CssRule, CSSStyleRule: A.CssRule, CSSSupportsRule: A.CssRule, CSSViewportRule: A.CssRule, CSSStyleDeclaration: A.CssStyleDeclaration, MSStyleCSSProperties: A.CssStyleDeclaration, CSS2Properties: A.CssStyleDeclaration, CSSImageValue: A.CssStyleValue, CSSKeywordValue: A.CssStyleValue, CSSNumericValue: A.CssStyleValue, CSSPositionValue: A.CssStyleValue, CSSResourceValue: A.CssStyleValue, CSSUnitValue: A.CssStyleValue, CSSURLImageValue: A.CssStyleValue, CSSStyleValue: A.CssStyleValue, CSSMatrixComponent: A.CssTransformComponent, CSSRotation: A.CssTransformComponent, CSSScale: A.CssTransformComponent, CSSSkew: A.CssTransformComponent, CSSTranslation: A.CssTransformComponent, CSSTransformComponent: A.CssTransformComponent, CSSTransformValue: A.CssTransformValue, CSSUnparsedValue: A.CssUnparsedValue, DataTransferItemList: A.DataTransferItemList, DOMException: A.DomException, ClientRectList: A.DomRectList, DOMRectList: A.DomRectList, DOMRectReadOnly: A.DomRectReadOnly, DOMStringList: A.DomStringList, DOMTokenList: A.DomTokenList, MathMLElement: A.Element, SVGAElement: A.Element, SVGAnimateElement: A.Element, SVGAnimateMotionElement: A.Element, SVGAnimateTransformElement: A.Element, SVGAnimationElement: A.Element, SVGCircleElement: A.Element, SVGClipPathElement: A.Element, SVGDefsElement: A.Element, SVGDescElement: A.Element, SVGDiscardElement: A.Element, SVGEllipseElement: A.Element, SVGFEBlendElement: A.Element, SVGFEColorMatrixElement: A.Element, SVGFEComponentTransferElement: A.Element, SVGFECompositeElement: A.Element, SVGFEConvolveMatrixElement: A.Element, SVGFEDiffuseLightingElement: A.Element, SVGFEDisplacementMapElement: A.Element, SVGFEDistantLightElement: A.Element, SVGFEFloodElement: A.Element, SVGFEFuncAElement: A.Element, SVGFEFuncBElement: A.Element, SVGFEFuncGElement: A.Element, SVGFEFuncRElement: A.Element, SVGFEGaussianBlurElement: A.Element, SVGFEImageElement: A.Element, SVGFEMergeElement: A.Element, SVGFEMergeNodeElement: A.Element, SVGFEMorphologyElement: A.Element, SVGFEOffsetElement: A.Element, SVGFEPointLightElement: A.Element, SVGFESpecularLightingElement: A.Element, SVGFESpotLightElement: A.Element, SVGFETileElement: A.Element, SVGFETurbulenceElement: A.Element, SVGFilterElement: A.Element, SVGForeignObjectElement: A.Element, SVGGElement: A.Element, SVGGeometryElement: A.Element, SVGGraphicsElement: A.Element, SVGImageElement: A.Element, SVGLineElement: A.Element, SVGLinearGradientElement: A.Element, SVGMarkerElement: A.Element, SVGMaskElement: A.Element, SVGMetadataElement: A.Element, SVGPathElement: A.Element, SVGPatternElement: A.Element, SVGPolygonElement: A.Element, SVGPolylineElement: A.Element, SVGRadialGradientElement: A.Element, SVGRectElement: A.Element, SVGScriptElement: A.Element, SVGSetElement: A.Element, SVGStopElement: A.Element, SVGStyleElement: A.Element, SVGElement: A.Element, SVGSVGElement: A.Element, SVGSwitchElement: A.Element, SVGSymbolElement: A.Element, SVGTSpanElement: A.Element, SVGTextContentElement: A.Element, SVGTextElement: A.Element, SVGTextPathElement: A.Element, SVGTextPositioningElement: A.Element, SVGTitleElement: A.Element, SVGUseElement: A.Element, SVGViewElement: A.Element, SVGGradientElement: A.Element, SVGComponentTransferFunctionElement: A.Element, SVGFEDropShadowElement: A.Element, SVGMPathElement: A.Element, Element: A.Element, AbsoluteOrientationSensor: A.EventTarget, Accelerometer: A.EventTarget, AccessibleNode: A.EventTarget, AmbientLightSensor: A.EventTarget, Animation: A.EventTarget, ApplicationCache: A.EventTarget, DOMApplicationCache: A.EventTarget, OfflineResourceList: A.EventTarget, BackgroundFetchRegistration: A.EventTarget, BatteryManager: A.EventTarget, BroadcastChannel: A.EventTarget, CanvasCaptureMediaStreamTrack: A.EventTarget, DedicatedWorkerGlobalScope: A.EventTarget, EventSource: A.EventTarget, FileReader: A.EventTarget, FontFaceSet: A.EventTarget, Gyroscope: A.EventTarget, XMLHttpRequest: A.EventTarget, XMLHttpRequestEventTarget: A.EventTarget, XMLHttpRequestUpload: A.EventTarget, LinearAccelerationSensor: A.EventTarget, Magnetometer: A.EventTarget, MediaDevices: A.EventTarget, MediaKeySession: A.EventTarget, MediaQueryList: A.EventTarget, MediaRecorder: A.EventTarget, MediaSource: A.EventTarget, MediaStream: A.EventTarget, MediaStreamTrack: A.EventTarget, MessagePort: A.EventTarget, MIDIAccess: A.EventTarget, MIDIInput: A.EventTarget, MIDIOutput: A.EventTarget, MIDIPort: A.EventTarget, NetworkInformation: A.EventTarget, Notification: A.EventTarget, OffscreenCanvas: A.EventTarget, OrientationSensor: A.EventTarget, PaymentRequest: A.EventTarget, Performance: A.EventTarget, PermissionStatus: A.EventTarget, PresentationAvailability: A.EventTarget, PresentationConnection: A.EventTarget, PresentationConnectionList: A.EventTarget, PresentationRequest: A.EventTarget, RelativeOrientationSensor: A.EventTarget, RemotePlayback: A.EventTarget, RTCDataChannel: A.EventTarget, DataChannel: A.EventTarget, RTCDTMFSender: A.EventTarget, RTCPeerConnection: A.EventTarget, webkitRTCPeerConnection: A.EventTarget, mozRTCPeerConnection: A.EventTarget, ScreenOrientation: A.EventTarget, Sensor: A.EventTarget, ServiceWorker: A.EventTarget, ServiceWorkerContainer: A.EventTarget, ServiceWorkerGlobalScope: A.EventTarget, ServiceWorkerRegistration: A.EventTarget, SharedWorker: A.EventTarget, SharedWorkerGlobalScope: A.EventTarget, SpeechRecognition: A.EventTarget, SpeechSynthesis: A.EventTarget, SpeechSynthesisUtterance: A.EventTarget, VR: A.EventTarget, VRDevice: A.EventTarget, VRDisplay: A.EventTarget, VRSession: A.EventTarget, VisualViewport: A.EventTarget, WebSocket: A.EventTarget, Window: A.EventTarget, DOMWindow: A.EventTarget, Worker: A.EventTarget, WorkerGlobalScope: A.EventTarget, WorkerPerformance: A.EventTarget, BluetoothDevice: A.EventTarget, BluetoothRemoteGATTCharacteristic: A.EventTarget, Clipboard: A.EventTarget, MojoInterfaceInterceptor: A.EventTarget, USB: A.EventTarget, IDBDatabase: A.EventTarget, IDBOpenDBRequest: A.EventTarget, IDBVersionChangeRequest: A.EventTarget, IDBRequest: A.EventTarget, IDBTransaction: A.EventTarget, AnalyserNode: A.EventTarget, RealtimeAnalyserNode: A.EventTarget, AudioBufferSourceNode: A.EventTarget, AudioDestinationNode: A.EventTarget, AudioNode: A.EventTarget, AudioScheduledSourceNode: A.EventTarget, AudioWorkletNode: A.EventTarget, BiquadFilterNode: A.EventTarget, ChannelMergerNode: A.EventTarget, AudioChannelMerger: A.EventTarget, ChannelSplitterNode: A.EventTarget, AudioChannelSplitter: A.EventTarget, ConstantSourceNode: A.EventTarget, ConvolverNode: A.EventTarget, DelayNode: A.EventTarget, DynamicsCompressorNode: A.EventTarget, GainNode: A.EventTarget, AudioGainNode: A.EventTarget, IIRFilterNode: A.EventTarget, MediaElementAudioSourceNode: A.EventTarget, MediaStreamAudioDestinationNode: A.EventTarget, MediaStreamAudioSourceNode: A.EventTarget, OscillatorNode: A.EventTarget, Oscillator: A.EventTarget, PannerNode: A.EventTarget, AudioPannerNode: A.EventTarget, webkitAudioPannerNode: A.EventTarget, ScriptProcessorNode: A.EventTarget, JavaScriptAudioNode: A.EventTarget, StereoPannerNode: A.EventTarget, WaveShaperNode: A.EventTarget, EventTarget: A.EventTarget, File: A.File, FileList: A.FileList, FileWriter: A.FileWriter, HTMLFormElement: A.FormElement, Gamepad: A.Gamepad, History: A.History, HTMLCollection: A.HtmlCollection, HTMLFormControlsCollection: A.HtmlCollection, HTMLOptionsCollection: A.HtmlCollection, Location: A.Location, MediaList: A.MediaList, MIDIInputMap: A.MidiInputMap, MIDIOutputMap: A.MidiOutputMap, MimeType: A.MimeType, MimeTypeArray: A.MimeTypeArray, Document: A.Node, DocumentFragment: A.Node, HTMLDocument: A.Node, ShadowRoot: A.Node, XMLDocument: A.Node, Attr: A.Node, DocumentType: A.Node, Node: A.Node, NodeList: A.NodeList, RadioNodeList: A.NodeList, Plugin: A.Plugin, PluginArray: A.PluginArray, RTCStatsReport: A.RtcStatsReport, HTMLSelectElement: A.SelectElement, SourceBuffer: A.SourceBuffer, SourceBufferList: A.SourceBufferList, SpeechGrammar: A.SpeechGrammar, SpeechGrammarList: A.SpeechGrammarList, SpeechRecognitionResult: A.SpeechRecognitionResult, Storage: A.Storage, CSSStyleSheet: A.StyleSheet, StyleSheet: A.StyleSheet, TextTrack: A.TextTrack, TextTrackCue: A.TextTrackCue, VTTCue: A.TextTrackCue, TextTrackCueList: A.TextTrackCueList, TextTrackList: A.TextTrackList, TimeRanges: A.TimeRanges, Touch: A.Touch, TouchList: A.TouchList, TrackDefaultList: A.TrackDefaultList, URL: A.Url, VideoTrackList: A.VideoTrackList, CSSRuleList: A._CssRuleList, ClientRect: A._DomRect, DOMRect: A._DomRect, GamepadList: A._GamepadList, NamedNodeMap: A._NamedNodeMap, MozNamedAttrMap: A._NamedNodeMap, SpeechRecognitionResultList: A._SpeechRecognitionResultList, StyleSheetList: A._StyleSheetList, SVGLength: A.Length, SVGLengthList: A.LengthList, SVGNumber: A.Number, SVGNumberList: A.NumberList, SVGPointList: A.PointList, SVGStringList: A.StringList, SVGTransform: A.Transform, SVGTransformList: A.TransformList, AudioBuffer: A.AudioBuffer, AudioParamMap: A.AudioParamMap, AudioTrackList: A.AudioTrackList, AudioContext: A.BaseAudioContext, webkitAudioContext: A.BaseAudioContext, BaseAudioContext: A.BaseAudioContext, OfflineAudioContext: A.OfflineAudioContext});
- hunkHelpers.setOrUpdateLeafTags({ArrayBuffer: true, WebGL: true, AbortPaymentEvent: true, AnimationEffectReadOnly: true, AnimationEffectTiming: true, AnimationEffectTimingReadOnly: true, AnimationEvent: true, AnimationPlaybackEvent: true, AnimationTimeline: true, AnimationWorkletGlobalScope: true, ApplicationCacheErrorEvent: true, AuthenticatorAssertionResponse: true, AuthenticatorAttestationResponse: true, AuthenticatorResponse: true, BackgroundFetchClickEvent: true, BackgroundFetchEvent: true, BackgroundFetchFailEvent: true, BackgroundFetchFetch: true, BackgroundFetchManager: true, BackgroundFetchSettledFetch: true, BackgroundFetchedEvent: true, BarProp: true, BarcodeDetector: true, BeforeInstallPromptEvent: true, BeforeUnloadEvent: true, BlobEvent: true, BluetoothRemoteGATTDescriptor: true, Body: true, BudgetState: true, CacheStorage: true, CanMakePaymentEvent: true, CanvasGradient: true, CanvasPattern: true, CanvasRenderingContext2D: true, Client: true, Clients: true, ClipboardEvent: true, CloseEvent: true, CompositionEvent: true, CookieStore: true, Coordinates: true, Credential: true, CredentialUserData: true, CredentialsContainer: true, Crypto: true, CryptoKey: true, CSS: true, CSSVariableReferenceValue: true, CustomElementRegistry: true, CustomEvent: true, DataTransfer: true, DataTransferItem: true, DeprecatedStorageInfo: true, DeprecatedStorageQuota: true, DeprecationReport: true, DetectedBarcode: true, DetectedFace: true, DetectedText: true, DeviceAcceleration: true, DeviceMotionEvent: true, DeviceOrientationEvent: true, DeviceRotationRate: true, DirectoryEntry: true, webkitFileSystemDirectoryEntry: true, FileSystemDirectoryEntry: true, DirectoryReader: true, WebKitDirectoryReader: true, webkitFileSystemDirectoryReader: true, FileSystemDirectoryReader: true, DocumentOrShadowRoot: true, DocumentTimeline: true, DOMError: true, DOMImplementation: true, Iterator: true, DOMMatrix: true, DOMMatrixReadOnly: true, DOMParser: true, DOMPoint: true, DOMPointReadOnly: true, DOMQuad: true, DOMStringMap: true, Entry: true, webkitFileSystemEntry: true, FileSystemEntry: true, ErrorEvent: true, Event: true, InputEvent: true, SubmitEvent: true, ExtendableEvent: true, ExtendableMessageEvent: true, External: true, FaceDetector: true, FederatedCredential: true, FetchEvent: true, FileEntry: true, webkitFileSystemFileEntry: true, FileSystemFileEntry: true, DOMFileSystem: true, WebKitFileSystem: true, webkitFileSystem: true, FileSystem: true, FocusEvent: true, FontFace: true, FontFaceSetLoadEvent: true, FontFaceSource: true, ForeignFetchEvent: true, FormData: true, GamepadButton: true, GamepadEvent: true, GamepadPose: true, Geolocation: true, Position: true, GeolocationPosition: true, HashChangeEvent: true, Headers: true, HTMLHyperlinkElementUtils: true, IdleDeadline: true, ImageBitmap: true, ImageBitmapRenderingContext: true, ImageCapture: true, ImageData: true, InputDeviceCapabilities: true, InstallEvent: true, IntersectionObserver: true, IntersectionObserverEntry: true, InterventionReport: true, KeyboardEvent: true, KeyframeEffect: true, KeyframeEffectReadOnly: true, MediaCapabilities: true, MediaCapabilitiesInfo: true, MediaDeviceInfo: true, MediaEncryptedEvent: true, MediaError: true, MediaKeyMessageEvent: true, MediaKeyStatusMap: true, MediaKeySystemAccess: true, MediaKeys: true, MediaKeysPolicy: true, MediaMetadata: true, MediaQueryListEvent: true, MediaSession: true, MediaSettingsRange: true, MediaStreamEvent: true, MediaStreamTrackEvent: true, MemoryInfo: true, MessageChannel: true, MessageEvent: true, Metadata: true, MIDIConnectionEvent: true, MIDIMessageEvent: true, MouseEvent: true, DragEvent: true, MutationEvent: true, MutationObserver: true, WebKitMutationObserver: true, MutationRecord: true, NavigationPreloadManager: true, Navigator: true, NavigatorAutomationInformation: true, NavigatorConcurrentHardware: true, NavigatorCookies: true, NavigatorUserMediaError: true, NodeFilter: true, NodeIterator: true, NonDocumentTypeChildNode: true, NonElementParentNode: true, NoncedElement: true, NotificationEvent: true, OffscreenCanvasRenderingContext2D: true, OverconstrainedError: true, PageTransitionEvent: true, PaintRenderingContext2D: true, PaintSize: true, PaintWorkletGlobalScope: true, PasswordCredential: true, Path2D: true, PaymentAddress: true, PaymentInstruments: true, PaymentManager: true, PaymentRequestEvent: true, PaymentRequestUpdateEvent: true, PaymentResponse: true, PerformanceEntry: true, PerformanceLongTaskTiming: true, PerformanceMark: true, PerformanceMeasure: true, PerformanceNavigation: true, PerformanceNavigationTiming: true, PerformanceObserver: true, PerformanceObserverEntryList: true, PerformancePaintTiming: true, PerformanceResourceTiming: true, PerformanceServerTiming: true, PerformanceTiming: true, Permissions: true, PhotoCapabilities: true, PointerEvent: true, PopStateEvent: true, PositionError: true, GeolocationPositionError: true, Presentation: true, PresentationConnectionAvailableEvent: true, PresentationConnectionCloseEvent: true, PresentationReceiver: true, ProgressEvent: true, PromiseRejectionEvent: true, PublicKeyCredential: true, PushEvent: true, PushManager: true, PushMessageData: true, PushSubscription: true, PushSubscriptionOptions: true, Range: true, RelatedApplication: true, ReportBody: true, ReportingObserver: true, ResizeObserver: true, ResizeObserverEntry: true, RTCCertificate: true, RTCDataChannelEvent: true, RTCDTMFToneChangeEvent: true, RTCIceCandidate: true, mozRTCIceCandidate: true, RTCLegacyStatsReport: true, RTCPeerConnectionIceEvent: true, RTCRtpContributingSource: true, RTCRtpReceiver: true, RTCRtpSender: true, RTCSessionDescription: true, mozRTCSessionDescription: true, RTCStatsResponse: true, RTCTrackEvent: true, Screen: true, ScrollState: true, ScrollTimeline: true, SecurityPolicyViolationEvent: true, Selection: true, SensorErrorEvent: true, SharedArrayBuffer: true, SpeechRecognitionAlternative: true, SpeechRecognitionError: true, SpeechRecognitionEvent: true, SpeechSynthesisEvent: true, SpeechSynthesisVoice: true, StaticRange: true, StorageEvent: true, StorageManager: true, StyleMedia: true, StylePropertyMap: true, StylePropertyMapReadonly: true, SyncEvent: true, SyncManager: true, TaskAttributionTiming: true, TextDetector: true, TextEvent: true, TextMetrics: true, TouchEvent: true, TrackDefault: true, TrackEvent: true, TransitionEvent: true, WebKitTransitionEvent: true, TreeWalker: true, TrustedHTML: true, TrustedScriptURL: true, TrustedURL: true, UIEvent: true, UnderlyingSourceBase: true, URLSearchParams: true, VRCoordinateSystem: true, VRDeviceEvent: true, VRDisplayCapabilities: true, VRDisplayEvent: true, VREyeParameters: true, VRFrameData: true, VRFrameOfReference: true, VRPose: true, VRSessionEvent: true, VRStageBounds: true, VRStageBoundsPoint: true, VRStageParameters: true, ValidityState: true, VideoPlaybackQuality: true, VideoTrack: true, VTTRegion: true, WheelEvent: true, WindowClient: true, WorkletAnimation: true, WorkletGlobalScope: true, XPathEvaluator: true, XPathExpression: true, XPathNSResolver: true, XPathResult: true, XMLSerializer: true, XSLTProcessor: true, Bluetooth: true, BluetoothCharacteristicProperties: true, BluetoothRemoteGATTServer: true, BluetoothRemoteGATTService: true, BluetoothUUID: true, BudgetService: true, Cache: true, DOMFileSystemSync: true, DirectoryEntrySync: true, DirectoryReaderSync: true, EntrySync: true, FileEntrySync: true, FileReaderSync: true, FileWriterSync: true, HTMLAllCollection: true, Mojo: true, MojoHandle: true, MojoInterfaceRequestEvent: true, MojoWatcher: true, NFC: true, PagePopupController: true, Report: true, Request: true, ResourceProgressEvent: true, Response: true, SubtleCrypto: true, USBAlternateInterface: true, USBConfiguration: true, USBConnectionEvent: true, USBDevice: true, USBEndpoint: true, USBInTransferResult: true, USBInterface: true, USBIsochronousInTransferPacket: true, USBIsochronousInTransferResult: true, USBIsochronousOutTransferPacket: true, USBIsochronousOutTransferResult: true, USBOutTransferResult: true, WorkerLocation: true, WorkerNavigator: true, Worklet: true, IDBCursor: true, IDBCursorWithValue: true, IDBFactory: true, IDBIndex: true, IDBKeyRange: true, IDBObjectStore: true, IDBObservation: true, IDBObserver: true, IDBObserverChanges: true, IDBVersionChangeEvent: true, SVGAngle: true, SVGAnimatedAngle: true, SVGAnimatedBoolean: true, SVGAnimatedEnumeration: true, SVGAnimatedInteger: true, SVGAnimatedLength: true, SVGAnimatedLengthList: true, SVGAnimatedNumber: true, SVGAnimatedNumberList: true, SVGAnimatedPreserveAspectRatio: true, SVGAnimatedRect: true, SVGAnimatedString: true, SVGAnimatedTransformList: true, SVGMatrix: true, SVGPoint: true, SVGPreserveAspectRatio: true, SVGRect: true, SVGUnitTypes: true, AudioListener: true, AudioParam: true, AudioProcessingEvent: true, AudioTrack: true, AudioWorkletGlobalScope: true, AudioWorkletProcessor: true, OfflineAudioCompletionEvent: true, PeriodicWave: true, WebGLActiveInfo: true, ANGLEInstancedArrays: true, ANGLE_instanced_arrays: true, WebGLBuffer: true, WebGLCanvas: true, WebGLColorBufferFloat: true, WebGLCompressedTextureASTC: true, WebGLCompressedTextureATC: true, WEBGL_compressed_texture_atc: true, WebGLCompressedTextureETC1: true, WEBGL_compressed_texture_etc1: true, WebGLCompressedTextureETC: true, WebGLCompressedTexturePVRTC: true, WEBGL_compressed_texture_pvrtc: true, WebGLCompressedTextureS3TC: true, WEBGL_compressed_texture_s3tc: true, WebGLCompressedTextureS3TCsRGB: true, WebGLContextEvent: true, WebGLDebugRendererInfo: true, WEBGL_debug_renderer_info: true, WebGLDebugShaders: true, WEBGL_debug_shaders: true, WebGLDepthTexture: true, WEBGL_depth_texture: true, WebGLDrawBuffers: true, WEBGL_draw_buffers: true, EXTsRGB: true, EXT_sRGB: true, EXTBlendMinMax: true, EXT_blend_minmax: true, EXTColorBufferFloat: true, EXTColorBufferHalfFloat: true, EXTDisjointTimerQuery: true, EXTDisjointTimerQueryWebGL2: true, EXTFragDepth: true, EXT_frag_depth: true, EXTShaderTextureLOD: true, EXT_shader_texture_lod: true, EXTTextureFilterAnisotropic: true, EXT_texture_filter_anisotropic: true, WebGLFramebuffer: true, WebGLGetBufferSubDataAsync: true, WebGLLoseContext: true, WebGLExtensionLoseContext: true, WEBGL_lose_context: true, OESElementIndexUint: true, OES_element_index_uint: true, OESStandardDerivatives: true, OES_standard_derivatives: true, OESTextureFloat: true, OES_texture_float: true, OESTextureFloatLinear: true, OES_texture_float_linear: true, OESTextureHalfFloat: true, OES_texture_half_float: true, OESTextureHalfFloatLinear: true, OES_texture_half_float_linear: true, OESVertexArrayObject: true, OES_vertex_array_object: true, WebGLProgram: true, WebGLQuery: true, WebGLRenderbuffer: true, WebGLRenderingContext: true, WebGL2RenderingContext: true, WebGLSampler: true, WebGLShader: true, WebGLShaderPrecisionFormat: true, WebGLSync: true, WebGLTexture: true, WebGLTimerQueryEXT: true, WebGLTransformFeedback: true, WebGLUniformLocation: true, WebGLVertexArrayObject: true, WebGLVertexArrayObjectOES: true, WebGL2RenderingContextBase: true, DataView: true, ArrayBufferView: false, Float32Array: true, Float64Array: true, Int16Array: true, Int32Array: true, Int8Array: true, Uint16Array: true, Uint32Array: true, Uint8ClampedArray: true, CanvasPixelArray: true, Uint8Array: false, HTMLAudioElement: true, HTMLBRElement: true, HTMLBaseElement: true, HTMLBodyElement: true, HTMLButtonElement: true, HTMLCanvasElement: true, HTMLContentElement: true, HTMLDListElement: true, HTMLDataElement: true, HTMLDataListElement: true, HTMLDetailsElement: true, HTMLDialogElement: true, HTMLDivElement: true, HTMLEmbedElement: true, HTMLFieldSetElement: true, HTMLHRElement: true, HTMLHeadElement: true, HTMLHeadingElement: true, HTMLHtmlElement: true, HTMLIFrameElement: true, HTMLImageElement: true, HTMLInputElement: true, HTMLLIElement: true, HTMLLabelElement: true, HTMLLegendElement: true, HTMLLinkElement: true, HTMLMapElement: true, HTMLMediaElement: true, HTMLMenuElement: true, HTMLMetaElement: true, HTMLMeterElement: true, HTMLModElement: true, HTMLOListElement: true, HTMLObjectElement: true, HTMLOptGroupElement: true, HTMLOptionElement: true, HTMLOutputElement: true, HTMLParagraphElement: true, HTMLParamElement: true, HTMLPictureElement: true, HTMLPreElement: true, HTMLProgressElement: true, HTMLQuoteElement: true, HTMLScriptElement: true, HTMLShadowElement: true, HTMLSlotElement: true, HTMLSourceElement: true, HTMLSpanElement: true, HTMLStyleElement: true, HTMLTableCaptionElement: true, HTMLTableCellElement: true, HTMLTableDataCellElement: true, HTMLTableHeaderCellElement: true, HTMLTableColElement: true, HTMLTableElement: true, HTMLTableRowElement: true, HTMLTableSectionElement: true, HTMLTemplateElement: true, HTMLTextAreaElement: true, HTMLTimeElement: true, HTMLTitleElement: true, HTMLTrackElement: true, HTMLUListElement: true, HTMLUnknownElement: true, HTMLVideoElement: true, HTMLDirectoryElement: true, HTMLFontElement: true, HTMLFrameElement: true, HTMLFrameSetElement: true, HTMLMarqueeElement: true, HTMLElement: false, AccessibleNodeList: true, HTMLAnchorElement: true, HTMLAreaElement: true, Blob: false, CDATASection: true, CharacterData: true, Comment: true, ProcessingInstruction: true, Text: true, CSSPerspective: true, CSSCharsetRule: true, CSSConditionRule: true, CSSFontFaceRule: true, CSSGroupingRule: true, CSSImportRule: true, CSSKeyframeRule: true, MozCSSKeyframeRule: true, WebKitCSSKeyframeRule: true, CSSKeyframesRule: true, MozCSSKeyframesRule: true, WebKitCSSKeyframesRule: true, CSSMediaRule: true, CSSNamespaceRule: true, CSSPageRule: true, CSSRule: true, CSSStyleRule: true, CSSSupportsRule: true, CSSViewportRule: true, CSSStyleDeclaration: true, MSStyleCSSProperties: true, CSS2Properties: true, CSSImageValue: true, CSSKeywordValue: true, CSSNumericValue: true, CSSPositionValue: true, CSSResourceValue: true, CSSUnitValue: true, CSSURLImageValue: true, CSSStyleValue: false, CSSMatrixComponent: true, CSSRotation: true, CSSScale: true, CSSSkew: true, CSSTranslation: true, CSSTransformComponent: false, CSSTransformValue: true, CSSUnparsedValue: true, DataTransferItemList: true, DOMException: true, ClientRectList: true, DOMRectList: true, DOMRectReadOnly: false, DOMStringList: true, DOMTokenList: true, MathMLElement: true, SVGAElement: true, SVGAnimateElement: true, SVGAnimateMotionElement: true, SVGAnimateTransformElement: true, SVGAnimationElement: true, SVGCircleElement: true, SVGClipPathElement: true, SVGDefsElement: true, SVGDescElement: true, SVGDiscardElement: true, SVGEllipseElement: true, SVGFEBlendElement: true, SVGFEColorMatrixElement: true, SVGFEComponentTransferElement: true, SVGFECompositeElement: true, SVGFEConvolveMatrixElement: true, SVGFEDiffuseLightingElement: true, SVGFEDisplacementMapElement: true, SVGFEDistantLightElement: true, SVGFEFloodElement: true, SVGFEFuncAElement: true, SVGFEFuncBElement: true, SVGFEFuncGElement: true, SVGFEFuncRElement: true, SVGFEGaussianBlurElement: true, SVGFEImageElement: true, SVGFEMergeElement: true, SVGFEMergeNodeElement: true, SVGFEMorphologyElement: true, SVGFEOffsetElement: true, SVGFEPointLightElement: true, SVGFESpecularLightingElement: true, SVGFESpotLightElement: true, SVGFETileElement: true, SVGFETurbulenceElement: true, SVGFilterElement: true, SVGForeignObjectElement: true, SVGGElement: true, SVGGeometryElement: true, SVGGraphicsElement: true, SVGImageElement: true, SVGLineElement: true, SVGLinearGradientElement: true, SVGMarkerElement: true, SVGMaskElement: true, SVGMetadataElement: true, SVGPathElement: true, SVGPatternElement: true, SVGPolygonElement: true, SVGPolylineElement: true, SVGRadialGradientElement: true, SVGRectElement: true, SVGScriptElement: true, SVGSetElement: true, SVGStopElement: true, SVGStyleElement: true, SVGElement: true, SVGSVGElement: true, SVGSwitchElement: true, SVGSymbolElement: true, SVGTSpanElement: true, SVGTextContentElement: true, SVGTextElement: true, SVGTextPathElement: true, SVGTextPositioningElement: true, SVGTitleElement: true, SVGUseElement: true, SVGViewElement: true, SVGGradientElement: true, SVGComponentTransferFunctionElement: true, SVGFEDropShadowElement: true, SVGMPathElement: true, Element: false, AbsoluteOrientationSensor: true, Accelerometer: true, AccessibleNode: true, AmbientLightSensor: true, Animation: true, ApplicationCache: true, DOMApplicationCache: true, OfflineResourceList: true, BackgroundFetchRegistration: true, BatteryManager: true, BroadcastChannel: true, CanvasCaptureMediaStreamTrack: true, DedicatedWorkerGlobalScope: true, EventSource: true, FileReader: true, FontFaceSet: true, Gyroscope: true, XMLHttpRequest: true, XMLHttpRequestEventTarget: true, XMLHttpRequestUpload: true, LinearAccelerationSensor: true, Magnetometer: true, MediaDevices: true, MediaKeySession: true, MediaQueryList: true, MediaRecorder: true, MediaSource: true, MediaStream: true, MediaStreamTrack: true, MessagePort: true, MIDIAccess: true, MIDIInput: true, MIDIOutput: true, MIDIPort: true, NetworkInformation: true, Notification: true, OffscreenCanvas: true, OrientationSensor: true, PaymentRequest: true, Performance: true, PermissionStatus: true, PresentationAvailability: true, PresentationConnection: true, PresentationConnectionList: true, PresentationRequest: true, RelativeOrientationSensor: true, RemotePlayback: true, RTCDataChannel: true, DataChannel: true, RTCDTMFSender: true, RTCPeerConnection: true, webkitRTCPeerConnection: true, mozRTCPeerConnection: true, ScreenOrientation: true, Sensor: true, ServiceWorker: true, ServiceWorkerContainer: true, ServiceWorkerGlobalScope: true, ServiceWorkerRegistration: true, SharedWorker: true, SharedWorkerGlobalScope: true, SpeechRecognition: true, SpeechSynthesis: true, SpeechSynthesisUtterance: true, VR: true, VRDevice: true, VRDisplay: true, VRSession: true, VisualViewport: true, WebSocket: true, Window: true, DOMWindow: true, Worker: true, WorkerGlobalScope: true, WorkerPerformance: true, BluetoothDevice: true, BluetoothRemoteGATTCharacteristic: true, Clipboard: true, MojoInterfaceInterceptor: true, USB: true, IDBDatabase: true, IDBOpenDBRequest: true, IDBVersionChangeRequest: true, IDBRequest: true, IDBTransaction: true, AnalyserNode: true, RealtimeAnalyserNode: true, AudioBufferSourceNode: true, AudioDestinationNode: true, AudioNode: true, AudioScheduledSourceNode: true, AudioWorkletNode: true, BiquadFilterNode: true, ChannelMergerNode: true, AudioChannelMerger: true, ChannelSplitterNode: true, AudioChannelSplitter: true, ConstantSourceNode: true, ConvolverNode: true, DelayNode: true, DynamicsCompressorNode: true, GainNode: true, AudioGainNode: true, IIRFilterNode: true, MediaElementAudioSourceNode: true, MediaStreamAudioDestinationNode: true, MediaStreamAudioSourceNode: true, OscillatorNode: true, Oscillator: true, PannerNode: true, AudioPannerNode: true, webkitAudioPannerNode: true, ScriptProcessorNode: true, JavaScriptAudioNode: true, StereoPannerNode: true, WaveShaperNode: true, EventTarget: false, File: true, FileList: true, FileWriter: true, HTMLFormElement: true, Gamepad: true, History: true, HTMLCollection: true, HTMLFormControlsCollection: true, HTMLOptionsCollection: true, Location: true, MediaList: true, MIDIInputMap: true, MIDIOutputMap: true, MimeType: true, MimeTypeArray: true, Document: true, DocumentFragment: true, HTMLDocument: true, ShadowRoot: true, XMLDocument: true, Attr: true, DocumentType: true, Node: false, NodeList: true, RadioNodeList: true, Plugin: true, PluginArray: true, RTCStatsReport: true, HTMLSelectElement: true, SourceBuffer: true, SourceBufferList: true, SpeechGrammar: true, SpeechGrammarList: true, SpeechRecognitionResult: true, Storage: true, CSSStyleSheet: true, StyleSheet: true, TextTrack: true, TextTrackCue: true, VTTCue: true, TextTrackCueList: true, TextTrackList: true, TimeRanges: true, Touch: true, TouchList: true, TrackDefaultList: true, URL: true, VideoTrackList: true, CSSRuleList: true, ClientRect: true, DOMRect: true, GamepadList: true, NamedNodeMap: true, MozNamedAttrMap: true, SpeechRecognitionResultList: true, StyleSheetList: true, SVGLength: true, SVGLengthList: true, SVGNumber: true, SVGNumberList: true, SVGPointList: true, SVGStringList: true, SVGTransform: true, SVGTransformList: true, AudioBuffer: true, AudioParamMap: true, AudioTrackList: true, AudioContext: true, webkitAudioContext: true, BaseAudioContext: false, OfflineAudioContext: true});
+ hunkHelpers.setOrUpdateInterceptorsByTag({WebGL: J.Interceptor, AbortPaymentEvent: J.JavaScriptObject, AnimationEffectReadOnly: J.JavaScriptObject, AnimationEffectTiming: J.JavaScriptObject, AnimationEffectTimingReadOnly: J.JavaScriptObject, AnimationEvent: J.JavaScriptObject, AnimationPlaybackEvent: J.JavaScriptObject, AnimationTimeline: J.JavaScriptObject, AnimationWorkletGlobalScope: J.JavaScriptObject, ApplicationCacheErrorEvent: J.JavaScriptObject, AuthenticatorAssertionResponse: J.JavaScriptObject, AuthenticatorAttestationResponse: J.JavaScriptObject, AuthenticatorResponse: J.JavaScriptObject, BackgroundFetchClickEvent: J.JavaScriptObject, BackgroundFetchEvent: J.JavaScriptObject, BackgroundFetchFailEvent: J.JavaScriptObject, BackgroundFetchFetch: J.JavaScriptObject, BackgroundFetchManager: J.JavaScriptObject, BackgroundFetchSettledFetch: J.JavaScriptObject, BackgroundFetchedEvent: J.JavaScriptObject, BarProp: J.JavaScriptObject, BarcodeDetector: J.JavaScriptObject, BeforeInstallPromptEvent: J.JavaScriptObject, BeforeUnloadEvent: J.JavaScriptObject, BlobEvent: J.JavaScriptObject, BluetoothRemoteGATTDescriptor: J.JavaScriptObject, Body: J.JavaScriptObject, BudgetState: J.JavaScriptObject, CacheStorage: J.JavaScriptObject, CanMakePaymentEvent: J.JavaScriptObject, CanvasGradient: J.JavaScriptObject, CanvasPattern: J.JavaScriptObject, CanvasRenderingContext2D: J.JavaScriptObject, Client: J.JavaScriptObject, Clients: J.JavaScriptObject, ClipboardEvent: J.JavaScriptObject, CloseEvent: J.JavaScriptObject, CompositionEvent: J.JavaScriptObject, CookieStore: J.JavaScriptObject, Coordinates: J.JavaScriptObject, Credential: J.JavaScriptObject, CredentialUserData: J.JavaScriptObject, CredentialsContainer: J.JavaScriptObject, Crypto: J.JavaScriptObject, CryptoKey: J.JavaScriptObject, CSS: J.JavaScriptObject, CSSVariableReferenceValue: J.JavaScriptObject, CustomElementRegistry: J.JavaScriptObject, CustomEvent: J.JavaScriptObject, DataTransfer: J.JavaScriptObject, DataTransferItem: J.JavaScriptObject, DeprecatedStorageInfo: J.JavaScriptObject, DeprecatedStorageQuota: J.JavaScriptObject, DeprecationReport: J.JavaScriptObject, DetectedBarcode: J.JavaScriptObject, DetectedFace: J.JavaScriptObject, DetectedText: J.JavaScriptObject, DeviceAcceleration: J.JavaScriptObject, DeviceMotionEvent: J.JavaScriptObject, DeviceOrientationEvent: J.JavaScriptObject, DeviceRotationRate: J.JavaScriptObject, DirectoryEntry: J.JavaScriptObject, webkitFileSystemDirectoryEntry: J.JavaScriptObject, FileSystemDirectoryEntry: J.JavaScriptObject, DirectoryReader: J.JavaScriptObject, WebKitDirectoryReader: J.JavaScriptObject, webkitFileSystemDirectoryReader: J.JavaScriptObject, FileSystemDirectoryReader: J.JavaScriptObject, DocumentOrShadowRoot: J.JavaScriptObject, DocumentTimeline: J.JavaScriptObject, DOMError: J.JavaScriptObject, DOMImplementation: J.JavaScriptObject, Iterator: J.JavaScriptObject, DOMMatrix: J.JavaScriptObject, DOMMatrixReadOnly: J.JavaScriptObject, DOMParser: J.JavaScriptObject, DOMPoint: J.JavaScriptObject, DOMPointReadOnly: J.JavaScriptObject, DOMQuad: J.JavaScriptObject, DOMStringMap: J.JavaScriptObject, Entry: J.JavaScriptObject, webkitFileSystemEntry: J.JavaScriptObject, FileSystemEntry: J.JavaScriptObject, ErrorEvent: J.JavaScriptObject, Event: J.JavaScriptObject, InputEvent: J.JavaScriptObject, SubmitEvent: J.JavaScriptObject, ExtendableEvent: J.JavaScriptObject, ExtendableMessageEvent: J.JavaScriptObject, External: J.JavaScriptObject, FaceDetector: J.JavaScriptObject, FederatedCredential: J.JavaScriptObject, FetchEvent: J.JavaScriptObject, FileEntry: J.JavaScriptObject, webkitFileSystemFileEntry: J.JavaScriptObject, FileSystemFileEntry: J.JavaScriptObject, DOMFileSystem: J.JavaScriptObject, WebKitFileSystem: J.JavaScriptObject, webkitFileSystem: J.JavaScriptObject, FileSystem: J.JavaScriptObject, FocusEvent: J.JavaScriptObject, FontFace: J.JavaScriptObject, FontFaceSetLoadEvent: J.JavaScriptObject, FontFaceSource: J.JavaScriptObject, ForeignFetchEvent: J.JavaScriptObject, FormData: J.JavaScriptObject, GamepadButton: J.JavaScriptObject, GamepadEvent: J.JavaScriptObject, GamepadPose: J.JavaScriptObject, Geolocation: J.JavaScriptObject, Position: J.JavaScriptObject, GeolocationPosition: J.JavaScriptObject, HashChangeEvent: J.JavaScriptObject, Headers: J.JavaScriptObject, HTMLHyperlinkElementUtils: J.JavaScriptObject, IdleDeadline: J.JavaScriptObject, ImageBitmap: J.JavaScriptObject, ImageBitmapRenderingContext: J.JavaScriptObject, ImageCapture: J.JavaScriptObject, ImageData: J.JavaScriptObject, InputDeviceCapabilities: J.JavaScriptObject, InstallEvent: J.JavaScriptObject, IntersectionObserver: J.JavaScriptObject, IntersectionObserverEntry: J.JavaScriptObject, InterventionReport: J.JavaScriptObject, KeyboardEvent: J.JavaScriptObject, KeyframeEffect: J.JavaScriptObject, KeyframeEffectReadOnly: J.JavaScriptObject, MediaCapabilities: J.JavaScriptObject, MediaCapabilitiesInfo: J.JavaScriptObject, MediaDeviceInfo: J.JavaScriptObject, MediaEncryptedEvent: J.JavaScriptObject, MediaError: J.JavaScriptObject, MediaKeyMessageEvent: J.JavaScriptObject, MediaKeyStatusMap: J.JavaScriptObject, MediaKeySystemAccess: J.JavaScriptObject, MediaKeys: J.JavaScriptObject, MediaKeysPolicy: J.JavaScriptObject, MediaMetadata: J.JavaScriptObject, MediaQueryListEvent: J.JavaScriptObject, MediaSession: J.JavaScriptObject, MediaSettingsRange: J.JavaScriptObject, MediaStreamEvent: J.JavaScriptObject, MediaStreamTrackEvent: J.JavaScriptObject, MemoryInfo: J.JavaScriptObject, MessageChannel: J.JavaScriptObject, MessageEvent: J.JavaScriptObject, Metadata: J.JavaScriptObject, MIDIConnectionEvent: J.JavaScriptObject, MIDIMessageEvent: J.JavaScriptObject, MouseEvent: J.JavaScriptObject, DragEvent: J.JavaScriptObject, MutationEvent: J.JavaScriptObject, MutationObserver: J.JavaScriptObject, WebKitMutationObserver: J.JavaScriptObject, MutationRecord: J.JavaScriptObject, NavigationPreloadManager: J.JavaScriptObject, Navigator: J.JavaScriptObject, NavigatorAutomationInformation: J.JavaScriptObject, NavigatorConcurrentHardware: J.JavaScriptObject, NavigatorCookies: J.JavaScriptObject, NavigatorUserMediaError: J.JavaScriptObject, NodeFilter: J.JavaScriptObject, NodeIterator: J.JavaScriptObject, NonDocumentTypeChildNode: J.JavaScriptObject, NonElementParentNode: J.JavaScriptObject, NoncedElement: J.JavaScriptObject, NotificationEvent: J.JavaScriptObject, OffscreenCanvasRenderingContext2D: J.JavaScriptObject, OverconstrainedError: J.JavaScriptObject, PageTransitionEvent: J.JavaScriptObject, PaintRenderingContext2D: J.JavaScriptObject, PaintSize: J.JavaScriptObject, PaintWorkletGlobalScope: J.JavaScriptObject, PasswordCredential: J.JavaScriptObject, Path2D: J.JavaScriptObject, PaymentAddress: J.JavaScriptObject, PaymentInstruments: J.JavaScriptObject, PaymentManager: J.JavaScriptObject, PaymentRequestEvent: J.JavaScriptObject, PaymentRequestUpdateEvent: J.JavaScriptObject, PaymentResponse: J.JavaScriptObject, PerformanceEntry: J.JavaScriptObject, PerformanceLongTaskTiming: J.JavaScriptObject, PerformanceMark: J.JavaScriptObject, PerformanceMeasure: J.JavaScriptObject, PerformanceNavigation: J.JavaScriptObject, PerformanceNavigationTiming: J.JavaScriptObject, PerformanceObserver: J.JavaScriptObject, PerformanceObserverEntryList: J.JavaScriptObject, PerformancePaintTiming: J.JavaScriptObject, PerformanceResourceTiming: J.JavaScriptObject, PerformanceServerTiming: J.JavaScriptObject, PerformanceTiming: J.JavaScriptObject, Permissions: J.JavaScriptObject, PhotoCapabilities: J.JavaScriptObject, PointerEvent: J.JavaScriptObject, PopStateEvent: J.JavaScriptObject, PositionError: J.JavaScriptObject, GeolocationPositionError: J.JavaScriptObject, Presentation: J.JavaScriptObject, PresentationConnectionAvailableEvent: J.JavaScriptObject, PresentationConnectionCloseEvent: J.JavaScriptObject, PresentationReceiver: J.JavaScriptObject, ProgressEvent: J.JavaScriptObject, PromiseRejectionEvent: J.JavaScriptObject, PublicKeyCredential: J.JavaScriptObject, PushEvent: J.JavaScriptObject, PushManager: J.JavaScriptObject, PushMessageData: J.JavaScriptObject, PushSubscription: J.JavaScriptObject, PushSubscriptionOptions: J.JavaScriptObject, Range: J.JavaScriptObject, RelatedApplication: J.JavaScriptObject, ReportBody: J.JavaScriptObject, ReportingObserver: J.JavaScriptObject, ResizeObserver: J.JavaScriptObject, ResizeObserverEntry: J.JavaScriptObject, RTCCertificate: J.JavaScriptObject, RTCDataChannelEvent: J.JavaScriptObject, RTCDTMFToneChangeEvent: J.JavaScriptObject, RTCIceCandidate: J.JavaScriptObject, mozRTCIceCandidate: J.JavaScriptObject, RTCLegacyStatsReport: J.JavaScriptObject, RTCPeerConnectionIceEvent: J.JavaScriptObject, RTCRtpContributingSource: J.JavaScriptObject, RTCRtpReceiver: J.JavaScriptObject, RTCRtpSender: J.JavaScriptObject, RTCSessionDescription: J.JavaScriptObject, mozRTCSessionDescription: J.JavaScriptObject, RTCStatsResponse: J.JavaScriptObject, RTCTrackEvent: J.JavaScriptObject, Screen: J.JavaScriptObject, ScrollState: J.JavaScriptObject, ScrollTimeline: J.JavaScriptObject, SecurityPolicyViolationEvent: J.JavaScriptObject, Selection: J.JavaScriptObject, SensorErrorEvent: J.JavaScriptObject, SharedArrayBuffer: J.JavaScriptObject, SpeechRecognitionAlternative: J.JavaScriptObject, SpeechRecognitionError: J.JavaScriptObject, SpeechRecognitionEvent: J.JavaScriptObject, SpeechSynthesisEvent: J.JavaScriptObject, SpeechSynthesisVoice: J.JavaScriptObject, StaticRange: J.JavaScriptObject, StorageEvent: J.JavaScriptObject, StorageManager: J.JavaScriptObject, StyleMedia: J.JavaScriptObject, StylePropertyMap: J.JavaScriptObject, StylePropertyMapReadonly: J.JavaScriptObject, SyncEvent: J.JavaScriptObject, SyncManager: J.JavaScriptObject, TaskAttributionTiming: J.JavaScriptObject, TextDetector: J.JavaScriptObject, TextEvent: J.JavaScriptObject, TextMetrics: J.JavaScriptObject, TouchEvent: J.JavaScriptObject, TrackDefault: J.JavaScriptObject, TrackEvent: J.JavaScriptObject, TransitionEvent: J.JavaScriptObject, WebKitTransitionEvent: J.JavaScriptObject, TreeWalker: J.JavaScriptObject, TrustedHTML: J.JavaScriptObject, TrustedScriptURL: J.JavaScriptObject, TrustedURL: J.JavaScriptObject, UIEvent: J.JavaScriptObject, UnderlyingSourceBase: J.JavaScriptObject, URLSearchParams: J.JavaScriptObject, VRCoordinateSystem: J.JavaScriptObject, VRDeviceEvent: J.JavaScriptObject, VRDisplayCapabilities: J.JavaScriptObject, VRDisplayEvent: J.JavaScriptObject, VREyeParameters: J.JavaScriptObject, VRFrameData: J.JavaScriptObject, VRFrameOfReference: J.JavaScriptObject, VRPose: J.JavaScriptObject, VRSessionEvent: J.JavaScriptObject, VRStageBounds: J.JavaScriptObject, VRStageBoundsPoint: J.JavaScriptObject, VRStageParameters: J.JavaScriptObject, ValidityState: J.JavaScriptObject, VideoPlaybackQuality: J.JavaScriptObject, VideoTrack: J.JavaScriptObject, VTTRegion: J.JavaScriptObject, WheelEvent: J.JavaScriptObject, WindowClient: J.JavaScriptObject, WorkletAnimation: J.JavaScriptObject, WorkletGlobalScope: J.JavaScriptObject, XPathEvaluator: J.JavaScriptObject, XPathExpression: J.JavaScriptObject, XPathNSResolver: J.JavaScriptObject, XPathResult: J.JavaScriptObject, XMLSerializer: J.JavaScriptObject, XSLTProcessor: J.JavaScriptObject, Bluetooth: J.JavaScriptObject, BluetoothCharacteristicProperties: J.JavaScriptObject, BluetoothRemoteGATTServer: J.JavaScriptObject, BluetoothRemoteGATTService: J.JavaScriptObject, BluetoothUUID: J.JavaScriptObject, BudgetService: J.JavaScriptObject, Cache: J.JavaScriptObject, DOMFileSystemSync: J.JavaScriptObject, DirectoryEntrySync: J.JavaScriptObject, DirectoryReaderSync: J.JavaScriptObject, EntrySync: J.JavaScriptObject, FileEntrySync: J.JavaScriptObject, FileReaderSync: J.JavaScriptObject, FileWriterSync: J.JavaScriptObject, HTMLAllCollection: J.JavaScriptObject, Mojo: J.JavaScriptObject, MojoHandle: J.JavaScriptObject, MojoInterfaceRequestEvent: J.JavaScriptObject, MojoWatcher: J.JavaScriptObject, NFC: J.JavaScriptObject, PagePopupController: J.JavaScriptObject, Report: J.JavaScriptObject, Request: J.JavaScriptObject, ResourceProgressEvent: J.JavaScriptObject, Response: J.JavaScriptObject, SubtleCrypto: J.JavaScriptObject, USBAlternateInterface: J.JavaScriptObject, USBConfiguration: J.JavaScriptObject, USBConnectionEvent: J.JavaScriptObject, USBDevice: J.JavaScriptObject, USBEndpoint: J.JavaScriptObject, USBInTransferResult: J.JavaScriptObject, USBInterface: J.JavaScriptObject, USBIsochronousInTransferPacket: J.JavaScriptObject, USBIsochronousInTransferResult: J.JavaScriptObject, USBIsochronousOutTransferPacket: J.JavaScriptObject, USBIsochronousOutTransferResult: J.JavaScriptObject, USBOutTransferResult: J.JavaScriptObject, WorkerLocation: J.JavaScriptObject, WorkerNavigator: J.JavaScriptObject, Worklet: J.JavaScriptObject, IDBCursor: J.JavaScriptObject, IDBCursorWithValue: J.JavaScriptObject, IDBFactory: J.JavaScriptObject, IDBIndex: J.JavaScriptObject, IDBKeyRange: J.JavaScriptObject, IDBObjectStore: J.JavaScriptObject, IDBObservation: J.JavaScriptObject, IDBObserver: J.JavaScriptObject, IDBObserverChanges: J.JavaScriptObject, IDBVersionChangeEvent: J.JavaScriptObject, SVGAngle: J.JavaScriptObject, SVGAnimatedAngle: J.JavaScriptObject, SVGAnimatedBoolean: J.JavaScriptObject, SVGAnimatedEnumeration: J.JavaScriptObject, SVGAnimatedInteger: J.JavaScriptObject, SVGAnimatedLength: J.JavaScriptObject, SVGAnimatedLengthList: J.JavaScriptObject, SVGAnimatedNumber: J.JavaScriptObject, SVGAnimatedNumberList: J.JavaScriptObject, SVGAnimatedPreserveAspectRatio: J.JavaScriptObject, SVGAnimatedRect: J.JavaScriptObject, SVGAnimatedString: J.JavaScriptObject, SVGAnimatedTransformList: J.JavaScriptObject, SVGMatrix: J.JavaScriptObject, SVGPoint: J.JavaScriptObject, SVGPreserveAspectRatio: J.JavaScriptObject, SVGRect: J.JavaScriptObject, SVGUnitTypes: J.JavaScriptObject, AudioListener: J.JavaScriptObject, AudioParam: J.JavaScriptObject, AudioProcessingEvent: J.JavaScriptObject, AudioTrack: J.JavaScriptObject, AudioWorkletGlobalScope: J.JavaScriptObject, AudioWorkletProcessor: J.JavaScriptObject, OfflineAudioCompletionEvent: J.JavaScriptObject, PeriodicWave: J.JavaScriptObject, WebGLActiveInfo: J.JavaScriptObject, ANGLEInstancedArrays: J.JavaScriptObject, ANGLE_instanced_arrays: J.JavaScriptObject, WebGLBuffer: J.JavaScriptObject, WebGLCanvas: J.JavaScriptObject, WebGLColorBufferFloat: J.JavaScriptObject, WebGLCompressedTextureASTC: J.JavaScriptObject, WebGLCompressedTextureATC: J.JavaScriptObject, WEBGL_compressed_texture_atc: J.JavaScriptObject, WebGLCompressedTextureETC1: J.JavaScriptObject, WEBGL_compressed_texture_etc1: J.JavaScriptObject, WebGLCompressedTextureETC: J.JavaScriptObject, WebGLCompressedTexturePVRTC: J.JavaScriptObject, WEBGL_compressed_texture_pvrtc: J.JavaScriptObject, WebGLCompressedTextureS3TC: J.JavaScriptObject, WEBGL_compressed_texture_s3tc: J.JavaScriptObject, WebGLCompressedTextureS3TCsRGB: J.JavaScriptObject, WebGLContextEvent: J.JavaScriptObject, WebGLDebugRendererInfo: J.JavaScriptObject, WEBGL_debug_renderer_info: J.JavaScriptObject, WebGLDebugShaders: J.JavaScriptObject, WEBGL_debug_shaders: J.JavaScriptObject, WebGLDepthTexture: J.JavaScriptObject, WEBGL_depth_texture: J.JavaScriptObject, WebGLDrawBuffers: J.JavaScriptObject, WEBGL_draw_buffers: J.JavaScriptObject, EXTsRGB: J.JavaScriptObject, EXT_sRGB: J.JavaScriptObject, EXTBlendMinMax: J.JavaScriptObject, EXT_blend_minmax: J.JavaScriptObject, EXTColorBufferFloat: J.JavaScriptObject, EXTColorBufferHalfFloat: J.JavaScriptObject, EXTDisjointTimerQuery: J.JavaScriptObject, EXTDisjointTimerQueryWebGL2: J.JavaScriptObject, EXTFragDepth: J.JavaScriptObject, EXT_frag_depth: J.JavaScriptObject, EXTShaderTextureLOD: J.JavaScriptObject, EXT_shader_texture_lod: J.JavaScriptObject, EXTTextureFilterAnisotropic: J.JavaScriptObject, EXT_texture_filter_anisotropic: J.JavaScriptObject, WebGLFramebuffer: J.JavaScriptObject, WebGLGetBufferSubDataAsync: J.JavaScriptObject, WebGLLoseContext: J.JavaScriptObject, WebGLExtensionLoseContext: J.JavaScriptObject, WEBGL_lose_context: J.JavaScriptObject, OESElementIndexUint: J.JavaScriptObject, OES_element_index_uint: J.JavaScriptObject, OESStandardDerivatives: J.JavaScriptObject, OES_standard_derivatives: J.JavaScriptObject, OESTextureFloat: J.JavaScriptObject, OES_texture_float: J.JavaScriptObject, OESTextureFloatLinear: J.JavaScriptObject, OES_texture_float_linear: J.JavaScriptObject, OESTextureHalfFloat: J.JavaScriptObject, OES_texture_half_float: J.JavaScriptObject, OESTextureHalfFloatLinear: J.JavaScriptObject, OES_texture_half_float_linear: J.JavaScriptObject, OESVertexArrayObject: J.JavaScriptObject, OES_vertex_array_object: J.JavaScriptObject, WebGLProgram: J.JavaScriptObject, WebGLQuery: J.JavaScriptObject, WebGLRenderbuffer: J.JavaScriptObject, WebGLRenderingContext: J.JavaScriptObject, WebGL2RenderingContext: J.JavaScriptObject, WebGLSampler: J.JavaScriptObject, WebGLShader: J.JavaScriptObject, WebGLShaderPrecisionFormat: J.JavaScriptObject, WebGLSync: J.JavaScriptObject, WebGLTexture: J.JavaScriptObject, WebGLTimerQueryEXT: J.JavaScriptObject, WebGLTransformFeedback: J.JavaScriptObject, WebGLUniformLocation: J.JavaScriptObject, WebGLVertexArrayObject: J.JavaScriptObject, WebGLVertexArrayObjectOES: J.JavaScriptObject, WebGL2RenderingContextBase: J.JavaScriptObject, ArrayBuffer: A.NativeByteBuffer, ArrayBufferView: A.NativeTypedData, DataView: A.NativeByteData, Float32Array: A.NativeFloat32List, Float64Array: A.NativeFloat64List, Int16Array: A.NativeInt16List, Int32Array: A.NativeInt32List, Int8Array: A.NativeInt8List, Uint16Array: A.NativeUint16List, Uint32Array: A.NativeUint32List, Uint8ClampedArray: A.NativeUint8ClampedList, CanvasPixelArray: A.NativeUint8ClampedList, Uint8Array: A.NativeUint8List, HTMLAudioElement: A.HtmlElement, HTMLBRElement: A.HtmlElement, HTMLBaseElement: A.HtmlElement, HTMLBodyElement: A.HtmlElement, HTMLButtonElement: A.HtmlElement, HTMLCanvasElement: A.HtmlElement, HTMLContentElement: A.HtmlElement, HTMLDListElement: A.HtmlElement, HTMLDataElement: A.HtmlElement, HTMLDataListElement: A.HtmlElement, HTMLDetailsElement: A.HtmlElement, HTMLDialogElement: A.HtmlElement, HTMLDivElement: A.HtmlElement, HTMLEmbedElement: A.HtmlElement, HTMLFieldSetElement: A.HtmlElement, HTMLHRElement: A.HtmlElement, HTMLHeadElement: A.HtmlElement, HTMLHeadingElement: A.HtmlElement, HTMLHtmlElement: A.HtmlElement, HTMLIFrameElement: A.HtmlElement, HTMLImageElement: A.HtmlElement, HTMLInputElement: A.HtmlElement, HTMLLIElement: A.HtmlElement, HTMLLabelElement: A.HtmlElement, HTMLLegendElement: A.HtmlElement, HTMLLinkElement: A.HtmlElement, HTMLMapElement: A.HtmlElement, HTMLMediaElement: A.HtmlElement, HTMLMenuElement: A.HtmlElement, HTMLMetaElement: A.HtmlElement, HTMLMeterElement: A.HtmlElement, HTMLModElement: A.HtmlElement, HTMLOListElement: A.HtmlElement, HTMLObjectElement: A.HtmlElement, HTMLOptGroupElement: A.HtmlElement, HTMLOptionElement: A.HtmlElement, HTMLOutputElement: A.HtmlElement, HTMLParagraphElement: A.HtmlElement, HTMLParamElement: A.HtmlElement, HTMLPictureElement: A.HtmlElement, HTMLPreElement: A.HtmlElement, HTMLProgressElement: A.HtmlElement, HTMLQuoteElement: A.HtmlElement, HTMLScriptElement: A.HtmlElement, HTMLShadowElement: A.HtmlElement, HTMLSlotElement: A.HtmlElement, HTMLSourceElement: A.HtmlElement, HTMLSpanElement: A.HtmlElement, HTMLStyleElement: A.HtmlElement, HTMLTableCaptionElement: A.HtmlElement, HTMLTableCellElement: A.HtmlElement, HTMLTableDataCellElement: A.HtmlElement, HTMLTableHeaderCellElement: A.HtmlElement, HTMLTableColElement: A.HtmlElement, HTMLTableElement: A.HtmlElement, HTMLTableRowElement: A.HtmlElement, HTMLTableSectionElement: A.HtmlElement, HTMLTemplateElement: A.HtmlElement, HTMLTextAreaElement: A.HtmlElement, HTMLTimeElement: A.HtmlElement, HTMLTitleElement: A.HtmlElement, HTMLTrackElement: A.HtmlElement, HTMLUListElement: A.HtmlElement, HTMLUnknownElement: A.HtmlElement, HTMLVideoElement: A.HtmlElement, HTMLDirectoryElement: A.HtmlElement, HTMLFontElement: A.HtmlElement, HTMLFrameElement: A.HtmlElement, HTMLFrameSetElement: A.HtmlElement, HTMLMarqueeElement: A.HtmlElement, HTMLElement: A.HtmlElement, AccessibleNodeList: A.AccessibleNodeList, HTMLAnchorElement: A.AnchorElement, HTMLAreaElement: A.AreaElement, Blob: A.Blob, CDATASection: A.CharacterData, CharacterData: A.CharacterData, Comment: A.CharacterData, ProcessingInstruction: A.CharacterData, Text: A.CharacterData, CSSPerspective: A.CssPerspective, CSSCharsetRule: A.CssRule, CSSConditionRule: A.CssRule, CSSFontFaceRule: A.CssRule, CSSGroupingRule: A.CssRule, CSSImportRule: A.CssRule, CSSKeyframeRule: A.CssRule, MozCSSKeyframeRule: A.CssRule, WebKitCSSKeyframeRule: A.CssRule, CSSKeyframesRule: A.CssRule, MozCSSKeyframesRule: A.CssRule, WebKitCSSKeyframesRule: A.CssRule, CSSMediaRule: A.CssRule, CSSNamespaceRule: A.CssRule, CSSPageRule: A.CssRule, CSSRule: A.CssRule, CSSStyleRule: A.CssRule, CSSSupportsRule: A.CssRule, CSSViewportRule: A.CssRule, CSSStyleDeclaration: A.CssStyleDeclaration, MSStyleCSSProperties: A.CssStyleDeclaration, CSS2Properties: A.CssStyleDeclaration, CSSImageValue: A.CssStyleValue, CSSKeywordValue: A.CssStyleValue, CSSNumericValue: A.CssStyleValue, CSSPositionValue: A.CssStyleValue, CSSResourceValue: A.CssStyleValue, CSSUnitValue: A.CssStyleValue, CSSURLImageValue: A.CssStyleValue, CSSStyleValue: A.CssStyleValue, CSSMatrixComponent: A.CssTransformComponent, CSSRotation: A.CssTransformComponent, CSSScale: A.CssTransformComponent, CSSSkew: A.CssTransformComponent, CSSTranslation: A.CssTransformComponent, CSSTransformComponent: A.CssTransformComponent, CSSTransformValue: A.CssTransformValue, CSSUnparsedValue: A.CssUnparsedValue, DataTransferItemList: A.DataTransferItemList, DOMException: A.DomException, ClientRectList: A.DomRectList, DOMRectList: A.DomRectList, DOMRectReadOnly: A.DomRectReadOnly, DOMStringList: A.DomStringList, DOMTokenList: A.DomTokenList, MathMLElement: A.Element, SVGAElement: A.Element, SVGAnimateElement: A.Element, SVGAnimateMotionElement: A.Element, SVGAnimateTransformElement: A.Element, SVGAnimationElement: A.Element, SVGCircleElement: A.Element, SVGClipPathElement: A.Element, SVGDefsElement: A.Element, SVGDescElement: A.Element, SVGDiscardElement: A.Element, SVGEllipseElement: A.Element, SVGFEBlendElement: A.Element, SVGFEColorMatrixElement: A.Element, SVGFEComponentTransferElement: A.Element, SVGFECompositeElement: A.Element, SVGFEConvolveMatrixElement: A.Element, SVGFEDiffuseLightingElement: A.Element, SVGFEDisplacementMapElement: A.Element, SVGFEDistantLightElement: A.Element, SVGFEFloodElement: A.Element, SVGFEFuncAElement: A.Element, SVGFEFuncBElement: A.Element, SVGFEFuncGElement: A.Element, SVGFEFuncRElement: A.Element, SVGFEGaussianBlurElement: A.Element, SVGFEImageElement: A.Element, SVGFEMergeElement: A.Element, SVGFEMergeNodeElement: A.Element, SVGFEMorphologyElement: A.Element, SVGFEOffsetElement: A.Element, SVGFEPointLightElement: A.Element, SVGFESpecularLightingElement: A.Element, SVGFESpotLightElement: A.Element, SVGFETileElement: A.Element, SVGFETurbulenceElement: A.Element, SVGFilterElement: A.Element, SVGForeignObjectElement: A.Element, SVGGElement: A.Element, SVGGeometryElement: A.Element, SVGGraphicsElement: A.Element, SVGImageElement: A.Element, SVGLineElement: A.Element, SVGLinearGradientElement: A.Element, SVGMarkerElement: A.Element, SVGMaskElement: A.Element, SVGMetadataElement: A.Element, SVGPathElement: A.Element, SVGPatternElement: A.Element, SVGPolygonElement: A.Element, SVGPolylineElement: A.Element, SVGRadialGradientElement: A.Element, SVGRectElement: A.Element, SVGScriptElement: A.Element, SVGSetElement: A.Element, SVGStopElement: A.Element, SVGStyleElement: A.Element, SVGElement: A.Element, SVGSVGElement: A.Element, SVGSwitchElement: A.Element, SVGSymbolElement: A.Element, SVGTSpanElement: A.Element, SVGTextContentElement: A.Element, SVGTextElement: A.Element, SVGTextPathElement: A.Element, SVGTextPositioningElement: A.Element, SVGTitleElement: A.Element, SVGUseElement: A.Element, SVGViewElement: A.Element, SVGGradientElement: A.Element, SVGComponentTransferFunctionElement: A.Element, SVGFEDropShadowElement: A.Element, SVGMPathElement: A.Element, Element: A.Element, AbsoluteOrientationSensor: A.EventTarget, Accelerometer: A.EventTarget, AccessibleNode: A.EventTarget, AmbientLightSensor: A.EventTarget, Animation: A.EventTarget, ApplicationCache: A.EventTarget, DOMApplicationCache: A.EventTarget, OfflineResourceList: A.EventTarget, BackgroundFetchRegistration: A.EventTarget, BatteryManager: A.EventTarget, BroadcastChannel: A.EventTarget, CanvasCaptureMediaStreamTrack: A.EventTarget, DedicatedWorkerGlobalScope: A.EventTarget, EventSource: A.EventTarget, FileReader: A.EventTarget, FontFaceSet: A.EventTarget, Gyroscope: A.EventTarget, XMLHttpRequest: A.EventTarget, XMLHttpRequestEventTarget: A.EventTarget, XMLHttpRequestUpload: A.EventTarget, LinearAccelerationSensor: A.EventTarget, Magnetometer: A.EventTarget, MediaDevices: A.EventTarget, MediaKeySession: A.EventTarget, MediaQueryList: A.EventTarget, MediaRecorder: A.EventTarget, MediaSource: A.EventTarget, MediaStream: A.EventTarget, MediaStreamTrack: A.EventTarget, MessagePort: A.EventTarget, MIDIAccess: A.EventTarget, MIDIInput: A.EventTarget, MIDIOutput: A.EventTarget, MIDIPort: A.EventTarget, NetworkInformation: A.EventTarget, Notification: A.EventTarget, OffscreenCanvas: A.EventTarget, OrientationSensor: A.EventTarget, PaymentRequest: A.EventTarget, Performance: A.EventTarget, PermissionStatus: A.EventTarget, PresentationAvailability: A.EventTarget, PresentationConnection: A.EventTarget, PresentationConnectionList: A.EventTarget, PresentationRequest: A.EventTarget, RelativeOrientationSensor: A.EventTarget, RemotePlayback: A.EventTarget, RTCDataChannel: A.EventTarget, DataChannel: A.EventTarget, RTCDTMFSender: A.EventTarget, RTCPeerConnection: A.EventTarget, webkitRTCPeerConnection: A.EventTarget, mozRTCPeerConnection: A.EventTarget, ScreenOrientation: A.EventTarget, Sensor: A.EventTarget, ServiceWorker: A.EventTarget, ServiceWorkerContainer: A.EventTarget, ServiceWorkerGlobalScope: A.EventTarget, ServiceWorkerRegistration: A.EventTarget, SharedWorker: A.EventTarget, SharedWorkerGlobalScope: A.EventTarget, SpeechRecognition: A.EventTarget, webkitSpeechRecognition: A.EventTarget, SpeechSynthesis: A.EventTarget, SpeechSynthesisUtterance: A.EventTarget, VR: A.EventTarget, VRDevice: A.EventTarget, VRDisplay: A.EventTarget, VRSession: A.EventTarget, VisualViewport: A.EventTarget, WebSocket: A.EventTarget, Window: A.EventTarget, DOMWindow: A.EventTarget, Worker: A.EventTarget, WorkerGlobalScope: A.EventTarget, WorkerPerformance: A.EventTarget, BluetoothDevice: A.EventTarget, BluetoothRemoteGATTCharacteristic: A.EventTarget, Clipboard: A.EventTarget, MojoInterfaceInterceptor: A.EventTarget, USB: A.EventTarget, IDBDatabase: A.EventTarget, IDBOpenDBRequest: A.EventTarget, IDBVersionChangeRequest: A.EventTarget, IDBRequest: A.EventTarget, IDBTransaction: A.EventTarget, AnalyserNode: A.EventTarget, RealtimeAnalyserNode: A.EventTarget, AudioBufferSourceNode: A.EventTarget, AudioDestinationNode: A.EventTarget, AudioNode: A.EventTarget, AudioScheduledSourceNode: A.EventTarget, AudioWorkletNode: A.EventTarget, BiquadFilterNode: A.EventTarget, ChannelMergerNode: A.EventTarget, AudioChannelMerger: A.EventTarget, ChannelSplitterNode: A.EventTarget, AudioChannelSplitter: A.EventTarget, ConstantSourceNode: A.EventTarget, ConvolverNode: A.EventTarget, DelayNode: A.EventTarget, DynamicsCompressorNode: A.EventTarget, GainNode: A.EventTarget, AudioGainNode: A.EventTarget, IIRFilterNode: A.EventTarget, MediaElementAudioSourceNode: A.EventTarget, MediaStreamAudioDestinationNode: A.EventTarget, MediaStreamAudioSourceNode: A.EventTarget, OscillatorNode: A.EventTarget, Oscillator: A.EventTarget, PannerNode: A.EventTarget, AudioPannerNode: A.EventTarget, webkitAudioPannerNode: A.EventTarget, ScriptProcessorNode: A.EventTarget, JavaScriptAudioNode: A.EventTarget, StereoPannerNode: A.EventTarget, WaveShaperNode: A.EventTarget, EventTarget: A.EventTarget, File: A.File, FileList: A.FileList, FileWriter: A.FileWriter, HTMLFormElement: A.FormElement, Gamepad: A.Gamepad, History: A.History, HTMLCollection: A.HtmlCollection, HTMLFormControlsCollection: A.HtmlCollection, HTMLOptionsCollection: A.HtmlCollection, Location: A.Location, MediaList: A.MediaList, MIDIInputMap: A.MidiInputMap, MIDIOutputMap: A.MidiOutputMap, MimeType: A.MimeType, MimeTypeArray: A.MimeTypeArray, Document: A.Node, DocumentFragment: A.Node, HTMLDocument: A.Node, ShadowRoot: A.Node, XMLDocument: A.Node, Attr: A.Node, DocumentType: A.Node, Node: A.Node, NodeList: A.NodeList, RadioNodeList: A.NodeList, Plugin: A.Plugin, PluginArray: A.PluginArray, RTCStatsReport: A.RtcStatsReport, HTMLSelectElement: A.SelectElement, SourceBuffer: A.SourceBuffer, SourceBufferList: A.SourceBufferList, SpeechGrammar: A.SpeechGrammar, SpeechGrammarList: A.SpeechGrammarList, SpeechRecognitionResult: A.SpeechRecognitionResult, Storage: A.Storage, CSSStyleSheet: A.StyleSheet, StyleSheet: A.StyleSheet, TextTrack: A.TextTrack, TextTrackCue: A.TextTrackCue, VTTCue: A.TextTrackCue, TextTrackCueList: A.TextTrackCueList, TextTrackList: A.TextTrackList, TimeRanges: A.TimeRanges, Touch: A.Touch, TouchList: A.TouchList, TrackDefaultList: A.TrackDefaultList, URL: A.Url, VideoTrackList: A.VideoTrackList, CSSRuleList: A._CssRuleList, ClientRect: A._DomRect, DOMRect: A._DomRect, GamepadList: A._GamepadList, NamedNodeMap: A._NamedNodeMap, MozNamedAttrMap: A._NamedNodeMap, SpeechRecognitionResultList: A._SpeechRecognitionResultList, StyleSheetList: A._StyleSheetList, SVGLength: A.Length, SVGLengthList: A.LengthList, SVGNumber: A.Number, SVGNumberList: A.NumberList, SVGPointList: A.PointList, SVGStringList: A.StringList, SVGTransform: A.Transform, SVGTransformList: A.TransformList, AudioBuffer: A.AudioBuffer, AudioParamMap: A.AudioParamMap, AudioTrackList: A.AudioTrackList, AudioContext: A.BaseAudioContext, webkitAudioContext: A.BaseAudioContext, BaseAudioContext: A.BaseAudioContext, OfflineAudioContext: A.OfflineAudioContext});
+ hunkHelpers.setOrUpdateLeafTags({WebGL: true, AbortPaymentEvent: true, AnimationEffectReadOnly: true, AnimationEffectTiming: true, AnimationEffectTimingReadOnly: true, AnimationEvent: true, AnimationPlaybackEvent: true, AnimationTimeline: true, AnimationWorkletGlobalScope: true, ApplicationCacheErrorEvent: true, AuthenticatorAssertionResponse: true, AuthenticatorAttestationResponse: true, AuthenticatorResponse: true, BackgroundFetchClickEvent: true, BackgroundFetchEvent: true, BackgroundFetchFailEvent: true, BackgroundFetchFetch: true, BackgroundFetchManager: true, BackgroundFetchSettledFetch: true, BackgroundFetchedEvent: true, BarProp: true, BarcodeDetector: true, BeforeInstallPromptEvent: true, BeforeUnloadEvent: true, BlobEvent: true, BluetoothRemoteGATTDescriptor: true, Body: true, BudgetState: true, CacheStorage: true, CanMakePaymentEvent: true, CanvasGradient: true, CanvasPattern: true, CanvasRenderingContext2D: true, Client: true, Clients: true, ClipboardEvent: true, CloseEvent: true, CompositionEvent: true, CookieStore: true, Coordinates: true, Credential: true, CredentialUserData: true, CredentialsContainer: true, Crypto: true, CryptoKey: true, CSS: true, CSSVariableReferenceValue: true, CustomElementRegistry: true, CustomEvent: true, DataTransfer: true, DataTransferItem: true, DeprecatedStorageInfo: true, DeprecatedStorageQuota: true, DeprecationReport: true, DetectedBarcode: true, DetectedFace: true, DetectedText: true, DeviceAcceleration: true, DeviceMotionEvent: true, DeviceOrientationEvent: true, DeviceRotationRate: true, DirectoryEntry: true, webkitFileSystemDirectoryEntry: true, FileSystemDirectoryEntry: true, DirectoryReader: true, WebKitDirectoryReader: true, webkitFileSystemDirectoryReader: true, FileSystemDirectoryReader: true, DocumentOrShadowRoot: true, DocumentTimeline: true, DOMError: true, DOMImplementation: true, Iterator: true, DOMMatrix: true, DOMMatrixReadOnly: true, DOMParser: true, DOMPoint: true, DOMPointReadOnly: true, DOMQuad: true, DOMStringMap: true, Entry: true, webkitFileSystemEntry: true, FileSystemEntry: true, ErrorEvent: true, Event: true, InputEvent: true, SubmitEvent: true, ExtendableEvent: true, ExtendableMessageEvent: true, External: true, FaceDetector: true, FederatedCredential: true, FetchEvent: true, FileEntry: true, webkitFileSystemFileEntry: true, FileSystemFileEntry: true, DOMFileSystem: true, WebKitFileSystem: true, webkitFileSystem: true, FileSystem: true, FocusEvent: true, FontFace: true, FontFaceSetLoadEvent: true, FontFaceSource: true, ForeignFetchEvent: true, FormData: true, GamepadButton: true, GamepadEvent: true, GamepadPose: true, Geolocation: true, Position: true, GeolocationPosition: true, HashChangeEvent: true, Headers: true, HTMLHyperlinkElementUtils: true, IdleDeadline: true, ImageBitmap: true, ImageBitmapRenderingContext: true, ImageCapture: true, ImageData: true, InputDeviceCapabilities: true, InstallEvent: true, IntersectionObserver: true, IntersectionObserverEntry: true, InterventionReport: true, KeyboardEvent: true, KeyframeEffect: true, KeyframeEffectReadOnly: true, MediaCapabilities: true, MediaCapabilitiesInfo: true, MediaDeviceInfo: true, MediaEncryptedEvent: true, MediaError: true, MediaKeyMessageEvent: true, MediaKeyStatusMap: true, MediaKeySystemAccess: true, MediaKeys: true, MediaKeysPolicy: true, MediaMetadata: true, MediaQueryListEvent: true, MediaSession: true, MediaSettingsRange: true, MediaStreamEvent: true, MediaStreamTrackEvent: true, MemoryInfo: true, MessageChannel: true, MessageEvent: true, Metadata: true, MIDIConnectionEvent: true, MIDIMessageEvent: true, MouseEvent: true, DragEvent: true, MutationEvent: true, MutationObserver: true, WebKitMutationObserver: true, MutationRecord: true, NavigationPreloadManager: true, Navigator: true, NavigatorAutomationInformation: true, NavigatorConcurrentHardware: true, NavigatorCookies: true, NavigatorUserMediaError: true, NodeFilter: true, NodeIterator: true, NonDocumentTypeChildNode: true, NonElementParentNode: true, NoncedElement: true, NotificationEvent: true, OffscreenCanvasRenderingContext2D: true, OverconstrainedError: true, PageTransitionEvent: true, PaintRenderingContext2D: true, PaintSize: true, PaintWorkletGlobalScope: true, PasswordCredential: true, Path2D: true, PaymentAddress: true, PaymentInstruments: true, PaymentManager: true, PaymentRequestEvent: true, PaymentRequestUpdateEvent: true, PaymentResponse: true, PerformanceEntry: true, PerformanceLongTaskTiming: true, PerformanceMark: true, PerformanceMeasure: true, PerformanceNavigation: true, PerformanceNavigationTiming: true, PerformanceObserver: true, PerformanceObserverEntryList: true, PerformancePaintTiming: true, PerformanceResourceTiming: true, PerformanceServerTiming: true, PerformanceTiming: true, Permissions: true, PhotoCapabilities: true, PointerEvent: true, PopStateEvent: true, PositionError: true, GeolocationPositionError: true, Presentation: true, PresentationConnectionAvailableEvent: true, PresentationConnectionCloseEvent: true, PresentationReceiver: true, ProgressEvent: true, PromiseRejectionEvent: true, PublicKeyCredential: true, PushEvent: true, PushManager: true, PushMessageData: true, PushSubscription: true, PushSubscriptionOptions: true, Range: true, RelatedApplication: true, ReportBody: true, ReportingObserver: true, ResizeObserver: true, ResizeObserverEntry: true, RTCCertificate: true, RTCDataChannelEvent: true, RTCDTMFToneChangeEvent: true, RTCIceCandidate: true, mozRTCIceCandidate: true, RTCLegacyStatsReport: true, RTCPeerConnectionIceEvent: true, RTCRtpContributingSource: true, RTCRtpReceiver: true, RTCRtpSender: true, RTCSessionDescription: true, mozRTCSessionDescription: true, RTCStatsResponse: true, RTCTrackEvent: true, Screen: true, ScrollState: true, ScrollTimeline: true, SecurityPolicyViolationEvent: true, Selection: true, SensorErrorEvent: true, SharedArrayBuffer: true, SpeechRecognitionAlternative: true, SpeechRecognitionError: true, SpeechRecognitionEvent: true, SpeechSynthesisEvent: true, SpeechSynthesisVoice: true, StaticRange: true, StorageEvent: true, StorageManager: true, StyleMedia: true, StylePropertyMap: true, StylePropertyMapReadonly: true, SyncEvent: true, SyncManager: true, TaskAttributionTiming: true, TextDetector: true, TextEvent: true, TextMetrics: true, TouchEvent: true, TrackDefault: true, TrackEvent: true, TransitionEvent: true, WebKitTransitionEvent: true, TreeWalker: true, TrustedHTML: true, TrustedScriptURL: true, TrustedURL: true, UIEvent: true, UnderlyingSourceBase: true, URLSearchParams: true, VRCoordinateSystem: true, VRDeviceEvent: true, VRDisplayCapabilities: true, VRDisplayEvent: true, VREyeParameters: true, VRFrameData: true, VRFrameOfReference: true, VRPose: true, VRSessionEvent: true, VRStageBounds: true, VRStageBoundsPoint: true, VRStageParameters: true, ValidityState: true, VideoPlaybackQuality: true, VideoTrack: true, VTTRegion: true, WheelEvent: true, WindowClient: true, WorkletAnimation: true, WorkletGlobalScope: true, XPathEvaluator: true, XPathExpression: true, XPathNSResolver: true, XPathResult: true, XMLSerializer: true, XSLTProcessor: true, Bluetooth: true, BluetoothCharacteristicProperties: true, BluetoothRemoteGATTServer: true, BluetoothRemoteGATTService: true, BluetoothUUID: true, BudgetService: true, Cache: true, DOMFileSystemSync: true, DirectoryEntrySync: true, DirectoryReaderSync: true, EntrySync: true, FileEntrySync: true, FileReaderSync: true, FileWriterSync: true, HTMLAllCollection: true, Mojo: true, MojoHandle: true, MojoInterfaceRequestEvent: true, MojoWatcher: true, NFC: true, PagePopupController: true, Report: true, Request: true, ResourceProgressEvent: true, Response: true, SubtleCrypto: true, USBAlternateInterface: true, USBConfiguration: true, USBConnectionEvent: true, USBDevice: true, USBEndpoint: true, USBInTransferResult: true, USBInterface: true, USBIsochronousInTransferPacket: true, USBIsochronousInTransferResult: true, USBIsochronousOutTransferPacket: true, USBIsochronousOutTransferResult: true, USBOutTransferResult: true, WorkerLocation: true, WorkerNavigator: true, Worklet: true, IDBCursor: true, IDBCursorWithValue: true, IDBFactory: true, IDBIndex: true, IDBKeyRange: true, IDBObjectStore: true, IDBObservation: true, IDBObserver: true, IDBObserverChanges: true, IDBVersionChangeEvent: true, SVGAngle: true, SVGAnimatedAngle: true, SVGAnimatedBoolean: true, SVGAnimatedEnumeration: true, SVGAnimatedInteger: true, SVGAnimatedLength: true, SVGAnimatedLengthList: true, SVGAnimatedNumber: true, SVGAnimatedNumberList: true, SVGAnimatedPreserveAspectRatio: true, SVGAnimatedRect: true, SVGAnimatedString: true, SVGAnimatedTransformList: true, SVGMatrix: true, SVGPoint: true, SVGPreserveAspectRatio: true, SVGRect: true, SVGUnitTypes: true, AudioListener: true, AudioParam: true, AudioProcessingEvent: true, AudioTrack: true, AudioWorkletGlobalScope: true, AudioWorkletProcessor: true, OfflineAudioCompletionEvent: true, PeriodicWave: true, WebGLActiveInfo: true, ANGLEInstancedArrays: true, ANGLE_instanced_arrays: true, WebGLBuffer: true, WebGLCanvas: true, WebGLColorBufferFloat: true, WebGLCompressedTextureASTC: true, WebGLCompressedTextureATC: true, WEBGL_compressed_texture_atc: true, WebGLCompressedTextureETC1: true, WEBGL_compressed_texture_etc1: true, WebGLCompressedTextureETC: true, WebGLCompressedTexturePVRTC: true, WEBGL_compressed_texture_pvrtc: true, WebGLCompressedTextureS3TC: true, WEBGL_compressed_texture_s3tc: true, WebGLCompressedTextureS3TCsRGB: true, WebGLContextEvent: true, WebGLDebugRendererInfo: true, WEBGL_debug_renderer_info: true, WebGLDebugShaders: true, WEBGL_debug_shaders: true, WebGLDepthTexture: true, WEBGL_depth_texture: true, WebGLDrawBuffers: true, WEBGL_draw_buffers: true, EXTsRGB: true, EXT_sRGB: true, EXTBlendMinMax: true, EXT_blend_minmax: true, EXTColorBufferFloat: true, EXTColorBufferHalfFloat: true, EXTDisjointTimerQuery: true, EXTDisjointTimerQueryWebGL2: true, EXTFragDepth: true, EXT_frag_depth: true, EXTShaderTextureLOD: true, EXT_shader_texture_lod: true, EXTTextureFilterAnisotropic: true, EXT_texture_filter_anisotropic: true, WebGLFramebuffer: true, WebGLGetBufferSubDataAsync: true, WebGLLoseContext: true, WebGLExtensionLoseContext: true, WEBGL_lose_context: true, OESElementIndexUint: true, OES_element_index_uint: true, OESStandardDerivatives: true, OES_standard_derivatives: true, OESTextureFloat: true, OES_texture_float: true, OESTextureFloatLinear: true, OES_texture_float_linear: true, OESTextureHalfFloat: true, OES_texture_half_float: true, OESTextureHalfFloatLinear: true, OES_texture_half_float_linear: true, OESVertexArrayObject: true, OES_vertex_array_object: true, WebGLProgram: true, WebGLQuery: true, WebGLRenderbuffer: true, WebGLRenderingContext: true, WebGL2RenderingContext: true, WebGLSampler: true, WebGLShader: true, WebGLShaderPrecisionFormat: true, WebGLSync: true, WebGLTexture: true, WebGLTimerQueryEXT: true, WebGLTransformFeedback: true, WebGLUniformLocation: true, WebGLVertexArrayObject: true, WebGLVertexArrayObjectOES: true, WebGL2RenderingContextBase: true, ArrayBuffer: true, ArrayBufferView: false, DataView: true, Float32Array: true, Float64Array: true, Int16Array: true, Int32Array: true, Int8Array: true, Uint16Array: true, Uint32Array: true, Uint8ClampedArray: true, CanvasPixelArray: true, Uint8Array: false, HTMLAudioElement: true, HTMLBRElement: true, HTMLBaseElement: true, HTMLBodyElement: true, HTMLButtonElement: true, HTMLCanvasElement: true, HTMLContentElement: true, HTMLDListElement: true, HTMLDataElement: true, HTMLDataListElement: true, HTMLDetailsElement: true, HTMLDialogElement: true, HTMLDivElement: true, HTMLEmbedElement: true, HTMLFieldSetElement: true, HTMLHRElement: true, HTMLHeadElement: true, HTMLHeadingElement: true, HTMLHtmlElement: true, HTMLIFrameElement: true, HTMLImageElement: true, HTMLInputElement: true, HTMLLIElement: true, HTMLLabelElement: true, HTMLLegendElement: true, HTMLLinkElement: true, HTMLMapElement: true, HTMLMediaElement: true, HTMLMenuElement: true, HTMLMetaElement: true, HTMLMeterElement: true, HTMLModElement: true, HTMLOListElement: true, HTMLObjectElement: true, HTMLOptGroupElement: true, HTMLOptionElement: true, HTMLOutputElement: true, HTMLParagraphElement: true, HTMLParamElement: true, HTMLPictureElement: true, HTMLPreElement: true, HTMLProgressElement: true, HTMLQuoteElement: true, HTMLScriptElement: true, HTMLShadowElement: true, HTMLSlotElement: true, HTMLSourceElement: true, HTMLSpanElement: true, HTMLStyleElement: true, HTMLTableCaptionElement: true, HTMLTableCellElement: true, HTMLTableDataCellElement: true, HTMLTableHeaderCellElement: true, HTMLTableColElement: true, HTMLTableElement: true, HTMLTableRowElement: true, HTMLTableSectionElement: true, HTMLTemplateElement: true, HTMLTextAreaElement: true, HTMLTimeElement: true, HTMLTitleElement: true, HTMLTrackElement: true, HTMLUListElement: true, HTMLUnknownElement: true, HTMLVideoElement: true, HTMLDirectoryElement: true, HTMLFontElement: true, HTMLFrameElement: true, HTMLFrameSetElement: true, HTMLMarqueeElement: true, HTMLElement: false, AccessibleNodeList: true, HTMLAnchorElement: true, HTMLAreaElement: true, Blob: false, CDATASection: true, CharacterData: true, Comment: true, ProcessingInstruction: true, Text: true, CSSPerspective: true, CSSCharsetRule: true, CSSConditionRule: true, CSSFontFaceRule: true, CSSGroupingRule: true, CSSImportRule: true, CSSKeyframeRule: true, MozCSSKeyframeRule: true, WebKitCSSKeyframeRule: true, CSSKeyframesRule: true, MozCSSKeyframesRule: true, WebKitCSSKeyframesRule: true, CSSMediaRule: true, CSSNamespaceRule: true, CSSPageRule: true, CSSRule: true, CSSStyleRule: true, CSSSupportsRule: true, CSSViewportRule: true, CSSStyleDeclaration: true, MSStyleCSSProperties: true, CSS2Properties: true, CSSImageValue: true, CSSKeywordValue: true, CSSNumericValue: true, CSSPositionValue: true, CSSResourceValue: true, CSSUnitValue: true, CSSURLImageValue: true, CSSStyleValue: false, CSSMatrixComponent: true, CSSRotation: true, CSSScale: true, CSSSkew: true, CSSTranslation: true, CSSTransformComponent: false, CSSTransformValue: true, CSSUnparsedValue: true, DataTransferItemList: true, DOMException: true, ClientRectList: true, DOMRectList: true, DOMRectReadOnly: false, DOMStringList: true, DOMTokenList: true, MathMLElement: true, SVGAElement: true, SVGAnimateElement: true, SVGAnimateMotionElement: true, SVGAnimateTransformElement: true, SVGAnimationElement: true, SVGCircleElement: true, SVGClipPathElement: true, SVGDefsElement: true, SVGDescElement: true, SVGDiscardElement: true, SVGEllipseElement: true, SVGFEBlendElement: true, SVGFEColorMatrixElement: true, SVGFEComponentTransferElement: true, SVGFECompositeElement: true, SVGFEConvolveMatrixElement: true, SVGFEDiffuseLightingElement: true, SVGFEDisplacementMapElement: true, SVGFEDistantLightElement: true, SVGFEFloodElement: true, SVGFEFuncAElement: true, SVGFEFuncBElement: true, SVGFEFuncGElement: true, SVGFEFuncRElement: true, SVGFEGaussianBlurElement: true, SVGFEImageElement: true, SVGFEMergeElement: true, SVGFEMergeNodeElement: true, SVGFEMorphologyElement: true, SVGFEOffsetElement: true, SVGFEPointLightElement: true, SVGFESpecularLightingElement: true, SVGFESpotLightElement: true, SVGFETileElement: true, SVGFETurbulenceElement: true, SVGFilterElement: true, SVGForeignObjectElement: true, SVGGElement: true, SVGGeometryElement: true, SVGGraphicsElement: true, SVGImageElement: true, SVGLineElement: true, SVGLinearGradientElement: true, SVGMarkerElement: true, SVGMaskElement: true, SVGMetadataElement: true, SVGPathElement: true, SVGPatternElement: true, SVGPolygonElement: true, SVGPolylineElement: true, SVGRadialGradientElement: true, SVGRectElement: true, SVGScriptElement: true, SVGSetElement: true, SVGStopElement: true, SVGStyleElement: true, SVGElement: true, SVGSVGElement: true, SVGSwitchElement: true, SVGSymbolElement: true, SVGTSpanElement: true, SVGTextContentElement: true, SVGTextElement: true, SVGTextPathElement: true, SVGTextPositioningElement: true, SVGTitleElement: true, SVGUseElement: true, SVGViewElement: true, SVGGradientElement: true, SVGComponentTransferFunctionElement: true, SVGFEDropShadowElement: true, SVGMPathElement: true, Element: false, AbsoluteOrientationSensor: true, Accelerometer: true, AccessibleNode: true, AmbientLightSensor: true, Animation: true, ApplicationCache: true, DOMApplicationCache: true, OfflineResourceList: true, BackgroundFetchRegistration: true, BatteryManager: true, BroadcastChannel: true, CanvasCaptureMediaStreamTrack: true, DedicatedWorkerGlobalScope: true, EventSource: true, FileReader: true, FontFaceSet: true, Gyroscope: true, XMLHttpRequest: true, XMLHttpRequestEventTarget: true, XMLHttpRequestUpload: true, LinearAccelerationSensor: true, Magnetometer: true, MediaDevices: true, MediaKeySession: true, MediaQueryList: true, MediaRecorder: true, MediaSource: true, MediaStream: true, MediaStreamTrack: true, MessagePort: true, MIDIAccess: true, MIDIInput: true, MIDIOutput: true, MIDIPort: true, NetworkInformation: true, Notification: true, OffscreenCanvas: true, OrientationSensor: true, PaymentRequest: true, Performance: true, PermissionStatus: true, PresentationAvailability: true, PresentationConnection: true, PresentationConnectionList: true, PresentationRequest: true, RelativeOrientationSensor: true, RemotePlayback: true, RTCDataChannel: true, DataChannel: true, RTCDTMFSender: true, RTCPeerConnection: true, webkitRTCPeerConnection: true, mozRTCPeerConnection: true, ScreenOrientation: true, Sensor: true, ServiceWorker: true, ServiceWorkerContainer: true, ServiceWorkerGlobalScope: true, ServiceWorkerRegistration: true, SharedWorker: true, SharedWorkerGlobalScope: true, SpeechRecognition: true, webkitSpeechRecognition: true, SpeechSynthesis: true, SpeechSynthesisUtterance: true, VR: true, VRDevice: true, VRDisplay: true, VRSession: true, VisualViewport: true, WebSocket: true, Window: true, DOMWindow: true, Worker: true, WorkerGlobalScope: true, WorkerPerformance: true, BluetoothDevice: true, BluetoothRemoteGATTCharacteristic: true, Clipboard: true, MojoInterfaceInterceptor: true, USB: true, IDBDatabase: true, IDBOpenDBRequest: true, IDBVersionChangeRequest: true, IDBRequest: true, IDBTransaction: true, AnalyserNode: true, RealtimeAnalyserNode: true, AudioBufferSourceNode: true, AudioDestinationNode: true, AudioNode: true, AudioScheduledSourceNode: true, AudioWorkletNode: true, BiquadFilterNode: true, ChannelMergerNode: true, AudioChannelMerger: true, ChannelSplitterNode: true, AudioChannelSplitter: true, ConstantSourceNode: true, ConvolverNode: true, DelayNode: true, DynamicsCompressorNode: true, GainNode: true, AudioGainNode: true, IIRFilterNode: true, MediaElementAudioSourceNode: true, MediaStreamAudioDestinationNode: true, MediaStreamAudioSourceNode: true, OscillatorNode: true, Oscillator: true, PannerNode: true, AudioPannerNode: true, webkitAudioPannerNode: true, ScriptProcessorNode: true, JavaScriptAudioNode: true, StereoPannerNode: true, WaveShaperNode: true, EventTarget: false, File: true, FileList: true, FileWriter: true, HTMLFormElement: true, Gamepad: true, History: true, HTMLCollection: true, HTMLFormControlsCollection: true, HTMLOptionsCollection: true, Location: true, MediaList: true, MIDIInputMap: true, MIDIOutputMap: true, MimeType: true, MimeTypeArray: true, Document: true, DocumentFragment: true, HTMLDocument: true, ShadowRoot: true, XMLDocument: true, Attr: true, DocumentType: true, Node: false, NodeList: true, RadioNodeList: true, Plugin: true, PluginArray: true, RTCStatsReport: true, HTMLSelectElement: true, SourceBuffer: true, SourceBufferList: true, SpeechGrammar: true, SpeechGrammarList: true, SpeechRecognitionResult: true, Storage: true, CSSStyleSheet: true, StyleSheet: true, TextTrack: true, TextTrackCue: true, VTTCue: true, TextTrackCueList: true, TextTrackList: true, TimeRanges: true, Touch: true, TouchList: true, TrackDefaultList: true, URL: true, VideoTrackList: true, CSSRuleList: true, ClientRect: true, DOMRect: true, GamepadList: true, NamedNodeMap: true, MozNamedAttrMap: true, SpeechRecognitionResultList: true, StyleSheetList: true, SVGLength: true, SVGLengthList: true, SVGNumber: true, SVGNumberList: true, SVGPointList: true, SVGStringList: true, SVGTransform: true, SVGTransformList: true, AudioBuffer: true, AudioParamMap: true, AudioTrackList: true, AudioContext: true, webkitAudioContext: true, BaseAudioContext: false, OfflineAudioContext: true});
A.NativeTypedArray.$nativeSuperclassTag = "ArrayBufferView";
A._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin.$nativeSuperclassTag = "ArrayBufferView";
A._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin.$nativeSuperclassTag = "ArrayBufferView";
@@ -17203,6 +18217,9 @@
Function.prototype.call$1$2 = function(a, b) {
return this(a, b);
};
+ Function.prototype.call$1$0 = function() {
+ return this();
+ };
Function.prototype.call$2$3 = function(a, b, c) {
return this(a, b, c);
};
diff --git a/pkgs/test/lib/src/runner/executable_settings.dart b/pkgs/test/lib/src/runner/executable_settings.dart
index cf073de..cd67b93 100644
--- a/pkgs/test/lib/src/runner/executable_settings.dart
+++ b/pkgs/test/lib/src/runner/executable_settings.dart
@@ -34,10 +34,16 @@
/// `PROGRAMFILES(X64)` environment variables.
final String? _windowsExecutable;
+ /// The environment variable, if any, to use as an override for the default
+ /// path.
+ final String? _environmentOverride;
+
/// The path to the executable for the current operating system.
String get executable {
- final envVariable = Platform.environment['CHROME_EXECUTABLE'];
- if (envVariable != null) return envVariable;
+ if (_environmentOverride != null) {
+ final envVariable = Platform.environment[_environmentOverride];
+ if (envVariable != null) return envVariable;
+ }
if (Platform.isMacOS) return _macOSExecutable!;
if (!Platform.isWindows) return _linuxExecutable!;
@@ -172,11 +178,13 @@
String? linuxExecutable,
String? macOSExecutable,
String? windowsExecutable,
+ String? environmentOverride,
bool? headless})
: arguments = arguments == null ? const [] : List.unmodifiable(arguments),
_linuxExecutable = linuxExecutable,
_macOSExecutable = macOSExecutable,
_windowsExecutable = windowsExecutable,
+ _environmentOverride = environmentOverride,
_headless = headless;
/// Merges [this] with [other], with [other]'s settings taking priority.
diff --git a/pkgs/test/lib/src/runner/node/platform.dart b/pkgs/test/lib/src/runner/node/platform.dart
index e2df55c..9e42fa8 100644
--- a/pkgs/test/lib/src/runner/node/platform.dart
+++ b/pkgs/test/lib/src/runner/node/platform.dart
@@ -11,9 +11,8 @@
import 'package:package_config/package_config.dart';
import 'package:path/path.dart' as p;
import 'package:stream_channel/stream_channel.dart';
-// ignore: deprecated_member_use
import 'package:test_api/backend.dart'
- show Runtime, StackTraceMapper, SuitePlatform;
+ show Compiler, Runtime, StackTraceMapper, SuitePlatform;
import 'package:test_core/src/runner/application_exception.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/dart2js_compiler_pool.dart'; // ignore: implementation_imports
@@ -82,7 +81,11 @@
@override
Future<RunnerSuite> load(String path, SuitePlatform platform,
SuiteConfiguration suiteConfig, Map<String, Object?> message) async {
- var pair = await _loadChannel(path, platform.runtime, suiteConfig);
+ if (platform.compiler != Compiler.dart2js) {
+ throw StateError(
+ 'Unsupported compiler for the Node platform ${platform.compiler}.');
+ }
+ var pair = await _loadChannel(path, platform, suiteConfig);
var controller = deserializeSuite(
path, platform, suiteConfig, PluginEnvironment(), pair.first, message);
@@ -96,12 +99,14 @@
/// Returns that channel along with a [StackTraceMapper] representing the
/// source map for the compiled suite.
Future<Pair<StreamChannel<Object?>, StackTraceMapper?>> _loadChannel(
- String path, Runtime runtime, SuiteConfiguration suiteConfig) async {
+ String path,
+ SuitePlatform platform,
+ SuiteConfiguration suiteConfig) async {
final servers = await _loopback();
try {
- var pair =
- await _spawnProcess(path, runtime, suiteConfig, servers.first.port);
+ var pair = await _spawnProcess(
+ path, platform.runtime, suiteConfig, servers.first.port);
var process = pair.first;
// Forward Node's standard IO to the print handler so it's associated with
@@ -292,7 +297,7 @@
await _compilers.close();
if (_config.pubServeUrl == null) {
- Directory(_compiledDir).deleteSync(recursive: true);
+ await Directory(_compiledDir).deleteWithRetry();
} else {
_http!.close();
}
diff --git a/pkgs/test/lib/src/runner/wasm/platform.dart b/pkgs/test/lib/src/runner/wasm/platform.dart
index 437c9bb..803927c 100644
--- a/pkgs/test/lib/src/runner/wasm/platform.dart
+++ b/pkgs/test/lib/src/runner/wasm/platform.dart
@@ -14,8 +14,7 @@
import 'package:shelf_packages_handler/shelf_packages_handler.dart';
import 'package:shelf_static/shelf_static.dart';
import 'package:shelf_web_socket/shelf_web_socket.dart';
-// ignore: deprecated_member_use
-import 'package:test_api/backend.dart' show Runtime, SuitePlatform;
+import 'package:test_api/backend.dart' show Compiler, Runtime, SuitePlatform;
import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/package_version.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/platform.dart'; // ignore: implementation_imports
@@ -201,11 +200,16 @@
@override
Future<RunnerSuite?> load(String path, SuitePlatform platform,
SuiteConfiguration suiteConfig, Map<String, Object?> message) async {
+ if (platform.compiler != Compiler.dart2wasm) {
+ throw StateError(
+ 'Unsupported compiler for experimental-chrome-wasm platform '
+ '${platform.compiler}');
+ }
+
if (suiteConfig.precompiledPath != null) {
throw UnsupportedError(
'The wasm platform doesn\'t support precompiled suites');
}
-
var browser = platform.runtime;
assert(suiteConfig.runtimes.contains(browser.identifier));
@@ -216,6 +220,7 @@
// TODO: Support custom html?
Uri suiteUrl;
+
await _compileSuite(path, suiteConfig);
if (_closed) return null;
@@ -227,7 +232,8 @@
var browserManager = await _browserManagerFor(browser);
if (_closed || browserManager == null) return null;
- var suite = await browserManager.load(path, suiteUrl, suiteConfig, message);
+ var suite = await browserManager.load(
+ path, suiteUrl, suiteConfig, message, platform.compiler);
if (_closed) return null;
return suite;
}
@@ -351,9 +357,8 @@
browser.then((b) => b?.close()),
_server.close(),
_compilers.close(),
+ Directory(_compiledDir).deleteWithRetry(),
]);
-
- Directory(_compiledDir).deleteSync(recursive: true);
});
final _closeMemo = AsyncMemoizer<void>();
}
diff --git a/pkgs/test/lib/src/util/path_handler.dart b/pkgs/test/lib/src/util/path_handler.dart
index ee43351..10a8c4e 100644
--- a/pkgs/test/lib/src/util/path_handler.dart
+++ b/pkgs/test/lib/src/util/path_handler.dart
@@ -30,7 +30,7 @@
void add(String path, shelf.Handler handler) {
var node = _paths;
for (var component in p.url.split(path)) {
- node = node.children.putIfAbsent(component, () => _Node());
+ node = node.children.putIfAbsent(component, _Node.new);
}
node.handler = handler;
}
diff --git a/pkgs/test/lib/test.dart b/pkgs/test/lib/test.dart
index 961dae1..7bcc673 100644
--- a/pkgs/test/lib/test.dart
+++ b/pkgs/test/lib/test.dart
@@ -2,5 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+export 'package:matcher/expect.dart';
+// Deprecated exports not surfaced through focused libraries.
+// ignore: deprecated_member_use
+export 'package:matcher/src/expect/expect.dart' show ErrorFormatter;
+// ignore: deprecated_member_use
+export 'package:matcher/src/expect/expect_async.dart' show expectAsync;
+// ignore: deprecated_member_use
+export 'package:matcher/src/expect/throws_matcher.dart' show Throws, throws;
+// The non-deprecated API (through a deprecated import).
// ignore: deprecated_member_use
export 'package:test_core/test_core.dart';
diff --git a/pkgs/test/pubspec.yaml b/pkgs/test/pubspec.yaml
index d232530..872b96a 100644
--- a/pkgs/test/pubspec.yaml
+++ b/pkgs/test/pubspec.yaml
@@ -1,14 +1,14 @@
name: test
-version: 1.23.0-dev
+version: 1.24.7-wip
description: >-
A full featured library for writing and running Dart tests across platforms.
repository: https://github.com/dart-lang/test/tree/master/pkgs/test
environment:
- sdk: '>=2.18.0 <3.0.0'
+ sdk: ^3.0.0
dependencies:
- analyzer: '>=2.0.0 <6.0.0'
+ analyzer: '>=5.12.0 <7.0.0'
async: ^2.5.0
boolean_selector: ^2.1.0
collection: ^1.15.0
@@ -16,6 +16,11 @@
http_multi_server: ^3.0.0
io: ^1.0.0
js: ^0.6.4
+
+ # Use a tight version constraint to ensure that a constraint on matcher
+ # properly constrains all features it provides.
+ matcher: '>=0.12.16 <0.12.17'
+
node_preamble: ^2.0.0
package_config: ^2.0.0
path: ^1.8.0
@@ -27,17 +32,19 @@
source_span: ^1.8.0
stack_trace: ^1.10.0
stream_channel: ^2.1.0
+
+ # Use an exact version until the test_api and test_core package are stable.
+ test_api: 0.6.1
+ test_core: 0.5.6
+
typed_data: ^1.3.0
web_socket_channel: ^2.0.0
webkit_inspection_protocol: ^1.0.0
yaml: ^3.0.0
- # Use an exact version until the test_api and test_core package are stable.
- test_api: 0.4.18
- test_core: 0.4.23
dev_dependencies:
+ dart_flutter_team_lints: ^1.0.0
fake_async: ^1.0.0
glob: ^2.0.0
- lints: '>=1.0.0 <3.0.0'
test_descriptor: ^2.0.0
test_process: ^2.0.0
diff --git a/pkgs/test/test/runner/browser/chrome_test.dart b/pkgs/test/test/runner/browser/chrome_test.dart
index 3e97944..6f291b9 100644
--- a/pkgs/test/test/runner/browser/chrome_test.dart
+++ b/pkgs/test/test/runner/browser/chrome_test.dart
@@ -4,6 +4,7 @@
@TestOn('vm')
@Tags(['chrome'])
+library;
import 'package:test/src/runner/browser/chrome.dart';
import 'package:test/src/runner/executable_settings.dart';
diff --git a/pkgs/test/test/runner/browser/code_server.dart b/pkgs/test/test/runner/browser/code_server.dart
index 881aa89..85705cc 100644
--- a/pkgs/test/test/runner/browser/code_server.dart
+++ b/pkgs/test/test/runner/browser/code_server.dart
@@ -9,7 +9,7 @@
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_web_socket/shelf_web_socket.dart';
-import 'package:test/test.dart' show printOnFailure, TestFailure;
+import 'package:test/test.dart' show TestFailure, printOnFailure;
import 'package:web_socket_channel/web_socket_channel.dart';
/// A class that serves Dart and/or JS code and receives WebSocket connections.
diff --git a/pkgs/test/test/runner/browser/compact_reporter_test.dart b/pkgs/test/test/runner/browser/compact_reporter_test.dart
index 4d1cbb4..753ffa1 100644
--- a/pkgs/test/test/runner/browser/compact_reporter_test.dart
+++ b/pkgs/test/test/runner/browser/compact_reporter_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
@@ -28,7 +29,7 @@
['-p', 'chrome', '-p', 'vm', '-j', '1', 'test.dart'],
reporter: 'compact');
- expect(test.stdout, containsInOrder(['[Chrome]', '[VM]']));
+ expect(test.stdout, containsInOrder(['[Chrome, Dart2Js]', '[VM, Kernel]']));
await test.shouldExit(0);
}, tags: 'chrome');
}
diff --git a/pkgs/test/test/runner/browser/expanded_reporter_test.dart b/pkgs/test/test/runner/browser/expanded_reporter_test.dart
index dab8d52..875aaba 100644
--- a/pkgs/test/test/runner/browser/expanded_reporter_test.dart
+++ b/pkgs/test/test/runner/browser/expanded_reporter_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
@@ -28,8 +29,8 @@
'test.dart'
]);
- expect(test.stdoutStream(), emitsThrough(contains('[VM]')));
- expect(test.stdout, emitsThrough(contains('[Chrome]')));
+ expect(test.stdoutStream(), emitsThrough(contains('[VM, Kernel]')));
+ expect(test.stdout, emitsThrough(contains('[Chrome, Dart2Js]')));
await test.shouldExit(0);
}, tags: ['chrome']);
}
diff --git a/pkgs/test/test/runner/browser/firefox_html_test.dart b/pkgs/test/test/runner/browser/firefox_html_test.dart
index 0ba4111..c9a5302 100644
--- a/pkgs/test/test/runner/browser/firefox_html_test.dart
+++ b/pkgs/test/test/runner/browser/firefox_html_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('firefox')
+library;
import 'package:test/src/runner/browser/dom.dart' as dom;
import 'package:test/test.dart';
diff --git a/pkgs/test/test/runner/browser/firefox_test.dart b/pkgs/test/test/runner/browser/firefox_test.dart
index a1189d8..7aa0074 100644
--- a/pkgs/test/test/runner/browser/firefox_test.dart
+++ b/pkgs/test/test/runner/browser/firefox_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
@Tags(['firefox'])
+library;
import 'package:test/src/runner/browser/firefox.dart';
import 'package:test/src/runner/executable_settings.dart';
@@ -79,4 +80,36 @@
expect(test.stdout, emitsThrough(contains('-1: Some tests failed.')));
await test.shouldExit(1);
});
+
+ test('can override firefox location with FIREFOX_EXECUTABLE var', () async {
+ await d.file('test.dart', '''
+import 'package:test/test.dart';
+
+void main() {
+ test("success", () {});
+}
+''').create();
+ var test = await runTest(['-p', 'firefox', 'test.dart'],
+ environment: {'FIREFOX_EXECUTABLE': '/some/bad/path'});
+ expect(test.stdout, emitsThrough(contains('Failed to run Firefox:')));
+ await test.shouldExit(1);
+ });
+
+ test('not impacted by CHROME_EXECUTABLE var', () async {
+ await d.file('test.dart', '''
+import 'dart:html';
+
+import 'package:test/test.dart';
+
+void main() {
+ test("success", () {
+ assert(window.navigator.vendor != 'Google Inc.');
+ });
+}
+''').create();
+ var test = await runTest(['-p', 'firefox', 'test.dart'],
+ environment: {'CHROME_EXECUTABLE': '/some/bad/path'});
+ expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
+ await test.shouldExit(0);
+ });
}
diff --git a/pkgs/test/test/runner/browser/internet_explorer_test.dart b/pkgs/test/test/runner/browser/internet_explorer_test.dart
index 9f3f5b8..02fe29e 100644
--- a/pkgs/test/test/runner/browser/internet_explorer_test.dart
+++ b/pkgs/test/test/runner/browser/internet_explorer_test.dart
@@ -4,6 +4,7 @@
@TestOn('vm')
@Tags(['ie'])
+library;
import 'package:test/src/runner/browser/internet_explorer.dart';
import 'package:test/src/runner/executable_settings.dart';
diff --git a/pkgs/test/test/runner/browser/loader_test.dart b/pkgs/test/test/runner/browser/loader_test.dart
index 495cf3a..17cdb9a 100644
--- a/pkgs/test/test/runner/browser/loader_test.dart
+++ b/pkgs/test/test/runner/browser/loader_test.dart
@@ -4,6 +4,8 @@
@TestOn('vm')
@Tags(['chrome'])
+library;
+
import 'dart:io';
import 'package:path/path.dart' as p;
@@ -67,6 +69,7 @@
test('returns a suite with the file path and platform', () {
expect(suite.path, equals(p.join(d.sandbox, 'a_test.dart')));
expect(suite.platform.runtime, equals(Runtime.chrome));
+ expect(suite.platform.compiler, equals(Runtime.chrome.defaultCompiler));
});
test('returns tests with the correct names', () {
@@ -142,8 +145,10 @@
.cast<RunnerSuite>()
.toList();
expect(suites[0].platform.runtime, equals(Runtime.vm));
+ expect(suites[0].platform.compiler, equals(Runtime.vm.defaultCompiler));
expect(suites[0].path, equals(path));
expect(suites[1].platform.runtime, equals(Runtime.chrome));
+ expect(suites[1].platform.compiler, equals(Runtime.chrome.defaultCompiler));
expect(suites[1].path, equals(path));
for (var suite in suites) {
diff --git a/pkgs/test/test/runner/browser/microsoft_edge_test.dart b/pkgs/test/test/runner/browser/microsoft_edge_test.dart
new file mode 100644
index 0000000..2d3e4cf
--- /dev/null
+++ b/pkgs/test/test/runner/browser/microsoft_edge_test.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('vm')
+@Tags(['edge'])
+library;
+
+import 'package:test/src/runner/browser/microsoft_edge.dart';
+import 'package:test/src/runner/executable_settings.dart';
+import 'package:test/test.dart';
+import 'package:test_descriptor/test_descriptor.dart' as d;
+
+import '../../io.dart';
+import '../../utils.dart';
+import 'code_server.dart';
+
+void main() {
+ setUpAll(precompileTestExecutable);
+
+ test('starts edge with the given URL', () async {
+ var server = await CodeServer.start();
+
+ server.handleJavaScript('''
+var webSocket = new WebSocket(window.location.href.replace("http://", "ws://"));
+webSocket.addEventListener("open", function() {
+ webSocket.send("loaded!");
+});
+''');
+ var webSocket = server.handleWebSocket();
+
+ var edge = MicrosoftEdge(server.url, configuration());
+ addTearDown(() => edge.close());
+
+ expect(await (await webSocket).stream.first, equals('loaded!'));
+ }, timeout: Timeout.factor(2));
+
+ test('reports an error in onExit', () {
+ var edge = MicrosoftEdge(Uri.parse('https://dart.dev'), configuration(),
+ settings: ExecutableSettings(
+ linuxExecutable: '_does_not_exist',
+ macOSExecutable: '_does_not_exist',
+ windowsExecutable: '_does_not_exist'));
+ expect(
+ edge.onExit,
+ throwsA(isApplicationException(
+ startsWith('Failed to run Edge: $noSuchFileMessage'))));
+ });
+
+ test('can run successful tests', () async {
+ await d.file('test.dart', '''
+import 'package:test/test.dart';
+
+void main() {
+ test("success", () {});
+}
+''').create();
+
+ var test = await runTest(['-p', 'edge', 'test.dart']);
+ expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
+ await test.shouldExit(0);
+ });
+
+ test('can run failing tests', () async {
+ await d.file('test.dart', '''
+import 'package:test/test.dart';
+
+void main() {
+ test("failure", () => throw TestFailure("oh no"));
+}
+''').create();
+
+ var test = await runTest(['-p', 'edge', 'test.dart']);
+ expect(test.stdout, emitsThrough(contains('-1: Some tests failed.')));
+ await test.shouldExit(1);
+ });
+
+ test('can override edge location with MS_EDGE_EXECUTABLE var', () async {
+ await d.file('test.dart', '''
+import 'package:test/test.dart';
+
+void main() {
+ test("success", () {});
+}
+''').create();
+ var test = await runTest(['-p', 'edge', 'test.dart'],
+ environment: {'MS_EDGE_EXECUTABLE': '/some/bad/path'});
+ expect(test.stdout, emitsThrough(contains('Failed to run Edge:')));
+ await test.shouldExit(1);
+ });
+}
diff --git a/pkgs/test/test/runner/browser/runner_test.dart b/pkgs/test/test/runner/browser/runner_test.dart
index c5fcb65..322c24a 100644
--- a/pkgs/test/test/runner/browser/runner_test.dart
+++ b/pkgs/test/test/runner/browser/runner_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'dart:convert';
import 'package:test/test.dart';
@@ -38,7 +40,7 @@
test.stdout,
containsInOrder([
'Error: Compilation failed.',
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": dart2js failed.'
]));
await test.shouldExit(1);
@@ -51,7 +53,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": oh no'
]));
await test.shouldExit(1);
@@ -64,7 +66,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": No top-level main() function defined.'
]));
await test.shouldExit(1);
@@ -77,7 +79,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": Top-level main getter is not a function.'
]));
await test.shouldExit(1);
@@ -90,7 +92,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": Top-level main() function takes arguments.'
]));
await test.shouldExit(1);
@@ -111,7 +113,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": "test.html" must contain '
'<script src="packages/test/dart.js"></script>.'
]));
@@ -133,7 +135,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": Expected exactly 1 '
'<link rel="x-dart-test"> in test.html, found 0.'
]));
@@ -157,7 +159,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": Expected exactly 1 '
'<link rel="x-dart-test"> in test.html, found 2.'
]));
@@ -180,7 +182,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": Expected <link rel="x-dart-test"> in '
'test.html to have an "href" attribute.'
]));
@@ -203,7 +205,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": Failed to load script at '
]));
await test.shouldExit(1);
@@ -246,7 +248,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": "test.html" must contain '
'<script src="packages/test/dart.js"></script>.'
]));
@@ -270,7 +272,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": "html_template.html.tpl" does not exist or is not readable'
]));
await test.shouldExit(1);
@@ -293,7 +295,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": "html_template.html.tpl" must contain exactly one {{testScript}} placeholder'
]));
await test.shouldExit(1);
@@ -318,7 +320,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": "html_template.html.tpl" must contain exactly one {{testScript}} placeholder'
]));
await test.shouldExit(1);
@@ -338,7 +340,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": "html_template.html.tpl" must contain '
'<script src="packages/test/dart.js"></script>.'
]));
@@ -364,7 +366,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": template file "test.html" cannot be named '
'like the test file.'
]));
diff --git a/pkgs/test/test/runner/browser/safari_test.dart b/pkgs/test/test/runner/browser/safari_test.dart
index 7fa839b..d37db95 100644
--- a/pkgs/test/test/runner/browser/safari_test.dart
+++ b/pkgs/test/test/runner/browser/safari_test.dart
@@ -4,6 +4,7 @@
@TestOn('vm')
@Tags(['safari'])
+library;
import 'package:test/src/runner/browser/safari.dart';
import 'package:test/src/runner/executable_settings.dart';
@@ -80,4 +81,18 @@
expect(test.stdout, emitsThrough(contains('-1: Some tests failed.')));
await test.shouldExit(1);
});
+
+ test('can override safari location with SAFARI_EXECUTABLE var', () async {
+ await d.file('test.dart', '''
+import 'package:test/test.dart';
+
+void main() {
+ test("success", () {});
+}
+''').create();
+ var test = await runTest(['-p', 'safari', 'test.dart'],
+ environment: {'SAFARI_EXECUTABLE': '/some/bad/path'});
+ expect(test.stdout, emitsThrough(contains('Failed to run Safari:')));
+ await test.shouldExit(1);
+ });
}
diff --git a/pkgs/test/test/runner/compact_reporter_test.dart b/pkgs/test/test/runner/compact_reporter_test.dart
index 741a10d..c935e02 100644
--- a/pkgs/test/test/runner/compact_reporter_test.dart
+++ b/pkgs/test/test/runner/compact_reporter_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:async';
import 'dart:io';
diff --git a/pkgs/test/test/runner/compiler_runtime_matrix_test.dart b/pkgs/test/test/runner/compiler_runtime_matrix_test.dart
new file mode 100644
index 0000000..cef5815
--- /dev/null
+++ b/pkgs/test/test/runner/compiler_runtime_matrix_test.dart
@@ -0,0 +1,166 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('vm')
+library;
+
+import 'dart:io';
+
+import 'package:test/test.dart';
+import 'package:test_api/backend.dart';
+import 'package:test_descriptor/test_descriptor.dart' as d;
+
+import '../io.dart';
+
+void main() {
+ setUpAll(() async {
+ await precompileTestExecutable();
+ });
+
+ for (var runtime in Runtime.builtIn) {
+ for (var compiler in runtime.supportedCompilers) {
+ // Ignore the platforms we can't run on this OS.
+ if (runtime == Runtime.internetExplorer && !Platform.isWindows ||
+ runtime == Runtime.safari && !Platform.isMacOS) {
+ continue;
+ }
+ group('--runtime ${runtime.identifier} --compiler ${compiler.identifier}',
+ () {
+ final testArgs = [
+ 'test.dart',
+ '-p',
+ runtime.identifier,
+ '-c',
+ compiler.identifier
+ ];
+
+ test('can run passing tests', () async {
+ await d.file('test.dart', _goodTest).create();
+ var test = await runTest(testArgs);
+
+ expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
+ await test.shouldExit(0);
+ });
+
+ test('fails gracefully for invalid code', () async {
+ await d.file('test.dart', _compileErrorTest).create();
+ var test = await runTest(testArgs);
+
+ expect(
+ test.stdout,
+ containsInOrder([
+ "Error: A value of type 'String' can't be assigned to a variable of type 'int'.",
+ "int x = 'hello';",
+ ]));
+
+ await test.shouldExit(1);
+ });
+
+ test('fails gracefully for test failures', () async {
+ await d.file('test.dart', _failingTest).create();
+ var test = await runTest(testArgs);
+
+ expect(
+ test.stdout,
+ containsInOrder([
+ 'Expected: <2>',
+ 'Actual: <1>',
+ 'test.dart 5',
+ '+0 -1: Some tests failed.',
+ ]));
+
+ await test.shouldExit(1);
+ });
+
+ test('fails gracefully if a test file throws in main', () async {
+ await d.file('test.dart', _throwingTest).create();
+ var test = await runTest(testArgs);
+ expect(
+ test.stdout,
+ containsInOrder([
+ '-1: [${runtime.name}, ${compiler.name}] loading test.dart [E]',
+ 'Failed to load "test.dart": oh no'
+ ]));
+ await test.shouldExit(1);
+ });
+
+ test('captures prints', () async {
+ await d.file('test.dart', _testWithPrints).create();
+ var test = await runTest([...testArgs, '-r', 'json']);
+
+ expect(
+ test.stdout,
+ containsInOrder([
+ '"messageType":"print","message":"hello","type":"print"',
+ ]));
+
+ await test.shouldExit(0);
+ });
+
+ if (runtime.isDartVM) {
+ test('forwards stdout/stderr', () async {
+ await d.file('test.dart', _testWithStdOutAndErr).create();
+ var test = await runTest(testArgs);
+
+ expect(test.stdout, emitsThrough('hello'));
+ expect(test.stderr, emits('world'));
+ await test.shouldExit(0);
+ });
+ }
+ },
+ skip: compiler == Compiler.dart2wasm
+ ? 'Wasm tests are experimental and require special setup'
+ : [Runtime.firefox, Runtime.nodeJS, Runtime.internetExplorer]
+ .contains(runtime) &&
+ Platform.isWindows
+ ? 'https://github.com/dart-lang/test/issues/1942'
+ : null);
+ }
+ }
+}
+
+final _goodTest = '''
+ import 'package:test/test.dart';
+
+ void main() {
+ test("success", () {});
+ }
+''';
+
+final _failingTest = '''
+ import 'package:test/test.dart';
+
+ void main() {
+ test("failure", () {
+ expect(1, 2);
+ });
+ }
+''';
+
+final _compileErrorTest = '''
+int x = 'hello';
+
+void main() {}
+''';
+
+final _throwingTest = "void main() => throw 'oh no';";
+
+final _testWithPrints = '''
+import 'package:test/test.dart';
+
+void main() {
+ print('hello');
+ test('success', () {});
+}''';
+
+final _testWithStdOutAndErr = '''
+import 'dart:io';
+import 'package:test/test.dart';
+
+void main() async {
+ stdout.writeln('hello');
+ await stdout.flush();
+ stderr.writeln('world');
+ test('success', () {});
+}''';
diff --git a/pkgs/test/test/runner/compiler_test.dart b/pkgs/test/test/runner/compiler_test.dart
new file mode 100644
index 0000000..5cf7a47
--- /dev/null
+++ b/pkgs/test/test/runner/compiler_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('vm')
+library;
+
+import 'package:test/test.dart';
+import 'package:test_descriptor/test_descriptor.dart' as d;
+
+import '../io.dart';
+
+final _test = '''
+ import 'package:test/test.dart';
+
+ void main() {
+ test("success", () {});
+ }
+''';
+
+void main() {
+ setUpAll(() async {
+ await precompileTestExecutable();
+ await d.file('test.dart', _test).create();
+ });
+
+ group('--compiler', () {
+ test(
+ 'uses the default compiler if none other is specified for the platform',
+ () async {
+ var test =
+ await runTest(['test.dart', '-p', 'chrome,vm', '-c', 'dart2js']);
+
+ expect(test.stdout, emitsThrough(contains('[Chrome, Dart2Js]')));
+ expect(test.stdout, emitsThrough(contains('[VM, Kernel]')));
+ expect(test.stdout, emitsThrough(contains('+2: All tests passed!')));
+ await test.shouldExit(0);
+ });
+
+ test('runs all supported compiler and platform combinations', () async {
+ var test = await runTest(
+ ['test.dart', '-p', 'chrome,vm', '-c', 'dart2js,kernel,source']);
+
+ expect(test.stdout, emitsThrough(contains('[Chrome, Dart2Js]')));
+ expect(test.stdout, emitsThrough(contains('[VM, Kernel]')));
+ expect(test.stdout, emitsThrough(contains('[VM, Source]')));
+ expect(test.stdout, emitsThrough(contains('+3: All tests passed!')));
+ await test.shouldExit(0);
+ });
+
+ test('supports platform selectors', () async {
+ var test = await runTest(
+ ['test.dart', '-p', 'vm', '-c', 'vm:source,browser:kernel']);
+
+ expect(test.stdout, emitsThrough(contains('[VM, Source]')));
+ expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
+ await test.shouldExit(0);
+ });
+
+ test(
+ 'will only run a given test once for each compiler, even if there are '
+ 'multiple matches', () async {
+ var test =
+ await runTest(['test.dart', '-p', 'vm', '-c', 'vm:source,source']);
+
+ expect(test.stdout, emitsThrough(contains('[VM, Source]')));
+ expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
+ await test.shouldExit(0);
+ });
+
+ test('fails on unknown compilers', () async {
+ var test = await runTest(['test.dart', '-c', 'fake']);
+ expect(test.stderr, emitsThrough(contains('Invalid compiler `fake`')));
+ await test.shouldExit(64);
+ });
+ });
+}
diff --git a/pkgs/test/test/runner/configuration/compiler_test.dart b/pkgs/test/test/runner/configuration/compiler_test.dart
new file mode 100644
index 0000000..d8f8d33
--- /dev/null
+++ b/pkgs/test/test/runner/configuration/compiler_test.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('vm')
+library;
+
+import 'dart:convert';
+
+import 'package:test/test.dart';
+import 'package:test_descriptor/test_descriptor.dart' as d;
+
+import '../../io.dart';
+
+void main() {
+ setUpAll(precompileTestExecutable);
+
+ group('compilers', () {
+ test('uses specified compilers for supporting platforms', () async {
+ await d
+ .file(
+ 'dart_test.yaml',
+ jsonEncode({
+ 'compilers': ['source']
+ }))
+ .create();
+
+ await d.file('test.dart', '''
+ import 'package:test/test.dart';
+
+ void main() {
+ test("test", () {});
+ }
+ ''').create();
+
+ var test = await runTest(['-p', 'chrome,vm', 'test.dart']);
+ expect(
+ test.stdout,
+ containsInOrder([
+ '+0: [Chrome, Dart2Js]',
+ '+1: [VM, Source]',
+ '+2: All tests passed!',
+ ]));
+ await test.shouldExit(0);
+ });
+
+ test('supports platform selectors with compilers', () async {
+ await d
+ .file(
+ 'dart_test.yaml',
+ jsonEncode({
+ 'compilers': ['vm:source', 'browser:kernel']
+ }))
+ .create();
+
+ await d.file('test.dart', '''
+ import 'package:test/test.dart';
+
+ void main() {
+ test("test", () {});
+ }
+ ''').create();
+
+ var test = await runTest(['-p', 'chrome,vm', 'test.dart']);
+ expect(
+ test.stdout,
+ containsInOrder([
+ '+0: [Chrome, Dart2Js]',
+ '+1: [VM, Source]',
+ '+2: All tests passed!',
+ ]));
+ await test.shouldExit(0);
+ });
+ });
+}
diff --git a/pkgs/test/test/runner/configuration/configuration_test.dart b/pkgs/test/test/runner/configuration/configuration_test.dart
index 4b360be..3e09082 100644
--- a/pkgs/test/test/runner/configuration/configuration_test.dart
+++ b/pkgs/test/test/runner/configuration/configuration_test.dart
@@ -3,9 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'package:boolean_selector/boolean_selector.dart';
import 'package:test/test.dart';
-
import 'package:test_core/src/runner/configuration/reporters.dart';
import 'package:test_core/src/runner/suite.dart';
import 'package:test_core/src/util/io.dart';
diff --git a/pkgs/test/test/runner/configuration/custom_platform_test.dart b/pkgs/test/test/runner/configuration/custom_platform_test.dart
index af3721d..ca9ec05 100644
--- a/pkgs/test/test/runner/configuration/custom_platform_test.dart
+++ b/pkgs/test/test/runner/configuration/custom_platform_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:io';
diff --git a/pkgs/test/test/runner/configuration/duplicate_names_test.dart b/pkgs/test/test/runner/configuration/duplicate_names_test.dart
index d9afc44..5a02f52 100644
--- a/pkgs/test/test/runner/configuration/duplicate_names_test.dart
+++ b/pkgs/test/test/runner/configuration/duplicate_names_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'dart:convert';
import 'package:path/path.dart' as p;
diff --git a/pkgs/test/test/runner/configuration/global_test.dart b/pkgs/test/test/runner/configuration/global_test.dart
index 930be57..6d3e76b 100644
--- a/pkgs/test/test/runner/configuration/global_test.dart
+++ b/pkgs/test/test/runner/configuration/global_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'dart:convert';
import 'package:test/test.dart';
diff --git a/pkgs/test/test/runner/configuration/include_test.dart b/pkgs/test/test/runner/configuration/include_test.dart
index 6c91503..5d064cf 100644
--- a/pkgs/test/test/runner/configuration/include_test.dart
+++ b/pkgs/test/test/runner/configuration/include_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:test_core/src/runner/configuration.dart';
diff --git a/pkgs/test/test/runner/configuration/platform_test.dart b/pkgs/test/test/runner/configuration/platform_test.dart
index 0a9f427..014c0ed 100644
--- a/pkgs/test/test/runner/configuration/platform_test.dart
+++ b/pkgs/test/test/runner/configuration/platform_test.dart
@@ -3,8 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'dart:convert';
-import 'dart:io';
import 'package:test/test.dart';
import 'package:test_core/src/util/exit_codes.dart' as exit_codes;
@@ -42,7 +43,7 @@
expect(
test.stdout,
containsInOrder(
- ['-1: [Chrome] test [E]', '+1 -1: Some tests failed.']));
+ ['-1: [Chrome, Dart2Js] test [E]', '+1 -1: Some tests failed.']));
await test.shouldExit(1);
}, tags: ['chrome']);
@@ -71,8 +72,8 @@
expect(
test.stdout,
containsInOrder([
- '-1: [Chrome] test [E]',
- '-2: [VM] test [E]',
+ '-1: [Chrome, Dart2Js] test [E]',
+ '-2: [VM, Kernel] test [E]',
'-2: Some tests failed.'
]));
await test.shouldExit(1);
@@ -205,10 +206,8 @@
var test = await runTest(['.']);
expect(
test.stdout,
- containsInOrder([
- '+0: .${Platform.pathSeparator}test_foo.dart: test_foo',
- '+1: All tests passed!'
- ]));
+ containsInOrder(
+ ['+0: ./test_foo.dart: test_foo', '+1: All tests passed!']));
await test.shouldExit(0);
});
@@ -243,10 +242,8 @@
var test = await runTest(['.']);
expect(
test.stdout,
- containsInOrder([
- '+0: .${Platform.pathSeparator}foo_test.dart: foo_test',
- '+1: All tests passed!'
- ]));
+ containsInOrder(
+ ['+0: ./foo_test.dart: foo_test', '+1: All tests passed!']));
await test.shouldExit(0);
});
diff --git a/pkgs/test/test/runner/configuration/presets_test.dart b/pkgs/test/test/runner/configuration/presets_test.dart
index 01568e4..193f12e 100644
--- a/pkgs/test/test/runner/configuration/presets_test.dart
+++ b/pkgs/test/test/runner/configuration/presets_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'dart:convert';
import 'package:test/test.dart';
diff --git a/pkgs/test/test/runner/configuration/randomize_order_test.dart b/pkgs/test/test/runner/configuration/randomize_order_test.dart
index c7cf3f1..690f54b 100644
--- a/pkgs/test/test/runner/configuration/randomize_order_test.dart
+++ b/pkgs/test/test/runner/configuration/randomize_order_test.dart
@@ -3,8 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'dart:convert';
-import 'dart:io';
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
@@ -148,14 +149,14 @@
test.stdout,
emitsInAnyOrder([
containsInOrder([
- '.${Platform.pathSeparator}1_test.dart: test 1.2',
- '.${Platform.pathSeparator}1_test.dart: test 1.3',
- '.${Platform.pathSeparator}1_test.dart: test 1.1'
+ './1_test.dart: test 1.2',
+ './1_test.dart: test 1.3',
+ './1_test.dart: test 1.1'
]),
containsInOrder([
- '.${Platform.pathSeparator}2_test.dart: test 2.2',
- '.${Platform.pathSeparator}2_test.dart: test 2.3',
- '.${Platform.pathSeparator}2_test.dart: test 2.1'
+ './2_test.dart: test 2.2',
+ './2_test.dart: test 2.3',
+ './2_test.dart: test 2.1'
]),
contains('+6: All tests passed!')
]));
diff --git a/pkgs/test/test/runner/configuration/suite_test.dart b/pkgs/test/test/runner/configuration/suite_test.dart
index a8e13cb..1c2fc62 100644
--- a/pkgs/test/test/runner/configuration/suite_test.dart
+++ b/pkgs/test/test/runner/configuration/suite_test.dart
@@ -3,11 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'package:boolean_selector/boolean_selector.dart';
import 'package:test/test.dart';
-
import 'package:test_api/src/backend/platform_selector.dart';
import 'package:test_api/src/backend/runtime.dart';
+import 'package:test_core/src/runner/compiler_selection.dart';
import 'package:test_core/src/runner/runtime_selection.dart';
import '../../utils.dart';
@@ -21,6 +23,7 @@
expect(merged.runSkipped, isFalse);
expect(merged.precompiledPath, isNull);
expect(merged.runtimes, equals([Runtime.vm.identifier]));
+ expect(merged.compilerSelections, isNull);
});
test("if only the old configuration's is defined, uses it", () {
@@ -28,13 +31,16 @@
jsTrace: true,
runSkipped: true,
precompiledPath: '/tmp/js',
- runtimes: [RuntimeSelection(Runtime.chrome.identifier)])
+ runtimes: [RuntimeSelection(Runtime.chrome.identifier)],
+ compilerSelections: [CompilerSelection.parse('dart2js')])
.merge(suiteConfiguration());
expect(merged.jsTrace, isTrue);
expect(merged.runSkipped, isTrue);
expect(merged.precompiledPath, equals('/tmp/js'));
expect(merged.runtimes, equals([Runtime.chrome.identifier]));
+ expect(merged.compilerSelections,
+ equals([CompilerSelection.parse('dart2js')]));
});
test("if only the configuration's is defined, uses it", () {
@@ -42,12 +48,15 @@
jsTrace: true,
runSkipped: true,
precompiledPath: '/tmp/js',
- runtimes: [RuntimeSelection(Runtime.chrome.identifier)]));
+ runtimes: [RuntimeSelection(Runtime.chrome.identifier)],
+ compilerSelections: [CompilerSelection.parse('dart2js')]));
expect(merged.jsTrace, isTrue);
expect(merged.runSkipped, isTrue);
expect(merged.precompiledPath, equals('/tmp/js'));
expect(merged.runtimes, equals([Runtime.chrome.identifier]));
+ expect(merged.compilerSelections,
+ equals([CompilerSelection.parse('dart2js')]));
});
test(
@@ -57,18 +66,22 @@
jsTrace: false,
runSkipped: true,
precompiledPath: '/tmp/js',
- runtimes: [RuntimeSelection(Runtime.chrome.identifier)]);
+ runtimes: [RuntimeSelection(Runtime.chrome.identifier)],
+ compilerSelections: [CompilerSelection.parse('dart2js')]);
var newer = suiteConfiguration(
jsTrace: true,
runSkipped: false,
precompiledPath: '../js',
- runtimes: [RuntimeSelection(Runtime.firefox.identifier)]);
+ runtimes: [RuntimeSelection(Runtime.firefox.identifier)],
+ compilerSelections: [CompilerSelection.parse('source')]);
var merged = older.merge(newer);
expect(merged.jsTrace, isTrue);
expect(merged.runSkipped, isFalse);
expect(merged.precompiledPath, equals('../js'));
expect(merged.runtimes, equals([Runtime.firefox.identifier]));
+ expect(merged.compilerSelections,
+ equals([CompilerSelection.parse('source')]));
});
});
diff --git a/pkgs/test/test/runner/configuration/tags_test.dart b/pkgs/test/test/runner/configuration/tags_test.dart
index e3aace3..bbdb1d1 100644
--- a/pkgs/test/test/runner/configuration/tags_test.dart
+++ b/pkgs/test/test/runner/configuration/tags_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:convert';
diff --git a/pkgs/test/test/runner/configuration/top_level_error_test.dart b/pkgs/test/test/runner/configuration/top_level_error_test.dart
index ea2ffbe..abe5d01 100644
--- a/pkgs/test/test/runner/configuration/top_level_error_test.dart
+++ b/pkgs/test/test/runner/configuration/top_level_error_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'dart:convert';
import 'package:test/test.dart';
@@ -273,7 +275,7 @@
var test = await runTest(['test.dart']);
expect(test.stderr,
- containsInOrder(['Invalid name: Unterminated group(foo', '^^^^^^']));
+ containsInOrder(['Invalid name: Unterminated group', '^^^^^^']));
await test.shouldExit(exit_codes.data);
});
});
diff --git a/pkgs/test/test/runner/configuration/top_level_test.dart b/pkgs/test/test/runner/configuration/top_level_test.dart
index af0c644..8158cc5 100644
--- a/pkgs/test/test/runner/configuration/top_level_test.dart
+++ b/pkgs/test/test/runner/configuration/top_level_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:async';
import 'dart:convert';
@@ -481,7 +482,8 @@
''').create();
var test = await runTest(['test.dart']);
- expect(test.stdout, containsInOrder(['[VM] success', '[Chrome] success']));
+ expect(test.stdout,
+ containsInOrder(['[VM, Kernel] success', '[Chrome, Dart2Js] success']));
await test.shouldExit(0);
}, tags: 'chrome');
diff --git a/pkgs/test/test/runner/coverage_test.dart b/pkgs/test/test/runner/coverage_test.dart
index 398be5d..b149345 100644
--- a/pkgs/test/test/runner/coverage_test.dart
+++ b/pkgs/test/test/runner/coverage_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:convert';
import 'dart:io';
diff --git a/pkgs/test/test/runner/data_isolate_strategy_test.dart b/pkgs/test/test/runner/data_isolate_strategy_test.dart
deleted file mode 100644
index a19bf1f..0000000
--- a/pkgs/test/test/runner/data_isolate_strategy_test.dart
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-@TestOn('vm')
-
-import 'dart:convert';
-import 'dart:isolate';
-
-import 'package:package_config/package_config.dart';
-import 'package:test/test.dart';
-import 'package:test_descriptor/test_descriptor.dart' as d;
-
-import '../io.dart';
-
-void main() {
- late PackageConfig currentPackageConfig;
-
- setUpAll(() async {
- await precompileTestExecutable();
- currentPackageConfig =
- await loadPackageConfigUri((await Isolate.packageConfig)!);
- });
-
- setUp(() async {
- await d
- .file('package_config.json',
- jsonEncode(PackageConfig.toJson(currentPackageConfig)))
- .create();
- });
-
- group('The data isolate strategy', () {
- test('can be enabled', () async {
- // We confirm it is enabled by checking the error output for an invalid
- // test, it looks a bit different.
- await d.file('test.dart', 'invalid Dart file').create();
- var test = await runTest(['--use-data-isolate-strategy', 'test.dart']);
-
- expect(
- test.stdout,
- containsInOrder([
- 'Failed to load "test.dart":',
- "Unable to spawn isolate: test.dart:1:9: Error: Expected ';' after this.",
- 'invalid Dart file'
- ]));
-
- await test.shouldExit(1);
- });
-
- test('can run tests', () async {
- await d.file('test.dart', '''
-import 'package:test/test.dart';
-
-void main() {
- test('true is true', () {
- expect(true, isTrue);
- });
-}
- ''').create();
- var test = await runTest(['--use-data-isolate-strategy', 'test.dart']);
-
- expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
- await test.shouldExit(0);
- });
- });
-}
diff --git a/pkgs/test/test/runner/engine_test.dart b/pkgs/test/test/runner/engine_test.dart
index 189c548..428ca0f 100644
--- a/pkgs/test/test/runner/engine_test.dart
+++ b/pkgs/test/test/runner/engine_test.dart
@@ -129,6 +129,19 @@
expect(engine.run(), completion(isFalse));
});
+ test('.run() does not run more tests after failure for stopOnFirstFailure',
+ () async {
+ var secondTestRan = false;
+ var engine = declareEngine(() {
+ test('failure', () => throw 'oh no');
+ test('subsequent', () {
+ secondTestRan = true;
+ });
+ }, stopOnFirstFailure: true);
+ await expectLater(engine.run(), completion(isFalse));
+ expect(secondTestRan, false);
+ });
+
test('.run() may not be called more than once', () {
var engine = Engine.withSuites([]);
expect(engine.run(), completes);
diff --git a/pkgs/test/test/runner/expanded_reporter_test.dart b/pkgs/test/test/runner/expanded_reporter_test.dart
index 5471fd1..1c11686 100644
--- a/pkgs/test/test/runner/expanded_reporter_test.dart
+++ b/pkgs/test/test/runner/expanded_reporter_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:async';
@@ -27,6 +28,7 @@
test('success 1', () {});
test('success 2', () {});
test('success 3', () {});''', '''
+ +0: loading test.dart
+0: success 1
+1: success 2
+2: success 3
@@ -38,6 +40,7 @@
test('failure 1', () => throw TestFailure('oh no'));
test('failure 2', () => throw TestFailure('oh no'));
test('failure 3', () => throw TestFailure('oh no'));''', '''
+ +0: loading test.dart
+0: failure 1
+0 -1: failure 1 [E]
oh no
@@ -78,6 +81,7 @@
test('success 1', () {});
test('failure 2', () => throw TestFailure('oh no'));
test('success 2', () {});''', '''
+ +0: loading test.dart
+0: failure 1
+0 -1: failure 1 [E]
oh no
@@ -99,6 +103,7 @@
'really gosh dang long test name. Even longer than that. No, yet '
'longer. A little more... okay, that should do it.',
() {});''', '''
+ +0: loading test.dart
+0: really gosh dang long test name. Even longer than that. No, yet longer. A little more... okay, that should do it.
+1: All tests passed!''');
});
@@ -115,6 +120,7 @@
Future.microtask(completer.complete);
});
test('wait', () => completer.future);''', '''
+ +0: loading test.dart
+0: failures
+0 -1: failures [E]
first error
@@ -148,6 +154,7 @@
print("three");
print("four");
});''', '''
+ +0: loading test.dart
+0: test
one
two
@@ -176,6 +183,7 @@
waitStarted.complete();
return testDone.future;
});''', '''
+ +0: loading test.dart
+0: test
+1: wait
+1: test
@@ -210,6 +218,7 @@
});
test('wait', () => completer.future);''', '''
+ +0: loading test.dart
+0: test
one
two
@@ -238,6 +247,7 @@
test('skip 1', () {}, skip: true);
test('skip 2', () {}, skip: true);
test('skip 3', () {}, skip: true);''', '''
+ +0: loading test.dart
+0: skip 1
+0 ~1: skip 2
+0 ~2: skip 3
@@ -251,6 +261,7 @@
test('test 2', () {});
test('test 3', () {});
}, skip: true);''', '''
+ +0: loading test.dart
+0: skip test 1
+0 ~1: skip test 2
+0 ~2: skip test 3
@@ -263,6 +274,7 @@
test('success 1', () {});
test('skip 2', () {}, skip: true);
test('success 2', () {});''', '''
+ +0: loading test.dart
+0: skip 1
+0 ~1: success 1
+1 ~1: skip 2
@@ -278,6 +290,7 @@
test('failure 2', () => throw TestFailure('oh no'));
test('skip 2', () {}, skip: true);
test('success 2', () {});''', '''
+ +0: loading test.dart
+0: failure 1
+0 -1: failure 1 [E]
oh no
@@ -299,6 +312,7 @@
return _expectReport('''
test('skip 1', () {}, skip: 'some reason');
test('skip 2', () {}, skip: 'or another');''', '''
+ +0: loading test.dart
+0: skip 1
Skip: some reason
+0 ~1: skip 2
@@ -310,6 +324,7 @@
return _expectReport('''
test('skip 1', () {}, skip: 'some reason');
test('skip 2', () {}, skip: 'or another');''', '''
+ +0: loading test.dart
+0: skip 1
+1: skip 2
+2: All tests passed!''', args: ['--run-skipped']);
@@ -319,6 +334,7 @@
test('Directs users to enable stack trace chaining if disabled', () async {
await _expectReport(
'''test('failure 1', () => throw TestFailure('oh no'));''', '''
+ +0: loading test.dart
+0: failure 1
+0 -1: failure 1 [E]
oh no
diff --git a/pkgs/test/test/runner/github_reporter_test.dart b/pkgs/test/test/runner/github_reporter_test.dart
index ba094fb..db50058 100644
--- a/pkgs/test/test/runner/github_reporter_test.dart
+++ b/pkgs/test/test/runner/github_reporter_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:async';
@@ -36,8 +37,8 @@
test('includes the platform name when multiple platforms are run', () {
return _expectReportLines('''
test('success 1', () {});''', [
- '✅ [VM] success 1',
- '✅ [Chrome] success 1',
+ '✅ [VM, Kernel] success 1',
+ '✅ [Chrome, Dart2Js] success 1',
'🎉 2 tests passed.',
], args: [
'-p',
@@ -154,8 +155,9 @@
test.dart 8:62 main.<fn>.<fn>
::endgroup::
::group::❌ fail after completion (failed after test completion)
- This test failed after it had already completed. Make sure to use [expectAsync]
- or the [completes] matcher when testing async code.
+ This test failed after it had already completed.
+ Make sure to use a matching library which informs the test runner
+ of pending async work.
test.dart 8:62 main.<fn>.<fn>
::endgroup::
✅ second test so that the first failure is reported
diff --git a/pkgs/test/test/runner/json_file_reporter_test.dart b/pkgs/test/test/runner/json_file_reporter_test.dart
index a4da453..ce3bd42 100644
--- a/pkgs/test/test/runner/json_file_reporter_test.dart
+++ b/pkgs/test/test/runner/json_file_reporter_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:async';
import 'dart:io';
@@ -24,6 +25,7 @@
test('success 2', () {});
test('success 3', () {});
''', '''
+ +0: loading test.dart
+0: success 1
+1: success 2
+2: success 3
@@ -51,6 +53,7 @@
test('failure 2', () => throw new TestFailure('oh no'));
test('failure 3', () => throw new TestFailure('oh no'));
''', '''
+ +0: loading test.dart
+0: failure 1
+0 -1: failure 1 [E]
oh no
diff --git a/pkgs/test/test/runner/json_reporter_test.dart b/pkgs/test/test/runner/json_reporter_test.dart
index 029d557..a771438 100644
--- a/pkgs/test/test/runner/json_reporter_test.dart
+++ b/pkgs/test/test/runner/json_reporter_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:async';
@@ -172,9 +173,9 @@
errorJson(3, 'oh no'),
errorJson(
3,
- 'This test failed after it had already completed. Make sure to '
- 'use [expectAsync]\n'
- 'or the [completes] matcher when testing async code.'),
+ 'This test failed after it had already completed.\n'
+ 'Make sure to use a matching library which informs the '
+ 'test runner\nof pending async work.'),
testDoneJson(4),
]
], doneJson(success: false));
@@ -494,7 +495,7 @@
[
[
suiteJson(0, platform: 'chrome'),
- testStartJson(1, 'compiling test.dart', groupIDs: []),
+ testStartJson(1, 'loading test.dart', groupIDs: []),
printJson(
1,
isA<String>().having((s) => s.split('\n'), 'lines',
@@ -511,7 +512,7 @@
args: ['-p', 'chrome']);
}, tags: ['chrome'], skip: 'https://github.com/dart-lang/test/issues/872');
- test('the root suite if applicable', () {
+ test('the root suite from a relative path', () {
return _expectReport(
'''
customTest('success 1', () {});
@@ -546,6 +547,46 @@
''',
});
});
+
+ test('the root suite from an absolute path', () {
+ final path = p.prettyUri(p.join(d.sandbox, 'test.dart'));
+ return _expectReport(
+ '''
+ customTest('success 1', () {});
+ test('success 2', () {});
+ ''',
+ useRelativePath: false,
+ [
+ [
+ suiteJson(0, path: equalsIgnoringCase(path)),
+ testStartJson(
+ 1, allOf(startsWith('loading '), endsWith('test.dart')),
+ groupIDs: []),
+ testDoneJson(1, hidden: true),
+ ],
+ [
+ groupJson(2, testCount: 2),
+ testStartJson(3, 'success 1',
+ line: 3,
+ column: 60,
+ url: p.toUri(p.join(d.sandbox, 'common.dart')).toString(),
+ rootColumn: 7,
+ rootLine: 7,
+ rootUrl: p.toUri(p.join(d.sandbox, 'test.dart')).toString()),
+ testDoneJson(3),
+ testStartJson(4, 'success 2', line: 8, column: 7),
+ testDoneJson(4),
+ ]
+ ],
+ doneJson(),
+ externalLibraries: {
+ 'common.dart': '''
+import 'package:test/test.dart';
+
+void customTest(String name, dynamic Function() testFn) => test(name, testFn);
+''',
+ });
+ });
});
test(
@@ -558,7 +599,7 @@
[
[
suiteJson(0, platform: 'chrome'),
- testStartJson(1, 'compiling test.dart', groupIDs: []),
+ testStartJson(1, 'loading test.dart', groupIDs: []),
printJson(
1,
isA<String>().having((s) => s.split('\n'), 'lines',
@@ -585,6 +626,7 @@
Future<void> _expectReport(String tests,
List<List<Object /*Map|Matcher*/ >> expected, Map<Object, Object> done,
{List<String> args = const [],
+ bool useRelativePath = true,
Map<String, String> externalLibraries = const {}}) async {
var testContent = StringBuffer('''
import 'dart:async';
@@ -602,8 +644,9 @@
..writeln('}');
await d.file('test.dart', testContent.toString()).create();
+ var testPath = useRelativePath ? 'test.dart' : p.join(d.sandbox, 'test.dart');
- var test = await runTest(['test.dart', '--chain-stack-traces', ...args],
+ var test = await runTest([testPath, '--chain-stack-traces', ...args],
reporter: 'json');
await test.shouldExit();
diff --git a/pkgs/test/test/runner/json_reporter_utils.dart b/pkgs/test/test/runner/json_reporter_utils.dart
index 816cb26..bbdbb78 100644
--- a/pkgs/test/test/runner/json_reporter_utils.dart
+++ b/pkgs/test/test/runner/json_reporter_utils.dart
@@ -24,12 +24,15 @@
expect(outputLines,
hasLength(expected.fold<int>(3, (int a, m) => a + m.length)));
- dynamic decodeLine(String l) => jsonDecode(l)
- ..remove('time')
- ..remove('stackTrace');
+ final decoded = [
+ for (final line in outputLines)
+ (jsonDecode(line) as Map)
+ ..remove('time')
+ ..remove('stackTrace')
+ ];
// Should contain all suites message.
- expect(outputLines.map(decodeLine), containsAll([allSuitesJson()]));
+ expect(decoded, containsAll([_allSuitesJson()]));
// A single start event is emitted first.
final start = {
@@ -38,13 +41,13 @@
'runnerVersion': testVersion,
'pid': testPid,
};
- expect(decodeLine(outputLines.first), equals(start));
+ expect(decoded.first, equals(start));
// A single done event is emitted last.
- expect(decodeLine(outputLines.last), equals(done));
+ expect(decoded.last, equals(done));
for (var value in expected) {
- expect(outputLines.map(decodeLine), containsAllInOrder(value));
+ expect(decoded, containsAllInOrder(value));
}
}
@@ -52,25 +55,24 @@
/// all suites.
///
/// The [count] defaults to 1.
-Map<String, Object> allSuitesJson({int count = 1}) {
- return {'type': 'allSuites', 'count': count};
-}
+Map<String, Object> _allSuitesJson({int count = 1}) =>
+ {'type': 'allSuites', 'count': count};
/// Returns the event emitted by the JSON reporter indicating that a suite has
/// begun running.
///
-/// The [platform] defaults to `"vm"`, the [path] defaults to `"test.dart"`.
+/// The [platform] defaults to `'vm'`.
+/// The [path] defaults to `equals('test.dart')`.
Map<String, Object> suiteJson(int id,
- {String platform = 'vm', String path = 'test.dart'}) {
- return {
- 'type': 'suite',
- 'suite': {
- 'id': id,
- 'platform': platform,
- 'path': path,
- }
- };
-}
+ {String platform = 'vm', Matcher? path}) =>
+ {
+ 'type': 'suite',
+ 'suite': {
+ 'id': id,
+ 'platform': platform,
+ 'path': path ?? 'test.dart',
+ }
+ };
/// Returns the event emitted by the JSON reporter indicating that a group has
/// begun running.
@@ -101,7 +103,7 @@
'name': name ?? '',
'suiteID': suiteID ?? 0,
'parentID': parentID,
- 'metadata': metadataJson(skip: skip),
+ 'metadata': _metadataJson(skip: skip),
'testCount': testCount ?? 1,
'line': line,
'column': column,
@@ -119,7 +121,7 @@
/// [skip] is `true`, the test is expected to be marked as skipped without a
/// reason. If it's a [String], the test is expected to be marked as skipped
/// with that reason.
-Map<String, Object> testStartJson(int id, String name,
+Map<String, Object> testStartJson(int id, Object /*String|Matcher*/ name,
{int? suiteID,
Iterable<int>? groupIDs,
int? line,
@@ -136,58 +138,43 @@
url ??=
line == null ? null : p.toUri(p.join(d.sandbox, 'test.dart')).toString();
- var expected = {
+ return {
'type': 'testStart',
'test': {
'id': id,
'name': name,
'suiteID': suiteID ?? 0,
'groupIDs': groupIDs ?? [2],
- 'metadata': metadataJson(skip: skip),
+ 'metadata': _metadataJson(skip: skip),
'line': line,
'column': column,
'url': url,
+ if (rootLine != null) 'root_line': rootLine,
+ if (rootColumn != null) 'root_column': rootColumn,
+ if (rootUrl != null) 'root_url': rootUrl,
}
};
- var testObj = expected['test'] as Map<String, dynamic>;
- if (rootLine != null) {
- testObj['root_line'] = rootLine;
- }
- if (rootColumn != null) {
- testObj['root_column'] = rootColumn;
- }
- if (rootUrl != null) {
- testObj['root_url'] = rootUrl;
- }
- return expected;
}
/// Returns the event emitted by the JSON reporter indicating that a test
/// printed [message].
Matcher printJson(int id, dynamic /*String|Matcher*/ message,
- {String type = 'print'}) {
- return allOf(
- hasLength(4),
- containsPair('type', 'print'),
- containsPair('testID', id),
- containsPair('message', message),
- containsPair('messageType', type),
- );
-}
+ {String type = 'print'}) =>
+ allOf(
+ hasLength(4),
+ containsPair('type', 'print'),
+ containsPair('testID', id),
+ containsPair('message', message),
+ containsPair('messageType', type),
+ );
/// Returns the event emitted by the JSON reporter indicating that a test
/// emitted [error].
///
/// The [isFailure] parameter indicates whether the error was a [TestFailure] or
/// not.
-Map<String, Object> errorJson(int id, String error, {bool isFailure = false}) {
- return {
- 'type': 'error',
- 'testID': id,
- 'error': error,
- 'isFailure': isFailure
- };
-}
+Map<String, Object> errorJson(int id, String error, {bool isFailure = false}) =>
+ {'type': 'error', 'testID': id, 'error': error, 'isFailure': isFailure};
/// Returns the event emitted by the JSON reporter indicating that a test
/// finished.
@@ -199,15 +186,16 @@
/// after finishing. The [skipped] parameter indicates whether the test was
/// skipped.
Map<String, Object> testDoneJson(int id,
- {String result = 'success', bool hidden = false, bool skipped = false}) {
- return {
- 'type': 'testDone',
- 'testID': id,
- 'result': result,
- 'hidden': hidden,
- 'skipped': skipped
- };
-}
+ {String result = 'success',
+ bool hidden = false,
+ bool skipped = false}) =>
+ {
+ 'type': 'testDone',
+ 'testID': id,
+ 'result': result,
+ 'hidden': hidden,
+ 'skipped': skipped
+ };
/// Returns the event emitted by the JSON reporter indicating that the entire
/// run finished.
@@ -215,12 +203,7 @@
{'type': 'done', 'success': success};
/// Returns the serialized metadata corresponding to [skip].
-Map<String, Object?> metadataJson({skip}) {
- if (skip == true) {
- return {'skip': true, 'skipReason': null};
- } else if (skip is String) {
- return {'skip': true, 'skipReason': skip};
- } else {
- return {'skip': false, 'skipReason': null};
- }
-}
+Map<String, Object?> _metadataJson({Object? skip}) => {
+ 'skip': skip == true || skip is String,
+ 'skipReason': skip is String ? skip : null
+ };
diff --git a/pkgs/test/test/runner/line_and_col_test.dart b/pkgs/test/test/runner/line_and_col_test.dart
index a973dc6..c513cef 100644
--- a/pkgs/test/test/runner/line_and_col_test.dart
+++ b/pkgs/test/test/runner/line_and_col_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'package:test/test.dart';
import 'package:test_core/src/util/exit_codes.dart' as exit_codes;
diff --git a/pkgs/test/test/runner/load_suite_test.dart b/pkgs/test/test/runner/load_suite_test.dart
index 3f328a0..aa35d38 100644
--- a/pkgs/test/test/runner/load_suite_test.dart
+++ b/pkgs/test/test/runner/load_suite_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'dart:async';
import 'package:test/test.dart';
diff --git a/pkgs/test/test/runner/loader_test.dart b/pkgs/test/test/runner/loader_test.dart
index b6143b8..8d1d4ad 100644
--- a/pkgs/test/test/runner/loader_test.dart
+++ b/pkgs/test/test/runner/loader_test.dart
@@ -3,13 +3,18 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'dart:async';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
+import 'package:test_api/src/backend/compiler.dart';
import 'package:test_api/src/backend/runtime.dart';
import 'package:test_api/src/backend/state.dart';
import 'package:test_api/src/backend/test.dart';
+import 'package:test_core/src/runner/compiler_selection.dart';
+import 'package:test_core/src/runner/load_suite.dart';
import 'package:test_core/src/runner/loader.dart';
import 'package:test_core/src/runner/runner_suite.dart';
import 'package:test_core/src/runner/runner_test.dart';
@@ -41,44 +46,138 @@
group('.loadFile()', () {
late RunnerSuite suite;
- setUp(() async {
- await d.file('a_test.dart', _tests).create();
- var suites = await _loader
- .loadFile(p.join(d.sandbox, 'a_test.dart'), SuiteConfiguration.empty)
- .toList();
- expect(suites, hasLength(1));
- var loadSuite = suites.first;
- suite = (await loadSuite.getSuite())!;
+ group('with empty configuration', () {
+ setUp(() async {
+ await d.file('a_test.dart', _tests).create();
+ var suites = await _loader
+ .loadFile(
+ p.join(d.sandbox, 'a_test.dart'), SuiteConfiguration.empty)
+ .toList();
+ expect(suites, hasLength(1));
+ var loadSuite = suites.first;
+ suite = (await loadSuite.getSuite())!;
+ });
+
+ test('returns a suite with the file path and platform', () {
+ expect(suite.path, equals(p.join(d.sandbox, 'a_test.dart')));
+ expect(suite.platform.runtime, equals(Runtime.vm));
+ expect(suite.platform.compiler, equals(Runtime.vm.defaultCompiler));
+ });
+
+ test('returns entries with the correct names and platforms', () {
+ expect(suite.group.entries, hasLength(3));
+ expect(suite.group.entries[0].name, equals('success'));
+ expect(suite.group.entries[1].name, equals('failure'));
+ expect(suite.group.entries[2].name, equals('error'));
+ });
+
+ test('can load and run a successful test', () {
+ var liveTest = (suite.group.entries[0] as RunnerTest).load(suite);
+
+ expectStates(liveTest, [
+ const State(Status.running, Result.success),
+ const State(Status.complete, Result.success)
+ ]);
+ expectErrors(liveTest, []);
+
+ return liveTest.run().whenComplete(() => liveTest.close());
+ });
+
+ test('can load and run a failing test', () {
+ var liveTest = (suite.group.entries[1] as RunnerTest).load(suite);
+ expectSingleFailure(liveTest);
+ return liveTest.run().whenComplete(() => liveTest.close());
+ });
});
- test('returns a suite with the file path and platform', () {
- expect(suite.path, equals(p.join(d.sandbox, 'a_test.dart')));
- expect(suite.platform.runtime, equals(Runtime.vm));
- });
+ group('with compiler selection', () {
+ Future<List<LoadSuite>> loadSuitesWithConfig(
+ SuiteConfiguration suiteConfiguration) async {
+ await d.file('a_test.dart', _tests).create();
+ return _loader
+ .loadFile(p.join(d.sandbox, 'a_test.dart'), suiteConfiguration)
+ .toList();
+ }
- test('returns entries with the correct names and platforms', () {
- expect(suite.group.entries, hasLength(3));
- expect(suite.group.entries[0].name, equals('success'));
- expect(suite.group.entries[1].name, equals('failure'));
- expect(suite.group.entries[2].name, equals('error'));
- });
+ test('with a single compiler selection, uses the selected compiler',
+ () async {
+ var suites = await loadSuitesWithConfig(suiteConfiguration(
+ compilerSelections: [CompilerSelection.parse('source')]));
+ expect(suites, hasLength(1));
+ var loadSuite = suites.first;
+ suite = (await loadSuite.getSuite())!;
+ expect(suite.path, equals(p.join(d.sandbox, 'a_test.dart')));
+ expect(suite.platform.runtime, equals(Runtime.vm));
+ expect(suite.platform.compiler, equals(Compiler.source));
+ });
- test('can load and run a successful test', () {
- var liveTest = (suite.group.entries[0] as RunnerTest).load(suite);
+ test('with multiple compiler selections, returns a suite for each',
+ () async {
+ var suites = await loadSuitesWithConfig(suiteConfiguration(
+ compilerSelections: [
+ CompilerSelection.parse('source'),
+ CompilerSelection.parse('kernel')
+ ]));
- expectStates(liveTest, [
- const State(Status.running, Result.success),
- const State(Status.complete, Result.success)
- ]);
- expectErrors(liveTest, []);
+ expect(suites, hasLength(2));
+ var runnerSuites =
+ await Future.wait([for (var suite in suites) suite.getSuite()]);
+ expect(
+ runnerSuites,
+ unorderedEquals([
+ isA<RunnerSuite>()
+ .having(
+ (s) => s.platform.runtime, 'The vm runtime', Runtime.vm)
+ .having((s) => s.platform.compiler, 'The source compiler',
+ Compiler.source),
+ isA<RunnerSuite>()
+ .having(
+ (s) => s.platform.runtime, 'The vm runtime', Runtime.vm)
+ .having((s) => s.platform.compiler, 'The kernel compiler',
+ Compiler.kernel),
+ ]));
+ });
- return liveTest.run().whenComplete(() => liveTest.close());
- });
+ test('with unsupported compiler selections, uses the default compiler',
+ () async {
+ var suites =
+ await loadSuitesWithConfig(suiteConfiguration(compilerSelections: [
+ CompilerSelection.parse('dart2js'),
+ ]));
+ expect(suites, hasLength(1));
+ var loadSuite = suites.first;
+ suite = (await loadSuite.getSuite())!;
+ expect(suite.path, equals(p.join(d.sandbox, 'a_test.dart')));
+ expect(suite.platform.runtime, equals(Runtime.vm));
+ expect(suite.platform.compiler, equals(Runtime.vm.defaultCompiler));
+ });
- test('can load and run a failing test', () {
- var liveTest = (suite.group.entries[1] as RunnerTest).load(suite);
- expectSingleFailure(liveTest);
- return liveTest.run().whenComplete(() => liveTest.close());
+ test('compiler selections support matching boolean selectors', () async {
+ var suites =
+ await loadSuitesWithConfig(suiteConfiguration(compilerSelections: [
+ CompilerSelection.parse('vm:source'),
+ ]));
+ expect(suites, hasLength(1));
+ var loadSuite = suites.first;
+ suite = (await loadSuite.getSuite())!;
+ expect(suite.path, equals(p.join(d.sandbox, 'a_test.dart')));
+ expect(suite.platform.runtime, equals(Runtime.vm));
+ expect(suite.platform.compiler, equals(Compiler.source));
+ });
+
+ test('compiler selections support unmatched boolean selectors', () async {
+ var suites =
+ await loadSuitesWithConfig(suiteConfiguration(compilerSelections: [
+ CompilerSelection.parse('browser:source'),
+ ]));
+ expect(suites, hasLength(1));
+ var loadSuite = suites.first;
+ suite = (await loadSuite.getSuite())!;
+ expect(suite.path, equals(p.join(d.sandbox, 'a_test.dart')));
+ expect(suite.platform.runtime, equals(Runtime.vm));
+ expect(suite.platform.compiler,
+ allOf(Runtime.vm.defaultCompiler, isNot(Compiler.source)));
+ });
});
});
diff --git a/pkgs/test/test/runner/name_test.dart b/pkgs/test/test/runner/name_test.dart
index ed539d5..bd4dc21 100644
--- a/pkgs/test/test/runner/name_test.dart
+++ b/pkgs/test/test/runner/name_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'package:test/test.dart';
import 'package:test_core/src/util/exit_codes.dart' as exit_codes;
diff --git a/pkgs/test/test/runner/node/runner_test.dart b/pkgs/test/test/runner/node/runner_test.dart
index 522acd7..aba2604 100644
--- a/pkgs/test/test/runner/node/runner_test.dart
+++ b/pkgs/test/test/runner/node/runner_test.dart
@@ -4,6 +4,7 @@
@TestOn('vm')
@Tags(['node'])
+library;
import 'package:test/test.dart';
import 'package:test_core/src/util/io.dart';
@@ -39,7 +40,7 @@
test.stdout,
containsInOrder([
'Error: Compilation failed.',
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": dart2js failed.'
]));
await test.shouldExit(1);
@@ -52,7 +53,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": oh no'
]));
await test.shouldExit(1);
@@ -65,7 +66,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": No top-level main() function defined.'
]));
await test.shouldExit(1);
@@ -78,7 +79,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": Top-level main getter is not a function.'
]));
await test.shouldExit(1);
@@ -91,7 +92,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling test.dart [E]',
+ '-1: loading test.dart [E]',
'Failed to load "test.dart": Top-level main() function takes arguments.'
]));
await test.shouldExit(1);
diff --git a/pkgs/test/test/runner/parse_metadata_test.dart b/pkgs/test/test/runner/parse_metadata_test.dart
index 635d881..5fb7434 100644
--- a/pkgs/test/test/runner/parse_metadata_test.dart
+++ b/pkgs/test/test/runner/parse_metadata_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'package:test/test.dart';
import 'package:test_api/src/backend/platform_selector.dart';
import 'package:test_api/src/backend/runtime.dart';
@@ -30,15 +32,23 @@
"@foo.TestOn('vm')\n"
"import 'package:test/test.dart' as foo;",
{});
- expect(metadata.testOn.evaluate(SuitePlatform(Runtime.vm)), isTrue);
- expect(metadata.testOn.evaluate(SuitePlatform(Runtime.chrome)), isFalse);
+ expect(metadata.testOn.evaluate(SuitePlatform(Runtime.vm, compiler: null)),
+ isTrue);
+ expect(
+ metadata.testOn.evaluate(SuitePlatform(Runtime.chrome, compiler: null)),
+ isFalse);
});
group('@TestOn:', () {
test('parses a valid annotation', () {
var metadata = parseMetadata(_path, "@TestOn('vm')\nlibrary foo;", {});
- expect(metadata.testOn.evaluate(SuitePlatform(Runtime.vm)), isTrue);
- expect(metadata.testOn.evaluate(SuitePlatform(Runtime.chrome)), isFalse);
+ expect(
+ metadata.testOn.evaluate(SuitePlatform(Runtime.vm, compiler: null)),
+ isTrue);
+ expect(
+ metadata.testOn
+ .evaluate(SuitePlatform(Runtime.chrome, compiler: null)),
+ isFalse);
});
test('ignores a constructor named TestOn', () {
@@ -237,14 +247,16 @@
library foo;''', {});
var key = metadata.onPlatform.keys.first;
- expect(key.evaluate(SuitePlatform(Runtime.chrome)), isTrue);
- expect(key.evaluate(SuitePlatform(Runtime.vm)), isFalse);
+ expect(
+ key.evaluate(SuitePlatform(Runtime.chrome, compiler: null)), isTrue);
+ expect(key.evaluate(SuitePlatform(Runtime.vm, compiler: null)), isFalse);
var value = metadata.onPlatform.values.first;
expect(value.timeout.scaleFactor, equals(2));
key = metadata.onPlatform.keys.last;
- expect(key.evaluate(SuitePlatform(Runtime.vm)), isTrue);
- expect(key.evaluate(SuitePlatform(Runtime.chrome)), isFalse);
+ expect(key.evaluate(SuitePlatform(Runtime.vm, compiler: null)), isTrue);
+ expect(
+ key.evaluate(SuitePlatform(Runtime.chrome, compiler: null)), isFalse);
value = metadata.onPlatform.values.last;
expect(value.skip, isTrue);
expect(value.timeout.scaleFactor, equals(3));
@@ -260,14 +272,16 @@
''', {});
var key = metadata.onPlatform.keys.first;
- expect(key.evaluate(SuitePlatform(Runtime.chrome)), isTrue);
- expect(key.evaluate(SuitePlatform(Runtime.vm)), isFalse);
+ expect(
+ key.evaluate(SuitePlatform(Runtime.chrome, compiler: null)), isTrue);
+ expect(key.evaluate(SuitePlatform(Runtime.vm, compiler: null)), isFalse);
var value = metadata.onPlatform.values.first;
expect(value.timeout.scaleFactor, equals(2));
key = metadata.onPlatform.keys.last;
- expect(key.evaluate(SuitePlatform(Runtime.vm)), isTrue);
- expect(key.evaluate(SuitePlatform(Runtime.chrome)), isFalse);
+ expect(key.evaluate(SuitePlatform(Runtime.vm, compiler: null)), isTrue);
+ expect(
+ key.evaluate(SuitePlatform(Runtime.chrome, compiler: null)), isFalse);
value = metadata.onPlatform.values.last;
expect(value.skip, isTrue);
expect(value.timeout.scaleFactor, equals(3));
diff --git a/pkgs/test/test/runner/pause_after_load_test.dart b/pkgs/test/test/runner/pause_after_load_test.dart
index 8b48b2d..691a86d 100644
--- a/pkgs/test/test/runner/pause_after_load_test.dart
+++ b/pkgs/test/test/runner/pause_after_load_test.dart
@@ -4,6 +4,7 @@
@TestOn('vm')
@OnPlatform({'windows': Skip('https://github.com/dart-lang/test/issues/1613')})
+library;
import 'dart:async';
import 'dart:io';
@@ -115,7 +116,7 @@
var nextLineFired = false;
unawaited(test.stdout.next.then(expectAsync1((line) {
- expect(line, contains('+0: [Firefox] success'));
+ expect(line, contains('+0: [Firefox, Dart2Js] success'));
nextLineFired = true;
})));
@@ -137,7 +138,7 @@
nextLineFired = false;
unawaited(test.stdout.next.then(expectAsync1((line) {
- expect(line, contains('+1: [Chrome] success'));
+ expect(line, contains('+1: [Chrome, Dart2Js] success'));
nextLineFired = true;
})));
@@ -158,7 +159,7 @@
nextLineFired = false;
unawaited(test.stdout.next.then(expectAsync1((line) {
- expect(line, contains('+2: [VM] success'));
+ expect(line, contains('+2: [VM, Kernel] success'));
nextLineFired = true;
})));
diff --git a/pkgs/test/test/runner/precompiled_test.dart b/pkgs/test/test/runner/precompiled_test.dart
index 25bfac1..181d68f 100644
--- a/pkgs/test/test/runner/precompiled_test.dart
+++ b/pkgs/test/test/runner/precompiled_test.dart
@@ -4,6 +4,7 @@
@TestOn('vm')
@OnPlatform({'windows': Skip('https://github.com/dart-lang/test/issues/1617')})
+library;
import 'dart:async';
import 'dart:io';
diff --git a/pkgs/test/test/runner/pub_serve_test.dart b/pkgs/test/test/runner/pub_serve_test.dart
index 8c33699..8a0b2b2 100644
--- a/pkgs/test/test/runner/pub_serve_test.dart
+++ b/pkgs/test/test/runner/pub_serve_test.dart
@@ -5,6 +5,7 @@
@TestOn('vm')
@Tags(['pub'])
@Skip('https://github.com/dart-lang/test/issues/821')
+library;
import 'dart:io';
@@ -131,7 +132,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling ${p.join("test", "my_test.dart")} [E]',
+ '-1: loading ${p.join("test", "my_test.dart")} [E]',
'Failed to load "${p.join("test", "my_test.dart")}":',
'404 Not Found',
'Make sure "pub serve" is serving the test/ directory.'
@@ -152,7 +153,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling ${p.join("test", "my_test.dart")} [E]',
+ '-1: loading ${p.join("test", "my_test.dart")} [E]',
'Failed to load "${p.join("test", "my_test.dart")}":',
'404 Not Found',
'Make sure "pub serve" is serving the test/ directory.'
@@ -293,7 +294,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling ${p.join("test", "my_test.dart")} [E]',
+ '-1: loading ${p.join("test", "my_test.dart")} [E]',
'Failed to load "${p.join("test", "my_test.dart")}":',
'Error getting http://localhost:54321/my_test.dart.browser_test.dart.js'
'.map: $message',
@@ -311,7 +312,7 @@
expect(
test.stdout,
containsInOrder([
- '-1: compiling ${p.join("test", "my_test.dart")} [E]',
+ '-1: loading ${p.join("test", "my_test.dart")} [E]',
'Failed to load "${p.join("test", "my_test.dart")}":',
'Error getting http://localhost:54321/my_test.dart.node_test.dart.js:'
' $message',
@@ -344,7 +345,7 @@
/// as the first argument.
void testWithCompiler(
String name, dynamic Function(List<String> compilerArgs) testFn,
- {tags}) {
+ {Object? tags}) {
for (var compiler in _compilers) {
var compilerArgs = ['--web-compiler', compiler];
test('$name with $compiler', () => testFn(compilerArgs), tags: tags);
diff --git a/pkgs/test/test/runner/retry_test.dart b/pkgs/test/test/runner/retry_test.dart
index c45fbb5..0e16fef 100644
--- a/pkgs/test/test/runner/retry_test.dart
+++ b/pkgs/test/test/runner/retry_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
diff --git a/pkgs/test/test/runner/runner_test.dart b/pkgs/test/test/runner/runner_test.dart
index 19419af..6d9a2ff 100644
--- a/pkgs/test/test/runner/runner_test.dart
+++ b/pkgs/test/test/runner/runner_test.dart
@@ -3,10 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:io';
import 'dart:math' as math;
+import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:test_core/src/util/exit_codes.dart' as exit_codes;
import 'package:test_descriptor/test_descriptor.dart' as d;
@@ -69,7 +71,13 @@
Running Tests:
-p, --platform The platform(s) on which to run the tests.
- $_runtimes
+ $_runtimes.
+ Each platform supports the following compilers:
+$_runtimeCompilers
+-c, --compiler The compiler(s) to use to run tests, supported compilers are [dart2js, dart2wasm, exe, kernel, source].
+ Each platform has a default compiler but may support other compilers.
+ You can target a compiler to a specific platform using arguments of the following form [<platform-selector>:]<compiler>.
+ If a platform is specified but no given compiler is supported for that platform, then it will use its default compiler.
-P, --preset The configuration preset(s) to use.
-j, --concurrency=<threads> The number of concurrent test suites run.
(defaults to "$_defaultConcurrency")
@@ -90,13 +98,11 @@
to provide improved test performance but at the cost of
debuggability.
--no-retry Don't rerun tests that have retry set.
- --use-data-isolate-strategy Use `data:` uri isolates when spawning VM tests instead of the
- default strategy. This may be faster when you only ever run a
- single test suite at a time.
--test-randomize-ordering-seed Use the specified seed to randomize the execution order of test cases.
Must be a 32bit unsigned integer or "random".
If "random", pick a random seed to use.
If not passed, do not randomize test case execution order.
+ --[no-]fail-fast Stop running tests after the first failure.
Output:
-r, --reporter=<option> Set how to print test results.
@@ -112,14 +118,24 @@
--js-trace Emit raw JavaScript stack traces for browser tests.
--[no-]color Use terminal colors.
(auto-detected by default)
-
''';
final _runtimes = '[vm (default), chrome, firefox'
'${Platform.isMacOS ? ', safari' : ''}'
- '${Platform.isWindows ? ', ie' : ''}, node, '
+ '${Platform.isWindows ? ', ie' : ''}, edge, node, '
'experimental-chrome-wasm]';
+final _runtimeCompilers = [
+ '[vm]: kernel (default), source, exe',
+ '[chrome]: dart2js (default)',
+ '[firefox]: dart2js (default)',
+ if (Platform.isMacOS) '[safari]: dart2js (default)',
+ if (Platform.isWindows) '[ie]: dart2js (default)',
+ '[edge]: dart2js (default)',
+ '[node]: dart2js (default)',
+ '[experimental-chrome-wasm]: dart2wasm (default)',
+].map((str) => ' $str').join('\n');
+
void main() {
setUpAll(precompileTestExecutable);
@@ -362,6 +378,37 @@
expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
await test.shouldExit(0);
});
+
+ test('given a file: uri', () async {
+ await d.file('test.dart', _success).create();
+ var fileUri = p.toUri(d.path('test.dart')).toString();
+ expect(fileUri, startsWith('file:///'));
+ var test = await runTest([fileUri]);
+ expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
+ await test.shouldExit(0);
+ });
+
+ test('with platform specific relative paths', () async {
+ await d.dir('foo', [d.file('test.dart', _success)]).create();
+ var test = await runTest([p.join('foo', 'test.dart')]);
+ expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
+ await test.shouldExit(0);
+ });
+
+ test('with platform specific absolute paths', () async {
+ await d.dir('foo', [d.file('test.dart', _success)]).create();
+ var test = await runTest([d.path(p.join('foo', 'test.dart'))]);
+ expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
+ await test.shouldExit(0);
+ });
+
+ test('with platform specific relative paths containing query params',
+ () async {
+ await d.dir('foo', [d.file('test.dart', _success)]).create();
+ var test = await runTest(['${p.join('foo', 'test.dart')}?line=6']);
+ expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
+ await test.shouldExit(0);
+ });
});
group('runs successful tests with async setup', () {
diff --git a/pkgs/test/test/runner/set_up_all_test.dart b/pkgs/test/test/runner/set_up_all_test.dart
index bcad996..d1259e1 100644
--- a/pkgs/test/test/runner/set_up_all_test.dart
+++ b/pkgs/test/test/runner/set_up_all_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
diff --git a/pkgs/test/test/runner/shard_test.dart b/pkgs/test/test/runner/shard_test.dart
index 0d1f72b..8d4be86 100644
--- a/pkgs/test/test/runner/shard_test.dart
+++ b/pkgs/test/test/runner/shard_test.dart
@@ -3,8 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
-
-import 'dart:io';
+library;
import 'package:test/test.dart';
import 'package:test_core/src/util/exit_codes.dart' as exit_codes;
@@ -95,14 +94,10 @@
test.stdout,
emitsInOrder([
emitsAnyOf([
- containsInOrder([
- '+0: .${Platform.pathSeparator}1_test.dart: test 1.1',
- '+1: .${Platform.pathSeparator}2_test.dart: test 2.1'
- ]),
- containsInOrder([
- '+0: .${Platform.pathSeparator}2_test.dart: test 2.1',
- '+1: .${Platform.pathSeparator}1_test.dart: test 1.1'
- ])
+ containsInOrder(
+ ['+0: ./1_test.dart: test 1.1', '+1: ./2_test.dart: test 2.1']),
+ containsInOrder(
+ ['+0: ./2_test.dart: test 2.1', '+1: ./1_test.dart: test 1.1'])
]),
contains('+2: All tests passed!')
]));
@@ -113,14 +108,10 @@
test.stdout,
emitsInOrder([
emitsAnyOf([
- containsInOrder([
- '+0: .${Platform.pathSeparator}1_test.dart: test 1.2',
- '+1: .${Platform.pathSeparator}2_test.dart: test 2.2'
- ]),
- containsInOrder([
- '+0: .${Platform.pathSeparator}2_test.dart: test 2.2',
- '+1: .${Platform.pathSeparator}1_test.dart: test 1.2'
- ])
+ containsInOrder(
+ ['+0: ./1_test.dart: test 1.2', '+1: ./2_test.dart: test 2.2']),
+ containsInOrder(
+ ['+0: ./2_test.dart: test 2.2', '+1: ./1_test.dart: test 1.2'])
]),
contains('+2: All tests passed!')
]));
@@ -131,14 +122,10 @@
test.stdout,
emitsInOrder([
emitsAnyOf([
- containsInOrder([
- '+0: .${Platform.pathSeparator}1_test.dart: test 1.3',
- '+1: .${Platform.pathSeparator}2_test.dart: test 2.3'
- ]),
- containsInOrder([
- '+0: .${Platform.pathSeparator}2_test.dart: test 2.3',
- '+1: .${Platform.pathSeparator}1_test.dart: test 1.3'
- ])
+ containsInOrder(
+ ['+0: ./1_test.dart: test 1.3', '+1: ./2_test.dart: test 2.3']),
+ containsInOrder(
+ ['+0: ./2_test.dart: test 2.3', '+1: ./1_test.dart: test 1.3'])
]),
contains('+2: All tests passed!')
]));
diff --git a/pkgs/test/test/runner/signal_test.dart b/pkgs/test/test/runner/signal_test.dart
index 861ce9c..8a093d9 100644
--- a/pkgs/test/test/runner/signal_test.dart
+++ b/pkgs/test/test/runner/signal_test.dart
@@ -4,6 +4,7 @@
// Windows doesn't support sending signals.
@TestOn('vm && !windows')
+library;
import 'dart:async';
import 'dart:io';
@@ -48,7 +49,7 @@
var test = await _runTest(['-p', 'chrome', 'test.dart']);
await expectLater(
- test.stdout, emitsThrough(endsWith('compiling test.dart')));
+ test.stdout, emitsThrough(endsWith('loading test.dart')));
await signalAndQuit(test);
expectTempDirEmpty(skip: 'Failing on Travis.');
@@ -230,6 +231,6 @@
await expectLater(test.stderr, emitsDone);
}
-void expectTempDirEmpty({skip}) {
+void expectTempDirEmpty({Object? skip}) {
expect(Directory(_tempDir).listSync(), isEmpty, skip: skip);
}
diff --git a/pkgs/test/test/runner/skip_expect_test.dart b/pkgs/test/test/runner/skip_expect_test.dart
index 97e1330..e22332c 100644
--- a/pkgs/test/test/runner/skip_expect_test.dart
+++ b/pkgs/test/test/runner/skip_expect_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
@@ -197,9 +198,9 @@
'+0: skip',
'+1: wait',
'+0 -1: skip',
- 'This test was marked as skipped after it had already completed. '
- 'Make sure to use',
- '[expectAsync] or the [completes] matcher when testing async code.',
+ 'This test was marked as skipped after it had already completed.',
+ 'Make sure to use a matching library which informs the test runner',
+ 'of pending async work.',
'+1 -1: Some tests failed.'
]));
await test.shouldExit(1);
@@ -239,9 +240,9 @@
'+0: skip',
'+1: wait',
'+0 -1: skip',
- 'This test was marked as skipped after it had already completed. '
- 'Make sure to use',
- '[expectAsync] or the [completes] matcher when testing async code.',
+ 'This test was marked as skipped after it had already completed.',
+ 'Make sure to use a matching library which informs the test runner',
+ 'of pending async work.',
'+1 -1: Some tests failed.'
]));
await test.shouldExit(1);
diff --git a/pkgs/test/test/runner/solo_test.dart b/pkgs/test/test/runner/solo_test.dart
index 508ac67..87f6f25 100644
--- a/pkgs/test/test/runner/solo_test.dart
+++ b/pkgs/test/test/runner/solo_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
diff --git a/pkgs/test/test/runner/tag_test.dart b/pkgs/test/test/runner/tag_test.dart
index 129358c..da9dca7 100644
--- a/pkgs/test/test/runner/tag_test.dart
+++ b/pkgs/test/test/runner/tag_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
diff --git a/pkgs/test/test/runner/tear_down_all_test.dart b/pkgs/test/test/runner/tear_down_all_test.dart
index 3af6e56..93ede4f 100644
--- a/pkgs/test/test/runner/tear_down_all_test.dart
+++ b/pkgs/test/test/runner/tear_down_all_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
diff --git a/pkgs/test/test/runner/test_chain_test.dart b/pkgs/test/test/runner/test_chain_test.dart
index e7c1da0..ad814de 100644
--- a/pkgs/test/test/runner/test_chain_test.dart
+++ b/pkgs/test/test/runner/test_chain_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:convert';
diff --git a/pkgs/test/test/runner/test_on_test.dart b/pkgs/test/test/runner/test_on_test.dart
index d9ca7bf..96baf0b 100644
--- a/pkgs/test/test/runner/test_on_test.dart
+++ b/pkgs/test/test/runner/test_on_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'dart:async';
import 'dart:convert';
diff --git a/pkgs/test/test/runner/timeout_test.dart b/pkgs/test/test/runner/timeout_test.dart
index aa4764c..6f4b0e7 100644
--- a/pkgs/test/test/runner/timeout_test.dart
+++ b/pkgs/test/test/runner/timeout_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
diff --git a/pkgs/test/test/util/string_literal_iterator_test.dart b/pkgs/test/test/util/string_literal_iterator_test.dart
index 4bb5aa0..03c8e34 100644
--- a/pkgs/test/test/util/string_literal_iterator_test.dart
+++ b/pkgs/test/test/util/string_literal_iterator_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
@TestOn('vm')
+library;
+
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:test/test.dart';
diff --git a/pkgs/test/test/utils.dart b/pkgs/test/test/utils.dart
index 52b4e4c..52c708d 100644
--- a/pkgs/test/test/utils.dart
+++ b/pkgs/test/test/utils.dart
@@ -20,6 +20,7 @@
import 'package:test_api/src/backend/suite.dart';
import 'package:test_api/src/backend/suite_platform.dart';
import 'package:test_core/src/runner/application_exception.dart';
+import 'package:test_core/src/runner/compiler_selection.dart';
import 'package:test_core/src/runner/configuration.dart';
import 'package:test_core/src/runner/configuration/custom_runtime.dart';
import 'package:test_core/src/runner/configuration/runtime_settings.dart';
@@ -31,7 +32,7 @@
import 'package:test_core/src/runner/suite.dart';
/// A dummy suite platform to use for testing suites.
-final suitePlatform = SuitePlatform(Runtime.vm);
+final suitePlatform = SuitePlatform(Runtime.vm, compiler: null);
// The last state change detected via [expectStates].
State? lastState;
@@ -90,19 +91,19 @@
/// [TestFailure] with the given [message].
///
/// [message] can be a string or a [Matcher].
-Matcher throwsTestFailure(message) => throwsA(isTestFailure(message));
+Matcher throwsTestFailure(Object message) => throwsA(isTestFailure(message));
/// Returns a matcher that matches a [TestFailure] with the given [message].
///
/// [message] can be a string or a [Matcher].
-Matcher isTestFailure(message) => const TypeMatcher<TestFailure>()
+Matcher isTestFailure(Object message) => const TypeMatcher<TestFailure>()
.having((e) => e.message, 'message', message);
/// Returns a matcher that matches a [ApplicationException] with the given
/// [message].
///
/// [message] can be a string or a [Matcher].
-Matcher isApplicationException(message) =>
+Matcher isApplicationException(Object message) =>
const TypeMatcher<ApplicationException>()
.having((e) => e.message, 'message', message);
@@ -141,7 +142,7 @@
/// Asserts that [liveTest] failed with a single [TestFailure] whose message
/// matches [message].
-void expectTestFailed(LiveTest liveTest, message) {
+void expectTestFailed(LiveTest liveTest, Object message) {
expect(liveTest.state.status, equals(Status.complete));
expect(liveTest.state.result, equals(Result.failure));
expect(liveTest.errors, hasLength(1));
@@ -194,16 +195,24 @@
}
/// Runs [body] with a declarer and returns an engine that runs those tests.
-Engine declareEngine(void Function() body,
- {bool runSkipped = false, String? coverage}) {
+Engine declareEngine(
+ void Function() body, {
+ bool runSkipped = false,
+ String? coverage,
+ bool stopOnFirstFailure = false,
+}) {
var declarer = Declarer()..declare(body);
- return Engine.withSuites([
- RunnerSuite(
- const PluginEnvironment(),
- SuiteConfiguration.runSkipped(runSkipped),
- declarer.build(),
- suitePlatform)
- ], coverage: coverage);
+ return Engine.withSuites(
+ [
+ RunnerSuite(
+ const PluginEnvironment(),
+ SuiteConfiguration.runSkipped(runSkipped),
+ declarer.build(),
+ suitePlatform)
+ ],
+ coverage: coverage,
+ stopOnFirstFailure: stopOnFirstFailure,
+ );
}
/// Returns a [RunnerSuite] with a default environment and configuration.
@@ -221,6 +230,7 @@
bool? runSkipped,
Iterable<String>? dart2jsArgs,
String? precompiledPath,
+ Iterable<CompilerSelection>? compilerSelections,
Iterable<RuntimeSelection>? runtimes,
Map<BooleanSelector, SuiteConfiguration>? tags,
Map<PlatformSelector, SuiteConfiguration>? onPlatform,
@@ -242,6 +252,7 @@
runSkipped: runSkipped,
dart2jsArgs: dart2jsArgs,
precompiledPath: precompiledPath,
+ compilerSelections: compilerSelections,
runtimes: runtimes,
tags: tags,
onPlatform: onPlatform,
@@ -279,7 +290,6 @@
Map<String, RuntimeSettings>? overrideRuntimes,
Map<String, CustomRuntime>? defineRuntimes,
bool? noRetry,
- bool? useDataIsolateStrategy,
bool? ignoreTimeouts,
// Suite-level configuration
@@ -290,6 +300,7 @@
Iterable<String>? dart2jsArgs,
String? precompiledPath,
Iterable<Pattern>? globalPatterns,
+ Iterable<CompilerSelection>? compilerSelections,
Iterable<RuntimeSelection>? runtimes,
BooleanSelector? includeTags,
BooleanSelector? excludeTags,
@@ -330,7 +341,6 @@
overrideRuntimes: overrideRuntimes,
defineRuntimes: defineRuntimes,
noRetry: noRetry,
- useDataIsolateStrategy: useDataIsolateStrategy,
ignoreTimeouts: ignoreTimeouts,
allowDuplicateTestNames: allowDuplicateTestNames,
allowTestRandomization: allowTestRandomization,
@@ -339,12 +349,14 @@
dart2jsArgs: dart2jsArgs,
precompiledPath: precompiledPath,
globalPatterns: globalPatterns,
+ compilerSelections: compilerSelections,
runtimes: runtimes,
includeTags: includeTags,
excludeTags: excludeTags,
tags: tags,
onPlatform: onPlatform,
testRandomizeOrderingSeed: testRandomizeOrderingSeed,
+ stopOnFirstFailure: false,
timeout: timeout,
verboseTrace: verboseTrace,
chainStackTraces: chainStackTraces,
diff --git a/pkgs/test/tool/host.dart b/pkgs/test/tool/host.dart
index 23d83ae..8c0de4e 100644
--- a/pkgs/test/tool/host.dart
+++ b/pkgs/test/tool/host.dart
@@ -14,19 +14,6 @@
import 'package:stream_channel/stream_channel.dart';
import 'package:test/src/runner/browser/dom.dart' as dom;
-/// A class defined in content shell, used to control its behavior.
-@JS()
-@staticInterop
-class TestRunner {}
-
-extension TestRunnerExtension on TestRunner {
- external void waitUntilDone();
-}
-
-/// Returns the current content shell runner, or `null` if none exists.
-@JS()
-external TestRunner? get testRunner;
-
/// A class that exposes the test API to JS.
///
/// These are exposed so that tools like IDEs can interact with them via remote
@@ -59,8 +46,8 @@
final _iframes = <int, dom.HTMLIFrameElement>{};
/// Subscriptions created for each loaded test suite, indexed by the suite id.
-final _subscriptions = <int, List<StreamSubscription<void>>>{};
-final _domSubscriptions = <int, List<dom.Subscription>>{};
+final _subscriptions = <int, StreamSubscription<void>>{};
+final _domSubscriptions = <int, dom.Subscription>{};
/// The URL for the current page.
final _currentUrl = Uri.parse(dom.window.location.href);
@@ -104,7 +91,7 @@
/// connected to each test suite's iframe via a [MessageChannel].
///
/// Each iframe runs a `RemoteListener` which creates its own [MultiChannel] on
-/// top of the [MessageChannel] connection. One connection is used for
+/// top of a [MessageChannel] connection. One connection is used for
/// the `RemoteListener`, which sends messages like "here are all the tests in
/// this suite". The rest are used for each test, receiving messages like
/// "start running". A new connection is also created whenever a test begins
@@ -117,10 +104,6 @@
/// does mean that the server needs to be sure to nest its [MultiChannel]s at
/// the same place the client does.
void main() {
- // This tells content_shell not to close immediately after the page has
- // rendered.
- testRunner?.waitUntilDone();
-
if (_currentUrl.queryParameters['debug'] == 'true') {
dom.document.body!.classList.add('debug');
}
@@ -130,9 +113,9 @@
serverChannel.stream.listen((message) {
if (message['command'] == 'loadSuite') {
var suiteChannel =
- serverChannel.virtualChannel(message['channel'] as int);
- var iframeChannel =
- _connectToIframe(message['url'] as String, message['id'] as int);
+ serverChannel.virtualChannel((message['channel'] as num).toInt());
+ var iframeChannel = _connectToIframe(
+ message['url'] as String, (message['id'] as num).toInt());
suiteChannel.pipe(iframeChannel);
} else if (message['command'] == 'displayPause') {
dom.document.body!.classList.add('paused');
@@ -141,13 +124,8 @@
} else {
assert(message['command'] == 'closeSuite');
_iframes.remove(message['id'])!.remove();
-
- for (var subscription in _subscriptions.remove(message['id'])!) {
- subscription.cancel();
- }
- for (var subscription in _domSubscriptions.remove(message['id'])!) {
- subscription.cancel();
- }
+ _subscriptions.remove(message['id'])?.cancel();
+ _domSubscriptions.remove(message['id'])?.cancel();
}
});
@@ -195,74 +173,93 @@
return MultiChannel(controller.foreign);
}
-/// Creates an iframe with `src` [url] and establishes a connection to it using
-/// a [MessageChannel].
+/// Creates an iframe with `src` [url] and expects a message back to connect a
+/// message channel with the suite running in the frame.
///
/// [id] identifies the suite loaded in this iframe.
+///
+/// Before the frame is attached, adds a listener for `window.onMessage` which
+/// filters to only the messages coming from this frame (by it's URL) and
+/// expects the first message to be either an initialization message, (coming
+/// from the browser bootstrap message channel initialization), or a map with
+/// the key 'exception' set to true and details in the value for 'data' (coming
+/// from `dart.js` due to a load exception).
+///
+/// Legacy bootstrap implementations send a `{'ready': true}` message as a
+/// signal for this host to create a [MessageChannel] and send the port through
+/// the frame's `window.onMessage` channel.
+///
+/// Upcoming bootstrap implementations will send the string 'port' and include a
+/// port for a prepared [MessageChannel].
+///
+/// Returns a [StreamChannel] which will be connected to the frame once the
+/// message channel port is active.
StreamChannel<dynamic> _connectToIframe(String url, int id) {
var iframe = dom.createHTMLIFrameElement();
_iframes[id] = iframe;
- iframe.src = url;
- dom.document.body!.appendChild(iframe);
-
- // Use this to communicate securely with the iframe.
- var channel = dom.createMessageChannel();
var controller = StreamChannelController(sync: true);
- // Use this to avoid sending a message to the iframe before it's sent a
- // message to us. This ensures that no messages get dropped on the floor.
- var readyCompleter = Completer();
-
- var subscriptions = <StreamSubscription<void>>[];
- var domSubscriptions = <dom.Subscription>[];
- _subscriptions[id] = subscriptions;
- _domSubscriptions[id] = domSubscriptions;
-
- domSubscriptions.add(
+ late dom.Subscription windowSubscription;
+ windowSubscription =
dom.Subscription(dom.window, 'message', allowInterop((dom.Event event) {
// A message on the Window can theoretically come from any website. It's
// very unlikely that a malicious site would care about hacking someone's
// unit tests, let alone be able to find the test server while it's
// running, but it's good practice to check the origin anyway.
- dom.MessageEvent message = event as dom.MessageEvent;
+ var message = event as dom.MessageEvent;
if (message.origin != dom.window.location.origin) return;
-
- // TODO(nweiz): Stop manually checking href here once issue 22554 is
- // fixed.
- if (message.data['href'] != iframe.src) return;
+ // Disambiguate between frames for different test suites.
+ // Depending on the source type, the `location.href` may be missing.
+ var location = js_util.getProperty(message.source, 'location') as Object?;
+ if (location == null) return;
+ if (js_util.getProperty(location, 'href') != iframe.src) return;
message.stopPropagation();
+ windowSubscription.cancel();
- if (message.data['ready'] == true) {
- // This message indicates that the iframe is actively listening for
- // events, so the message channel's second port can now be transferred.
- channel.port2.start();
- // TODO(#1758): This is a work around for a crash in package:build.
- js_util.callMethod(
- js_util.getProperty(iframe, 'contentWindow'), 'postMessage', [
- 'port',
- dom.window.location.origin,
- [channel.port2]
- ]);
- readyCompleter.complete();
- } else if (message.data['exception'] == true) {
- // This message from `dart.js` indicates that an exception occurred
- // loading the test.
- controller.local.sink.add(message.data['data']);
+ switch (message.data) {
+ case 'port':
+ // The frame is starting and sending a port to forward for the suite.
+ final port = message.ports.first;
+ _domSubscriptions[id] =
+ dom.Subscription(port, 'message', allowInterop((event) {
+ controller.local.sink.add((event as dom.MessageEvent).data);
+ }));
+ port.start();
+
+ _subscriptions[id] = controller.local.stream.listen(port.postMessage);
+ case {'ready': true}:
+ // This message indicates that the iframe is actively listening for
+ // events, so the message channel's second port can now be transferred.
+ var channel = dom.createMessageChannel();
+ assert(!_domSubscriptions.containsKey(id));
+ _domSubscriptions[id] = dom.Subscription(channel.port1, 'message',
+ allowInterop((dom.Event event) {
+ controller.local.sink.add((event as dom.MessageEvent).data['data']);
+ }));
+
+ assert(!_subscriptions.containsKey(id));
+ _subscriptions[id] =
+ controller.local.stream.listen(channel.port1.postMessage);
+ channel
+ ..port2.start()
+ ..port1.start();
+ // TODO(#1758): This is a work around for a crash in package:build.
+ js_util.callMethod(
+ js_util.getProperty(iframe, 'contentWindow'), 'postMessage', [
+ 'port',
+ dom.window.location.origin,
+ [channel.port2]
+ ]);
+ case {'exception': true, 'data': final data}:
+ // This message from `dart.js` indicates that an exception occurred
+ // loading the test.
+ controller.local.sink.add(data);
}
- })));
-
- channel.port1.start();
- domSubscriptions.add(dom.Subscription(channel.port1, 'message',
- allowInterop((dom.Event event) {
- controller.local.sink.add((event as dom.MessageEvent).data['data']);
- })));
-
- subscriptions.add(controller.local.stream.listen((message) async {
- await readyCompleter.future;
-
- channel.port1.postMessage(message);
}));
+ iframe.src = url;
+ dom.document.body!.appendChild(iframe);
+
return controller.foreign;
}
diff --git a/pkgs/test_api/CHANGELOG.md b/pkgs/test_api/CHANGELOG.md
index 1632870..22731cb 100644
--- a/pkgs/test_api/CHANGELOG.md
+++ b/pkgs/test_api/CHANGELOG.md
@@ -1,3 +1,48 @@
+## 0.6.1
+
+* Drop support for null unsafe Dart, bump SDK constraint to `3.0.0`.
+* Make some implementation classes `final`. These classes were never intended to
+ be extended or implemented. `Metadata`, `PlatformSelector`, `RemoteListener`,
+ `Runtime`, `StackTraceFormatter`, `SuitePlatform`, `RemoteException`,
+ `TestHandle`, `OutstandingWork`, `OutsideTestException`, `OnPlatform`,
+ `Retry`, `Skip`, `Tags`, `TestOn`, `Timeout`.
+* Mark an implementation class `interface`: `StackTraceMapper`.
+* Change the `Compiler` class into an `enum`.
+* Make `Fake` a `mixin class`.
+* Allow the latest analyzer (6.x.x).
+
+## 0.6.0
+
+* Remove the `package:test_api/expect.dart' library. `test` will export from
+ `package:matcher` directly.
+* Fix compatibility with wasm number semantics.
+
+## 0.5.2
+
+* Remove deprecation for the `scaffolding.dart` and `backend.dart` libraries.
+* Export `registerException` from the `scaffolding.dart` library.
+
+## 0.5.1
+
+* Handle a missing `'compiler'` value when running a test compiled against a
+ newer `test_api` than the runner back end is using. The expectation was that
+ the json protocol is only used across packages compatible with the same major
+ version of the `test_api` package, but `flutter test` does not check the
+ version of packages in the pub solve for user test code.
+
+## 0.5.0
+
+* Add `Compiler` class, exposed through `backend.dart`.
+* Support compiler identifiers in platform selectors.
+* Add `compiler` field to `SuitePlatform`. This will become required in the next
+ major release.
+* **BREAKING** Add required `defaultCompiler` and `supportedCompilers` fields
+ to `Runtime`.
+* Add `package:test_api/hooks_testing.dart` library for writing tests against
+ code that uses `package:test_api/hooks.dart`.
+* **BREAKING** Remove `ErrorFormatter`, `expectAsync`, `throws`, and `Throws`
+ from `package:test_api/test_api.dart`.
+
## 0.4.18
* Don't run `tearDown` until the test body and outstanding work is complete,
diff --git a/pkgs/test_api/README.md b/pkgs/test_api/README.md
index 27c759b..aa1af49 100644
--- a/pkgs/test_api/README.md
+++ b/pkgs/test_api/README.md
@@ -1,3 +1,6 @@
+[![pub package](https://img.shields.io/pub/v/test_api.svg)](https://pub.dev/packages/test_api)
+[![package publisher](https://img.shields.io/pub/publisher/test_api.svg)](https://pub.dev/packages/test_api/publisher)
+
A minimal package for writing tests. At this time this package is not intended
to be publicly used as the API will take time to stabilize.
diff --git a/pkgs/test_api/lib/backend.dart b/pkgs/test_api/lib/backend.dart
index bb80812..5da47b6 100644
--- a/pkgs/test_api/lib/backend.dart
+++ b/pkgs/test_api/lib/backend.dart
@@ -2,10 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-@Deprecated('package:test_api is not intended for general use. '
- 'Please use package:test.')
-library test_api.backend;
-
+export 'src/backend/compiler.dart' show Compiler;
export 'src/backend/metadata.dart' show Metadata;
export 'src/backend/platform_selector.dart' show PlatformSelector;
export 'src/backend/remote_exception.dart' show RemoteException;
diff --git a/pkgs/test_api/lib/expect.dart b/pkgs/test_api/lib/expect.dart
deleted file mode 100644
index 30a8071..0000000
--- a/pkgs/test_api/lib/expect.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-export 'package:matcher/matcher.dart';
-
-export 'src/expect/expect.dart' show expect, expectLater, fail;
-export 'src/expect/expect_async.dart'
- show
- Func0,
- Func1,
- Func2,
- Func3,
- Func4,
- Func5,
- Func6,
- expectAsync0,
- expectAsync1,
- expectAsync2,
- expectAsync3,
- expectAsync4,
- expectAsync5,
- expectAsync6,
- expectAsyncUntil0,
- expectAsyncUntil1,
- expectAsyncUntil2,
- expectAsyncUntil3,
- expectAsyncUntil4,
- expectAsyncUntil5,
- expectAsyncUntil6;
-export 'src/expect/future_matchers.dart'
- show completes, completion, doesNotComplete;
-export 'src/expect/never_called.dart' show neverCalled;
-export 'src/expect/prints_matcher.dart' show prints;
-export 'src/expect/stream_matcher.dart' show StreamMatcher;
-export 'src/expect/stream_matchers.dart'
- show
- emitsDone,
- emits,
- emitsError,
- mayEmit,
- emitsAnyOf,
- emitsInOrder,
- emitsInAnyOrder,
- emitsThrough,
- mayEmitMultiple,
- neverEmits;
-export 'src/expect/throws_matcher.dart' show throwsA;
-export 'src/expect/throws_matchers.dart'
- show
- throwsArgumentError,
- throwsConcurrentModificationError,
- throwsCyclicInitializationError,
- throwsException,
- throwsFormatException,
- throwsNoSuchMethodError,
- throwsNullThrownError,
- throwsRangeError,
- throwsStateError,
- throwsUnimplementedError,
- throwsUnsupportedError;
diff --git a/pkgs/test_api/lib/hooks.dart b/pkgs/test_api/lib/hooks.dart
index b7e1455..126d322 100644
--- a/pkgs/test_api/lib/hooks.dart
+++ b/pkgs/test_api/lib/hooks.dart
@@ -13,7 +13,7 @@
export 'src/backend/test_failure.dart' show TestFailure;
export 'src/scaffolding/utils.dart' show pumpEventQueue;
-class TestHandle {
+final class TestHandle {
/// Returns handle for the currently running test.
///
/// This must be called from within the zone that the test is running in. If
@@ -65,7 +65,7 @@
_stackTraceFormatter.formatStackTrace(stackTrace);
}
-class OutstandingWork {
+final class OutstandingWork {
final Invoker _invoker;
final Zone _zone;
var _isComplete = false;
@@ -79,4 +79,4 @@
}
}
-class OutsideTestException implements Exception {}
+final class OutsideTestException implements Exception {}
diff --git a/pkgs/test_api/lib/hooks_testing.dart b/pkgs/test_api/lib/hooks_testing.dart
new file mode 100644
index 0000000..b0a6154
--- /dev/null
+++ b/pkgs/test_api/lib/hooks_testing.dart
@@ -0,0 +1,157 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'src/backend/group.dart';
+import 'src/backend/invoker.dart';
+import 'src/backend/live_test.dart';
+import 'src/backend/metadata.dart';
+import 'src/backend/runtime.dart';
+import 'src/backend/state.dart';
+import 'src/backend/suite.dart';
+import 'src/backend/suite_platform.dart';
+
+@Deprecated('These classes are unused for monitoring tests. Use `State`.')
+export 'src/backend/state.dart' show Result, Status;
+export 'src/backend/test_failure.dart' show TestFailure;
+
+/// A monitor for the behavior of a callback when it is run as the body of a
+/// test case.
+///
+/// Allows running a callback as the body of a local test case and querying for
+/// the current [state], and [errors], and subscribing to future errors.
+///
+/// Use [run] to run a test body and query for the success or failure.
+///
+/// Use [start] to start a test and query for whether it has finished running.
+final class TestCaseMonitor {
+ final LiveTest _liveTest;
+ final _done = Completer<void>();
+ TestCaseMonitor._(FutureOr<void> Function() body)
+ : _liveTest = _createTest(body);
+
+ /// Run [body] as a test case and return a [TestCaseMonitor] with the result.
+ ///
+ /// The [state] will either [State.passed], [State.skipped], or
+ /// [State.failed], the test will no longer be running.
+ ///
+ /// {@template result-late-fail}
+ /// Note that a test can change state from [State.passed] to [State.failed]
+ /// if the test surfaces an unawaited asynchronous error.
+ /// {@endtemplate}
+ ///
+ /// ```dart
+ /// final monitor = await TestCaseMonitor.run(() {
+ /// fail('oh no!');
+ /// });
+ /// assert(monitor.state == State.failed);
+ /// assert((monitor.errors.single.error as TestFailure).message == 'oh no!');
+ /// ```
+ static Future<TestCaseMonitor> run(FutureOr<void> Function() body) async {
+ final monitor = TestCaseMonitor.start(body);
+ await monitor.onDone;
+ return monitor;
+ }
+
+ /// Start [body] as a test case and return a [TestCaseMonitor] with the status
+ /// and result.
+ ///
+ /// The [state] will start as [State.pending] if queried synchronously, but it
+ /// will switch to [State.running]. After `onDone` completes the state will be
+ /// one of [State.passed], [State.skipped], or [State.failed].
+ ///
+ /// {@macro result-late-fail}
+ ///
+ /// ```dart
+ /// late void Function() completeWork;
+ /// final monitor = TestCaseMonitor.start(() {
+ /// final outstandingWork = TestHandle.current.markPending();
+ /// completeWork = outstandingWork.complete;
+ /// });
+ /// await pumpEventQueue();
+ /// assert(monitor.state == State.running);
+ /// completeWork();
+ /// await monitor.onDone;
+ /// assert(monitor.state == State.passed);
+ /// ```
+ static TestCaseMonitor start(FutureOr<void> Function() body) =>
+ TestCaseMonitor._(body).._start();
+
+ void _start() {
+ _liveTest.run().whenComplete(_done.complete);
+ }
+
+ /// A future that completes after this test has finished running, or has
+ /// surfaced an error.
+ Future<void> get onDone => _done.future;
+
+ /// The running and success or failure status for the test case.
+ State get state {
+ final status = _liveTest.state.status;
+ if (status == Status.pending) return State.pending;
+ if (status == Status.running) return State.running;
+ final result = _liveTest.state.result;
+ if (result == Result.skipped) return State.skipped;
+ if (result == Result.success) return State.passed;
+ // result == Result.failure || result == Result.error
+ return State.failed;
+ }
+
+ /// The errors surfaced by the test.
+ ///
+ /// A test with any errors will have a [state] of [State.failed].
+ ///
+ /// {@macro result-late-fail}
+ ///
+ /// A test may have more than one error if there were unhandled asynchronous
+ /// errors surfaced after the test is done.
+ Iterable<AsyncError> get errors => _liveTest.errors;
+
+ /// A stream of errors surfaced by the test.
+ ///
+ /// This stream will not close, asynchronous errors may be surfaced within the
+ /// test's error zone at any point.
+ Stream<AsyncError> get onError => _liveTest.onError;
+}
+
+/// Returns a local [LiveTest] that runs [body].
+LiveTest _createTest(FutureOr<void> Function() body) {
+ var test = LocalTest('test', Metadata(chainStackTraces: true), body);
+ var suite = Suite(Group.root([test]), _suitePlatform, ignoreTimeouts: false);
+ return test.load(suite);
+}
+
+/// A dummy suite platform to use for testing suites.
+final _suitePlatform =
+ SuitePlatform(Runtime.vm, compiler: Runtime.vm.defaultCompiler);
+
+/// The running and success state of a test monitored by a [TestCaseMonitor].
+enum State {
+ /// The test is has not yet started.
+ pending,
+
+ /// The test is running and has not yet failed.
+ running,
+
+ /// The test has completed without any error.
+ ///
+ /// This implies that the test body has completed, and no error has surfaced
+ /// *yet*. However, it this doesn't mean that the test won't fail in the
+ /// future.
+ passed,
+
+ /// The test, or some part of it, has been skipped.
+ ///
+ /// This does not imply that the test has not had an error, but if there are
+ /// errors they are ignored.
+ skipped,
+
+ /// The test has failed.
+ ///
+ /// An test fails when any exception, typically a [TestFailure], is thrown in
+ /// the test's zone. A test that has failed may still have additional errors
+ /// that surface as unhandled asynchronous errors.
+ failed,
+}
diff --git a/pkgs/test_api/lib/scaffolding.dart b/pkgs/test_api/lib/scaffolding.dart
index 57f9e9a..84185b8 100644
--- a/pkgs/test_api/lib/scaffolding.dart
+++ b/pkgs/test_api/lib/scaffolding.dart
@@ -8,8 +8,6 @@
/// {@canonicalFor tags.Tags}
/// {@canonicalFor test_on.TestOn}
/// {@canonicalFor timeout.Timeout}
-@Deprecated('package:test_api is not intended for general use. '
- 'Please use package:test.')
library test_api.scaffolding;
export 'src/backend/configuration/on_platform.dart' show OnPlatform;
@@ -18,8 +16,8 @@
export 'src/backend/configuration/tags.dart' show Tags;
export 'src/backend/configuration/test_on.dart' show TestOn;
export 'src/backend/configuration/timeout.dart' show Timeout;
-export 'src/scaffolding/spawn_hybrid.dart' show spawnHybridUri, spawnHybridCode;
+export 'src/scaffolding/spawn_hybrid.dart' show spawnHybridCode, spawnHybridUri;
export 'src/scaffolding/test_structure.dart'
- show group, test, setUp, setUpAll, tearDown, tearDownAll, addTearDown;
+ show addTearDown, group, setUp, setUpAll, tearDown, tearDownAll, test;
export 'src/scaffolding/utils.dart'
- show pumpEventQueue, printOnFailure, markTestSkipped;
+ show markTestSkipped, printOnFailure, pumpEventQueue, registerException;
diff --git a/pkgs/test_api/lib/src/backend/compiler.dart b/pkgs/test_api/lib/src/backend/compiler.dart
new file mode 100644
index 0000000..9d8c3f9
--- /dev/null
+++ b/pkgs/test_api/lib/src/backend/compiler.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// All the Dart compilers supported by the test runner.
+enum Compiler {
+ /// The production Dart to Javascript compiler (whole world, optimizing).
+ dart2js('Dart2Js', 'dart2js'),
+
+ /// Experimental Dart to Wasm compiler.
+ dart2wasm('Dart2WASM', 'dart2wasm'),
+
+ /// Compiles dart code to a native executable.
+ exe('Exe', 'exe'),
+
+ /// The standard compiler for vm tests, compiles tests to kernel before
+ /// running them on the VM.
+ kernel('Kernel', 'kernel'),
+
+ /// Runs tests directly from source, with no precompilation.
+ source('Source', 'source');
+
+ /// The compilers that are supported by the test runner by default.
+ static const List<Compiler> builtIn = [
+ Compiler.dart2js,
+ Compiler.dart2wasm,
+ Compiler.exe,
+ Compiler.kernel,
+ Compiler.source,
+ ];
+
+ /// The human-friendly name of the compiler.
+ final String name;
+
+ /// The identifier used to look up the compiler.
+ final String identifier;
+
+ const Compiler(this.name, this.identifier);
+
+ /// Converts a JSON-safe representation generated by [serialize] back into a
+ /// [Compiler].
+ ///
+ /// Note that custom [Compiler] implementations are not supported.
+ factory Compiler.deserialize(Object serialized) => builtIn
+ .firstWhere((compiler) => compiler.identifier == serialized as String);
+
+ /// Converts [this] into a JSON-safe object that can be converted back to a
+ /// [Compiler] using [Compiler.deserialize].
+ Object serialize() => identifier;
+
+ @override
+ String toString() => name;
+}
diff --git a/pkgs/test_api/lib/src/backend/configuration/on_platform.dart b/pkgs/test_api/lib/src/backend/configuration/on_platform.dart
index d88848d..02a5254 100644
--- a/pkgs/test_api/lib/src/backend/configuration/on_platform.dart
+++ b/pkgs/test_api/lib/src/backend/configuration/on_platform.dart
@@ -10,7 +10,7 @@
///
/// [onPlatform]: https://github.com/dart-lang/test/tree/master/pkgs/test#platform-specific-configuration
@Target({TargetKind.library})
-class OnPlatform {
+final class OnPlatform {
final Map<String, dynamic> annotationsByPlatform;
const OnPlatform(this.annotationsByPlatform);
diff --git a/pkgs/test_api/lib/src/backend/configuration/retry.dart b/pkgs/test_api/lib/src/backend/configuration/retry.dart
index b813526..1811814 100644
--- a/pkgs/test_api/lib/src/backend/configuration/retry.dart
+++ b/pkgs/test_api/lib/src/backend/configuration/retry.dart
@@ -9,7 +9,7 @@
/// A suite-level retry configuration will enable retries for every test in the
/// suite, unless the group or test is configured with a more specific retry.
@Target({TargetKind.library})
-class Retry {
+final class Retry {
/// The number of times the tests in the suite will be retried.
final int count;
diff --git a/pkgs/test_api/lib/src/backend/configuration/skip.dart b/pkgs/test_api/lib/src/backend/configuration/skip.dart
index 8be4b73..3927994 100644
--- a/pkgs/test_api/lib/src/backend/configuration/skip.dart
+++ b/pkgs/test_api/lib/src/backend/configuration/skip.dart
@@ -6,7 +6,7 @@
/// An annotation for marking a test suite as skipped.
@Target({TargetKind.library})
-class Skip {
+final class Skip {
/// The reason the test suite is skipped, or `null` if no reason is given.
final String? reason;
diff --git a/pkgs/test_api/lib/src/backend/configuration/tags.dart b/pkgs/test_api/lib/src/backend/configuration/tags.dart
index cb1ea2b..dbd03f3 100644
--- a/pkgs/test_api/lib/src/backend/configuration/tags.dart
+++ b/pkgs/test_api/lib/src/backend/configuration/tags.dart
@@ -10,7 +10,7 @@
///
/// [tagging tests]: https://github.com/dart-lang/test/blob/master/pkgs/test/README.md#tagging-tests
@Target({TargetKind.library})
-class Tags {
+final class Tags {
/// The tags for the test suite.
Set<String> get tags => _tags.toSet();
diff --git a/pkgs/test_api/lib/src/backend/configuration/test_on.dart b/pkgs/test_api/lib/src/backend/configuration/test_on.dart
index 4ffb016..dee7f40 100644
--- a/pkgs/test_api/lib/src/backend/configuration/test_on.dart
+++ b/pkgs/test_api/lib/src/backend/configuration/test_on.dart
@@ -10,7 +10,7 @@
///
/// [the README]: https://github.com/dart-lang/test/tree/master/pkgs/test#platform-selectors
@Target({TargetKind.library})
-class TestOn {
+final class TestOn {
/// The expression specifying the platform.
final String expression;
diff --git a/pkgs/test_api/lib/src/backend/configuration/timeout.dart b/pkgs/test_api/lib/src/backend/configuration/timeout.dart
index 5532318..e51d520 100644
--- a/pkgs/test_api/lib/src/backend/configuration/timeout.dart
+++ b/pkgs/test_api/lib/src/backend/configuration/timeout.dart
@@ -24,7 +24,7 @@
/// can be overridden entirely; with [Timeout.factor], it can be scaled
/// relative to the default.
@Target({TargetKind.library})
-class Timeout {
+final class Timeout {
/// A constant indicating that a test should never time out.
static const none = Timeout._none();
@@ -79,7 +79,7 @@
// Scan a number. This will be either a time unit or a scale factor.
scanner.expect(_untilUnit, name: 'number');
- var number = double.parse((scanner.lastMatch![0])!);
+ var number = double.parse(scanner.lastMatch![0]!);
// A number followed by "x" is a scale factor.
if (scanner.scan('x') || scanner.scan('X')) {
@@ -92,13 +92,13 @@
var microseconds = 0.0;
while (true) {
scanner.expect(_unit, name: 'unit');
- microseconds += _microsecondsFor(number, (scanner.lastMatch![0])!);
+ microseconds += _microsecondsFor(number, scanner.lastMatch![0]!);
scanner.scan(_whitespace);
// Scan the next number, if it's available.
if (!scanner.scan(_untilUnit)) break;
- number = double.parse((scanner.lastMatch![0])!);
+ number = double.parse(scanner.lastMatch![0]!);
}
scanner.expectDone();
@@ -106,24 +106,15 @@
}
/// Returns the number of microseconds in [number] [unit]s.
- static double _microsecondsFor(double number, String unit) {
- switch (unit) {
- case 'd':
- return number * 24 * 60 * 60 * 1000000;
- case 'h':
- return number * 60 * 60 * 1000000;
- case 'm':
- return number * 60 * 1000000;
- case 's':
- return number * 1000000;
- case 'ms':
- return number * 1000;
- case 'us':
- return number;
- default:
- throw ArgumentError('Unknown unit $unit.');
- }
- }
+ static double _microsecondsFor(double number, String unit) => switch (unit) {
+ 'd' => number * 24 * 60 * 60 * 1000000,
+ 'h' => number * 60 * 60 * 1000000,
+ 'm' => number * 60 * 1000000,
+ 's' => number * 1000000,
+ 'ms' => number * 1000,
+ 'us' => number,
+ _ => throw ArgumentError('Unknown unit $unit.'),
+ };
/// Returns a new [Timeout] that merges [this] with [other].
///
@@ -150,7 +141,7 @@
int get hashCode => duration.hashCode ^ 5 * scaleFactor.hashCode;
@override
- bool operator ==(other) =>
+ bool operator ==(Object other) =>
other is Timeout &&
other.duration == duration &&
other.scaleFactor == scaleFactor;
diff --git a/pkgs/test_api/lib/src/backend/declarer.dart b/pkgs/test_api/lib/src/backend/declarer.dart
index 7a37552..c3686dd 100644
--- a/pkgs/test_api/lib/src/backend/declarer.dart
+++ b/pkgs/test_api/lib/src/backend/declarer.dart
@@ -172,9 +172,9 @@
void test(String name, dynamic Function() body,
{String? testOn,
Timeout? timeout,
- skip,
+ Object? skip,
Map<String, dynamic>? onPlatform,
- tags,
+ Object? tags,
int? retry,
bool solo = false}) {
_checkNotBuilt('test');
@@ -228,9 +228,9 @@
void group(String name, void Function() body,
{String? testOn,
Timeout? timeout,
- skip,
+ Object? skip,
Map<String, dynamic>? onPlatform,
- tags,
+ Object? tags,
int? retry,
bool solo = false}) {
_checkNotBuilt('group');
diff --git a/pkgs/test_api/lib/src/backend/invoker.dart b/pkgs/test_api/lib/src/backend/invoker.dart
index 582d9f9..0274f90 100644
--- a/pkgs/test_api/lib/src/backend/invoker.dart
+++ b/pkgs/test_api/lib/src/backend/invoker.dart
@@ -305,9 +305,9 @@
// Set the state explicitly so we don't get an extra error about the test
// failing after being complete.
_controller.setState(const State(Status.complete, Result.error));
- throw 'This test was marked as skipped after it had already completed. '
- 'Make sure to use\n'
- '[expectAsync] or the [completes] matcher when testing async code.';
+ throw 'This test was marked as skipped after it had already completed.\n'
+ 'Make sure to use a matching library which informs the test runner\n'
+ 'of pending async work.';
}
if (message != null) _controller.message(Message.skip(message));
@@ -367,9 +367,9 @@
_handleError(
zone,
- 'This test failed after it had already completed. Make sure to use '
- '[expectAsync]\n'
- 'or the [completes] matcher when testing async code.',
+ 'This test failed after it had already completed.\n'
+ 'Make sure to use a matching library which informs the test runner\n'
+ 'of pending async work.',
stackTrace);
}
diff --git a/pkgs/test_api/lib/src/backend/live_test_controller.dart b/pkgs/test_api/lib/src/backend/live_test_controller.dart
index 94994c1..956c293 100644
--- a/pkgs/test_api/lib/src/backend/live_test_controller.dart
+++ b/pkgs/test_api/lib/src/backend/live_test_controller.dart
@@ -48,7 +48,7 @@
/// The current state of the test.
@override
- var state = const State(Status.pending, Result.success);
+ State state = const State(Status.pending, Result.success);
/// The controller for [onStateChange].
///
diff --git a/pkgs/test_api/lib/src/backend/message.dart b/pkgs/test_api/lib/src/backend/message.dart
index efe152f..a027460 100644
--- a/pkgs/test_api/lib/src/backend/message.dart
+++ b/pkgs/test_api/lib/src/backend/message.dart
@@ -28,16 +28,11 @@
/// The name of the message type.
final String name;
- factory MessageType.parse(String name) {
- switch (name) {
- case 'print':
- return MessageType.print;
- case 'skip':
- return MessageType.skip;
- default:
- throw ArgumentError('Invalid message type "$name".');
- }
- }
+ factory MessageType.parse(String name) => switch (name) {
+ 'print' => MessageType.print,
+ 'skip' => MessageType.skip,
+ _ => throw ArgumentError('Invalid message type "$name".'),
+ };
const MessageType._(this.name);
diff --git a/pkgs/test_api/lib/src/backend/metadata.dart b/pkgs/test_api/lib/src/backend/metadata.dart
index 0404dbf..3455a04 100644
--- a/pkgs/test_api/lib/src/backend/metadata.dart
+++ b/pkgs/test_api/lib/src/backend/metadata.dart
@@ -16,7 +16,7 @@
///
/// This metadata comes from declarations on the test itself; it doesn't include
/// configuration from the user.
-class Metadata {
+final class Metadata {
/// Empty metadata with only default values.
///
/// Using this is slightly more efficient than manually constructing a new
@@ -264,7 +264,7 @@
skipReason = serialized['skipReason'] as String?,
_verboseTrace = serialized['verboseTrace'] as bool?,
_chainStackTraces = serialized['chainStackTraces'] as bool?,
- _retry = serialized['retry'] as int?,
+ _retry = (serialized['retry'] as num?)?.toInt(),
tags = Set.from(serialized['tags'] as Iterable),
onPlatform = {
for (var pair in serialized['onPlatform'] as List)
@@ -282,7 +282,8 @@
if (serialized == 'none') return Timeout.none;
var scaleFactor = serialized['scaleFactor'];
if (scaleFactor != null) return Timeout.factor(scaleFactor as num);
- return Timeout(Duration(microseconds: serialized['duration'] as int));
+ return Timeout(
+ Duration(microseconds: (serialized['duration'] as num).toInt()));
}
/// Throws an [ArgumentError] if any tags in [tags] aren't hyphenated
diff --git a/pkgs/test_api/lib/src/backend/operating_system.dart b/pkgs/test_api/lib/src/backend/operating_system.dart
index f33e739..a86c1e7 100644
--- a/pkgs/test_api/lib/src/backend/operating_system.dart
+++ b/pkgs/test_api/lib/src/backend/operating_system.dart
@@ -49,22 +49,14 @@
/// `Platform.operatingSystem`.
///
/// If no operating system is found, returns [none].
- static OperatingSystem findByIoName(String name) {
- switch (name) {
- case 'windows':
- return windows;
- case 'macos':
- return macOS;
- case 'linux':
- return linux;
- case 'android':
- return android;
- case 'ios':
- return iOS;
- default:
- return none;
- }
- }
+ static OperatingSystem findByIoName(String name) => switch (name) {
+ 'windows' => windows,
+ 'macos' => macOS,
+ 'linux' => linux,
+ 'android' => android,
+ 'ios' => iOS,
+ _ => none,
+ };
/// The human-friendly of the operating system.
final String name;
diff --git a/pkgs/test_api/lib/src/backend/platform_selector.dart b/pkgs/test_api/lib/src/backend/platform_selector.dart
index 8d6d60c..2ad59b2 100644
--- a/pkgs/test_api/lib/src/backend/platform_selector.dart
+++ b/pkgs/test_api/lib/src/backend/platform_selector.dart
@@ -5,6 +5,7 @@
import 'package:boolean_selector/boolean_selector.dart';
import 'package:source_span/source_span.dart';
+import 'compiler.dart';
import 'operating_system.dart';
import 'runtime.dart';
import 'suite_platform.dart';
@@ -19,6 +20,7 @@
'google',
'wasm',
for (var runtime in Runtime.builtIn) runtime.identifier,
+ for (var compiler in Compiler.builtIn) compiler.identifier,
for (var os in OperatingSystem.all) os.identifier,
};
@@ -28,7 +30,7 @@
/// This uses the [boolean selector][] syntax.
///
/// [boolean selector]: https://pub.dev/packages/boolean_selector
-class PlatformSelector {
+final class PlatformSelector {
/// A selector that declares that a test can be run on all platforms.
static const all = PlatformSelector._(BooleanSelector.all);
@@ -77,31 +79,23 @@
}
/// Returns whether the selector matches the given [platform].
- bool evaluate(SuitePlatform platform) {
- return _inner.evaluate((String variable) {
- if (variable == platform.runtime.identifier) return true;
- if (variable == platform.runtime.parent?.identifier) return true;
- if (variable == platform.os.identifier) return true;
- switch (variable) {
- case 'dart-vm':
- return platform.runtime.isDartVM;
- case 'browser':
- return platform.runtime.isBrowser;
- case 'js':
- return platform.runtime.isJS;
- case 'blink':
- return platform.runtime.isBlink;
- case 'posix':
- return platform.os.isPosix;
- case 'google':
- return platform.inGoogle;
- case 'wasm':
- return platform.runtime.isWasm;
- default:
- return false;
- }
- });
- }
+ bool evaluate(SuitePlatform platform) =>
+ _inner.evaluate((String variable) => switch (variable) {
+ _
+ when variable == platform.runtime.identifier ||
+ variable == platform.runtime.parent?.identifier ||
+ variable == platform.os.identifier ||
+ variable == platform.compiler.identifier =>
+ true,
+ 'dart-vm' => platform.runtime.isDartVM,
+ 'browser' => platform.runtime.isBrowser,
+ 'js' => platform.runtime.isJS,
+ 'blink' => platform.runtime.isBlink,
+ 'posix' => platform.os.isPosix,
+ 'google' => platform.inGoogle,
+ 'wasm' => platform.runtime.isWasm,
+ _ => false,
+ });
/// Returns a new [PlatformSelector] that matches only platforms matched by
/// both [this] and [other].
@@ -114,7 +108,7 @@
String toString() => _inner.toString();
@override
- bool operator ==(other) =>
+ bool operator ==(Object other) =>
other is PlatformSelector && _inner == other._inner;
@override
diff --git a/pkgs/test_api/lib/src/backend/remote_exception.dart b/pkgs/test_api/lib/src/backend/remote_exception.dart
index ef47ea1..560f70e 100644
--- a/pkgs/test_api/lib/src/backend/remote_exception.dart
+++ b/pkgs/test_api/lib/src/backend/remote_exception.dart
@@ -12,7 +12,7 @@
///
/// This could be an exception thrown in a different isolate, a different
/// process, or on an entirely different computer.
-class RemoteException implements Exception {
+final class RemoteException implements Exception {
/// The original exception's message, if it had one.
///
/// If the original exception was a plain string, this will contain that
@@ -29,7 +29,7 @@
///
/// Other than JSON- and isolate-safety, no guarantees are made about the
/// serialized format.
- static Map<String, dynamic> serialize(error, StackTrace stackTrace) {
+ static Map<String, dynamic> serialize(dynamic error, StackTrace stackTrace) {
String? message;
if (error is String) {
message = error;
@@ -56,23 +56,21 @@
///
/// The returned [AsyncError] is guaranteed to have a [RemoteException] as its
/// error and a [Chain] as its stack trace.
- static AsyncError deserialize(serialized) {
+ static AsyncError deserialize(Map serialized) {
return AsyncError(_deserializeException(serialized),
Chain.parse(serialized['stackChain'] as String));
}
/// Deserializes the exception portion of [serialized].
- static RemoteException _deserializeException(serialized) {
+ static RemoteException _deserializeException(Map serialized) {
final message = serialized['message'] as String?;
final type = serialized['type'] as String;
final toString = serialized['toString'] as String;
- switch (serialized['supertype'] as String?) {
- case 'TestFailure':
- return _RemoteTestFailure(message, type, toString);
- default:
- return RemoteException._(message, type, toString);
- }
+ return switch (serialized['supertype'] as String?) {
+ 'TestFailure' => _RemoteTestFailure(message, type, toString),
+ _ => RemoteException._(message, type, toString),
+ };
}
RemoteException._(this.message, this.type, this._toString);
@@ -85,7 +83,7 @@
///
/// It's important to preserve [TestFailure]-ness, because tests have different
/// results depending on whether an exception was a failure or an error.
-class _RemoteTestFailure extends RemoteException implements TestFailure {
+final class _RemoteTestFailure extends RemoteException implements TestFailure {
_RemoteTestFailure(String? message, String type, String toString)
: super._(message, type, toString);
}
diff --git a/pkgs/test_api/lib/src/backend/remote_listener.dart b/pkgs/test_api/lib/src/backend/remote_listener.dart
index 5aa0638..f47c4ea 100644
--- a/pkgs/test_api/lib/src/backend/remote_listener.dart
+++ b/pkgs/test_api/lib/src/backend/remote_listener.dart
@@ -20,7 +20,7 @@
import 'suite_platform.dart';
import 'test.dart';
-class RemoteListener {
+final class RemoteListener {
/// The test suite to run.
final Suite _suite;
diff --git a/pkgs/test_api/lib/src/backend/runtime.dart b/pkgs/test_api/lib/src/backend/runtime.dart
index 6b189c6..c70eb99 100644
--- a/pkgs/test_api/lib/src/backend/runtime.dart
+++ b/pkgs/test_api/lib/src/backend/runtime.dart
@@ -2,37 +2,57 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'compiler.dart';
+
/// An enum of all Dart runtimes supported by the test runner.
-class Runtime {
+final class Runtime {
// When adding new runtimes, be sure to update the baseline and derived
// variable tests in test/backend/platform_selector/evaluate_test.
/// The command-line Dart VM.
- static const Runtime vm = Runtime('VM', 'vm', isDartVM: true);
+ static const Runtime vm = Runtime('VM', 'vm', Compiler.kernel,
+ [Compiler.kernel, Compiler.source, Compiler.exe],
+ isDartVM: true);
/// Google Chrome.
- static const Runtime chrome =
- Runtime('Chrome', 'chrome', isBrowser: true, isJS: true, isBlink: true);
+ static const Runtime chrome = Runtime(
+ 'Chrome', 'chrome', Compiler.dart2js, [Compiler.dart2js],
+ isBrowser: true, isJS: true, isBlink: true);
/// Mozilla Firefox.
- static const Runtime firefox =
- Runtime('Firefox', 'firefox', isBrowser: true, isJS: true);
+ static const Runtime firefox = Runtime(
+ 'Firefox', 'firefox', Compiler.dart2js, [Compiler.dart2js],
+ isBrowser: true, isJS: true);
/// Apple Safari.
- static const Runtime safari =
- Runtime('Safari', 'safari', isBrowser: true, isJS: true);
+ static const Runtime safari = Runtime(
+ 'Safari', 'safari', Compiler.dart2js, [Compiler.dart2js],
+ isBrowser: true, isJS: true);
/// Microsoft Internet Explorer.
- static const Runtime internetExplorer =
- Runtime('Internet Explorer', 'ie', isBrowser: true, isJS: true);
+ static const Runtime internetExplorer = Runtime(
+ 'Internet Explorer', 'ie', Compiler.dart2js, [Compiler.dart2js],
+ isBrowser: true, isJS: true);
+
+ /// Microsoft Edge (based on Chromium).
+ static const Runtime edge = Runtime(
+ 'Microsoft Edge', 'edge', Compiler.dart2js, [Compiler.dart2js],
+ isBrowser: true, isJS: true, isBlink: true);
/// The command-line Node.js VM.
- static const Runtime nodeJS = Runtime('Node.js', 'node', isJS: true);
+ static const Runtime nodeJS = Runtime(
+ 'Node.js', 'node', Compiler.dart2js, [Compiler.dart2js],
+ isJS: true);
/// Google Chrome.
static const Runtime experimentalChromeWasm = Runtime(
- 'ExperimentalChromeWasm', 'experimental-chrome-wasm',
- isBrowser: true, isBlink: true, isWasm: true);
+ 'ExperimentalChromeWasm',
+ 'experimental-chrome-wasm',
+ Compiler.dart2wasm,
+ [Compiler.dart2wasm],
+ isBrowser: true,
+ isBlink: true,
+ isWasm: true);
/// The platforms that are supported by the test runner by default.
static const List<Runtime> builtIn = [
@@ -41,6 +61,7 @@
Runtime.firefox,
Runtime.safari,
Runtime.internetExplorer,
+ Runtime.edge,
Runtime.nodeJS,
Runtime.experimentalChromeWasm,
];
@@ -82,7 +103,14 @@
/// That is, returns [parent] if it's non-`null` or [this] if it's `null`.
Runtime get root => parent ?? this;
- const Runtime(this.name, this.identifier,
+ /// The default compiler to use with this runtime.
+ final Compiler defaultCompiler;
+
+ /// All the supported compilers for this runtime.
+ final List<Compiler> supportedCompilers;
+
+ const Runtime(
+ this.name, this.identifier, this.defaultCompiler, this.supportedCompilers,
{this.isDartVM = false,
this.isBrowser = false,
this.isJS = false,
@@ -91,7 +119,8 @@
this.isWasm = false})
: parent = null;
- Runtime._child(this.name, this.identifier, Runtime this.parent)
+ Runtime._child(this.name, this.identifier, this.defaultCompiler,
+ this.supportedCompilers, Runtime this.parent)
: isDartVM = parent.isDartVM,
isBrowser = parent.isBrowser,
isJS = parent.isJS,
@@ -108,17 +137,26 @@
}
var map = serialized as Map;
+ var name = map['name'] as String;
+ var identifier = map['identifier'] as String;
+ var defaultCompiler =
+ Compiler.deserialize(map['defaultCompiler'] as Object);
+ var supportedCompilers = [
+ for (var compiler in map['supportedCompilers'] as List)
+ Compiler.deserialize(compiler as Object),
+ ];
+
var parent = map['parent'];
if (parent != null) {
// Note that the returned platform's [parent] won't necessarily be `==` to
// a separately-deserialized parent platform. This should be fine, though,
// since we only deserialize platforms in the remote execution context
// where they're only used to evaluate platform selectors.
- return Runtime._child(map['name'] as String, map['identifier'] as String,
- Runtime.deserialize(parent as Object));
+ return Runtime._child(name, identifier, defaultCompiler,
+ supportedCompilers, Runtime.deserialize(parent as Object));
}
- return Runtime(map['name'] as String, map['identifier'] as String,
+ return Runtime(name, identifier, defaultCompiler, supportedCompilers,
isDartVM: map['isDartVM'] as bool,
isBrowser: map['isBrowser'] as bool,
isJS: map['isJS'] as bool,
@@ -135,6 +173,10 @@
if (parent != null) {
return {
'name': name,
+ 'defaultCompiler': defaultCompiler.serialize(),
+ 'supportedCompilers': [
+ for (var compiler in supportedCompilers) compiler.serialize(),
+ ],
'identifier': identifier,
'parent': parent!.serialize()
};
@@ -142,6 +184,10 @@
return {
'name': name,
+ 'defaultCompiler': defaultCompiler.serialize(),
+ 'supportedCompilers': [
+ for (var compiler in supportedCompilers) compiler.serialize(),
+ ],
'identifier': identifier,
'isDartVM': isDartVM,
'isBrowser': isBrowser,
@@ -157,7 +203,10 @@
///
/// This may not be called on a platform that's already a child.
Runtime extend(String name, String identifier) {
- if (parent == null) return Runtime._child(name, identifier, this);
+ if (parent == null) {
+ return Runtime._child(
+ name, identifier, defaultCompiler, supportedCompilers, this);
+ }
throw StateError('A child platform may not be extended.');
}
diff --git a/pkgs/test_api/lib/src/backend/stack_trace_formatter.dart b/pkgs/test_api/lib/src/backend/stack_trace_formatter.dart
index d200143..a495e89 100644
--- a/pkgs/test_api/lib/src/backend/stack_trace_formatter.dart
+++ b/pkgs/test_api/lib/src/backend/stack_trace_formatter.dart
@@ -17,13 +17,13 @@
///
/// This can convert JavaScript stack traces to Dart using source maps, and fold
/// irrelevant frames out of the stack trace.
-class StackTraceFormatter {
+final class StackTraceFormatter {
/// A class that converts [trace] into a Dart stack trace, or `null` to use it
/// as-is.
StackTraceMapper? _mapper;
/// The set of packages to fold when producing terse [Chain]s.
- var _except = {'test', 'stream_channel', 'test_api'};
+ var _except = {'matcher', 'stream_channel', 'test', 'test_api'};
/// If non-empty, all packages not in this list will be folded when producing
/// terse [Chain]s.
diff --git a/pkgs/test_api/lib/src/backend/stack_trace_mapper.dart b/pkgs/test_api/lib/src/backend/stack_trace_mapper.dart
index fd7298b..b091bbe 100644
--- a/pkgs/test_api/lib/src/backend/stack_trace_mapper.dart
+++ b/pkgs/test_api/lib/src/backend/stack_trace_mapper.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
/// A class for mapping JS stack traces to Dart stack traces using source maps.
-abstract class StackTraceMapper {
+abstract interface class StackTraceMapper {
/// Converts [trace] into a Dart stack trace.
StackTrace mapStackTrace(StackTrace trace);
diff --git a/pkgs/test_api/lib/src/backend/state.dart b/pkgs/test_api/lib/src/backend/state.dart
index ba82cd0..5a37654 100644
--- a/pkgs/test_api/lib/src/backend/state.dart
+++ b/pkgs/test_api/lib/src/backend/state.dart
@@ -28,7 +28,7 @@
const State(this.status, this.result);
@override
- bool operator ==(other) =>
+ bool operator ==(Object other) =>
other is State && status == other.status && result == other.result;
@override
@@ -44,12 +44,12 @@
}
/// Where the test is in its process of running.
-class Status {
+enum Status {
/// The test has not yet begun running.
- static const pending = Status._('pending');
+ pending,
/// The test is currently running.
- static const running = Status._('running');
+ running,
/// The test has finished running.
///
@@ -58,56 +58,37 @@
/// first error or when all [expectAsync] callbacks have been called and any
/// returned [Future] has completed, but it's possible for further processing
/// to happen, which may cause further errors.
- static const complete = Status._('complete');
+ complete;
- /// The name of the status.
- final String name;
-
- factory Status.parse(String name) {
- switch (name) {
- case 'pending':
- return Status.pending;
- case 'running':
- return Status.running;
- case 'complete':
- return Status.complete;
- default:
- throw ArgumentError('Invalid status name "$name".');
- }
- }
-
- const Status._(this.name);
+ factory Status.parse(String name) => Status.values.byName(name);
@override
String toString() => name;
}
/// The outcome of the test, as far as it's known.
-class Result {
+enum Result {
/// The test has not yet failed in any way.
///
/// Note that this doesn't mean that the test won't fail in the future.
- static const success = Result._('success');
+ success,
/// The test, or some part of it, has been skipped.
///
/// This implies that the test hasn't failed *yet*. However, it this doesn't
/// mean that the test won't fail in the future.
- static const skipped = Result._('skipped');
+ skipped,
/// The test has failed.
///
/// A failure is specifically caused by a [TestFailure] being thrown; any
/// other exception causes an error.
- static const failure = Result._('failure');
+ failure,
/// The test has crashed.
///
/// Any exception other than a [TestFailure] is considered to be an error.
- static const error = Result._('error');
-
- /// The name of the result.
- final String name;
+ error;
/// Whether this is a passing result.
///
@@ -121,22 +102,7 @@
/// error.
bool get isFailing => !isPassing;
- factory Result.parse(String name) {
- switch (name) {
- case 'success':
- return Result.success;
- case 'skipped':
- return Result.skipped;
- case 'failure':
- return Result.failure;
- case 'error':
- return Result.error;
- default:
- throw ArgumentError('Invalid result name "$name".');
- }
- }
-
- const Result._(this.name);
+ factory Result.parse(String name) => Result.values.byName(name);
@override
String toString() => name;
diff --git a/pkgs/test_api/lib/src/backend/suite_channel_manager.dart b/pkgs/test_api/lib/src/backend/suite_channel_manager.dart
index 3cd4723..26a21c9 100644
--- a/pkgs/test_api/lib/src/backend/suite_channel_manager.dart
+++ b/pkgs/test_api/lib/src/backend/suite_channel_manager.dart
@@ -20,7 +20,7 @@
/// Creates a connection to the test runnner's channel with the given [name].
StreamChannel<Object?> connectOut(String name) {
if (_incomingConnections.containsKey(name)) {
- return (_incomingConnections[name])!;
+ return _incomingConnections[name]!;
} else if (_names.contains(name)) {
throw StateError('Duplicate suiteChannel() connection "$name".');
} else {
diff --git a/pkgs/test_api/lib/src/backend/suite_platform.dart b/pkgs/test_api/lib/src/backend/suite_platform.dart
index bcdb6a5..baab6ce 100644
--- a/pkgs/test_api/lib/src/backend/suite_platform.dart
+++ b/pkgs/test_api/lib/src/backend/suite_platform.dart
@@ -2,11 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'compiler.dart';
import 'operating_system.dart';
import 'runtime.dart';
/// The platform on which a test suite is loaded.
-class SuitePlatform {
+final class SuitePlatform {
/// The runtime that hosts the suite.
final Runtime runtime;
@@ -19,16 +20,31 @@
/// Whether we're running on Google-internal infrastructure.
final bool inGoogle;
+ /// The compiler that should used for this platform.
+ final Compiler compiler;
+
/// Creates a new platform with the given [runtime] and [os], which defaults
/// to [OperatingSystem.none].
///
/// Throws an [ArgumentError] if [runtime] is a browser and [os] is not
/// `null` or [OperatingSystem.none].
+ ///
+ /// If [compiler] is `null`, then the default compiler for [runtime] will be
+ /// used.
SuitePlatform(this.runtime,
- {this.os = OperatingSystem.none, this.inGoogle = false}) {
+ {
+ // TODO(https://github.com/dart-lang/test/issues/1935): make required
+ Compiler? compiler,
+ this.os = OperatingSystem.none,
+ this.inGoogle = false})
+ : compiler = compiler ?? runtime.defaultCompiler {
if (runtime.isBrowser && os != OperatingSystem.none) {
throw ArgumentError('No OS should be passed for runtime "$runtime".');
}
+ if (!runtime.supportedCompilers.contains(this.compiler)) {
+ throw ArgumentError(
+ 'The platform $runtime does not support the compiler ${this.compiler}');
+ }
}
/// Converts a JSON-safe representation generated by [serialize] back into a
@@ -36,6 +52,9 @@
factory SuitePlatform.deserialize(Object serialized) {
var map = serialized as Map;
return SuitePlatform(Runtime.deserialize(map['runtime'] as Object),
+ compiler: map.containsKey('compiler')
+ ? Compiler.deserialize(map['compiler'] as Object)
+ : null,
os: OperatingSystem.find(map['os'] as String),
inGoogle: map['inGoogle'] as bool);
}
@@ -44,6 +63,7 @@
/// [SuitePlatform] using [SuitePlatform.deserialize].
Object serialize() => {
'runtime': runtime.serialize(),
+ 'compiler': compiler.serialize(),
'os': os.identifier,
'inGoogle': inGoogle
};
diff --git a/pkgs/test_api/lib/src/expect/async_matcher.dart b/pkgs/test_api/lib/src/expect/async_matcher.dart
deleted file mode 100644
index a3cc965..0000000
--- a/pkgs/test_api/lib/src/expect/async_matcher.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:matcher/matcher.dart';
-import 'package:test_api/hooks.dart';
-
-import 'expect.dart';
-
-/// A matcher that does asynchronous computation.
-///
-/// Rather than implementing [matches], subclasses implement [matchAsync].
-/// [AsyncMatcher.matches] ensures that the test doesn't complete until the
-/// returned future completes, and [expect] returns a future that completes when
-/// the returned future completes so that tests can wait for it.
-abstract class AsyncMatcher extends Matcher {
- const AsyncMatcher();
-
- /// Returns `null` if this matches [item], or a [String] description of the
- /// failure if it doesn't match.
- ///
- /// This can return a [Future] or a synchronous value. If it returns a
- /// [Future], neither [expect] nor the test will complete until that [Future]
- /// completes.
- ///
- /// If this returns a [String] synchronously, [expect] will synchronously
- /// throw a [TestFailure] and [matches] will synchronously return `false`.
- dynamic /*FutureOr<String>*/ matchAsync(item);
-
- @override
- bool matches(item, Map matchState) {
- final result = matchAsync(item);
- expect(result,
- anyOf([equals(null), TypeMatcher<Future>(), TypeMatcher<String>()]),
- reason: 'matchAsync() may only return a String, a Future, or null.');
-
- if (result is Future) {
- final outstandingWork = TestHandle.current.markPending();
- result.then((realResult) {
- if (realResult != null) {
- fail(formatFailure(this, item, realResult as String));
- }
- outstandingWork.complete();
- });
- } else if (result is String) {
- matchState[this] = result;
- return false;
- }
-
- return true;
- }
-
- @override
- Description describeMismatch(item, Description mismatchDescription,
- Map matchState, bool verbose) =>
- StringDescription(matchState[this] as String);
-}
diff --git a/pkgs/test_api/lib/src/expect/expect.dart b/pkgs/test_api/lib/src/expect/expect.dart
deleted file mode 100644
index 3773000..0000000
--- a/pkgs/test_api/lib/src/expect/expect.dart
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:matcher/matcher.dart';
-import 'package:test_api/hooks.dart';
-
-import 'async_matcher.dart';
-import 'util/pretty_print.dart';
-
-/// The type used for functions that can be used to build up error reports
-/// upon failures in [expect].
-@Deprecated('Will be removed in 0.13.0.')
-typedef ErrorFormatter = String Function(dynamic actual, Matcher matcher,
- String? reason, Map matchState, bool verbose);
-
-/// Assert that [actual] matches [matcher].
-///
-/// This is the main assertion function. [reason] is optional and is typically
-/// not supplied, as a reason is generated from [matcher]; if [reason]
-/// is included it is appended to the reason generated by the matcher.
-///
-/// [matcher] can be a value in which case it will be wrapped in an
-/// [equals] matcher.
-///
-/// If the assertion fails a [TestFailure] is thrown.
-///
-/// If [skip] is a String or `true`, the assertion is skipped. The arguments are
-/// still evaluated, but [actual] is not verified to match [matcher]. If
-/// [actual] is a [Future], the test won't complete until the future emits a
-/// value.
-///
-/// If [skip] is a string, it should explain why the assertion is skipped; this
-/// reason will be printed when running the test.
-///
-/// Certain matchers, like [completion] and [throwsA], either match or fail
-/// asynchronously. When you use [expect] with these matchers, it ensures that
-/// the test doesn't complete until the matcher has either matched or failed. If
-/// you want to wait for the matcher to complete before continuing the test, you
-/// can call [expectLater] instead and `await` the result.
-void expect(actual, matcher,
- {String? reason,
- skip,
- @Deprecated('Will be removed in 0.13.0.') bool verbose = false,
- @Deprecated('Will be removed in 0.13.0.') ErrorFormatter? formatter}) {
- _expect(actual, matcher,
- reason: reason, skip: skip, verbose: verbose, formatter: formatter);
-}
-
-/// Just like [expect], but returns a [Future] that completes when the matcher
-/// has finished matching.
-///
-/// For the [completes] and [completion] matchers, as well as [throwsA] and
-/// related matchers when they're matched against a [Future], the returned
-/// future completes when the matched future completes. For the [prints]
-/// matcher, it completes when the future returned by the callback completes.
-/// Otherwise, it completes immediately.
-///
-/// If the matcher fails asynchronously, that failure is piped to the returned
-/// future where it can be handled by user code.
-Future expectLater(actual, matcher, {String? reason, skip}) =>
- _expect(actual, matcher, reason: reason, skip: skip);
-
-/// The implementation of [expect] and [expectLater].
-Future _expect(actual, matcher,
- {String? reason, skip, bool verbose = false, ErrorFormatter? formatter}) {
- final test = TestHandle.current;
- formatter ??= (actual, matcher, reason, matchState, verbose) {
- var mismatchDescription = StringDescription();
- matcher.describeMismatch(actual, mismatchDescription, matchState, verbose);
-
- return formatFailure(matcher, actual, mismatchDescription.toString(),
- reason: reason);
- };
-
- if (skip != null && skip is! bool && skip is! String) {
- throw ArgumentError.value(skip, 'skip', 'must be a bool or a String');
- }
-
- matcher = wrapMatcher(matcher);
- if (skip != null && skip != false) {
- String message;
- if (skip is String) {
- message = 'Skip expect: $skip';
- } else if (reason != null) {
- message = 'Skip expect ($reason).';
- } else {
- var description = StringDescription().addDescriptionOf(matcher);
- message = 'Skip expect ($description).';
- }
-
- test.markSkipped(message);
- return Future.sync(() {});
- }
-
- if (matcher is AsyncMatcher) {
- // Avoid async/await so that expect() throws synchronously when possible.
- var result = matcher.matchAsync(actual);
- expect(result,
- anyOf([equals(null), TypeMatcher<Future>(), TypeMatcher<String>()]),
- reason: 'matchAsync() may only return a String, a Future, or null.');
-
- if (result is String) {
- fail(formatFailure(matcher, actual, result, reason: reason));
- } else if (result is Future) {
- final outstandingWork = test.markPending();
- return result.then((realResult) {
- if (realResult == null) return;
- fail(formatFailure(matcher as Matcher, actual, realResult as String,
- reason: reason));
- }).whenComplete(() {
- // Always remove this, in case the failure is caught and handled
- // gracefully.
- outstandingWork.complete();
- });
- }
-
- return Future.sync(() {});
- }
-
- var matchState = {};
- try {
- if ((matcher as Matcher).matches(actual, matchState)) {
- return Future.sync(() {});
- }
- } catch (e, trace) {
- reason ??= '$e at $trace';
- }
- fail(formatter(actual, matcher as Matcher, reason, matchState, verbose));
-}
-
-/// Convenience method for throwing a new [TestFailure] with the provided
-/// [message].
-Never fail(String message) => throw TestFailure(message);
-
-// The default error formatter.
-@Deprecated('Will be removed in 0.13.0.')
-String formatFailure(Matcher expected, actual, String which, {String? reason}) {
- var buffer = StringBuffer();
- buffer.writeln(indent(prettyPrint(expected), first: 'Expected: '));
- buffer.writeln(indent(prettyPrint(actual), first: ' Actual: '));
- if (which.isNotEmpty) buffer.writeln(indent(which, first: ' Which: '));
- if (reason != null) buffer.writeln(reason);
- return buffer.toString();
-}
diff --git a/pkgs/test_api/lib/src/expect/expect_async.dart b/pkgs/test_api/lib/src/expect/expect_async.dart
deleted file mode 100644
index dee7c1e..0000000
--- a/pkgs/test_api/lib/src/expect/expect_async.dart
+++ /dev/null
@@ -1,585 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test_api/hooks.dart';
-
-import 'util/placeholder.dart';
-
-// Function types returned by expectAsync# methods.
-
-typedef Func0<T> = T Function();
-typedef Func1<T, A> = T Function([A a]);
-typedef Func2<T, A, B> = T Function([A a, B b]);
-typedef Func3<T, A, B, C> = T Function([A a, B b, C c]);
-typedef Func4<T, A, B, C, D> = T Function([A a, B b, C c, D d]);
-typedef Func5<T, A, B, C, D, E> = T Function([A a, B b, C c, D d, E e]);
-typedef Func6<T, A, B, C, D, E, F> = T Function([A a, B b, C c, D d, E e, F f]);
-
-/// A wrapper for a function that ensures that it's called the appropriate
-/// number of times.
-///
-/// The containing test won't be considered to have completed successfully until
-/// this function has been called the appropriate number of times.
-///
-/// The wrapper function is accessible via [func]. It supports up to six
-/// optional and/or required positional arguments, but no named arguments.
-class _ExpectedFunction<T> {
- /// The wrapped callback.
- final Function _callback;
-
- /// The minimum number of calls that are expected to be made to the function.
- ///
- /// If fewer calls than this are made, the test will fail.
- final int _minExpectedCalls;
-
- /// The maximum number of calls that are expected to be made to the function.
- ///
- /// If more calls than this are made, the test will fail.
- final int _maxExpectedCalls;
-
- /// A callback that should return whether the function is not expected to have
- /// any more calls.
- ///
- /// This will be called after every time the function is run. The test case
- /// won't be allowed to terminate until it returns `true`.
- ///
- /// This may be `null`. If so, the function is considered to be done after
- /// it's been run once.
- final bool Function()? _isDone;
-
- /// A descriptive name for the function.
- final String _id;
-
- /// An optional description of why the function is expected to be called.
- ///
- /// If not passed, this will be an empty string.
- final String _reason;
-
- /// The number of times the function has been called.
- int _actualCalls = 0;
-
- /// The test in which this function was wrapped.
- late final TestHandle _test;
-
- /// Whether this function has been called the requisite number of times.
- late bool _complete;
-
- OutstandingWork? _outstandingWork;
-
- /// Wraps [callback] in a function that asserts that it's called at least
- /// [minExpected] times and no more than [maxExpected] times.
- ///
- /// If passed, [id] is used as a descriptive name fo the function and [reason]
- /// as a reason it's expected to be called. If [isDone] is passed, the test
- /// won't be allowed to complete until it returns `true`.
- _ExpectedFunction(Function callback, int minExpected, int maxExpected,
- {String? id, String? reason, bool Function()? isDone})
- : _callback = callback,
- _minExpectedCalls = minExpected,
- _maxExpectedCalls =
- (maxExpected == 0 && minExpected > 0) ? minExpected : maxExpected,
- _isDone = isDone,
- _reason = reason == null ? '' : '\n$reason',
- _id = _makeCallbackId(id, callback) {
- try {
- _test = TestHandle.current;
- } on OutsideTestException {
- throw StateError('`expectAsync` must be called within a test.');
- }
-
- if (maxExpected > 0 && minExpected > maxExpected) {
- throw ArgumentError('max ($maxExpected) may not be less than count '
- '($minExpected).');
- }
-
- if (isDone != null || minExpected > 0) {
- _outstandingWork = _test.markPending();
- _complete = false;
- } else {
- _complete = true;
- }
- }
-
- /// Tries to find a reasonable name for [callback].
- ///
- /// If [id] is passed, uses that. Otherwise, tries to determine a name from
- /// calling `toString`. If no name can be found, returns the empty string.
- static String _makeCallbackId(String? id, Function callback) {
- if (id != null) return '$id ';
-
- // If the callback is not an anonymous closure, try to get the
- // name.
- var toString = callback.toString();
- var prefix = "Function '";
- var start = toString.indexOf(prefix);
- if (start == -1) return '';
-
- start += prefix.length;
- var end = toString.indexOf("'", start);
- if (end == -1) return '';
- return '${toString.substring(start, end)} ';
- }
-
- /// Returns a function that has the same number of positional arguments as the
- /// wrapped function (up to a total of 6).
- Function get func {
- if (_callback is Function(Never, Never, Never, Never, Never, Never)) {
- return max6;
- }
- if (_callback is Function(Never, Never, Never, Never, Never)) return max5;
- if (_callback is Function(Never, Never, Never, Never)) return max4;
- if (_callback is Function(Never, Never, Never)) return max3;
- if (_callback is Function(Never, Never)) return max2;
- if (_callback is Function(Never)) return max1;
- if (_callback is Function()) return max0;
-
- _outstandingWork?.complete();
- throw ArgumentError(
- 'The wrapped function has more than 6 required arguments');
- }
-
- // This indirection is critical. It ensures the returned function has an
- // argument count of zero.
- T max0() => max6();
-
- T max1([Object? a0 = placeholder]) => max6(a0);
-
- T max2([Object? a0 = placeholder, Object? a1 = placeholder]) => max6(a0, a1);
-
- T max3(
- [Object? a0 = placeholder,
- Object? a1 = placeholder,
- Object? a2 = placeholder]) =>
- max6(a0, a1, a2);
-
- T max4(
- [Object? a0 = placeholder,
- Object? a1 = placeholder,
- Object? a2 = placeholder,
- Object? a3 = placeholder]) =>
- max6(a0, a1, a2, a3);
-
- T max5(
- [Object? a0 = placeholder,
- Object? a1 = placeholder,
- Object? a2 = placeholder,
- Object? a3 = placeholder,
- Object? a4 = placeholder]) =>
- max6(a0, a1, a2, a3, a4);
-
- T max6(
- [Object? a0 = placeholder,
- Object? a1 = placeholder,
- Object? a2 = placeholder,
- Object? a3 = placeholder,
- Object? a4 = placeholder,
- Object? a5 = placeholder]) =>
- _run([a0, a1, a2, a3, a4, a5].where((a) => a != placeholder));
-
- /// Runs the wrapped function with [args] and returns its return value.
- T _run(Iterable args) {
- // Note that in the old test, this returned `null` if it encountered an
- // error, where now it just re-throws that error because Zone machinery will
- // pass it to the invoker anyway.
- try {
- _actualCalls++;
- if (_test.shouldBeDone) {
- throw 'Callback ${_id}called ($_actualCalls) after test case '
- '${_test.name} had already completed.$_reason';
- } else if (_maxExpectedCalls >= 0 && _actualCalls > _maxExpectedCalls) {
- throw TestFailure('Callback ${_id}called more times than expected '
- '($_maxExpectedCalls).$_reason');
- }
-
- return Function.apply(_callback, args.toList()) as T;
- } finally {
- _afterRun();
- }
- }
-
- /// After each time the function is run, check to see if it's complete.
- void _afterRun() {
- if (_complete) return;
- if (_minExpectedCalls > 0 && _actualCalls < _minExpectedCalls) return;
- if (_isDone != null && !_isDone!()) return;
-
- // Mark this callback as complete and remove it from the test case's
- // outstanding callback count; if that hits zero the test is done.
- _complete = true;
- _outstandingWork?.complete();
- }
-}
-
-/// This function is deprecated because it doesn't work well with strong mode.
-/// Use [expectAsync0], [expectAsync1],
-/// [expectAsync2], [expectAsync3], [expectAsync4], [expectAsync5], or
-/// [expectAsync6] instead.
-@Deprecated('Will be removed in 0.13.0')
-Function expectAsync(Function callback,
- {int count = 1, int max = 0, String? id, String? reason}) =>
- _ExpectedFunction(callback, count, max, id: id, reason: reason).func;
-
-/// Informs the framework that the given [callback] of arity 0 is expected to be
-/// called [count] number of times (by default 1).
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// The test framework will wait for the callback to run the [count] times
-/// before it considers the current test to be complete.
-///
-/// [max] can be used to specify an upper bound on the number of calls; if this
-/// is exceeded the test will fail. If [max] is `0` (the default), the callback
-/// is expected to be called exactly [count] times. If [max] is `-1`, the
-/// callback is allowed to be called any number of times greater than [count].
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with zero arguments. See also
-/// [expectAsync1], [expectAsync2], [expectAsync3], [expectAsync4],
-/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func0<T> expectAsync0<T>(T Function() callback,
- {int count = 1, int max = 0, String? id, String? reason}) =>
- _ExpectedFunction<T>(callback, count, max, id: id, reason: reason).max0;
-
-/// Informs the framework that the given [callback] of arity 1 is expected to be
-/// called [count] number of times (by default 1).
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// The test framework will wait for the callback to run the [count] times
-/// before it considers the current test to be complete.
-///
-/// [max] can be used to specify an upper bound on the number of calls; if this
-/// is exceeded the test will fail. If [max] is `0` (the default), the callback
-/// is expected to be called exactly [count] times. If [max] is `-1`, the
-/// callback is allowed to be called any number of times greater than [count].
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with one argument. See also
-/// [expectAsync0], [expectAsync2], [expectAsync3], [expectAsync4],
-/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func1<T, A> expectAsync1<T, A>(T Function(A) callback,
- {int count = 1, int max = 0, String? id, String? reason}) =>
- _ExpectedFunction<T>(callback, count, max, id: id, reason: reason).max1;
-
-/// Informs the framework that the given [callback] of arity 2 is expected to be
-/// called [count] number of times (by default 1).
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// The test framework will wait for the callback to run the [count] times
-/// before it considers the current test to be complete.
-///
-/// [max] can be used to specify an upper bound on the number of calls; if this
-/// is exceeded the test will fail. If [max] is `0` (the default), the callback
-/// is expected to be called exactly [count] times. If [max] is `-1`, the
-/// callback is allowed to be called any number of times greater than [count].
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with two arguments. See also
-/// [expectAsync0], [expectAsync1], [expectAsync3], [expectAsync4],
-/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func2<T, A, B> expectAsync2<T, A, B>(T Function(A, B) callback,
- {int count = 1, int max = 0, String? id, String? reason}) =>
- _ExpectedFunction<T>(callback, count, max, id: id, reason: reason).max2;
-
-/// Informs the framework that the given [callback] of arity 3 is expected to be
-/// called [count] number of times (by default 1).
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// The test framework will wait for the callback to run the [count] times
-/// before it considers the current test to be complete.
-///
-/// [max] can be used to specify an upper bound on the number of calls; if this
-/// is exceeded the test will fail. If [max] is `0` (the default), the callback
-/// is expected to be called exactly [count] times. If [max] is `-1`, the
-/// callback is allowed to be called any number of times greater than [count].
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with three arguments. See also
-/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync4],
-/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func3<T, A, B, C> expectAsync3<T, A, B, C>(T Function(A, B, C) callback,
- {int count = 1, int max = 0, String? id, String? reason}) =>
- _ExpectedFunction<T>(callback, count, max, id: id, reason: reason).max3;
-
-/// Informs the framework that the given [callback] of arity 4 is expected to be
-/// called [count] number of times (by default 1).
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// The test framework will wait for the callback to run the [count] times
-/// before it considers the current test to be complete.
-///
-/// [max] can be used to specify an upper bound on the number of calls; if this
-/// is exceeded the test will fail. If [max] is `0` (the default), the callback
-/// is expected to be called exactly [count] times. If [max] is `-1`, the
-/// callback is allowed to be called any number of times greater than [count].
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with four arguments. See also
-/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
-/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func4<T, A, B, C, D> expectAsync4<T, A, B, C, D>(
- T Function(A, B, C, D) callback,
- {int count = 1,
- int max = 0,
- String? id,
- String? reason}) =>
- _ExpectedFunction<T>(callback, count, max, id: id, reason: reason).max4;
-
-/// Informs the framework that the given [callback] of arity 5 is expected to be
-/// called [count] number of times (by default 1).
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// The test framework will wait for the callback to run the [count] times
-/// before it considers the current test to be complete.
-///
-/// [max] can be used to specify an upper bound on the number of calls; if this
-/// is exceeded the test will fail. If [max] is `0` (the default), the callback
-/// is expected to be called exactly [count] times. If [max] is `-1`, the
-/// callback is allowed to be called any number of times greater than [count].
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with five arguments. See also
-/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
-/// [expectAsync4], and [expectAsync6] for callbacks with different arity.
-Func5<T, A, B, C, D, E> expectAsync5<T, A, B, C, D, E>(
- T Function(A, B, C, D, E) callback,
- {int count = 1,
- int max = 0,
- String? id,
- String? reason}) =>
- _ExpectedFunction<T>(callback, count, max, id: id, reason: reason).max5;
-
-/// Informs the framework that the given [callback] of arity 6 is expected to be
-/// called [count] number of times (by default 1).
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// The test framework will wait for the callback to run the [count] times
-/// before it considers the current test to be complete.
-///
-/// [max] can be used to specify an upper bound on the number of calls; if this
-/// is exceeded the test will fail. If [max] is `0` (the default), the callback
-/// is expected to be called exactly [count] times. If [max] is `-1`, the
-/// callback is allowed to be called any number of times greater than [count].
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with six arguments. See also
-/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
-/// [expectAsync4], and [expectAsync5] for callbacks with different arity.
-Func6<T, A, B, C, D, E, F> expectAsync6<T, A, B, C, D, E, F>(
- T Function(A, B, C, D, E, F) callback,
- {int count = 1,
- int max = 0,
- String? id,
- String? reason}) =>
- _ExpectedFunction<T>(callback, count, max, id: id, reason: reason).max6;
-
-/// This function is deprecated because it doesn't work well with strong mode.
-/// Use [expectAsyncUntil0], [expectAsyncUntil1],
-/// [expectAsyncUntil2], [expectAsyncUntil3], [expectAsyncUntil4],
-/// [expectAsyncUntil5], or [expectAsyncUntil6] instead.
-@Deprecated('Will be removed in 0.13.0')
-Function expectAsyncUntil(Function callback, bool Function() isDone,
- {String? id, String? reason}) =>
- _ExpectedFunction(callback, 0, -1, id: id, reason: reason, isDone: isDone)
- .func;
-
-/// Informs the framework that the given [callback] of arity 0 is expected to be
-/// called until [isDone] returns true.
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// [isDone] is called after each time the function is run. Only when it returns
-/// true will the callback be considered complete.
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with zero arguments. See also
-/// [expectAsyncUntil1], [expectAsyncUntil2], [expectAsyncUntil3],
-/// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
-/// callbacks with different arity.
-Func0<T> expectAsyncUntil0<T>(T Function() callback, bool Function() isDone,
- {String? id, String? reason}) =>
- _ExpectedFunction<T>(callback, 0, -1,
- id: id, reason: reason, isDone: isDone)
- .max0;
-
-/// Informs the framework that the given [callback] of arity 1 is expected to be
-/// called until [isDone] returns true.
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// [isDone] is called after each time the function is run. Only when it returns
-/// true will the callback be considered complete.
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with one argument. See also
-/// [expectAsyncUntil0], [expectAsyncUntil2], [expectAsyncUntil3],
-/// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
-/// callbacks with different arity.
-Func1<T, A> expectAsyncUntil1<T, A>(
- T Function(A) callback, bool Function() isDone,
- {String? id, String? reason}) =>
- _ExpectedFunction<T>(callback, 0, -1,
- id: id, reason: reason, isDone: isDone)
- .max1;
-
-/// Informs the framework that the given [callback] of arity 2 is expected to be
-/// called until [isDone] returns true.
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// [isDone] is called after each time the function is run. Only when it returns
-/// true will the callback be considered complete.
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with two arguments. See also
-/// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil3],
-/// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
-/// callbacks with different arity.
-Func2<T, A, B> expectAsyncUntil2<T, A, B>(
- T Function(A, B) callback, bool Function() isDone,
- {String? id, String? reason}) =>
- _ExpectedFunction<T>(callback, 0, -1,
- id: id, reason: reason, isDone: isDone)
- .max2;
-
-/// Informs the framework that the given [callback] of arity 3 is expected to be
-/// called until [isDone] returns true.
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// [isDone] is called after each time the function is run. Only when it returns
-/// true will the callback be considered complete.
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with three arguments. See also
-/// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil2],
-/// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
-/// callbacks with different arity.
-Func3<T, A, B, C> expectAsyncUntil3<T, A, B, C>(
- T Function(A, B, C) callback, bool Function() isDone,
- {String? id, String? reason}) =>
- _ExpectedFunction<T>(callback, 0, -1,
- id: id, reason: reason, isDone: isDone)
- .max3;
-
-/// Informs the framework that the given [callback] of arity 4 is expected to be
-/// called until [isDone] returns true.
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// [isDone] is called after each time the function is run. Only when it returns
-/// true will the callback be considered complete.
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with four arguments. See also
-/// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil2],
-/// [expectAsyncUntil3], [expectAsyncUntil5], and [expectAsyncUntil6] for
-/// callbacks with different arity.
-Func4<T, A, B, C, D> expectAsyncUntil4<T, A, B, C, D>(
- T Function(A, B, C, D) callback, bool Function() isDone,
- {String? id, String? reason}) =>
- _ExpectedFunction<T>(callback, 0, -1,
- id: id, reason: reason, isDone: isDone)
- .max4;
-
-/// Informs the framework that the given [callback] of arity 5 is expected to be
-/// called until [isDone] returns true.
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// [isDone] is called after each time the function is run. Only when it returns
-/// true will the callback be considered complete.
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with five arguments. See also
-/// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil2],
-/// [expectAsyncUntil3], [expectAsyncUntil4], and [expectAsyncUntil6] for
-/// callbacks with different arity.
-Func5<T, A, B, C, D, E> expectAsyncUntil5<T, A, B, C, D, E>(
- T Function(A, B, C, D, E) callback, bool Function() isDone,
- {String? id, String? reason}) =>
- _ExpectedFunction<T>(callback, 0, -1,
- id: id, reason: reason, isDone: isDone)
- .max5;
-
-/// Informs the framework that the given [callback] of arity 6 is expected to be
-/// called until [isDone] returns true.
-///
-/// Returns a wrapped function that should be used as a replacement of the
-/// original callback.
-///
-/// [isDone] is called after each time the function is run. Only when it returns
-/// true will the callback be considered complete.
-///
-/// Both [id] and [reason] are optional and provide extra information about the
-/// callback when debugging. [id] should be the name of the callback, while
-/// [reason] should be the reason the callback is expected to be called.
-///
-/// This method takes callbacks with six arguments. See also
-/// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil2],
-/// [expectAsyncUntil3], [expectAsyncUntil4], and [expectAsyncUntil5] for
-/// callbacks with different arity.
-Func6<T, A, B, C, D, E, F> expectAsyncUntil6<T, A, B, C, D, E, F>(
- T Function(A, B, C, D, E, F) callback, bool Function() isDone,
- {String? id, String? reason}) =>
- _ExpectedFunction<T>(callback, 0, -1,
- id: id, reason: reason, isDone: isDone)
- .max6;
diff --git a/pkgs/test_api/lib/src/expect/future_matchers.dart b/pkgs/test_api/lib/src/expect/future_matchers.dart
deleted file mode 100644
index 9900c97..0000000
--- a/pkgs/test_api/lib/src/expect/future_matchers.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:matcher/matcher.dart';
-import 'package:test_api/hooks.dart' show pumpEventQueue;
-
-import 'async_matcher.dart';
-import 'expect.dart';
-import 'util/pretty_print.dart';
-
-/// Matches a [Future] that completes successfully with any value.
-///
-/// This creates an asynchronous expectation. The call to [expect] will return
-/// immediately and execution will continue. Later, when the future completes,
-/// the expectation against [matcher] will run. To wait for the future to
-/// complete and the expectation to run use [expectLater] and wait on the
-/// returned future.
-///
-/// To test that a Future completes with an exception, you can use [throws] and
-/// [throwsA].
-final Matcher completes = const _Completes(null);
-
-/// Matches a [Future] that completes successfully with a value that matches
-/// [matcher].
-///
-/// This creates an asynchronous expectation. The call to [expect] will return
-/// immediately and execution will continue. Later, when the future completes,
-/// the expectation against [matcher] will run. To wait for the future to
-/// complete and the expectation to run use [expectLater] and wait on the
-/// returned future.
-///
-/// To test that a Future completes with an exception, you can use [throws] and
-/// [throwsA].
-Matcher completion(matcher,
- [@Deprecated('this parameter is ignored') String? description]) =>
- _Completes(wrapMatcher(matcher));
-
-class _Completes extends AsyncMatcher {
- final Matcher? _matcher;
-
- const _Completes(this._matcher);
-
- // Avoid async/await so we synchronously start listening to [item].
- @override
- dynamic /*FutureOr<String>*/ matchAsync(item) {
- if (item is! Future) return 'was not a Future';
-
- return item.then((value) async {
- if (_matcher == null) return null;
-
- String? result;
- if (_matcher is AsyncMatcher) {
- result = await (_matcher as AsyncMatcher).matchAsync(value) as String?;
- if (result == null) return null;
- } else {
- var matchState = {};
- if (_matcher!.matches(value, matchState)) return null;
- result = _matcher!
- .describeMismatch(value, StringDescription(), matchState, false)
- .toString();
- }
-
- var buffer = StringBuffer();
- buffer.writeln(indent(prettyPrint(value), first: 'emitted '));
- if (result.isNotEmpty) buffer.writeln(indent(result, first: ' which '));
- return buffer.toString().trimRight();
- });
- }
-
- @override
- Description describe(Description description) {
- if (_matcher == null) {
- description.add('completes successfully');
- } else {
- description.add('completes to a value that ').addDescriptionOf(_matcher);
- }
- return description;
- }
-}
-
-/// Matches a [Future] that does not complete.
-///
-/// Note that this creates an asynchronous expectation. The call to
-/// `expect()` that includes this will return immediately and execution will
-/// continue.
-final Matcher doesNotComplete = const _DoesNotComplete();
-
-class _DoesNotComplete extends Matcher {
- const _DoesNotComplete();
-
- @override
- Description describe(Description description) {
- description.add('does not complete');
- return description;
- }
-
- @override
- bool matches(item, Map matchState) {
- if (item is! Future) return false;
- item.then((value) {
- fail('Future was not expected to complete but completed with a value of '
- '$value');
- });
- expect(pumpEventQueue(), completes);
- return true;
- }
-
- @override
- Description describeMismatch(
- item, Description description, Map matchState, bool verbose) {
- if (item is! Future) return description.add('$item is not a Future');
- return description;
- }
-}
diff --git a/pkgs/test_api/lib/src/expect/never_called.dart b/pkgs/test_api/lib/src/expect/never_called.dart
deleted file mode 100644
index 96c81cb..0000000
--- a/pkgs/test_api/lib/src/expect/never_called.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:stack_trace/stack_trace.dart';
-import 'package:test_api/hooks.dart';
-
-import 'expect.dart';
-import 'future_matchers.dart';
-import 'util/placeholder.dart';
-import 'util/pretty_print.dart';
-
-/// Returns a function that causes the test to fail if it's called.
-///
-/// This can safely be passed in place of any callback that takes ten or fewer
-/// positional parameters. For example:
-///
-/// ```
-/// // Asserts that the stream never emits an event.
-/// stream.listen(neverCalled);
-/// ```
-///
-/// This also ensures that the test doesn't complete until a call to
-/// [pumpEventQueue] finishes, so that the callback has a chance to be called.
-Null Function(
- [Object?,
- Object?,
- Object?,
- Object?,
- Object?,
- Object?,
- Object?,
- Object?,
- Object?,
- Object?]) get neverCalled {
- // Make sure the test stays alive long enough to call the function if it's
- // going to.
- expect(pumpEventQueue(), completes);
-
- var zone = Zone.current;
- return (
- [a1 = placeholder,
- a2 = placeholder,
- a3 = placeholder,
- a4 = placeholder,
- a5 = placeholder,
- a6 = placeholder,
- a7 = placeholder,
- a8 = placeholder,
- a9 = placeholder,
- a10 = placeholder]) {
- var arguments = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]
- .where((argument) => argument != placeholder)
- .toList();
-
- var argsText = arguments.isEmpty
- ? ' no arguments.'
- : ':\n${bullet(arguments.map(prettyPrint))}';
- zone.handleUncaughtError(
- TestFailure(
- 'Callback should never have been called, but it was called with'
- '$argsText'),
- zone.run(() => Chain.current()));
- return null;
- };
-}
diff --git a/pkgs/test_api/lib/src/expect/prints_matcher.dart b/pkgs/test_api/lib/src/expect/prints_matcher.dart
deleted file mode 100644
index 5e9769b..0000000
--- a/pkgs/test_api/lib/src/expect/prints_matcher.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:matcher/matcher.dart';
-
-import 'async_matcher.dart';
-import 'expect.dart';
-import 'util/pretty_print.dart';
-
-/// Matches a [Function] that prints text that matches [matcher].
-///
-/// [matcher] may be a String or a [Matcher].
-///
-/// If the function this runs against returns a [Future], all text printed by
-/// the function (using [Zone] scoping) until that Future completes is matched.
-///
-/// This only tracks text printed using the [print] function.
-///
-/// This returns an [AsyncMatcher], so [expect] won't complete until the matched
-/// function does.
-Matcher prints(matcher) => _Prints(wrapMatcher(matcher));
-
-class _Prints extends AsyncMatcher {
- final Matcher _matcher;
-
- _Prints(this._matcher);
-
- // Avoid async/await so we synchronously fail if the function is
- // synchronous.
- @override
- dynamic /*FutureOr<String>*/ matchAsync(item) {
- if (item is! Function()) return 'was not a unary Function';
-
- var buffer = StringBuffer();
- var result = runZoned(item,
- zoneSpecification: ZoneSpecification(print: (_, __, ____, line) {
- buffer.writeln(line);
- }));
-
- return result is Future
- ? result.then((_) => _check(buffer.toString()))
- : _check(buffer.toString());
- }
-
- @override
- Description describe(Description description) =>
- description.add('prints ').addDescriptionOf(_matcher);
-
- /// Verifies that [actual] matches [_matcher] and returns a [String]
- /// description of the failure if it doesn't.
- String? _check(String actual) {
- var matchState = {};
- if (_matcher.matches(actual, matchState)) return null;
-
- var result = _matcher
- .describeMismatch(actual, StringDescription(), matchState, false)
- .toString();
-
- var buffer = StringBuffer();
- if (actual.isEmpty) {
- buffer.writeln('printed nothing');
- } else {
- buffer.writeln(indent(prettyPrint(actual), first: 'printed '));
- }
- if (result.isNotEmpty) buffer.writeln(indent(result, first: ' which '));
- return buffer.toString().trimRight();
- }
-}
diff --git a/pkgs/test_api/lib/src/expect/stream_matcher.dart b/pkgs/test_api/lib/src/expect/stream_matcher.dart
deleted file mode 100644
index 6d7bddf..0000000
--- a/pkgs/test_api/lib/src/expect/stream_matcher.dart
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:async/async.dart';
-import 'package:matcher/matcher.dart';
-import 'package:test_api/hooks.dart';
-
-import 'async_matcher.dart';
-import 'util/pretty_print.dart';
-
-/// A matcher that matches events from [Stream]s or [StreamQueue]s.
-///
-/// Stream matchers are designed to make it straightforward to create complex
-/// expectations for streams, and to interleave expectations with the rest of a
-/// test. They can be used on a [Stream] to match all events it emits:
-///
-/// ```dart
-/// expect(stream, emitsInOrder([
-/// // Values match individual events.
-/// "Ready.",
-///
-/// // Matchers also run against individual events.
-/// startsWith("Loading took"),
-///
-/// // Stream matchers can be nested. This asserts that one of two events are
-/// // emitted after the "Loading took" line.
-/// emitsAnyOf(["Succeeded!", "Failed!"]),
-///
-/// // By default, more events are allowed after the matcher finishes
-/// // matching. This asserts instead that the stream emits a done event and
-/// // nothing else.
-/// emitsDone
-/// ]));
-/// ```
-///
-/// It can also match a [StreamQueue], in which case it consumes the matched
-/// events. The call to [expect] returns a [Future] that completes when the
-/// matcher is done matching. You can `await` this to consume different events
-/// at different times:
-///
-/// ```dart
-/// var stdout = StreamQueue(stdoutLineStream);
-///
-/// // Ignore lines from the process until it's about to emit the URL.
-/// await expectLater(stdout, emitsThrough('WebSocket URL:'));
-///
-/// // Parse the next line as a URL.
-/// var url = Uri.parse(await stdout.next);
-/// expect(url.host, equals('localhost'));
-///
-/// // You can match against the same StreamQueue multiple times.
-/// await expectLater(stdout, emits('Waiting for connection...'));
-/// ```
-///
-/// Users can call [StreamMatcher] to create custom matchers.
-abstract class StreamMatcher extends Matcher {
- /// The description of this matcher.
- ///
- /// This is in the subjunctive mood, which means it can be used after the word
- /// "should". For example, it might be "emit the right events".
- String get description;
-
- /// Creates a new [StreamMatcher] described by [description] that matches
- /// events with [matchQueue].
- ///
- /// The [matchQueue] callback is used to implement [StreamMatcher.matchQueue],
- /// and should follow all the guarantees of that method. In particular:
- ///
- /// * If it matches successfully, it should return `null` and possibly consume
- /// events.
- /// * If it fails to match, consume no events and return a description of the
- /// failure.
- /// * The description should be in past tense.
- /// * The description should be grammatically valid when used after "the
- /// stream"—"emitted the wrong events", for example.
- ///
- /// The [matchQueue] callback may return the empty string to indicate a
- /// failure if it has no information to add beyond the description of the
- /// failure and the events actually emitted by the stream.
- ///
- /// The [description] should be in the subjunctive mood. This means that it
- /// should be grammatically valid when used after the word "should". For
- /// example, it might be "emit the right events".
- factory StreamMatcher(Future<String?> Function(StreamQueue) matchQueue,
- String description) = _StreamMatcher;
-
- /// Tries to match events emitted by [queue].
- ///
- /// If this matches successfully, it consumes the matching events from [queue]
- /// and returns `null`.
- ///
- /// If this fails to match, it doesn't consume any events and returns a
- /// description of the failure. This description is in the past tense, and
- /// could grammatically be used after "the stream". For example, it might
- /// return "emitted the wrong events".
- ///
- /// The description string may also be empty, which indicates that the
- /// matcher's description and the events actually emitted by the stream are
- /// enough to understand the failure.
- ///
- /// If the queue emits an error, that error is re-thrown unless otherwise
- /// indicated by the matcher.
- Future<String?> matchQueue(StreamQueue queue);
-}
-
-/// A concrete implementation of [StreamMatcher].
-///
-/// This is separate from the original type to hide the private [AsyncMatcher]
-/// interface.
-class _StreamMatcher extends AsyncMatcher implements StreamMatcher {
- @override
- final String description;
-
- /// The callback used to implement [matchQueue].
- final Future<String?> Function(StreamQueue) _matchQueue;
-
- _StreamMatcher(this._matchQueue, this.description);
-
- @override
- Future<String?> matchQueue(StreamQueue queue) => _matchQueue(queue);
-
- @override
- dynamic /*FutureOr<String>*/ matchAsync(item) {
- StreamQueue queue;
- var shouldCancelQueue = false;
- if (item is StreamQueue) {
- queue = item;
- } else if (item is Stream) {
- queue = StreamQueue(item);
- shouldCancelQueue = true;
- } else {
- return 'was not a Stream or a StreamQueue';
- }
-
- // Avoid async/await in the outer method so that we synchronously error out
- // for an invalid argument type.
- var transaction = queue.startTransaction();
- var copy = transaction.newQueue();
- return matchQueue(copy).then((result) async {
- // Accept the transaction if the result is null, indicating that the match
- // succeeded.
- if (result == null) {
- transaction.commit(copy);
- return null;
- }
-
- // Get a list of events emitted by the stream so we can emit them as part
- // of the error message.
- var replay = transaction.newQueue();
- var events = <Result?>[];
- var subscription = Result.captureStreamTransformer
- .bind(replay.rest.cast())
- .listen(events.add, onDone: () => events.add(null));
-
- // Wait on a timer tick so all buffered events are emitted.
- await Future.delayed(Duration.zero);
- _unawaited(subscription.cancel());
-
- var eventsString = events.map((event) {
- if (event == null) {
- return 'x Stream closed.';
- } else if (event.isValue) {
- return addBullet(event.asValue!.value.toString());
- } else {
- var error = event.asError!;
- var chain = TestHandle.current.formatStackTrace(error.stackTrace);
- var text = '${error.error}\n$chain';
- return indent(text, first: '! ');
- }
- }).join('\n');
- if (eventsString.isEmpty) eventsString = 'no events';
-
- transaction.reject();
-
- var buffer = StringBuffer();
- buffer.writeln(indent(eventsString, first: 'emitted '));
- if (result.isNotEmpty) buffer.writeln(indent(result, first: ' which '));
- return buffer.toString().trimRight();
- }, onError: (Object error) {
- transaction.reject();
- throw error;
- }).then((result) {
- if (shouldCancelQueue) queue.cancel();
- return result;
- });
- }
-
- @override
- Description describe(Description description) =>
- description.add('should ').add(this.description);
-}
-
-void _unawaited(Future<void> f) {}
diff --git a/pkgs/test_api/lib/src/expect/stream_matchers.dart b/pkgs/test_api/lib/src/expect/stream_matchers.dart
deleted file mode 100644
index df2fbbd..0000000
--- a/pkgs/test_api/lib/src/expect/stream_matchers.dart
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:async/async.dart';
-import 'package:matcher/matcher.dart';
-
-import 'async_matcher.dart';
-import 'stream_matcher.dart';
-import 'throws_matcher.dart';
-import 'util/pretty_print.dart';
-
-/// Returns a [StreamMatcher] that asserts that the stream emits a "done" event.
-final emitsDone = StreamMatcher(
- (queue) async => (await queue.hasNext) ? '' : null, 'be done');
-
-/// Returns a [StreamMatcher] for [matcher].
-///
-/// If [matcher] is already a [StreamMatcher], it's returned as-is. If it's any
-/// other [Matcher], this matches a single event that matches that matcher. If
-/// it's any other Object, this matches a single event that's equal to that
-/// object.
-///
-/// This functions like [wrapMatcher] for [StreamMatcher]s: it can convert any
-/// matcher-like value into a proper [StreamMatcher].
-StreamMatcher emits(matcher) {
- if (matcher is StreamMatcher) return matcher;
- var wrapped = wrapMatcher(matcher);
-
- var matcherDescription = wrapped.describe(StringDescription());
-
- return StreamMatcher((queue) async {
- if (!await queue.hasNext) return '';
-
- var matchState = {};
- var actual = await queue.next;
- if (wrapped.matches(actual, matchState)) return null;
-
- var mismatchDescription = StringDescription();
- wrapped.describeMismatch(actual, mismatchDescription, matchState, false);
-
- if (mismatchDescription.length == 0) return '';
- return 'emitted an event that $mismatchDescription';
- },
- // TODO(nweiz): add "should" once matcher#42 is fixed.
- 'emit an event that $matcherDescription');
-}
-
-/// Returns a [StreamMatcher] that matches a single error event that matches
-/// [matcher].
-StreamMatcher emitsError(matcher) {
- var wrapped = wrapMatcher(matcher);
- var matcherDescription = wrapped.describe(StringDescription());
- var throwsMatcher = throwsA(wrapped) as AsyncMatcher;
-
- return StreamMatcher(
- (queue) => throwsMatcher.matchAsync(queue.next) as Future<String?>,
- // TODO(nweiz): add "should" once matcher#42 is fixed.
- 'emit an error that $matcherDescription');
-}
-
-/// Returns a [StreamMatcher] that allows (but doesn't require) [matcher] to
-/// match the stream.
-///
-/// This matcher always succeeds; if [matcher] doesn't match, this just consumes
-/// no events.
-StreamMatcher mayEmit(matcher) {
- var streamMatcher = emits(matcher);
- return StreamMatcher((queue) async {
- await queue.withTransaction(
- (copy) async => (await streamMatcher.matchQueue(copy)) == null);
- return null;
- }, 'maybe ${streamMatcher.description}');
-}
-
-/// Returns a [StreamMatcher] that matches the stream if at least one of
-/// [matchers] matches.
-///
-/// If multiple matchers match the stream, this chooses the matcher that
-/// consumes as many events as possible.
-///
-/// If any matchers match the stream, no errors from other matchers are thrown.
-/// If no matchers match and multiple matchers threw errors, the first error is
-/// re-thrown.
-StreamMatcher emitsAnyOf(Iterable matchers) {
- var streamMatchers = matchers.map(emits).toList();
- if (streamMatchers.isEmpty) {
- throw ArgumentError('matcher may not be empty');
- }
-
- if (streamMatchers.length == 1) return streamMatchers.first;
- var description = 'do one of the following:\n'
- '${bullet(streamMatchers.map((matcher) => matcher.description))}';
-
- return StreamMatcher((queue) async {
- var transaction = queue.startTransaction();
-
- // Allocate the failures list ahead of time so that its order matches the
- // order of [matchers], and thus the order the matchers will be listed in
- // the description.
- var failures = List<String?>.filled(matchers.length, null);
-
- // The first error thrown. If no matchers match and this exists, we rethrow
- // it.
- Object? firstError;
- StackTrace? firstStackTrace;
-
- var futures = <Future>[];
- StreamQueue? consumedMost;
- for (var i = 0; i < matchers.length; i++) {
- futures.add(() async {
- var copy = transaction.newQueue();
-
- String? result;
- try {
- result = await streamMatchers[i].matchQueue(copy);
- } catch (error, stackTrace) {
- if (firstError == null) {
- firstError = error;
- firstStackTrace = stackTrace;
- }
- return;
- }
-
- if (result != null) {
- failures[i] = result;
- } else if (consumedMost == null ||
- consumedMost!.eventsDispatched < copy.eventsDispatched) {
- consumedMost = copy;
- }
- }());
- }
-
- await Future.wait(futures);
-
- if (consumedMost == null) {
- transaction.reject();
- if (firstError != null) {
- await Future.error(firstError!, firstStackTrace);
- }
-
- var failureMessages = <String>[];
- for (var i = 0; i < matchers.length; i++) {
- var message = 'failed to ${streamMatchers[i].description}';
- if ((failures[i])!.isNotEmpty) {
- message += message.contains('\n') ? '\n' : ' ';
- message += 'because it ${failures[i]}';
- }
-
- failureMessages.add(message);
- }
-
- return 'failed all options:\n${bullet(failureMessages)}';
- } else {
- transaction.commit(consumedMost!);
- return null;
- }
- }, description);
-}
-
-/// Returns a [StreamMatcher] that matches the stream if each matcher in
-/// [matchers] matches, one after another.
-///
-/// If any matcher fails to match, this fails and consumes no events.
-StreamMatcher emitsInOrder(Iterable matchers) {
- var streamMatchers = matchers.map(emits).toList();
- if (streamMatchers.length == 1) return streamMatchers.first;
-
- var description = 'do the following in order:\n'
- '${bullet(streamMatchers.map((matcher) => matcher.description))}';
-
- return StreamMatcher((queue) async {
- for (var i = 0; i < streamMatchers.length; i++) {
- var matcher = streamMatchers[i];
- var result = await matcher.matchQueue(queue);
- if (result == null) continue;
-
- var newResult = "didn't ${matcher.description}";
- if (result.isNotEmpty) {
- newResult += newResult.contains('\n') ? '\n' : ' ';
- newResult += 'because it $result';
- }
- return newResult;
- }
- return null;
- }, description);
-}
-
-/// Returns a [StreamMatcher] that matches any number of events followed by
-/// events that match [matcher].
-///
-/// This consumes all events matched by [matcher], as well as all events before.
-/// If the stream emits a done event without matching [matcher], this fails and
-/// consumes no events.
-StreamMatcher emitsThrough(matcher) {
- var streamMatcher = emits(matcher);
- return StreamMatcher((queue) async {
- var failures = <String>[];
-
- Future<bool> tryHere() => queue.withTransaction((copy) async {
- var result = await streamMatcher.matchQueue(copy);
- if (result == null) return true;
- failures.add(result);
- return false;
- });
-
- while (await queue.hasNext) {
- if (await tryHere()) return null;
- await queue.next;
- }
-
- // Try after the queue is done in case the matcher can match an empty
- // stream.
- if (await tryHere()) return null;
-
- var result = 'never did ${streamMatcher.description}';
-
- var failureMessages =
- bullet(failures.where((failure) => failure.isNotEmpty));
- if (failureMessages.isNotEmpty) {
- result += result.contains('\n') ? '\n' : ' ';
- result += 'because it:\n$failureMessages';
- }
-
- return result;
- }, 'eventually ${streamMatcher.description}');
-}
-
-/// Returns a [StreamMatcher] that matches any number of events that match
-/// [matcher].
-///
-/// This consumes events until [matcher] no longer matches. It always succeeds;
-/// if [matcher] doesn't match, this just consumes no events. It never rethrows
-/// errors.
-StreamMatcher mayEmitMultiple(matcher) {
- var streamMatcher = emits(matcher);
-
- var description = streamMatcher.description;
- description += description.contains('\n') ? '\n' : ' ';
- description += 'zero or more times';
-
- return StreamMatcher((queue) async {
- while (await _tryMatch(queue, streamMatcher)) {
- // Do nothing; the matcher presumably already consumed events.
- }
- return null;
- }, description);
-}
-
-/// Returns a [StreamMatcher] that matches a stream that never matches
-/// [matcher].
-///
-/// This doesn't complete until the stream emits a done event. It never consumes
-/// any events. It never re-throws errors.
-StreamMatcher neverEmits(matcher) {
- var streamMatcher = emits(matcher);
- return StreamMatcher((queue) async {
- var events = 0;
- var matched = false;
- await queue.withTransaction((copy) async {
- while (await copy.hasNext) {
- matched = await _tryMatch(copy, streamMatcher);
- if (matched) return false;
-
- events++;
-
- try {
- await copy.next;
- } catch (_) {
- // Ignore errors events.
- }
- }
-
- matched = await _tryMatch(copy, streamMatcher);
- return false;
- });
-
- if (!matched) return null;
- return "after $events ${pluralize('event', events)} did "
- '${streamMatcher.description}';
- }, 'never ${streamMatcher.description}');
-}
-
-/// Returns whether [matcher] matches [queue] at its current position.
-///
-/// This treats errors as failures to match.
-Future<bool> _tryMatch(StreamQueue queue, StreamMatcher matcher) {
- return queue.withTransaction((copy) async {
- try {
- return (await matcher.matchQueue(copy)) == null;
- } catch (_) {
- return false;
- }
- });
-}
-
-/// Returns a [StreamMatcher] that matches the stream if each matcher in
-/// [matchers] matches, in any order.
-///
-/// If any matcher fails to match, this fails and consumes no events. If the
-/// matchers match in multiple different possible orders, this chooses the order
-/// that consumes as many events as possible.
-///
-/// If any sequence of matchers matches the stream, no errors from other
-/// sequences are thrown. If no sequences match and multiple sequences throw
-/// errors, the first error is re-thrown.
-///
-/// Note that checking every ordering of [matchers] is O(n!) in the worst case,
-/// so this should only be called when there are very few [matchers].
-StreamMatcher emitsInAnyOrder(Iterable matchers) {
- var streamMatchers = matchers.map(emits).toSet();
- if (streamMatchers.length == 1) return streamMatchers.first;
- var description = 'do the following in any order:\n'
- '${bullet(streamMatchers.map((matcher) => matcher.description))}';
-
- return StreamMatcher(
- (queue) async => await _tryInAnyOrder(queue, streamMatchers) ? null : '',
- description);
-}
-
-/// Returns whether [queue] matches [matchers] in any order.
-Future<bool> _tryInAnyOrder(
- StreamQueue queue, Set<StreamMatcher> matchers) async {
- if (matchers.length == 1) {
- return await matchers.first.matchQueue(queue) == null;
- }
-
- var transaction = queue.startTransaction();
- StreamQueue? consumedMost;
-
- // The first error thrown. If no matchers match and this exists, we rethrow
- // it.
- Object? firstError;
- StackTrace? firstStackTrace;
-
- await Future.wait(matchers.map((matcher) async {
- var copy = transaction.newQueue();
- try {
- if (await matcher.matchQueue(copy) != null) return;
- } catch (error, stackTrace) {
- if (firstError == null) {
- firstError = error;
- firstStackTrace = stackTrace;
- }
- return;
- }
-
- var rest = Set<StreamMatcher>.from(matchers);
- rest.remove(matcher);
-
- try {
- if (!await _tryInAnyOrder(copy, rest)) return;
- } catch (error, stackTrace) {
- if (firstError == null) {
- firstError = error;
- firstStackTrace = stackTrace;
- }
- return;
- }
-
- if (consumedMost == null ||
- consumedMost!.eventsDispatched < copy.eventsDispatched) {
- consumedMost = copy;
- }
- }));
-
- if (consumedMost == null) {
- transaction.reject();
- if (firstError != null) await Future.error(firstError!, firstStackTrace);
- return false;
- } else {
- transaction.commit(consumedMost!);
- return true;
- }
-}
diff --git a/pkgs/test_api/lib/src/expect/throws_matcher.dart b/pkgs/test_api/lib/src/expect/throws_matcher.dart
deleted file mode 100644
index b4f081e..0000000
--- a/pkgs/test_api/lib/src/expect/throws_matcher.dart
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:matcher/matcher.dart';
-import 'package:test_api/hooks.dart';
-
-import 'async_matcher.dart';
-import 'util/pretty_print.dart';
-
-/// This function is deprecated.
-///
-/// Use [throwsA] instead. We strongly recommend that you add assertions about
-/// at least the type of the error, but you can write `throwsA(anything)` to
-/// mimic the behavior of this matcher.
-@Deprecated('Will be removed in 0.13.0')
-const Matcher throws = Throws();
-
-/// This can be used to match three kinds of objects:
-///
-/// * A [Function] that throws an exception when called. The function cannot
-/// take any arguments. If you want to test that a function expecting
-/// arguments throws, wrap it in another zero-argument function that calls
-/// the one you want to test.
-///
-/// * A [Future] that completes with an exception. Note that this creates an
-/// asynchronous expectation. The call to `expect()` that includes this will
-/// return immediately and execution will continue. Later, when the future
-/// completes, the actual expectation will run.
-///
-/// * A [Function] that returns a [Future] that completes with an exception.
-///
-/// In all three cases, when an exception is thrown, this will test that the
-/// exception object matches [matcher]. If [matcher] is not an instance of
-/// [Matcher], it will implicitly be treated as `equals(matcher)`.
-///
-/// Examples:
-/// ```dart
-/// void functionThatThrows() => throw SomeException();
-///
-/// void functionWithArgument(bool shouldThrow) {
-/// if (shouldThrow) {
-/// throw SomeException();
-/// }
-/// }
-///
-/// Future<void> asyncFunctionThatThrows() async => throw SomeException();
-///
-/// expect(functionThatThrows, throwsA(isA<SomeException>()));
-///
-/// expect(() => functionWithArgument(true), throwsA(isA<SomeException>()));
-///
-/// var future = asyncFunctionThatThrows();
-/// await expectLater(future, throwsA(isA<SomeException>()));
-///
-/// await expectLater(
-/// asyncFunctionThatThrows, throwsA(isA<SomeException>()));
-/// ```
-Matcher throwsA(matcher) => Throws(wrapMatcher(matcher));
-
-/// Use the [throwsA] function instead.
-@Deprecated('Will be removed in 0.13.0')
-class Throws extends AsyncMatcher {
- final Matcher? _matcher;
-
- const Throws([Matcher? matcher]) : _matcher = matcher;
-
- // Avoid async/await so we synchronously fail if we match a synchronous
- // function.
- @override
- dynamic /*FutureOr<String>*/ matchAsync(item) {
- if (item is! Function && item is! Future) {
- return 'was not a Function or Future';
- }
-
- if (item is Future) {
- return _matchFuture(item, 'emitted ');
- }
-
- try {
- var value = item();
- if (value is Future) {
- return _matchFuture(value, 'returned a Future that emitted ');
- }
-
- return indent(prettyPrint(value), first: 'returned ');
- } catch (error, trace) {
- return _check(error, trace);
- }
- }
-
- /// Matches [future], using try/catch since `onError` doesn't seem to work
- /// properly in nnbd.
- Future<String?> _matchFuture(
- Future<dynamic> future, String messagePrefix) async {
- try {
- var value = await future;
- return indent(prettyPrint(value), first: messagePrefix);
- } catch (error, trace) {
- return _check(error, trace);
- }
- }
-
- @override
- Description describe(Description description) {
- if (_matcher == null) {
- return description.add('throws');
- } else {
- return description.add('throws ').addDescriptionOf(_matcher);
- }
- }
-
- /// Verifies that [error] matches [_matcher] and returns a [String]
- /// description of the failure if it doesn't.
- String? _check(error, StackTrace? trace) {
- if (_matcher == null) return null;
-
- var matchState = {};
- if (_matcher!.matches(error, matchState)) return null;
-
- var result = _matcher!
- .describeMismatch(error, StringDescription(), matchState, false)
- .toString();
-
- var buffer = StringBuffer();
- buffer.writeln(indent(prettyPrint(error), first: 'threw '));
- if (trace != null) {
- buffer.writeln(indent(
- TestHandle.current.formatStackTrace(trace).toString(),
- first: 'stack '));
- }
- if (result.isNotEmpty) buffer.writeln(indent(result, first: 'which '));
- return buffer.toString().trimRight();
- }
-}
diff --git a/pkgs/test_api/lib/src/expect/throws_matchers.dart b/pkgs/test_api/lib/src/expect/throws_matchers.dart
deleted file mode 100644
index edf777b..0000000
--- a/pkgs/test_api/lib/src/expect/throws_matchers.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:matcher/matcher.dart';
-
-import 'throws_matcher.dart';
-
-/// A matcher for functions that throw ArgumentError.
-///
-/// See [throwsA] for objects that this can be matched against.
-const Matcher throwsArgumentError = Throws(isArgumentError);
-
-/// A matcher for functions that throw ConcurrentModificationError.
-///
-/// See [throwsA] for objects that this can be matched against.
-const Matcher throwsConcurrentModificationError =
- Throws(isConcurrentModificationError);
-
-/// A matcher for functions that throw CyclicInitializationError.
-///
-/// See [throwsA] for objects that this can be matched against.
-@Deprecated('throwsCyclicInitializationError has been deprecated, because '
- 'the type will longer exists in Dart 3.0. It will now catch any kind of '
- 'error, not only CyclicInitializationError.')
-const Matcher throwsCyclicInitializationError = Throws(TypeMatcher<Error>());
-
-/// A matcher for functions that throw Exception.
-///
-/// See [throwsA] for objects that this can be matched against.
-const Matcher throwsException = Throws(isException);
-
-/// A matcher for functions that throw FormatException.
-///
-/// See [throwsA] for objects that this can be matched against.
-const Matcher throwsFormatException = Throws(isFormatException);
-
-/// A matcher for functions that throw NoSuchMethodError.
-///
-/// See [throwsA] for objects that this can be matched against.
-const Matcher throwsNoSuchMethodError = Throws(isNoSuchMethodError);
-
-/// A matcher for functions that throw NullThrownError.
-///
-/// See [throwsA] for objects that this can be matched against.
-@Deprecated('throwsNullThrownError has been deprecated, because '
- 'NullThrownError has been replaced with TypeError. '
- 'Use `throwsA(isA<TypeError>())` instead.')
-const Matcher throwsNullThrownError = Throws(TypeMatcher<TypeError>());
-
-/// A matcher for functions that throw RangeError.
-///
-/// See [throwsA] for objects that this can be matched against.
-const Matcher throwsRangeError = Throws(isRangeError);
-
-/// A matcher for functions that throw StateError.
-///
-/// See [throwsA] for objects that this can be matched against.
-const Matcher throwsStateError = Throws(isStateError);
-
-/// A matcher for functions that throw Exception.
-///
-/// See [throwsA] for objects that this can be matched against.
-const Matcher throwsUnimplementedError = Throws(isUnimplementedError);
-
-/// A matcher for functions that throw UnsupportedError.
-///
-/// See [throwsA] for objects that this can be matched against.
-const Matcher throwsUnsupportedError = Throws(isUnsupportedError);
diff --git a/pkgs/test_api/lib/src/expect/util/placeholder.dart b/pkgs/test_api/lib/src/expect/util/placeholder.dart
deleted file mode 100644
index ee2dc70..0000000
--- a/pkgs/test_api/lib/src/expect/util/placeholder.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// A class that's used as a default argument to detect whether an argument was
-/// passed.
-///
-/// We use a custom class for this rather than just `const Object()` so that
-/// callers can't accidentally pass the placeholder value.
-class _Placeholder {
- const _Placeholder();
-}
-
-/// A placeholder to use as a default argument value to detect whether an
-/// argument was passed.
-const placeholder = _Placeholder();
diff --git a/pkgs/test_api/lib/src/expect/util/pretty_print.dart b/pkgs/test_api/lib/src/expect/util/pretty_print.dart
deleted file mode 100644
index f21399d..0000000
--- a/pkgs/test_api/lib/src/expect/util/pretty_print.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:matcher/matcher.dart';
-import 'package:term_glyph/term_glyph.dart' as glyph;
-
-/// Indent each line in [string] by [first.length] spaces.
-///
-/// [first] is used in place of the first line's indentation.
-String indent(String text, {required String first}) {
- final prefix = ' ' * first.length;
- var lines = text.split('\n');
- if (lines.length == 1) return '$first$text';
-
- var buffer = StringBuffer('$first${lines.first}\n');
-
- // Write out all but the first and last lines with [prefix].
- for (var line in lines.skip(1).take(lines.length - 2)) {
- buffer.writeln('$prefix$line');
- }
- buffer.write('$prefix${lines.last}');
- return buffer.toString();
-}
-
-/// Returns a pretty-printed representation of [value].
-///
-/// The matcher package doesn't expose its pretty-print function directly, but
-/// we can use it through StringDescription.
-String prettyPrint(value) =>
- StringDescription().addDescriptionOf(value).toString();
-
-/// Indents [text], and adds a bullet at the beginning.
-String addBullet(String text) => indent(text, first: '${glyph.bullet} ');
-
-/// Converts [strings] to a bulleted list.
-String bullet(Iterable<String> strings) => strings.map(addBullet).join('\n');
-
-/// Returns [name] if [number] is 1, or the plural of [name] otherwise.
-///
-/// By default, this just adds "s" to the end of [name] to get the plural. If
-/// [plural] is passed, that's used instead.
-String pluralize(String name, int number, {String? plural}) {
- if (number == 1) return name;
- if (plural != null) return plural;
- return '${name}s';
-}
diff --git a/pkgs/test_api/lib/src/frontend/async_matcher.dart b/pkgs/test_api/lib/src/frontend/async_matcher.dart
deleted file mode 100644
index a6b800a..0000000
--- a/pkgs/test_api/lib/src/frontend/async_matcher.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-@Deprecated('Moved to src/expect/async_matcher.dart')
-library test_api.src.frontend.async_matcher;
-
-// Temporary re-export to reduce churn in flutter_test.
-export '../expect/async_matcher.dart';
diff --git a/pkgs/test_api/lib/src/frontend/expect.dart b/pkgs/test_api/lib/src/frontend/expect.dart
deleted file mode 100644
index 4354058..0000000
--- a/pkgs/test_api/lib/src/frontend/expect.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-@Deprecated('Moved to src/expect/expect.dart')
-library test_api.src.frontend.expect;
-
-// Temporary re-export to avoid churn in analyzer tests.
-export '../expect/expect.dart';
diff --git a/pkgs/test_api/lib/src/frontend/fake.dart b/pkgs/test_api/lib/src/frontend/fake.dart
index 0057400..e3e0ea6 100644
--- a/pkgs/test_api/lib/src/frontend/fake.dart
+++ b/pkgs/test_api/lib/src/frontend/fake.dart
@@ -44,7 +44,7 @@
/// [Fake] should strictly _not_ be used in any production code, especially if
/// used within the context of Dart for Web (dart2js, DDC) and Dart for Mobile
/// (Flutter).
-abstract class Fake {
+abstract mixin class Fake {
@override
dynamic noSuchMethod(Invocation invocation) {
throw UnimplementedError(invocation.memberName.toString().split('"')[1]);
diff --git a/pkgs/test_api/lib/src/scaffolding/spawn_hybrid.dart b/pkgs/test_api/lib/src/scaffolding/spawn_hybrid.dart
index 6e01fe8..2186894 100644
--- a/pkgs/test_api/lib/src/scaffolding/spawn_hybrid.dart
+++ b/pkgs/test_api/lib/src/scaffolding/spawn_hybrid.dart
@@ -32,7 +32,7 @@
break;
case 'error':
- var error = RemoteException.deserialize(message['error']);
+ var error = RemoteException.deserialize(message['error'] as Map);
sink.addError(error.error, error.stackTrace);
break;
}
@@ -89,7 +89,11 @@
///
/// **Note**: If you use this API, be sure to add a dependency on the
/// **`stream_channel` package, since you're using its API as well!
-StreamChannel spawnHybridUri(uri, {Object? message, bool stayAlive = false}) {
+StreamChannel spawnHybridUri(
+ Object uri, {
+ Object? message,
+ bool stayAlive = false,
+}) {
if (uri is String) {
// Ensure that it can be parsed as a uri.
Uri.parse(uri);
diff --git a/pkgs/test_api/lib/src/scaffolding/test_structure.dart b/pkgs/test_api/lib/src/scaffolding/test_structure.dart
index ec8691d..97c6d79 100644
--- a/pkgs/test_api/lib/src/scaffolding/test_structure.dart
+++ b/pkgs/test_api/lib/src/scaffolding/test_structure.dart
@@ -70,11 +70,11 @@
/// avoid this flag if possible and instead use the test runner flag `-n` to
/// filter tests by name.
@isTest
-void test(description, dynamic Function() body,
+void test(Object? description, dynamic Function() body,
{String? testOn,
Timeout? timeout,
- skip,
- tags,
+ Object? skip,
+ Object? tags,
Map<String, dynamic>? onPlatform,
int? retry,
@Deprecated('Debug only') bool solo = false}) {
@@ -148,11 +148,11 @@
/// avoid this flag if possible, and instead use the test runner flag `-n` to
/// filter tests by name.
@isTestGroup
-void group(description, dynamic Function() body,
+void group(Object? description, dynamic Function() body,
{String? testOn,
Timeout? timeout,
- skip,
- tags,
+ Object? skip,
+ Object? tags,
Map<String, dynamic>? onPlatform,
int? retry,
@Deprecated('Debug only') bool solo = false}) {
diff --git a/pkgs/test_api/lib/test_api.dart b/pkgs/test_api/lib/test_api.dart
index 8e037cc..7804cda 100644
--- a/pkgs/test_api/lib/test_api.dart
+++ b/pkgs/test_api/lib/test_api.dart
@@ -6,12 +6,5 @@
'Please use package:test.')
library test_api;
-export 'expect.dart';
export 'hooks.dart' show TestFailure;
export 'scaffolding.dart';
-// Deprecated exports not surfaced through focused libraries.
-export 'src/expect/expect.dart' show ErrorFormatter;
-export 'src/expect/expect_async.dart' show expectAsync;
-export 'src/expect/throws_matcher.dart' show throws, Throws;
-// Not yet deprecated, but not exposed through focused libraries.
-export 'src/scaffolding/utils.dart' show registerException;
diff --git a/pkgs/test_api/pubspec.yaml b/pkgs/test_api/pubspec.yaml
index 51d5b23..c67c7ba 100644
--- a/pkgs/test_api/pubspec.yaml
+++ b/pkgs/test_api/pubspec.yaml
@@ -1,11 +1,11 @@
name: test_api
-version: 0.4.18
+version: 0.6.1
description: >-
The user facing API for structuring Dart tests and checking expectations.
repository: https://github.com/dart-lang/test/tree/master/pkgs/test_api
environment:
- sdk: ">=2.18.0 <3.0.0"
+ sdk: ^3.0.0
dependencies:
async: ^2.5.0
@@ -18,16 +18,12 @@
string_scanner: ^1.1.0
term_glyph: ^1.2.0
- # Use a tight version constraint to ensure that a constraint on matcher
- # properly constrains all features it provides.
- matcher: '>=0.12.11 <0.12.15'
-
dev_dependencies:
- analyzer: '>=2.1.0 <6.0.0'
+ analyzer: '>=2.1.0 <7.0.0'
+ dart_flutter_team_lints: ^1.0.0
fake_async: ^1.2.0
glob: ^2.0.0
graphs: ^2.0.0
path: ^1.8.0
- lints: '>=1.0.0 <3.0.0'
test: any
test_core: any
diff --git a/pkgs/test_api/test/backend/invoker_test.dart b/pkgs/test_api/test/backend/invoker_test.dart
index 490bb02..55e697b 100644
--- a/pkgs/test_api/test/backend/invoker_test.dart
+++ b/pkgs/test_api/test/backend/invoker_test.dart
@@ -184,10 +184,9 @@
expect(lastState, equals(const State(Status.complete, Result.error)));
expect(
error,
- equals(
- 'This test failed after it had already completed. Make sure to '
- 'use [expectAsync]\n'
- 'or the [completes] matcher when testing async code.'));
+ equals('This test failed after it had already completed.\n'
+ 'Make sure to use a matching library which informs the '
+ 'test runner\nof pending async work.'));
}
]);
@@ -316,10 +315,9 @@
(error) {
expect(
error,
- equals(
- 'This test failed after it had already completed. Make sure to '
- 'use [expectAsync]\n'
- 'or the [completes] matcher when testing async code.'));
+ equals('This test failed after it had already completed.\n'
+ 'Make sure to use a matching library which informs the '
+ 'test runner\nof pending async work.'));
}
]);
diff --git a/pkgs/test_api/test/backend/metadata_test.dart b/pkgs/test_api/test/backend/metadata_test.dart
index f900b13..c9a0f78 100644
--- a/pkgs/test_api/test/backend/metadata_test.dart
+++ b/pkgs/test_api/test/backend/metadata_test.dart
@@ -140,14 +140,16 @@
});
var key = metadata.onPlatform.keys.first;
- expect(key.evaluate(SuitePlatform(Runtime.chrome)), isTrue);
- expect(key.evaluate(SuitePlatform(Runtime.vm)), isFalse);
+ expect(
+ key.evaluate(SuitePlatform(Runtime.chrome, compiler: null)), isTrue);
+ expect(key.evaluate(SuitePlatform(Runtime.vm, compiler: null)), isFalse);
var value = metadata.onPlatform.values.first;
expect(value.timeout.scaleFactor, equals(2));
key = metadata.onPlatform.keys.last;
- expect(key.evaluate(SuitePlatform(Runtime.vm)), isTrue);
- expect(key.evaluate(SuitePlatform(Runtime.chrome)), isFalse);
+ expect(key.evaluate(SuitePlatform(Runtime.vm, compiler: null)), isTrue);
+ expect(
+ key.evaluate(SuitePlatform(Runtime.chrome, compiler: null)), isFalse);
value = metadata.onPlatform.values.last;
expect(value.skip, isTrue);
expect(value.timeout.scaleFactor, equals(3));
@@ -200,6 +202,10 @@
Metadata.parse(testOn: 'vm || browser').validatePlatformSelectors({'vm'});
});
+ test('succeeds if testOn uses valid compilers', () {
+ Metadata.parse(testOn: 'dart2js || kernel').validatePlatformSelectors({});
+ });
+
test('fails if onPlatform uses an invalid platform', () {
expect(() {
Metadata.parse(onPlatform: {'unknown': Skip()})
@@ -212,6 +218,12 @@
Metadata.parse(testOn: 'unknown').validatePlatformSelectors({'vm'});
}, throwsFormatException);
});
+
+ test('fails if testOn uses an invalid compiler', () {
+ expect(() {
+ Metadata.parse(testOn: 'foo2bar').validatePlatformSelectors({});
+ }, throwsFormatException);
+ });
});
group('change', () {
diff --git a/pkgs/test_api/test/frontend/expect_async_test.dart b/pkgs/test_api/test/frontend/expect_async_test.dart
deleted file mode 100644
index dde2e41..0000000
--- a/pkgs/test_api/test/frontend/expect_async_test.dart
+++ /dev/null
@@ -1,385 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:fake_async/fake_async.dart';
-import 'package:test/test.dart';
-import 'package:test_api/src/backend/live_test.dart';
-import 'package:test_api/src/backend/state.dart';
-
-import '../utils.dart';
-
-void main() {
- group('supports a function with this many arguments:', () {
- test('0', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync0(() {
- callbackRun = true;
- })();
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
-
- test('1', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync1((int arg) {
- expect(arg, equals(1));
- callbackRun = true;
- })(1);
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
-
- test('2', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync2((arg1, arg2) {
- expect(arg1, equals(1));
- expect(arg2, equals(2));
- callbackRun = true;
- })(1, 2);
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
-
- test('3', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync3((arg1, arg2, arg3) {
- expect(arg1, equals(1));
- expect(arg2, equals(2));
- expect(arg3, equals(3));
- callbackRun = true;
- })(1, 2, 3);
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
-
- test('4', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync4((arg1, arg2, arg3, arg4) {
- expect(arg1, equals(1));
- expect(arg2, equals(2));
- expect(arg3, equals(3));
- expect(arg4, equals(4));
- callbackRun = true;
- })(1, 2, 3, 4);
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
-
- test('5', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync5((arg1, arg2, arg3, arg4, arg5) {
- expect(arg1, equals(1));
- expect(arg2, equals(2));
- expect(arg3, equals(3));
- expect(arg4, equals(4));
- expect(arg5, equals(5));
- callbackRun = true;
- })(1, 2, 3, 4, 5);
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
-
- test('6', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync6((arg1, arg2, arg3, arg4, arg5, arg6) {
- expect(arg1, equals(1));
- expect(arg2, equals(2));
- expect(arg3, equals(3));
- expect(arg4, equals(4));
- expect(arg5, equals(5));
- expect(arg6, equals(6));
- callbackRun = true;
- })(1, 2, 3, 4, 5, 6);
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
- });
-
- group('with optional arguments', () {
- test('allows them to be passed', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync1(([arg = 1]) {
- expect(arg, equals(2));
- callbackRun = true;
- })(2);
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
-
- test('allows them not to be passed', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync1(([arg = 1]) {
- expect(arg, equals(1));
- callbackRun = true;
- })();
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
- });
-
- group('by default', () {
- test("won't allow the test to complete until it's called", () {
- return expectTestBlocks(
- () => expectAsync0(() {}), (callback) => callback());
- });
-
- test('may only be called once', () async {
- var liveTest = await runTestBody(() {
- var callback = expectAsync0(() {});
- callback();
- callback();
- });
-
- expectTestFailed(
- liveTest, 'Callback called more times than expected (1).');
- });
- });
-
- group('with count', () {
- test(
- "won't allow the test to complete until it's called at least that "
- 'many times', () async {
- late LiveTest liveTest;
- late Future future;
- liveTest = createTest(() {
- var callback = expectAsync0(() {}, count: 3);
-
- future = () async {
- await pumpEventQueue();
- expect(liveTest.state.status, equals(Status.running));
- callback();
-
- await pumpEventQueue();
- expect(liveTest.state.status, equals(Status.running));
- callback();
-
- await pumpEventQueue();
- expect(liveTest.state.status, equals(Status.running));
- callback();
- }();
- });
-
- await liveTest.run();
- expectTestPassed(liveTest);
- // Ensure that the outer test doesn't complete until the inner future
- // completes.
- await future;
- });
-
- test("will throw an error if it's called more than that many times",
- () async {
- var liveTest = await runTestBody(() {
- var callback = expectAsync0(() {}, count: 3);
- callback();
- callback();
- callback();
- callback();
- });
-
- expectTestFailed(
- liveTest, 'Callback called more times than expected (3).');
- });
-
- group('0,', () {
- test("won't block the test's completion", () {
- expectAsync0(() {}, count: 0);
- });
-
- test("will throw an error if it's ever called", () async {
- var liveTest = await runTestBody(() {
- expectAsync0(() {}, count: 0)();
- });
-
- expectTestFailed(
- liveTest, 'Callback called more times than expected (0).');
- });
- });
- });
-
- group('with max', () {
- test('will allow the callback to be called that many times', () {
- var callback = expectAsync0(() {}, max: 3);
- callback();
- callback();
- callback();
- });
-
- test('will allow the callback to be called fewer than that many times', () {
- var callback = expectAsync0(() {}, max: 3);
- callback();
- });
-
- test("will throw an error if it's called more than that many times",
- () async {
- var liveTest = await runTestBody(() {
- var callback = expectAsync0(() {}, max: 3);
- callback();
- callback();
- callback();
- callback();
- });
-
- expectTestFailed(
- liveTest, 'Callback called more times than expected (3).');
- });
-
- test('-1, will allow the callback to be called any number of times', () {
- var callback = expectAsync0(() {}, max: -1);
- for (var i = 0; i < 20; i++) {
- callback();
- }
- });
- });
-
- test('will throw an error if max is less than count', () {
- expect(() => expectAsync0(() {}, max: 1, count: 2), throwsArgumentError);
- });
-
- group('expectAsyncUntil()', () {
- test("won't allow the test to complete until isDone returns true",
- () async {
- late LiveTest liveTest;
- late Future future;
- liveTest = createTest(() {
- var done = false;
- var callback = expectAsyncUntil0(() {}, () => done);
-
- future = () async {
- await pumpEventQueue();
- expect(liveTest.state.status, equals(Status.running));
- callback();
- await pumpEventQueue();
- expect(liveTest.state.status, equals(Status.running));
- done = true;
- callback();
- }();
- });
-
- await liveTest.run();
- expectTestPassed(liveTest);
- // Ensure that the outer test doesn't complete until the inner future
- // completes.
- await future;
- });
-
- test("doesn't call isDone until after the callback is called", () {
- var callbackRun = false;
- expectAsyncUntil0(() => callbackRun = true, () {
- expect(callbackRun, isTrue);
- return true;
- })();
- });
- });
-
- test('allows errors', () async {
- var liveTest = await runTestBody(() {
- expect(expectAsync0(() => throw 'oh no'), throwsA('oh no'));
- });
-
- expectTestPassed(liveTest);
- });
-
- test('may be called in a non-test zone', () async {
- var liveTest = await runTestBody(() {
- var callback = expectAsync0(() {});
- Zone.root.run(callback);
- });
- expectTestPassed(liveTest);
- });
-
- test('may be called in a FakeAsync zone that does not run further', () async {
- var liveTest = await runTestBody(() {
- FakeAsync().run((_) {
- var callback = expectAsync0(() {});
- callback();
- });
- });
- expectTestPassed(liveTest);
- });
-
- group('old-style expectAsync()', () {
- test('works with no arguments', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync(() {
- callbackRun = true;
- })();
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
-
- test('works with dynamic arguments', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync((arg1, arg2) {
- callbackRun = true;
- })(1, 2);
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
-
- test('works with non-nullable arguments', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync((int arg1, int arg2) {
- callbackRun = true;
- })(1, 2);
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
-
- test('works with 6 arguments', () async {
- var callbackRun = false;
- var liveTest = await runTestBody(() {
- expectAsync((arg1, arg2, arg3, arg4, arg5, arg6) {
- callbackRun = true;
- })(1, 2, 3, 4, 5, 6);
- });
-
- expectTestPassed(liveTest);
- expect(callbackRun, isTrue);
- });
-
- test("doesn't support a function with 7 arguments", () {
- // ignore: no_leading_underscores_for_local_identifiers
- expect(() => expectAsync((_a, _b, _c, _d, _e, _f, _g) {}),
- throwsArgumentError);
- });
- });
-}
diff --git a/pkgs/test_api/test/frontend/expect_test.dart b/pkgs/test_api/test/frontend/expect_test.dart
deleted file mode 100644
index ee8d243..0000000
--- a/pkgs/test_api/test/frontend/expect_test.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test/test.dart';
-
-import '../utils.dart';
-
-void main() {
- group('returned Future from expectLater()', () {
- test('completes immediately for a sync matcher', () {
- expect(expectLater(true, isTrue), completes);
- });
-
- test('contains the expect failure', () {
- expect(expectLater(Future.value(true), completion(isFalse)),
- throwsA(isTestFailure(anything)));
- });
-
- test('contains an async error', () {
- expect(expectLater(Future.error('oh no'), completion(isFalse)),
- throwsA('oh no'));
- });
- });
-
- group('an async matcher that fails synchronously', () {
- test('throws synchronously', () {
- expect(() => expect(() {}, throws), throwsA(isTestFailure(anything)));
- });
-
- test('can be used with synchronous operators', () {
- expect(() {}, isNot(throws));
- });
- });
-}
diff --git a/pkgs/test_api/test/frontend/matcher/completion_test.dart b/pkgs/test_api/test/frontend/matcher/completion_test.dart
deleted file mode 100644
index 1aee139..0000000
--- a/pkgs/test_api/test/frontend/matcher/completion_test.dart
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:test/test.dart';
-import 'package:test_api/src/backend/state.dart';
-
-import '../../utils.dart';
-
-void main() {
- group('[doesNotComplete]', () {
- test('fails when provided a non future', () async {
- var liveTest = await runTestBody(() {
- expect(10, doesNotComplete);
- });
-
- expectTestFailed(liveTest, contains('10 is not a Future'));
- });
-
- test('succeeds when a future does not complete', () {
- var completer = Completer();
- expect(completer.future, doesNotComplete);
- });
-
- test('fails when a future does complete', () async {
- var liveTest = await runTestBody(() {
- var completer = Completer();
- completer.complete(null);
- expect(completer.future, doesNotComplete);
- });
-
- expectTestFailed(
- liveTest,
- 'Future was not expected to complete but completed with a value of'
- ' null');
- });
-
- test('fails when a future completes after the expect', () async {
- var liveTest = await runTestBody(() {
- var completer = Completer();
- expect(completer.future, doesNotComplete);
- completer.complete(null);
- });
-
- expectTestFailed(
- liveTest,
- 'Future was not expected to complete but completed with a value of'
- ' null');
- });
-
- test('fails when a future eventually completes', () async {
- var liveTest = await runTestBody(() {
- var completer = Completer();
- expect(completer.future, doesNotComplete);
- Future(() async {
- await pumpEventQueue(times: 10);
- }).then(completer.complete);
- });
-
- expectTestFailed(
- liveTest,
- 'Future was not expected to complete but completed with a value of'
- ' null');
- });
- });
- group('[completes]', () {
- test('blocks the test until the Future completes', () {
- return expectTestBlocks(() {
- var completer = Completer();
- expect(completer.future, completes);
- return completer;
- }, (completer) => completer.complete());
- });
-
- test('with an error', () async {
- var liveTest = await runTestBody(() {
- expect(Future.error('X'), completes);
- });
-
- expect(liveTest.state.status, equals(Status.complete));
- expect(liveTest.state.result, equals(Result.error));
- expect(liveTest.errors, hasLength(1));
- expect(liveTest.errors.first.error, equals('X'));
- });
-
- test('with a failure', () async {
- var liveTest = await runTestBody(() {
- expect(Future.error(TestFailure('oh no')), completes);
- });
-
- expectTestFailed(liveTest, 'oh no');
- });
-
- test('with a non-future', () async {
- var liveTest = await runTestBody(() {
- expect(10, completes);
- });
-
- expectTestFailed(
- liveTest,
- 'Expected: completes successfully\n'
- ' Actual: <10>\n'
- ' Which: was not a Future\n');
- });
-
- test('with a successful future', () {
- expect(Future.value('1'), completes);
- });
- });
-
- group('[completion]', () {
- test('blocks the test until the Future completes', () {
- return expectTestBlocks(() {
- var completer = Completer();
- expect(completer.future, completion(isNull));
- return completer;
- }, (completer) => completer.complete());
- });
-
- test('with an error', () async {
- var liveTest = await runTestBody(() {
- expect(Future.error('X'), completion(isNull));
- });
-
- expect(liveTest.state.status, equals(Status.complete));
- expect(liveTest.state.result, equals(Result.error));
- expect(liveTest.errors, hasLength(1));
- expect(liveTest.errors.first.error, equals('X'));
- });
-
- test('with a failure', () async {
- var liveTest = await runTestBody(() {
- expect(Future.error(TestFailure('oh no')), completion(isNull));
- });
-
- expectTestFailed(liveTest, 'oh no');
- });
-
- test('with a non-future', () async {
- var liveTest = await runTestBody(() {
- expect(10, completion(equals(10)));
- });
-
- expectTestFailed(
- liveTest,
- 'Expected: completes to a value that <10>\n'
- ' Actual: <10>\n'
- ' Which: was not a Future\n');
- });
-
- test('with an incorrect value', () async {
- var liveTest = await runTestBody(() {
- expect(Future.value('a'), completion(equals('b')));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: completes to a value that 'b'\n"
- ' Actual: <'),
- endsWith('>\n'
- " Which: emitted 'a'\n"
- ' which is different.\n'
- ' Expected: b\n'
- ' Actual: a\n'
- ' ^\n'
- ' Differ at offset 0\n')
- ]));
- });
-
- test("blocks expectLater's Future", () async {
- var completer = Completer();
- var fired = false;
- unawaited(expectLater(completer.future, completion(equals(1))).then((_) {
- fired = true;
- }));
-
- await pumpEventQueue();
- expect(fired, isFalse);
-
- completer.complete(1);
- await pumpEventQueue();
- expect(fired, isTrue);
- });
- });
-}
diff --git a/pkgs/test_api/test/frontend/matcher/prints_test.dart b/pkgs/test_api/test/frontend/matcher/prints_test.dart
deleted file mode 100644
index 92ab6a7..0000000
--- a/pkgs/test_api/test/frontend/matcher/prints_test.dart
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:test/test.dart';
-
-import '../../utils.dart';
-
-void main() {
- group('synchronous', () {
- test('passes with an expected print', () {
- expect(() => print('Hello, world!'), prints('Hello, world!\n'));
- });
-
- test('combines multiple prints', () {
- expect(() {
- print('Hello');
- print('World!');
- }, prints('Hello\nWorld!\n'));
- });
-
- test('works with a Matcher', () {
- expect(() => print('Hello, world!'), prints(contains('Hello')));
- });
-
- test('describes a failure nicely', () async {
- void local() => print('Hello, world!');
- var liveTest = await runTestBody(() {
- expect(local, prints('Goodbye, world!\n'));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: prints 'Goodbye, world!\\n'\n"
- " ''\n"
- ' Actual: <'),
- endsWith('>\n'
- " Which: printed 'Hello, world!\\n'\n"
- " ''\n"
- ' which is different.\n'
- ' Expected: Goodbye, w ...\n'
- ' Actual: Hello, wor ...\n'
- ' ^\n'
- ' Differ at offset 0\n')
- ]));
- });
-
- test('describes a failure with a non-descriptive Matcher nicely', () async {
- void local() => print('Hello, world!');
- var liveTest = await runTestBody(() {
- expect(local, prints(contains('Goodbye')));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: prints contains 'Goodbye'\n"
- ' Actual: <'),
- endsWith('>\n'
- " Which: printed 'Hello, world!\\n'\n"
- " ''\n")
- ]));
- });
-
- test('describes a failure with no text nicely', () async {
- void local() {}
- var liveTest = await runTestBody(() {
- expect(local, prints(contains('Goodbye')));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: prints contains 'Goodbye'\n"
- ' Actual: <'),
- endsWith('>\n'
- ' Which: printed nothing\n')
- ]));
- });
-
- test('with a non-function', () async {
- var liveTest = await runTestBody(() {
- expect(10, prints(contains('Goodbye')));
- });
-
- expectTestFailed(
- liveTest,
- "Expected: prints contains 'Goodbye'\n"
- ' Actual: <10>\n'
- ' Which: was not a unary Function\n');
- });
- });
-
- group('asynchronous', () {
- test('passes with an expected print', () {
- expect(() => Future(() => print('Hello, world!')),
- prints('Hello, world!\n'));
- });
-
- test('combines multiple prints', () {
- expect(
- () => Future(() {
- print('Hello');
- print('World!');
- }),
- prints('Hello\nWorld!\n'));
- });
-
- test('works with a Matcher', () {
- expect(() => Future(() => print('Hello, world!')),
- prints(contains('Hello')));
- });
-
- test('describes a failure nicely', () async {
- void local() => Future(() => print('Hello, world!'));
- var liveTest = await runTestBody(() {
- expect(local, prints('Goodbye, world!\n'));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: prints 'Goodbye, world!\\n'\n"
- " ''\n"
- ' Actual: <'),
- contains('>\n'
- " Which: printed 'Hello, world!\\n'\n"
- " ''\n"
- ' which is different.\n'
- ' Expected: Goodbye, w ...\n'
- ' Actual: Hello, wor ...\n'
- ' ^\n'
- ' Differ at offset 0')
- ]));
- });
-
- test('describes a failure with a non-descriptive Matcher nicely', () async {
- void local() => Future(() => print('Hello, world!'));
- var liveTest = await runTestBody(() {
- expect(local, prints(contains('Goodbye')));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: prints contains 'Goodbye'\n"
- ' Actual: <'),
- contains('>\n'
- " Which: printed 'Hello, world!\\n'\n"
- " ''")
- ]));
- });
-
- test('describes a failure with no text nicely', () async {
- void local() => Future.value();
- var liveTest = await runTestBody(() {
- expect(local, prints(contains('Goodbye')));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: prints contains 'Goodbye'\n"
- ' Actual: <'),
- contains('>\n'
- ' Which: printed nothing')
- ]));
- });
-
- test("won't let the test end until the Future completes", () {
- return expectTestBlocks(() {
- var completer = Completer();
- expect(() => completer.future, prints(isEmpty));
- return completer;
- }, (completer) => completer.complete());
- });
-
- test("blocks expectLater's Future", () async {
- var completer = Completer();
- var fired = false;
-
- unawaited(expectLater(() {
- scheduleMicrotask(() => print('hello!'));
- return completer.future;
- }, prints('hello!\n'))
- .then((_) {
- fired = true;
- }));
-
- await pumpEventQueue();
- expect(fired, isFalse);
-
- completer.complete();
- await pumpEventQueue();
- expect(fired, isTrue);
- });
- });
-}
diff --git a/pkgs/test_api/test/frontend/matcher/throws_test.dart b/pkgs/test_api/test/frontend/matcher/throws_test.dart
deleted file mode 100644
index 40b2be6..0000000
--- a/pkgs/test_api/test/frontend/matcher/throws_test.dart
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:test/test.dart';
-
-import '../../utils.dart';
-
-void main() {
- group('synchronous', () {
- group('[throws]', () {
- test('with a function that throws an error', () {
- expect(() => throw 'oh no', throws);
- });
-
- test("with a function that doesn't throw", () async {
- void local() {}
- var liveTest = await runTestBody(() {
- expect(local, throws);
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith('Expected: throws\n'
- ' Actual: <'),
- endsWith('>\n'
- ' Which: returned <null>\n')
- ]));
- });
-
- test('with a non-function', () async {
- var liveTest = await runTestBody(() {
- expect(10, throws);
- });
-
- expectTestFailed(
- liveTest,
- 'Expected: throws\n'
- ' Actual: <10>\n'
- ' Which: was not a Function or Future\n');
- });
- });
-
- group('[throwsA]', () {
- test('with a function that throws an identical error', () {
- expect(() => throw 'oh no', throwsA('oh no'));
- });
-
- test('with a function that throws a matching error', () {
- expect(() => throw FormatException('bad'), throwsA(isFormatException));
- });
-
- test("with a function that doesn't throw", () async {
- void local() {}
- var liveTest = await runTestBody(() {
- expect(local, throwsA('oh no'));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: throws 'oh no'\n"
- ' Actual: <'),
- endsWith('>\n'
- ' Which: returned <null>\n')
- ]));
- });
-
- test('with a non-function', () async {
- var liveTest = await runTestBody(() {
- expect(10, throwsA('oh no'));
- });
-
- expectTestFailed(
- liveTest,
- "Expected: throws 'oh no'\n"
- ' Actual: <10>\n'
- ' Which: was not a Function or Future\n');
- });
-
- test('with a function that throws the wrong error', () async {
- var liveTest = await runTestBody(() {
- expect(() => throw 'aw dang', throwsA('oh no'));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: throws 'oh no'\n"
- ' Actual: <'),
- contains('>\n'
- " Which: threw 'aw dang'\n"
- ' stack'),
- endsWith(' which is different.\n'
- ' Expected: oh no\n'
- ' Actual: aw dang\n'
- ' ^\n'
- ' Differ at offset 0\n')
- ]));
- });
- });
- });
-
- group('asynchronous', () {
- group('[throws]', () {
- test('with a Future that throws an error', () {
- expect(Future.error('oh no'), throws);
- });
-
- test("with a Future that doesn't throw", () async {
- var liveTest = await runTestBody(() {
- expect(Future.value(), throws);
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith('Expected: throws\n'
- ' Actual: <'),
- endsWith('>\n'
- ' Which: emitted <null>\n')
- ]));
- });
-
- test('with a closure that returns a Future that throws an error', () {
- expect(() => Future.error('oh no'), throws);
- });
-
- test("with a closure that returns a Future that doesn't throw", () async {
- var liveTest = await runTestBody(() {
- expect(() => Future.value(), throws);
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith('Expected: throws\n'
- ' Actual: <'),
- endsWith('>\n'
- ' Which: returned a Future that emitted <null>\n')
- ]));
- });
-
- test("won't let the test end until the Future completes", () {
- return expectTestBlocks(() {
- var completer = Completer();
- expect(completer.future, throws);
- return completer;
- }, (completer) => completer.completeError('oh no'));
- });
- });
-
- group('[throwsA]', () {
- test('with a Future that throws an identical error', () {
- expect(Future.error('oh no'), throwsA('oh no'));
- });
-
- test('with a Future that throws a matching error', () {
- expect(
- Future.error(FormatException('bad')), throwsA(isFormatException));
- });
-
- test("with a Future that doesn't throw", () async {
- var liveTest = await runTestBody(() {
- expect(Future.value(), throwsA('oh no'));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: throws 'oh no'\n"
- ' Actual: <'),
- endsWith('>\n'
- ' Which: emitted <null>\n')
- ]));
- });
-
- test('with a Future that throws the wrong error', () async {
- var liveTest = await runTestBody(() {
- expect(Future.error('aw dang'), throwsA('oh no'));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: throws 'oh no'\n"
- ' Actual: <'),
- contains('>\n'
- " Which: threw 'aw dang'\n")
- ]));
- });
-
- test('with a closure that returns a Future that throws a matching error',
- () {
- expect(() => Future.error(FormatException('bad')),
- throwsA(isFormatException));
- });
-
- test("with a closure that returns a Future that doesn't throw", () async {
- var liveTest = await runTestBody(() {
- expect(() => Future.value(), throwsA('oh no'));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: throws 'oh no'\n"
- ' Actual: <'),
- endsWith('>\n'
- ' Which: returned a Future that emitted <null>\n')
- ]));
- });
-
- test('with closure that returns a Future that throws the wrong error',
- () async {
- var liveTest = await runTestBody(() {
- expect(() => Future.error('aw dang'), throwsA('oh no'));
- });
-
- expectTestFailed(
- liveTest,
- allOf([
- startsWith("Expected: throws 'oh no'\n"
- ' Actual: <'),
- contains('>\n'
- " Which: threw 'aw dang'\n")
- ]));
- });
-
- test("won't let the test end until the Future completes", () {
- return expectTestBlocks(() {
- var completer = Completer();
- expect(completer.future, throwsA('oh no'));
- return completer;
- }, (completer) => completer.completeError('oh no'));
- });
-
- test("blocks expectLater's Future", () async {
- var completer = Completer();
- var fired = false;
- unawaited(expectLater(completer.future, throwsArgumentError).then((_) {
- fired = true;
- }));
-
- await pumpEventQueue();
- expect(fired, isFalse);
-
- completer.completeError(ArgumentError('oh no'));
- await pumpEventQueue();
- expect(fired, isTrue);
- });
- });
- });
-}
diff --git a/pkgs/test_api/test/frontend/matcher/throws_type_test.dart b/pkgs/test_api/test/frontend/matcher/throws_type_test.dart
deleted file mode 100644
index 6e0a482..0000000
--- a/pkgs/test_api/test/frontend/matcher/throws_type_test.dart
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test/test.dart';
-
-import '../../utils.dart';
-
-void main() {
- group('[throwsArgumentError]', () {
- test('passes when a ArgumentError is thrown', () {
- expect(() => throw ArgumentError(''), throwsArgumentError);
- });
-
- test('fails when a non-ArgumentError is thrown', () async {
- var liveTest = await runTestBody(() {
- expect(() => throw Exception(), throwsArgumentError);
- });
-
- expectTestFailed(liveTest,
- startsWith("Expected: throws <Instance of 'ArgumentError'>"));
- });
- });
-
- group('[throwsConcurrentModificationError]', () {
- test('passes when a ConcurrentModificationError is thrown', () {
- expect(() => throw ConcurrentModificationError(''),
- throwsConcurrentModificationError);
- });
-
- test('fails when a non-ConcurrentModificationError is thrown', () async {
- var liveTest = await runTestBody(() {
- expect(() => throw Exception(), throwsConcurrentModificationError);
- });
-
- expectTestFailed(
- liveTest,
- startsWith(
- "Expected: throws <Instance of 'ConcurrentModificationError'>"));
- });
- });
-
- group('[throwsCyclicInitializationError]', () {
- test('passes when a CyclicInitializationError is thrown', () {
- expect(
- () => _CyclicInitializationFailure().x,
- // ignore: deprecated_member_use
- throwsCyclicInitializationError);
- });
-
- test('fails when a non-CyclicInitializationError is thrown', () async {
- var liveTest = await runTestBody(() {
- expect(() => throw Exception(), throwsCyclicInitializationError);
- });
-
- expectTestFailed(
- liveTest, startsWith("Expected: throws <Instance of 'Error'>"));
- });
- });
-
- group('[throwsException]', () {
- test('passes when a Exception is thrown', () {
- expect(() => throw Exception(''), throwsException);
- });
-
- test('fails when a non-Exception is thrown', () async {
- var liveTest = await runTestBody(() {
- expect(() => throw 'oh no', throwsException);
- });
-
- expectTestFailed(
- liveTest, startsWith("Expected: throws <Instance of 'Exception'>"));
- });
- });
-
- group('[throwsFormatException]', () {
- test('passes when a FormatException is thrown', () {
- expect(() => throw FormatException(''), throwsFormatException);
- });
-
- test('fails when a non-FormatException is thrown', () async {
- var liveTest = await runTestBody(() {
- expect(() => throw Exception(), throwsFormatException);
- });
-
- expectTestFailed(liveTest,
- startsWith("Expected: throws <Instance of 'FormatException'>"));
- });
- });
-
- group('[throwsNoSuchMethodError]', () {
- test('passes when a NoSuchMethodError is thrown', () {
- expect(() {
- (1 as dynamic).notAMethodOnInt();
- }, throwsNoSuchMethodError);
- });
-
- test('fails when a non-NoSuchMethodError is thrown', () async {
- var liveTest = await runTestBody(() {
- expect(() => throw Exception(), throwsNoSuchMethodError);
- });
-
- expectTestFailed(liveTest,
- startsWith("Expected: throws <Instance of 'NoSuchMethodError'>"));
- });
- });
-
- group('[throwsRangeError]', () {
- test('passes when a RangeError is thrown', () {
- expect(() => throw RangeError(''), throwsRangeError);
- });
-
- test('fails when a non-RangeError is thrown', () async {
- var liveTest = await runTestBody(() {
- expect(() => throw Exception(), throwsRangeError);
- });
-
- expectTestFailed(
- liveTest, startsWith("Expected: throws <Instance of 'RangeError'>"));
- });
- });
-
- group('[throwsStateError]', () {
- test('passes when a StateError is thrown', () {
- expect(() => throw StateError(''), throwsStateError);
- });
-
- test('fails when a non-StateError is thrown', () async {
- var liveTest = await runTestBody(() {
- expect(() => throw Exception(), throwsStateError);
- });
-
- expectTestFailed(
- liveTest, startsWith("Expected: throws <Instance of 'StateError'>"));
- });
- });
-
- group('[throwsUnimplementedError]', () {
- test('passes when a UnimplementedError is thrown', () {
- expect(() => throw UnimplementedError(''), throwsUnimplementedError);
- });
-
- test('fails when a non-UnimplementedError is thrown', () async {
- var liveTest = await runTestBody(() {
- expect(() => throw Exception(), throwsUnimplementedError);
- });
-
- expectTestFailed(liveTest,
- startsWith("Expected: throws <Instance of 'UnimplementedError'>"));
- });
- });
-
- group('[throwsUnsupportedError]', () {
- test('passes when a UnsupportedError is thrown', () {
- expect(() => throw UnsupportedError(''), throwsUnsupportedError);
- });
-
- test('fails when a non-UnsupportedError is thrown', () async {
- var liveTest = await runTestBody(() {
- expect(() => throw Exception(), throwsUnsupportedError);
- });
-
- expectTestFailed(liveTest,
- startsWith("Expected: throws <Instance of 'UnsupportedError'>"));
- });
- });
-}
-
-class _CyclicInitializationFailure {
- late int x = y;
- late int y = x;
-}
diff --git a/pkgs/test_api/test/frontend/never_called_test.dart b/pkgs/test_api/test/frontend/never_called_test.dart
deleted file mode 100644
index e9170f9..0000000
--- a/pkgs/test_api/test/frontend/never_called_test.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:term_glyph/term_glyph.dart' as glyph;
-import 'package:test/test.dart';
-
-import '../utils.dart';
-
-void main() {
- setUpAll(() {
- glyph.ascii = true;
- });
-
- test("doesn't throw if it isn't called", () async {
- var liveTest = await runTestBody(() {
- const Stream.empty().listen(neverCalled);
- });
-
- expectTestPassed(liveTest);
- });
-
- group("if it's called", () {
- test('throws', () async {
- var liveTest = await runTestBody(() {
- neverCalled();
- });
-
- expectTestFailed(
- liveTest,
- 'Callback should never have been called, but it was called with no '
- 'arguments.');
- });
-
- test('pretty-prints arguments', () async {
- var liveTest = await runTestBody(() {
- neverCalled(1, 'foo\nbar');
- });
-
- expectTestFailed(
- liveTest,
- 'Callback should never have been called, but it was called with:\n'
- '* <1>\n'
- "* 'foo\\n'\n"
- " 'bar'");
- });
-
- test('keeps the test alive', () async {
- var liveTest = await runTestBody(() {
- pumpEventQueue(times: 10).then(neverCalled);
- });
-
- expectTestFailed(
- liveTest,
- 'Callback should never have been called, but it was called with:\n'
- '* <null>');
- });
-
- test("can't be caught", () async {
- var liveTest = await runTestBody(() {
- try {
- neverCalled();
- } catch (_) {
- // Do nothing.
- }
- });
-
- expectTestFailed(
- liveTest,
- 'Callback should never have been called, but it was called with '
- 'no arguments.');
- });
- });
-}
diff --git a/pkgs/test_api/test/frontend/stream_matcher_test.dart b/pkgs/test_api/test/frontend/stream_matcher_test.dart
deleted file mode 100644
index deb21fb..0000000
--- a/pkgs/test_api/test/frontend/stream_matcher_test.dart
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:async/async.dart';
-import 'package:term_glyph/term_glyph.dart' as glyph;
-import 'package:test/test.dart';
-
-import '../utils.dart';
-
-void main() {
- setUpAll(() {
- glyph.ascii = true;
- });
-
- late Stream stream;
- late StreamQueue queue;
- late Stream errorStream;
- late StreamQueue errorQueue;
- setUp(() {
- stream = Stream.fromIterable([1, 2, 3, 4, 5]);
- queue = StreamQueue(Stream.fromIterable([1, 2, 3, 4, 5]));
- errorStream = Stream.fromFuture(Future.error('oh no!', StackTrace.current));
- errorQueue = StreamQueue(
- Stream.fromFuture(Future.error('oh no!', StackTrace.current)));
- });
-
- group('emits()', () {
- test('matches the first event of a Stream', () {
- expect(stream, emits(1));
- });
-
- test('rejects the first event of a Stream', () {
- expect(
- expectLater(stream, emits(2)),
- throwsTestFailure(allOf([
- startsWith('Expected: should emit an event that <2>\n'),
- endsWith(' Which: emitted * 1\n'
- ' * 2\n'
- ' * 3\n'
- ' * 4\n'
- ' * 5\n'
- ' x Stream closed.\n')
- ])));
- });
-
- test('matches and consumes the next event of a StreamQueue', () {
- expect(queue, emits(1));
- expect(queue.next, completion(equals(2)));
- expect(queue, emits(3));
- expect(queue.next, completion(equals(4)));
- });
-
- test('rejects and does not consume the first event of a StreamQueue', () {
- expect(
- expectLater(queue, emits(2)),
- throwsTestFailure(allOf([
- startsWith('Expected: should emit an event that <2>\n'),
- endsWith(' Which: emitted * 1\n'
- ' * 2\n'
- ' * 3\n'
- ' * 4\n'
- ' * 5\n'
- ' x Stream closed.\n')
- ])));
-
- expect(queue, emits(1));
- });
-
- test('rejects an empty stream', () {
- expect(
- expectLater(Stream.empty(), emits(1)),
- throwsTestFailure(allOf([
- startsWith('Expected: should emit an event that <1>\n'),
- endsWith(' Which: emitted x Stream closed.\n')
- ])));
- });
-
- test('forwards a stream error', () {
- expect(expectLater(errorStream, emits(1)), throwsA('oh no!'));
- });
-
- test('wraps a normal matcher', () {
- expect(queue, emits(lessThan(5)));
- expect(expectLater(queue, emits(greaterThan(5))),
- throwsTestFailure(anything));
- });
-
- test('returns a StreamMatcher as-is', () {
- expect(queue, emits(emitsThrough(4)));
- expect(queue, emits(5));
- });
- });
-
- group('emitsDone', () {
- test('succeeds for an empty stream', () {
- expect(Stream.empty(), emitsDone);
- });
-
- test('fails for a stream with events', () {
- expect(
- expectLater(stream, emitsDone),
- throwsTestFailure(allOf([
- startsWith('Expected: should be done\n'),
- endsWith(' Which: emitted * 1\n'
- ' * 2\n'
- ' * 3\n'
- ' * 4\n'
- ' * 5\n'
- ' x Stream closed.\n')
- ])));
- });
- });
-
- group('emitsError()', () {
- test('consumes a matching error', () {
- expect(errorQueue, emitsError('oh no!'));
- expect(errorQueue.hasNext, completion(isFalse));
- });
-
- test('fails for a non-matching error', () {
- expect(
- expectLater(errorStream, emitsError('oh heck')),
- throwsTestFailure(allOf([
- startsWith("Expected: should emit an error that 'oh heck'\n"),
- contains(' Which: emitted ! oh no!\n'),
- contains(' x Stream closed.\n'
- " which threw 'oh no!'\n"
- ' stack '),
- endsWith(' which is different.\n'
- ' Expected: oh heck\n'
- ' Actual: oh no!\n'
- ' ^\n'
- ' Differ at offset 3\n')
- ])));
- });
-
- test('fails for a stream with events', () {
- expect(
- expectLater(stream, emitsDone),
- throwsTestFailure(allOf([
- startsWith('Expected: should be done\n'),
- endsWith(' Which: emitted * 1\n'
- ' * 2\n'
- ' * 3\n'
- ' * 4\n'
- ' * 5\n'
- ' x Stream closed.\n')
- ])));
- });
- });
-
- group('mayEmit()', () {
- test('consumes a matching event', () {
- expect(queue, mayEmit(1));
- expect(queue, emits(2));
- });
-
- test('allows a non-matching event', () {
- expect(queue, mayEmit('fish'));
- expect(queue, emits(1));
- });
- });
-
- group('emitsAnyOf()', () {
- test('consumes an event that matches a matcher', () {
- expect(queue, emitsAnyOf([2, 1, 3]));
- expect(queue, emits(2));
- });
-
- test('consumes as many events as possible', () {
- expect(
- queue,
- emitsAnyOf([
- 1,
- emitsInOrder([1, 2]),
- emitsInOrder([1, 2, 3])
- ]));
-
- expect(queue, emits(4));
- });
-
- test('fails if no matchers match', () {
- expect(
- expectLater(stream, emitsAnyOf([2, 3, 4])),
- throwsTestFailure(allOf([
- startsWith('Expected: should do one of the following:\n'
- ' * emit an event that <2>\n'
- ' * emit an event that <3>\n'
- ' * emit an event that <4>\n'),
- endsWith(' Which: emitted * 1\n'
- ' * 2\n'
- ' * 3\n'
- ' * 4\n'
- ' * 5\n'
- ' x Stream closed.\n'
- ' which failed all options:\n'
- ' * failed to emit an event that <2>\n'
- ' * failed to emit an event that <3>\n'
- ' * failed to emit an event that <4>\n')
- ])));
- });
-
- test('allows an error if any matcher matches', () {
- expect(errorStream, emitsAnyOf([1, 2, emitsError('oh no!')]));
- });
-
- test('rethrows an error if no matcher matches', () {
- expect(
- expectLater(errorStream, emitsAnyOf([1, 2, 3])), throwsA('oh no!'));
- });
- });
-
- group('emitsInOrder()', () {
- test('consumes matching events', () {
- expect(queue, emitsInOrder([1, 2, emitsThrough(4)]));
- expect(queue, emits(5));
- });
-
- test("fails if the matchers don't match in order", () {
- expect(
- expectLater(queue, emitsInOrder([1, 3, 2])),
- throwsTestFailure(allOf([
- startsWith('Expected: should do the following in order:\n'
- ' * emit an event that <1>\n'
- ' * emit an event that <3>\n'
- ' * emit an event that <2>\n'),
- endsWith(' Which: emitted * 1\n'
- ' * 2\n'
- ' * 3\n'
- ' * 4\n'
- ' * 5\n'
- ' x Stream closed.\n'
- " which didn't emit an event that <3>\n")
- ])));
- });
- });
-
- group('emitsThrough()', () {
- test('consumes events including those matching the matcher', () {
- expect(queue, emitsThrough(emitsInOrder([3, 4])));
- expect(queue, emits(5));
- });
-
- test('consumes the entire queue with emitsDone', () {
- expect(queue, emitsThrough(emitsDone));
- expect(queue.hasNext, completion(isFalse));
- });
-
- test('fails if the queue never matches the matcher', () {
- expect(
- expectLater(queue, emitsThrough(6)),
- throwsTestFailure(allOf([
- startsWith('Expected: should eventually emit an event that <6>\n'),
- endsWith(' Which: emitted * 1\n'
- ' * 2\n'
- ' * 3\n'
- ' * 4\n'
- ' * 5\n'
- ' x Stream closed.\n'
- ' which never did emit an event that <6>\n')
- ])));
- });
- });
-
- group('mayEmitMultiple()', () {
- test('consumes multiple instances of the given matcher', () {
- expect(queue, mayEmitMultiple(lessThan(3)));
- expect(queue, emits(3));
- });
-
- test('consumes zero instances of the given matcher', () {
- expect(queue, mayEmitMultiple(6));
- expect(queue, emits(1));
- });
-
- test("doesn't rethrow errors", () {
- expect(errorQueue, mayEmitMultiple(1));
- expect(errorQueue, emitsError('oh no!'));
- });
- });
-
- group('neverEmits()', () {
- test('succeeds if the event never matches', () {
- expect(queue, neverEmits(6));
- expect(queue, emits(1));
- });
-
- test('fails if the event matches', () {
- expect(
- expectLater(stream, neverEmits(4)),
- throwsTestFailure(allOf([
- startsWith('Expected: should never emit an event that <4>\n'),
- endsWith(' Which: emitted * 1\n'
- ' * 2\n'
- ' * 3\n'
- ' * 4\n'
- ' * 5\n'
- ' x Stream closed.\n'
- ' which after 3 events did emit an event that <4>\n')
- ])));
- });
-
- test('fails if emitsDone matches', () {
- expect(expectLater(stream, neverEmits(emitsDone)),
- throwsTestFailure(anything));
- });
-
- test("doesn't rethrow errors", () {
- expect(errorQueue, neverEmits(6));
- expect(errorQueue, emitsError('oh no!'));
- });
- });
-
- group('emitsInAnyOrder()', () {
- test('consumes events that match in any order', () {
- expect(queue, emitsInAnyOrder([3, 1, 2]));
- expect(queue, emits(4));
- });
-
- test("fails if the events don't match in any order", () {
- expect(
- expectLater(stream, emitsInAnyOrder([4, 1, 2])),
- throwsTestFailure(allOf([
- startsWith('Expected: should do the following in any order:\n'
- ' * emit an event that <4>\n'
- ' * emit an event that <1>\n'
- ' * emit an event that <2>\n'),
- endsWith(' Which: emitted * 1\n'
- ' * 2\n'
- ' * 3\n'
- ' * 4\n'
- ' * 5\n'
- ' x Stream closed.\n')
- ])));
- });
-
- test("doesn't rethrow if some ordering matches", () {
- expect(errorQueue, emitsInAnyOrder([emitsDone, emitsError('oh no!')]));
- });
-
- test('rethrows if no ordering matches', () {
- expect(
- expectLater(errorQueue, emitsInAnyOrder([1, emitsError('oh no!')])),
- throwsA('oh no!'));
- });
- });
-
- test('A custom StreamController doesn\'t hang on close', () async {
- var controller = StreamController<void>();
- var done = expectLater(controller.stream, emits(null));
- controller.add(null);
- await done;
- await controller.close();
- });
-}
diff --git a/pkgs/test_api/test/import_restrictions_test.dart b/pkgs/test_api/test/import_restrictions_test.dart
index f07c4c6..d155145 100644
--- a/pkgs/test_api/test/import_restrictions_test.dart
+++ b/pkgs/test_api/test/import_restrictions_test.dart
@@ -26,8 +26,8 @@
test('must not import from other subdirectories', () async {
final entryPoints = [
_testApiLibrary('backend.dart'),
- ...(await _ImportCheck.findEntrypointsUnder(
- _testApiLibrary('src/backend')))
+ ...await _ImportCheck.findEntrypointsUnder(
+ _testApiLibrary('src/backend'))
];
await for (final source
in importCheck.transitiveSamePackageSources(entryPoints)) {
@@ -38,39 +38,6 @@
}
});
});
-
- group('expect', () {
- test('must not be imported from any other library', () async {
- final entryPoints = [
- _testApiLibrary('hooks.dart'),
- _testApiLibrary('scaffolding.dart'),
- _testApiLibrary('fake.dart')
- ];
- await for (final source
- in importCheck.transitiveSamePackageSources(entryPoints)) {
- for (final import in source.imports) {
- expect(import.path, isNot(contains('test_api.dart')),
- reason: 'Invalid import from ${source.uri} : $import.');
- expect(import.path, isNot(contains('expect')),
- reason: 'Invalid import from ${source.uri} : $import.');
- }
- }
- });
-
- test('may only import hooks', () async {
- final entryPoint = _testApiLibrary('expect.dart');
- await for (final source
- in importCheck.transitiveSamePackageSources([entryPoint])) {
- // Transitive imports through `hooks.dart` don't follow this restriction
- if (!source.uri.path.contains('expect')) continue;
- for (final import in source.imports) {
- expect(import.path,
- anyOf(['test_api/hooks.dart', startsWith('test_api/src/expect')]),
- reason: 'Invalid import from ${source.uri} : $import');
- }
- }
- });
- });
}
Uri _testApiLibrary(String path) => Uri.parse('package:test_api/$path');
diff --git a/pkgs/test_api/test/utils.dart b/pkgs/test_api/test/utils.dart
index 65dd5c5..c1fb2e3 100644
--- a/pkgs/test_api/test/utils.dart
+++ b/pkgs/test_api/test/utils.dart
@@ -6,14 +6,10 @@
import 'package:test/test.dart';
import 'package:test_api/src/backend/declarer.dart';
-import 'package:test_api/src/backend/group.dart';
import 'package:test_api/src/backend/group_entry.dart';
-import 'package:test_api/src/backend/invoker.dart';
import 'package:test_api/src/backend/live_test.dart';
-import 'package:test_api/src/backend/metadata.dart';
import 'package:test_api/src/backend/runtime.dart';
import 'package:test_api/src/backend/state.dart';
-import 'package:test_api/src/backend/suite.dart';
import 'package:test_api/src/backend/suite_platform.dart';
import 'package:test_core/src/runner/engine.dart';
import 'package:test_core/src/runner/plugin/environment.dart';
@@ -21,7 +17,8 @@
import 'package:test_core/src/runner/suite.dart';
/// A dummy suite platform to use for testing suites.
-final suitePlatform = SuitePlatform(Runtime.vm);
+final suitePlatform =
+ SuitePlatform(Runtime.vm, compiler: Runtime.vm.defaultCompiler);
// The last state change detected via [expectStates].
State? lastState;
@@ -76,34 +73,12 @@
]);
}
-/// Returns a matcher that matches a callback or Future that throws a
-/// [TestFailure] with the given [message].
-///
-/// [message] can be a string or a [Matcher].
-Matcher throwsTestFailure(message) => throwsA(isTestFailure(message));
-
/// Returns a matcher that matches a [TestFailure] with the given [message].
///
/// [message] can be a string or a [Matcher].
-Matcher isTestFailure(message) => const TypeMatcher<TestFailure>()
+Matcher isTestFailure(Object message) => const TypeMatcher<TestFailure>()
.having((e) => e.message, 'message', message);
-/// Returns a local [LiveTest] that runs [body].
-LiveTest createTest(dynamic Function() body) {
- var test = LocalTest('test', Metadata(chainStackTraces: true), body);
- var suite = Suite(Group.root([test]), suitePlatform, ignoreTimeouts: false);
- return test.load(suite);
-}
-
-/// Runs [body] as a test.
-///
-/// Once it completes, returns the [LiveTest] used to run it.
-Future<LiveTest> runTestBody(dynamic Function() body) async {
- var liveTest = createTest(body);
- await liveTest.run();
- return liveTest;
-}
-
/// Asserts that [liveTest] has completed and passed.
///
/// If the test had any errors, they're surfaced nicely into the outer test.
@@ -123,36 +98,13 @@
/// Asserts that [liveTest] failed with a single [TestFailure] whose message
/// matches [message].
-void expectTestFailed(LiveTest liveTest, message) {
+void expectTestFailed(LiveTest liveTest, Object message) {
expect(liveTest.state.status, equals(Status.complete));
expect(liveTest.state.result, equals(Result.failure));
expect(liveTest.errors, hasLength(1));
expect(liveTest.errors.first.error, isTestFailure(message));
}
-/// Assert that the [test] callback causes a test to block until [stopBlocking]
-/// is called at some later time.
-///
-/// [stopBlocking] is passed the return value of [test].
-Future expectTestBlocks(
- dynamic Function() test, dynamic Function(dynamic) stopBlocking) async {
- late LiveTest liveTest;
- late Future future;
- liveTest = createTest(() {
- var value = test();
- future = pumpEventQueue().then((_) {
- expect(liveTest.state.status, equals(Status.running));
- stopBlocking(value);
- });
- });
-
- await liveTest.run();
- expectTestPassed(liveTest);
- // Ensure that the outer test doesn't complete until the inner future
- // completes.
- return future;
-}
-
/// Runs [body] with a declarer, runs all the declared tests, and asserts that
/// they pass.
///
diff --git a/pkgs/test_core/CHANGELOG.md b/pkgs/test_core/CHANGELOG.md
index 3cfc241..2a0b55f 100644
--- a/pkgs/test_core/CHANGELOG.md
+++ b/pkgs/test_core/CHANGELOG.md
@@ -1,15 +1,86 @@
-# 0.4.23-dev
+## 0.5.7-wip
+
+## 0.5.6
+
+* Add support for discontinuing after the first failing test with `--fail-fast`.
+
+## 0.5.5
+
+* Change "compiling <path>" to "loading <path>" message in all cases. Surface
+ the "loading" messages in the situations where previously only "compiling"
+ message would be used.
+
+## 0.5.4
+
+* Drop support for null unsafe Dart, bump SDK constraint to `3.0.0`.
+* Add `final` modifier on some implementation classes: `Configuration`,
+ `CustomRuntime`,`RuntimeSettings`, `SuiteConfiguration`.
+* Fix the `root_` fields in the JSON reporter when running a test on Windows
+ with an absolute path.
+* Allow the latest analyzer (6.x.x).
+
+## 0.5.3
+
+* Fix compatibility with wasm number semantics.
+
+## 0.5.2
+
+* Use the version `0.5.2` of `packge:test_api`.
+
+## 0.5.1
+
+* Start adding experimental support for native_assets.yaml, when
+ `--enable-experiment=native_assets` is passed.
+
+## 0.5.0
+
+* Support the `--compiler` flag, which can be used to configure which compiler
+ to use.
+ * To specify a compiler by platform, the argument supports platform selectors
+ through this syntax `[<platform>:]<compiler>`. For example the command line
+ argument `--compiler vm:source` would run all vm tests from source instead
+ of compiling to kernel first.
+ * If no given compiler is compatible for a platform, it will use its default
+ compiler instead.
+* Add support for `-c exe` (the native executable compiler) to the vm platform.
+* Add `Compiler` class, exposed through `backend.dart`.
+* Support compiler identifiers in platform selectors.
+* List the supported compilers for each platform in the usage text.
+* Update all reporters to print the compiler along with the platform name
+ when configured to print the platform. Extend the logic for printing platofrm
+ information to do so if any compilers are explicitly configured.
+* Deprecate `--use-data-isolate-strategy`. It is now an alias for `-c vm:source`
+ which is roughly equivalent. If this is breaking for you please file an issue.
+* **BREAKING** Add required `defaultCompiler` and `supportedCompilers` fields
+ to `Runtime`.
+* **BREAKING** Add required `compiler` field to `SuitePlatform`.
+* **BREAKING** Add required `compilerSelections` argument to some
+ `Configuration` and `SuiteConfiguration` constructors.
+* **BREAKING** Custom platform plugins need to respect the compiler option
+ given through the `SuitePlatform` argument to `PlatformPlugin.load`. This is
+ not statically breaking but it will be confusing for users if it isn't
+ supported.
+* **BREAKING** Remove `useDataIsolateStrategy` field from `Configuration`.
+* **BREAKING** Stop exporting APIs from `package:matcher/expect.dart`.
+
+## 0.4.24
+
+* Fix running paths by absolute path (with drive letter) on windows.
+
+## 0.4.23
* Avoid empty expandable groups for tests without extra output in Github
reporter.
+* Support running tests by absolute file uri.
+* Update `vm_service` constraint to `>=6.0.0 <12.0.0`.
-# 0.4.22
+## 0.4.22
* Don't run `tearDown` until the test body and outstanding work is complete,
even if the test has already failed.
* Update `vm_service` constraint to `>=6.0.0 <11.0.0`.
-# 0.4.21
+## 0.4.21
* Move `includeTags` and `excludeTags` from `SuiteConfiguration` to
`Configuration`.
@@ -18,24 +89,24 @@
* Fix VM tests which run after some test has changed the working directory.
There are still issues with browser tests after changing directory.
-# 0.4.20
+## 0.4.20
* Fix an issue with the github reporter where tests that fail asynchronously
after they've completed would show up as succeeded tests.
* Support the latest `package:test_api`.
* Refactor `CompilerPool` to be abstract, add wasm compiler pool.
-# 0.4.19
+## 0.4.19
* Support `package:matcher` version `0.12.13`.
* Require Dart SDK version 2.18.
-# 0.4.18
+## 0.4.18
* Support the latest `package:test_api`.
* Support the latest `package:analyzer`.
-# 0.4.17
+## 0.4.17
* Support the latest `package:test_api`.
* Support the latest `package:frontend_server_client`.
diff --git a/pkgs/test_core/README.md b/pkgs/test_core/README.md
index 46d64fd..67f21a8 100644
--- a/pkgs/test_core/README.md
+++ b/pkgs/test_core/README.md
@@ -1,3 +1,6 @@
+[![pub package](https://img.shields.io/pub/v/test_core.svg)](https://pub.dev/packages/test_core)
+[![package publisher](https://img.shields.io/pub/publisher/test_core.svg)](https://pub.dev/packages/test_core/publisher)
+
A minimal package for writing and running tests as well as extensions for
implementing a custom test runner.
diff --git a/pkgs/test_core/lib/backend.dart b/pkgs/test_core/lib/backend.dart
index 3a1506b..69f6552 100644
--- a/pkgs/test_core/lib/backend.dart
+++ b/pkgs/test_core/lib/backend.dart
@@ -6,9 +6,8 @@
'Please use package:test.')
library test_core.backend;
-//ignore: deprecated_member_use
export 'package:test_api/backend.dart'
- show Metadata, PlatformSelector, Runtime, SuitePlatform;
+ show Compiler, Metadata, PlatformSelector, Runtime, SuitePlatform;
export 'src/runner/configuration.dart' show Configuration;
export 'src/runner/configuration/custom_runtime.dart' show CustomRuntime;
diff --git a/pkgs/test_core/lib/scaffolding.dart b/pkgs/test_core/lib/scaffolding.dart
index 40e6d56..b6719fe 100644
--- a/pkgs/test_core/lib/scaffolding.dart
+++ b/pkgs/test_core/lib/scaffolding.dart
@@ -10,7 +10,7 @@
import 'package:meta/meta.dart' show isTest, isTestGroup;
import 'package:path/path.dart' as p;
-import 'package:test_api/backend.dart'; //ignore: deprecated_member_use
+import 'package:test_api/backend.dart';
import 'package:test_api/scaffolding.dart' show Timeout, pumpEventQueue;
import 'package:test_api/src/backend/declarer.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/invoker.dart'; // ignore: implementation_imports
@@ -28,7 +28,7 @@
// This file is an almost direct copy of import below, but with the global
// declarer added.
export 'package:test_api/scaffolding.dart'
- hide test, group, setUp, setUpAll, tearDown, tearDownAll;
+ hide group, setUp, setUpAll, tearDown, tearDownAll, test;
/// The global declarer.
///
@@ -54,8 +54,11 @@
() async {
await pumpEventQueue();
- var suite = RunnerSuite(const PluginEnvironment(), SuiteConfiguration.empty,
- _globalDeclarer!.build(), SuitePlatform(Runtime.vm, os: currentOSGuess),
+ var suite = RunnerSuite(
+ const PluginEnvironment(),
+ SuiteConfiguration.empty,
+ _globalDeclarer!.build(),
+ SuitePlatform(Runtime.vm, compiler: null, os: currentOSGuess),
path: p.prettyUri(Uri.base));
var engine = Engine();
@@ -130,11 +133,11 @@
/// avoid this flag if possible and instead use the test runner flag `-n` to
/// filter tests by name.
@isTest
-void test(description, dynamic Function() body,
+void test(Object? description, dynamic Function() body,
{String? testOn,
Timeout? timeout,
- skip,
- tags,
+ Object? skip,
+ Object? tags,
Map<String, dynamic>? onPlatform,
int? retry,
@Deprecated('Debug only') bool solo = false}) {
@@ -208,11 +211,11 @@
/// avoid this flag if possible, and instead use the test runner flag `-n` to
/// filter tests by name.
@isTestGroup
-void group(description, dynamic Function() body,
+void group(Object? description, dynamic Function() body,
{String? testOn,
Timeout? timeout,
- skip,
- tags,
+ Object? skip,
+ Object? tags,
Map<String, dynamic>? onPlatform,
int? retry,
@Deprecated('Debug only') bool solo = false}) {
diff --git a/pkgs/test_core/lib/src/bootstrap/vm.dart b/pkgs/test_core/lib/src/bootstrap/vm.dart
index d1eb59a..2166e7d 100644
--- a/pkgs/test_core/lib/src/bootstrap/vm.dart
+++ b/pkgs/test_core/lib/src/bootstrap/vm.dart
@@ -3,14 +3,16 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:developer';
+import 'dart:io';
import 'dart:isolate';
import 'package:stream_channel/isolate_channel.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:test_core/src/runner/plugin/remote_platform_helpers.dart';
+import 'package:test_core/src/runner/plugin/shared_platform_helpers.dart';
-/// Bootstraps a vm test to communicate with the test runner.
+/// Bootstraps a vm test to communicate with the test runner over an isolate.
void internalBootstrapVmTest(Function Function() getMain, SendPort sendPort) {
var platformChannel =
MultiChannel(IsolateChannel<Object?>.connectSend(sendPort));
@@ -24,3 +26,24 @@
platformChannel.sink.add('done');
});
}
+
+/// Bootstraps a native executable test to communicate with the test runner over
+/// a socket.
+void internalBootstrapNativeTest(
+ Function Function() getMain, List<String> args) async {
+ if (args.length != 2) {
+ throw StateError(
+ 'Expected exactly two args, a host and a port, but got $args');
+ }
+ var socket = await Socket.connect(args[0], int.parse(args[1]));
+ var platformChannel = MultiChannel<Object?>(jsonSocketStreamChannel(socket));
+ var testControlChannel = platformChannel.virtualChannel()
+ ..pipe(serializeSuite(getMain));
+ platformChannel.sink.add(testControlChannel.id);
+
+ platformChannel.stream.forEach((message) {
+ assert(message == 'debug');
+ debugger(message: 'Paused by test runner');
+ platformChannel.sink.add('done');
+ });
+}
diff --git a/pkgs/test_core/lib/src/direct_run.dart b/pkgs/test_core/lib/src/direct_run.dart
index f2b4e76..c574257 100644
--- a/pkgs/test_core/lib/src/direct_run.dart
+++ b/pkgs/test_core/lib/src/direct_run.dart
@@ -6,7 +6,7 @@
import 'dart:collection';
import 'package:path/path.dart' as p;
-import 'package:test_api/backend.dart'; //ignore: deprecated_member_use
+import 'package:test_api/backend.dart';
import 'package:test_api/src/backend/declarer.dart'; //ignore: implementation_imports
import 'package:test_api/src/backend/group.dart'; //ignore: implementation_imports
import 'package:test_api/src/backend/group_entry.dart'; //ignore: implementation_imports
@@ -68,8 +68,11 @@
allowDuplicateTestNames: allowDuplicateTestNames);
await declarer.declare(testMain);
- final suite = RunnerSuite(const PluginEnvironment(), SuiteConfiguration.empty,
- declarer.build(), SuitePlatform(Runtime.vm, os: currentOSGuess),
+ final suite = RunnerSuite(
+ const PluginEnvironment(),
+ SuiteConfiguration.empty,
+ declarer.build(),
+ SuitePlatform(Runtime.vm, compiler: null, os: currentOSGuess),
path: p.prettyUri(Uri.base));
final engine = Engine()
diff --git a/pkgs/test_core/lib/src/executable.dart b/pkgs/test_core/lib/src/executable.dart
index 0c7530b..7b7978c 100644
--- a/pkgs/test_core/lib/src/executable.dart
+++ b/pkgs/test_core/lib/src/executable.dart
@@ -39,6 +39,7 @@
completeShutdown();
}
+// ignore: unreachable_from_main
Future<void> runTests(List<String> args) async {
await _execute(args);
}
diff --git a/pkgs/test_core/lib/src/platform.dart b/pkgs/test_core/lib/src/platform.dart
index f1fc22b..af457b4 100644
--- a/pkgs/test_core/lib/src/platform.dart
+++ b/pkgs/test_core/lib/src/platform.dart
@@ -2,11 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// ignore: deprecated_member_use
-export 'package:test_api/backend.dart' show SuitePlatform, Runtime;
+export 'package:test_api/backend.dart' show Runtime, SuitePlatform;
export 'package:test_core/src/runner/configuration.dart' show Configuration;
export 'package:test_core/src/runner/environment.dart'
- show PluginEnvironment, Environment;
+ show Environment, PluginEnvironment;
export 'package:test_core/src/runner/hack_register_platform.dart'
show registerPlatformPlugin;
export 'package:test_core/src/runner/platform.dart' show PlatformPlugin;
diff --git a/pkgs/test_core/lib/src/runner.dart b/pkgs/test_core/lib/src/runner.dart
index ae7d6ee..c458b5d 100644
--- a/pkgs/test_core/lib/src/runner.dart
+++ b/pkgs/test_core/lib/src/runner.dart
@@ -7,9 +7,7 @@
import 'package:async/async.dart';
import 'package:boolean_selector/boolean_selector.dart';
-import 'package:path/path.dart' as p;
import 'package:stack_trace/stack_trace.dart';
-// ignore: deprecated_member_use
import 'package:test_api/backend.dart'
show PlatformSelector, Runtime, SuitePlatform;
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
@@ -77,9 +75,11 @@
/// Creates a new runner based on [configuration].
factory Runner(Configuration config) => config.asCurrent(() {
var engine = Engine(
- concurrency: config.concurrency,
- coverage: config.coverage,
- testRandomizeOrderingSeed: config.testRandomizeOrderingSeed);
+ concurrency: config.concurrency,
+ coverage: config.coverage,
+ testRandomizeOrderingSeed: config.testRandomizeOrderingSeed,
+ stopOnFirstFailure: config.stopOnFirstFailure,
+ );
var sinks = <IOSink>[];
Reporter createFileReporter(String reporterName, String filepath) {
@@ -169,14 +169,15 @@
var unsupportedRuntimes = _config.suiteDefaults.runtimes
.map(_loader.findRuntime)
.whereType<Runtime>()
- .where((runtime) => !testOn.evaluate(currentPlatform(runtime)))
+ .where((runtime) => !testOn.evaluate(currentPlatform(runtime, null)))
.toList();
+
if (unsupportedRuntimes.isEmpty) return;
// Human-readable names for all unsupported runtimes.
var unsupportedNames = [];
- // If the user tried to run on one or moe unsupported browsers, figure out
+ // If the user tried to run on one or more unsupported browsers, figure out
// whether we should warn about the individual browsers or whether all
// browsers are unsupported.
var unsupportedBrowsers =
@@ -184,7 +185,7 @@
if (unsupportedBrowsers.isNotEmpty) {
var supportsAnyBrowser = _loader.allRuntimes
.where((runtime) => runtime.isBrowser)
- .any((runtime) => testOn.evaluate(currentPlatform(runtime)));
+ .any((runtime) => testOn.evaluate(currentPlatform(runtime, null)));
if (supportsAnyBrowser) {
unsupportedNames
@@ -197,8 +198,9 @@
// If the user tried to run on the VM and it's not supported, figure out if
// that's because of the current OS or whether the VM is unsupported.
if (unsupportedRuntimes.contains(Runtime.vm)) {
- var supportsAnyOS = OperatingSystem.all.any((os) => testOn
- .evaluate(SuitePlatform(Runtime.vm, os: os, inGoogle: inGoogle)));
+ var supportsAnyOS = OperatingSystem.all.any((os) => testOn.evaluate(
+ SuitePlatform(Runtime.vm,
+ compiler: null, os: os, inGoogle: inGoogle)));
if (supportsAnyOS) {
unsupportedNames.add(currentOS.name);
@@ -317,7 +319,8 @@
'Cannot filter by line/column for this test suite, no suite'
'path available.');
}
- var absoluteSuitePath = p.absolute(path);
+ // The absolute path as it will appear in stack traces.
+ var absoluteSuitePath = File(path).absolute.uri.toFilePath();
bool matchLineAndCol(Frame frame) {
if (frame.uri.scheme != 'file' ||
diff --git a/pkgs/test_core/lib/src/runner/compiler_selection.dart b/pkgs/test_core/lib/src/runner/compiler_selection.dart
new file mode 100644
index 0000000..70ab553
--- /dev/null
+++ b/pkgs/test_core/lib/src/runner/compiler_selection.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:source_span/source_span.dart';
+import 'package:test_api/backend.dart';
+
+/// A compiler with which the user has chosen to run tests.
+class CompilerSelection {
+ /// The chosen compiler to use.
+ final Compiler compiler;
+
+ /// The location in the configuration file of this compiler string, or `null`
+ /// if it was defined outside a configuration file (for example, on the
+ /// command line).
+ final SourceSpan? span;
+
+ /// The platform selector for which platforms this compiler should apply to,
+ /// if specified. Defaults to all platforms where the compiler is supported.
+ final PlatformSelector? platformSelector;
+
+ CompilerSelection(String compiler,
+ {required this.platformSelector, required this.span})
+ : compiler = Compiler.builtIn.firstWhere((c) => c.identifier == compiler);
+
+ factory CompilerSelection.parse(String option, {SourceSpan? parentSpan}) {
+ var parts = option.split(':');
+ switch (parts.length) {
+ case 1:
+ _checkValidCompiler(option, parentSpan);
+ return CompilerSelection(option,
+ platformSelector: null, span: parentSpan);
+ case 2:
+ var compiler = parts[1];
+ _checkValidCompiler(compiler, parentSpan);
+ return CompilerSelection(compiler,
+ platformSelector: PlatformSelector.parse(parts[0]),
+ span: parentSpan);
+ default:
+ throw ArgumentError.value(
+ option,
+ '--compiler',
+ 'Must be of the format [<boolean-selector>:]<compiler>, but got '
+ 'more than one `:`.');
+ }
+ }
+
+ @override
+ bool operator ==(Object other) =>
+ other is CompilerSelection && other.compiler == compiler;
+
+ @override
+ int get hashCode => compiler.hashCode;
+}
+
+void _checkValidCompiler(String compiler, SourceSpan? span) {
+ if (Compiler.builtIn.any((c) => c.identifier == compiler)) return;
+ throw SourceSpanFormatException(
+ 'Invalid compiler `$compiler`, must be one of ${Compiler.builtIn.map((c) => c.identifier).join(', ')}',
+ span);
+}
diff --git a/pkgs/test_core/lib/src/runner/configuration.dart b/pkgs/test_core/lib/src/runner/configuration.dart
index 008f989..12d3aa6 100644
--- a/pkgs/test_core/lib/src/runner/configuration.dart
+++ b/pkgs/test_core/lib/src/runner/configuration.dart
@@ -10,13 +10,12 @@
import 'package:glob/glob.dart';
import 'package:path/path.dart' as p;
import 'package:source_span/source_span.dart';
-import 'package:test_api/scaffolding.dart' // ignore: deprecated_member_use
- show
- Timeout;
+import 'package:test_api/scaffolding.dart' show Timeout;
import 'package:test_api/src/backend/platform_selector.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import '../util/io.dart';
+import 'compiler_selection.dart';
import 'configuration/args.dart' as args;
import 'configuration/custom_runtime.dart';
import 'configuration/load.dart';
@@ -190,14 +189,6 @@
});
Set<String>? _knownPresets;
- /// Whether to use the original `data:` URI isolate spawning strategy for VM
- /// tests.
- ///
- /// This can make more sense than the default strategy in systems such as
- /// `bazel` where only a single test suite is ran at a time.
- bool get useDataIsolateStrategy => _useDataIsolateStrategy ?? false;
- final bool? _useDataIsolateStrategy;
-
/// Built-in runtimes whose settings are overridden by the user.
final Map<String, RuntimeSettings> overrideRuntimes;
@@ -216,6 +207,11 @@
/// The same seed will shuffle the tests in the same way every time.
final int? testRandomizeOrderingSeed;
+ final bool? _stopOnFirstFailure;
+
+ /// Whether to stop running subsequent tests after a test fails.
+ bool get stopOnFirstFailure => _stopOnFirstFailure ?? false;
+
/// Returns the current configuration, or a default configuration if no
/// current configuration is set.
///
@@ -278,8 +274,8 @@
required Map<String, RuntimeSettings>? overrideRuntimes,
required Map<String, CustomRuntime>? defineRuntimes,
required bool? noRetry,
- required bool? useDataIsolateStrategy,
required int? testRandomizeOrderingSeed,
+ required bool? stopOnFirstFailure,
// Suite-level configuration
required bool? allowDuplicateTestNames,
@@ -289,6 +285,7 @@
required Iterable<String>? dart2jsArgs,
required String? precompiledPath,
required Iterable<Pattern>? globalPatterns,
+ required Iterable<CompilerSelection>? compilerSelections,
required Iterable<RuntimeSelection>? runtimes,
required BooleanSelector? includeTags,
required BooleanSelector? excludeTags,
@@ -330,8 +327,8 @@
overrideRuntimes: overrideRuntimes,
defineRuntimes: defineRuntimes,
noRetry: noRetry,
- useDataIsolateStrategy: useDataIsolateStrategy,
testRandomizeOrderingSeed: testRandomizeOrderingSeed,
+ stopOnFirstFailure: stopOnFirstFailure,
includeTags: includeTags,
excludeTags: excludeTags,
globalPatterns: globalPatterns,
@@ -342,6 +339,7 @@
runSkipped: runSkipped,
dart2jsArgs: dart2jsArgs,
precompiledPath: precompiledPath,
+ compilerSelections: compilerSelections,
runtimes: runtimes,
tags: tags,
onPlatform: onPlatform,
@@ -387,8 +385,8 @@
Map<String, RuntimeSettings>? overrideRuntimes,
Map<String, CustomRuntime>? defineRuntimes,
bool? noRetry,
- bool? useDataIsolateStrategy,
int? testRandomizeOrderingSeed,
+ bool? stopOnFirstFailure,
// Suite-level configuration
bool? allowDuplicateTestNames,
@@ -398,6 +396,7 @@
Iterable<String>? dart2jsArgs,
String? precompiledPath,
Iterable<Pattern>? globalPatterns,
+ Iterable<CompilerSelection>? compilerSelections,
Iterable<RuntimeSelection>? runtimes,
BooleanSelector? includeTags,
BooleanSelector? excludeTags,
@@ -438,8 +437,8 @@
overrideRuntimes: overrideRuntimes,
defineRuntimes: defineRuntimes,
noRetry: noRetry,
- useDataIsolateStrategy: useDataIsolateStrategy,
testRandomizeOrderingSeed: testRandomizeOrderingSeed,
+ stopOnFirstFailure: stopOnFirstFailure,
allowDuplicateTestNames: allowDuplicateTestNames,
allowTestRandomization: allowTestRandomization,
jsTrace: jsTrace,
@@ -447,6 +446,7 @@
dart2jsArgs: dart2jsArgs,
precompiledPath: precompiledPath,
globalPatterns: globalPatterns,
+ compilerSelections: compilerSelections,
runtimes: runtimes,
includeTags: includeTags,
excludeTags: excludeTags,
@@ -504,8 +504,8 @@
overrideRuntimes: null,
defineRuntimes: null,
noRetry: null,
- useDataIsolateStrategy: null,
testRandomizeOrderingSeed: null,
+ stopOnFirstFailure: null,
ignoreTimeouts: null,
allowDuplicateTestNames: null,
allowTestRandomization: null,
@@ -513,6 +513,7 @@
dart2jsArgs: null,
precompiledPath: null,
globalPatterns: null,
+ compilerSelections: null,
runtimes: null,
includeTags: null,
excludeTags: null,
@@ -571,13 +572,14 @@
overrideRuntimes: null,
defineRuntimes: null,
noRetry: null,
- useDataIsolateStrategy: null,
testRandomizeOrderingSeed: null,
+ stopOnFirstFailure: null,
jsTrace: null,
runSkipped: null,
dart2jsArgs: null,
precompiledPath: null,
globalPatterns: null,
+ compilerSelections: null,
runtimes: null,
includeTags: null,
excludeTags: null,
@@ -604,6 +606,7 @@
required String? reporter,
required Map<String, String>? fileReporters,
required int? concurrency,
+ required Iterable<CompilerSelection>? compilerSelections,
required Iterable<RuntimeSelection>? runtimes,
required Iterable<String>? chosenPresets,
required Map<String, RuntimeSettings>? overrideRuntimes}) =>
@@ -614,6 +617,7 @@
reporter: reporter,
fileReporters: fileReporters,
concurrency: concurrency,
+ compilerSelections: compilerSelections,
runtimes: runtimes,
chosenPresets: chosenPresets,
overrideRuntimes: overrideRuntimes,
@@ -633,8 +637,8 @@
presets: null,
defineRuntimes: null,
noRetry: null,
- useDataIsolateStrategy: null,
testRandomizeOrderingSeed: null,
+ stopOnFirstFailure: null,
allowDuplicateTestNames: null,
allowTestRandomization: null,
jsTrace: null,
@@ -696,14 +700,15 @@
presets: null,
overrideRuntimes: null,
noRetry: null,
- useDataIsolateStrategy: null,
testRandomizeOrderingSeed: null,
+ stopOnFirstFailure: null,
allowDuplicateTestNames: null,
allowTestRandomization: null,
jsTrace: null,
runSkipped: null,
dart2jsArgs: null,
precompiledPath: null,
+ compilerSelections: null,
runtimes: null,
tags: null,
onPlatform: null,
@@ -761,8 +766,8 @@
required Map<String, RuntimeSettings>? overrideRuntimes,
required Map<String, CustomRuntime>? defineRuntimes,
required bool? noRetry,
- required bool? useDataIsolateStrategy,
required this.testRandomizeOrderingSeed,
+ required bool? stopOnFirstFailure,
required BooleanSelector? includeTags,
required BooleanSelector? excludeTags,
required Iterable<Pattern>? globalPatterns,
@@ -790,12 +795,12 @@
overrideRuntimes = _map(overrideRuntimes),
defineRuntimes = _map(defineRuntimes),
_noRetry = noRetry,
- _useDataIsolateStrategy = useDataIsolateStrategy,
includeTags = includeTags ?? BooleanSelector.all,
excludeTags = excludeTags ?? BooleanSelector.none,
globalPatterns = globalPatterns == null
? const {}
: UnmodifiableSetView(globalPatterns.toSet()),
+ _stopOnFirstFailure = stopOnFirstFailure,
suiteDefaults = (() {
var config = suiteDefaults ?? SuiteConfiguration.empty;
if (pauseAfterLoad == true) {
@@ -848,8 +853,8 @@
overrideRuntimes: null,
defineRuntimes: null,
noRetry: null,
- useDataIsolateStrategy: null,
testRandomizeOrderingSeed: null,
+ stopOnFirstFailure: null,
includeTags: null,
excludeTags: null,
);
@@ -953,10 +958,9 @@
defineRuntimes:
mergeUnmodifiableMaps(defineRuntimes, other.defineRuntimes),
noRetry: other._noRetry ?? _noRetry,
- useDataIsolateStrategy:
- other._useDataIsolateStrategy ?? _useDataIsolateStrategy,
testRandomizeOrderingSeed:
other.testRandomizeOrderingSeed ?? testRandomizeOrderingSeed,
+ stopOnFirstFailure: other._stopOnFirstFailure ?? _stopOnFirstFailure,
includeTags: includeTags.intersection(other.includeTags),
excludeTags: excludeTags.union(other.excludeTags),
globalPatterns: globalPatterns.union(other.globalPatterns),
@@ -997,7 +1001,6 @@
Map<String, RuntimeSettings>? overrideRuntimes,
Map<String, CustomRuntime>? defineRuntimes,
bool? noRetry,
- bool? useDataIsolateStrategy,
int? testRandomizeOrderingSeed,
bool? ignoreTimeouts,
@@ -1046,10 +1049,9 @@
overrideRuntimes: overrideRuntimes ?? this.overrideRuntimes,
defineRuntimes: defineRuntimes ?? this.defineRuntimes,
noRetry: noRetry ?? _noRetry,
- useDataIsolateStrategy:
- useDataIsolateStrategy ?? _useDataIsolateStrategy,
testRandomizeOrderingSeed:
testRandomizeOrderingSeed ?? this.testRandomizeOrderingSeed,
+ stopOnFirstFailure: _stopOnFirstFailure,
includeTags: includeTags,
excludeTags: excludeTags,
globalPatterns: globalPatterns,
diff --git a/pkgs/test_core/lib/src/runner/configuration/args.dart b/pkgs/test_core/lib/src/runner/configuration/args.dart
index fcd2e89..5faa52d 100644
--- a/pkgs/test_core/lib/src/runner/configuration/args.dart
+++ b/pkgs/test_core/lib/src/runner/configuration/args.dart
@@ -7,12 +7,11 @@
import 'package:args/args.dart';
import 'package:boolean_selector/boolean_selector.dart';
-import 'package:test_api/scaffolding.dart' // ignore: deprecated_member_use
- show
- Timeout;
-import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
+import 'package:test_api/backend.dart';
+import 'package:test_api/scaffolding.dart' show Timeout;
import '../../util/io.dart';
+import '../compiler_selection.dart';
import '../configuration.dart';
import '../runtime_selection.dart';
import 'reporters.dart';
@@ -70,7 +69,20 @@
abbr: 'p',
help: 'The platform(s) on which to run the tests.\n'
'[vm (default), '
- '${allRuntimes.map((runtime) => runtime.identifier).join(", ")}]');
+ '${allRuntimes.map((runtime) => runtime.identifier).join(", ")}].\n'
+ 'Each platform supports the following compilers:\n'
+ '${Runtime.vm.supportedCompilersText}\n'
+ '${allRuntimes.map((r) => r.supportedCompilersText).join('\n')}');
+ parser.addMultiOption('compiler',
+ abbr: 'c',
+ help: 'The compiler(s) to use to run tests, supported compilers are '
+ '[${Compiler.builtIn.map((c) => c.identifier).join(', ')}].\n'
+ 'Each platform has a default compiler but may support other '
+ 'compilers.\n'
+ 'You can target a compiler to a specific platform using arguments '
+ 'of the following form [<platform-selector>:]<compiler>.\n'
+ 'If a platform is specified but no given compiler is supported for '
+ 'that platform, then it will use its default compiler.');
parser.addMultiOption('preset',
abbr: 'P', help: 'The configuration preset(s) to use.');
parser.addOption('concurrency',
@@ -112,10 +124,9 @@
defaultsTo: false,
negatable: false);
parser.addFlag('use-data-isolate-strategy',
- help: 'Use `data:` uri isolates when spawning VM tests instead of the\n'
- 'default strategy. This may be faster when you only ever run a\n'
- 'single test suite at a time.',
+ help: '**DEPRECATED**: This is now just an alias for --compiler source.',
defaultsTo: false,
+ hide: true,
negatable: false);
parser.addOption('test-randomize-ordering-seed',
help: 'Use the specified seed to randomize the execution order of test'
@@ -123,6 +134,8 @@
'Must be a 32bit unsigned integer or "random".\n'
'If "random", pick a random seed to use.\n'
'If not passed, do not randomize test case execution order.');
+ parser.addFlag('fail-fast',
+ help: 'Stop running tests after the first failure.\n');
var reporterDescriptions = <String, String>{};
for (var reporter in allReporters.keys) {
@@ -177,41 +190,47 @@
void _parseTestSelection(
String option, Map<String, Set<TestSelection>> selections) {
- var firstQuestion = option.indexOf('?');
- TestSelection selection;
- String path;
- if (firstQuestion == -1) {
- path = option;
- selection = TestSelection();
- } else if (option.substring(0, firstQuestion).contains('\\')) {
- throw FormatException(
- 'When passing test path queries, you must pass the path in URI '
- 'format (use `/` for directory separators instead of `\\`).');
- } else {
- final uri = Uri.parse(option);
-
- final names = uri.queryParametersAll['name'];
- final fullName = uri.queryParameters['full-name'];
- final line = uri.queryParameters['line'];
- final col = uri.queryParameters['col'];
-
- if (names != null && names.isNotEmpty && fullName != null) {
- throw FormatException(
- 'Cannot specify both "name=<...>" and "full-name=<...>".',
- );
+ if (Platform.isWindows) {
+ // If given a path that starts with what looks like a drive letter, convert it
+ // into a file scheme URI. We can't parse using `Uri.file` because we do
+ // support query parameters which aren't valid file uris.
+ if (option.indexOf(':') == 1) {
+ option = 'file:///$option';
}
- path = uri.path;
- selection = TestSelection(
- testPatterns: fullName != null
- ? {RegExp('^${RegExp.escape(fullName)}\$')}
- : {
- if (names != null)
- for (var name in names) RegExp(name)
- },
- line: line == null ? null : int.parse(line),
- col: col == null ? null : int.parse(col),
+ }
+ final uri = Uri.parse(option);
+ // Decode the path segment. Specifically, on github actions back slashes on
+ // windows end up being encoded into the URI instead of converted into forward
+ // slashes.
+ var path = Uri.decodeComponent(uri.path);
+ // Strip out the leading slash before the drive letter on windows.
+ if (Platform.isWindows &&
+ path.startsWith('/') &&
+ path.length >= 3 &&
+ path[2] == ':') {
+ path = path.substring(1);
+ }
+
+ final names = uri.queryParametersAll['name'];
+ final fullName = uri.queryParameters['full-name'];
+ final line = uri.queryParameters['line'];
+ final col = uri.queryParameters['col'];
+
+ if (names != null && names.isNotEmpty && fullName != null) {
+ throw FormatException(
+ 'Cannot specify both "name=<...>" and "full-name=<...>".',
);
}
+ final selection = TestSelection(
+ testPatterns: fullName != null
+ ? {RegExp('^${RegExp.escape(fullName)}\$')}
+ : {
+ if (names != null)
+ for (var name in names) RegExp(name)
+ },
+ line: line == null ? null : int.parse(line),
+ col: col == null ? null : int.parse(col),
+ );
selections.update(path, (selections) => selections..add(selection),
ifAbsent: () => {selection});
@@ -280,9 +299,15 @@
var color = _ifParsed<bool>('color') ?? canUseSpecialChars;
- var platform = _ifParsed<List<String>>('platform')
- ?.map((runtime) => RuntimeSelection(runtime))
+ var runtimes =
+ _ifParsed<List<String>>('platform')?.map(RuntimeSelection.new).toList();
+ var compilerSelections = _ifParsed<List<String>>('compiler')
+ ?.map(CompilerSelection.parse)
.toList();
+ if (_ifParsed('use-data-isolate-strategy') == true) {
+ compilerSelections ??= [];
+ compilerSelections.add(CompilerSelection.parse('vm:source'));
+ }
final paths = _options.rest.isEmpty ? null : _options.rest;
@@ -313,18 +338,19 @@
concurrency: _parseOption('concurrency', int.parse),
shardIndex: shardIndex,
totalShards: totalShards,
- timeout: _parseOption('timeout', (value) => Timeout.parse(value)),
+ timeout: _parseOption('timeout', Timeout.parse),
globalPatterns: patterns,
- runtimes: platform,
+ compilerSelections: compilerSelections,
+ runtimes: runtimes,
runSkipped: _ifParsed('run-skipped'),
chosenPresets: _ifParsed('preset'),
testSelections: selections,
includeTags: includeTags,
excludeTags: excludeTags,
noRetry: _ifParsed('no-retry'),
- useDataIsolateStrategy: _ifParsed('use-data-isolate-strategy'),
testRandomizeOrderingSeed: testRandomizeOrderingSeed,
ignoreTimeouts: _ifParsed('ignore-timeouts'),
+ stopOnFirstFailure: _ifParsed('fail-fast'),
// Config that isn't supported on the command line
addTags: null,
allowTestRandomization: null,
@@ -392,3 +418,15 @@
}
}
}
+
+extension _RuntimeDescription on Runtime {
+ String get supportedCompilersText {
+ var message = StringBuffer('[$identifier]: ');
+ message.write('${defaultCompiler.identifier} (default)');
+ for (var compiler in supportedCompilers) {
+ if (compiler == defaultCompiler) continue;
+ message.write(', ${compiler.identifier}');
+ }
+ return message.toString();
+ }
+}
diff --git a/pkgs/test_core/lib/src/runner/configuration/custom_runtime.dart b/pkgs/test_core/lib/src/runner/configuration/custom_runtime.dart
index 0c99191..d1bd028 100644
--- a/pkgs/test_core/lib/src/runner/configuration/custom_runtime.dart
+++ b/pkgs/test_core/lib/src/runner/configuration/custom_runtime.dart
@@ -7,7 +7,7 @@
/// A user-defined test runtime, based on an existing runtime but with
/// different configuration.
-class CustomRuntime {
+final class CustomRuntime {
/// The human-friendly name of the runtime.
final String name;
diff --git a/pkgs/test_core/lib/src/runner/configuration/load.dart b/pkgs/test_core/lib/src/runner/configuration/load.dart
index 6f4a35c..9284ae1 100644
--- a/pkgs/test_core/lib/src/runner/configuration/load.dart
+++ b/pkgs/test_core/lib/src/runner/configuration/load.dart
@@ -8,9 +8,7 @@
import 'package:glob/glob.dart';
import 'package:path/path.dart' as p;
import 'package:source_span/source_span.dart';
-import 'package:test_api/scaffolding.dart' // ignore: deprecated_member_use
- show
- Timeout;
+import 'package:test_api/scaffolding.dart' show Timeout;
import 'package:test_api/src/backend/operating_system.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/platform_selector.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/util/identifier_regex.dart'; // ignore: implementation_imports
@@ -19,6 +17,7 @@
import '../../util/errors.dart';
import '../../util/io.dart';
import '../../util/pretty_print.dart';
+import '../compiler_selection.dart';
import '../configuration.dart';
import '../runtime_selection.dart';
import '../suite.dart';
@@ -119,7 +118,7 @@
var foldStackFrames = _loadFoldedStackFrames();
var jsTrace = _getBool('js_trace');
- var timeout = _parseValue('timeout', (value) => Timeout.parse(value));
+ var timeout = _parseValue('timeout', Timeout.parse);
var onPlatform = _getMap('on_platform',
key: (keyNode) => _parseNode(keyNode, 'on_platform key',
@@ -155,7 +154,7 @@
foldTraceExcept: foldStackFrames['except'],
foldTraceOnly: foldStackFrames['only'])
.merge(_extractPresets<PlatformSelector>(
- onPlatform, (map) => Configuration.onPlatform(map)));
+ onPlatform, Configuration.onPlatform));
var osConfig = onOS[currentOS];
return osConfig == null ? config : config.merge(osConfig);
@@ -195,8 +194,8 @@
'add_tags', (tagNode) => _parseIdentifierLike(tagNode, 'Tag name'));
var tags = _getMap('tags',
- key: (keyNode) => _parseNode(
- keyNode, 'tags key', (value) => BooleanSelector.parse(value)),
+ key: (keyNode) =>
+ _parseNode(keyNode, 'tags key', BooleanSelector.parse),
value: (valueNode) =>
_nestedConfig(valueNode, 'tag value', runnerConfig: false));
@@ -214,8 +213,7 @@
addTags: addTags,
allowTestRandomization: allowTestRandomization,
allowDuplicateTestNames: allowDuplicateTestNames)
- .merge(_extractPresets<BooleanSelector>(
- tags, (map) => Configuration.tags(map)));
+ .merge(_extractPresets<BooleanSelector>(tags, Configuration.tags));
}
/// Loads runner configuration that's allowed in the global configuration
@@ -272,6 +270,14 @@
_parseIdentifierLike(runtimeNode, 'Platform name'),
runtimeNode.span));
+ var compilerSelections = _getList(
+ 'compilers',
+ (node) => _parseNode(
+ node,
+ 'compiler',
+ (option) =>
+ CompilerSelection.parse(option, parentSpan: node.span)));
+
var chosenPresets = _getList('add_presets',
(presetNode) => _parseIdentifierLike(presetNode, 'Preset name'));
@@ -286,6 +292,7 @@
reporter: reporter,
fileReporters: fileReporters,
concurrency: concurrency,
+ compilerSelections: compilerSelections,
runtimes: runtimes,
chosenPresets: chosenPresets,
overrideRuntimes: overrideRuntimes);
@@ -338,12 +345,12 @@
var patterns = _getList('names', (nameNode) {
_validate(nameNode, 'Names must be strings.', (value) => value is String);
- return _parseNode(nameNode, 'name', (value) => RegExp(value));
+ return _parseNode(nameNode, 'name', RegExp.new);
})
..addAll(_getList('plain_names', (nameNode) {
_validate(
nameNode, 'Names must be strings.', (value) => value is String);
- return _parseNode(nameNode, 'name', (value) => RegExp(value));
+ return _parseNode(nameNode, 'name', RegExp.new);
}));
var paths = _getList('paths', (pathNode) {
@@ -353,7 +360,7 @@
return _parseNode(pathNode, 'path', p.fromUri);
});
- var filename = _parseValue('filename', (value) => Glob(value));
+ var filename = _parseValue('filename', Glob.new);
var includeTags = _parseBooleanSelector('include_tags');
var excludeTags = _parseBooleanSelector('exclude_tags');
@@ -541,7 +548,7 @@
/// Parses [node]'s value as a boolean selector.
BooleanSelector? _parseBooleanSelector(String name) =>
- _parseValue(name, (value) => BooleanSelector.parse(value));
+ _parseValue(name, BooleanSelector.parse);
/// Parses [node]'s value as a platform selector.
PlatformSelector? _parsePlatformSelector(String field) {
diff --git a/pkgs/test_core/lib/src/runner/configuration/reporters.dart b/pkgs/test_core/lib/src/runner/configuration/reporters.dart
index 2a724aa..d52f163 100644
--- a/pkgs/test_core/lib/src/runner/configuration/reporters.dart
+++ b/pkgs/test_core/lib/src/runner/configuration/reporters.dart
@@ -36,20 +36,23 @@
color: config.color,
printPath: config.testSelections.length > 1 ||
Directory(config.testSelections.keys.single).existsSync(),
- printPlatform: config.suiteDefaults.runtimes.length > 1)),
+ printPlatform: config.suiteDefaults.runtimes.length > 1 ||
+ config.suiteDefaults.compilerSelections != null)),
'compact': ReporterDetails(
'A single line, updated continuously.',
(config, engine, sink) => CompactReporter.watch(engine, sink,
color: config.color,
printPath: config.testSelections.length > 1 ||
Directory(config.testSelections.keys.single).existsSync(),
- printPlatform: config.suiteDefaults.runtimes.length > 1)),
+ printPlatform: config.suiteDefaults.runtimes.length > 1 ||
+ config.suiteDefaults.compilerSelections != null)),
'github': ReporterDetails(
'A custom reporter for GitHub Actions (the default reporter when running on GitHub Actions).',
(config, engine, sink) => GithubReporter.watch(engine, sink,
printPath: config.testSelections.length > 1 ||
Directory(config.testSelections.keys.single).existsSync(),
- printPlatform: config.suiteDefaults.runtimes.length > 1)),
+ printPlatform: config.suiteDefaults.runtimes.length > 1 ||
+ config.suiteDefaults.compilerSelections != null)),
'json': ReporterDetails(
'A machine-readable format (see '
'https://dart.dev/go/test-docs/json_reporter.md).',
diff --git a/pkgs/test_core/lib/src/runner/configuration/runtime_settings.dart b/pkgs/test_core/lib/src/runner/configuration/runtime_settings.dart
index 6e910a3..e366b4d 100644
--- a/pkgs/test_core/lib/src/runner/configuration/runtime_settings.dart
+++ b/pkgs/test_core/lib/src/runner/configuration/runtime_settings.dart
@@ -8,7 +8,7 @@
import '../plugin/customizable_platform.dart';
/// User-defined settings for a built-in test runtime.
-class RuntimeSettings {
+final class RuntimeSettings {
/// The identifier used to look up the runtime being overridden.
final String identifier;
diff --git a/pkgs/test_core/lib/src/runner/engine.dart b/pkgs/test_core/lib/src/runner/engine.dart
index 578a6bf..665fd60 100644
--- a/pkgs/test_core/lib/src/runner/engine.dart
+++ b/pkgs/test_core/lib/src/runner/engine.dart
@@ -69,6 +69,9 @@
/// The same seed will shuffle the tests in the same way every time.
int? testRandomizeOrderingSeed;
+ /// Whether to stop running tests after a failure.
+ bool _stopOnFirstFailure;
+
/// A pool that limits the number of test suites running concurrently.
final Pool _runPool;
@@ -202,8 +205,16 @@
/// Omitting this argument or passing `0` disables shuffling.
///
/// [coverage] specifies a directory to output coverage information.
- Engine({int? concurrency, String? coverage, this.testRandomizeOrderingSeed})
- : _runPool = Pool(concurrency ?? 1),
+ ///
+ /// If [stopOnFirstFailure] then a single failing test will cause the engine
+ /// to [close] and stop ruunning further tests.
+ Engine({
+ int? concurrency,
+ String? coverage,
+ this.testRandomizeOrderingSeed,
+ bool stopOnFirstFailure = false,
+ }) : _runPool = Pool(concurrency ?? 1),
+ _stopOnFirstFailure = stopOnFirstFailure,
_coverage = coverage {
_group.future.then((_) {
_onTestStartedGroup.close();
@@ -222,8 +233,12 @@
/// [concurrency] controls how many suites are run at once. If [runSkipped] is
/// `true`, skipped tests will be run as though they weren't skipped.
factory Engine.withSuites(List<RunnerSuite> suites,
- {int? concurrency, String? coverage}) {
- var engine = Engine(concurrency: concurrency, coverage: coverage);
+ {int? concurrency, String? coverage, bool stopOnFirstFailure = false}) {
+ var engine = Engine(
+ concurrency: concurrency,
+ coverage: coverage,
+ stopOnFirstFailure: stopOnFirstFailure,
+ );
for (var suite in suites) {
engine.suiteSink.add(suite);
}
@@ -371,7 +386,10 @@
// loop pump to avoid starving non-microtask events.
await Future(() {});
- if (!_restarted.contains(liveTest)) return;
+ if (!_restarted.contains(liveTest)) {
+ if (_stopOnFirstFailure && liveTest.state.result.isFailing) close();
+ return;
+ }
await _runLiveTest(suiteController, liveTest.copy(),
countSuccess: countSuccess);
_restarted.remove(liveTest);
diff --git a/pkgs/test_core/lib/src/runner/hybrid_listener.dart b/pkgs/test_core/lib/src/runner/hybrid_listener.dart
index f7fdb86..bf2daa2 100644
--- a/pkgs/test_core/lib/src/runner/hybrid_listener.dart
+++ b/pkgs/test_core/lib/src/runner/hybrid_listener.dart
@@ -9,7 +9,6 @@
import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/isolate_channel.dart';
import 'package:stream_channel/stream_channel.dart';
-// ignore: deprecated_member_use
import 'package:test_api/backend.dart' show RemoteException;
import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
diff --git a/pkgs/test_core/lib/src/runner/load_suite.dart b/pkgs/test_core/lib/src/runner/load_suite.dart
index 2c64fc0..db6b12e 100644
--- a/pkgs/test_core/lib/src/runner/load_suite.dart
+++ b/pkgs/test_core/lib/src/runner/load_suite.dart
@@ -5,7 +5,6 @@
import 'dart:async';
import 'package:stack_trace/stack_trace.dart';
-// ignore: deprecated_member_use
import 'package:test_api/scaffolding.dart' show Timeout;
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/invoker.dart'; // ignore: implementation_imports
@@ -136,7 +135,7 @@
return LoadSuite(
'loading ${exception.path}',
config ?? SuiteConfiguration.empty,
- platform ?? currentPlatform(Runtime.vm),
+ platform ?? currentPlatform(Runtime.vm, null),
() => Future.error(exception, stackTrace),
path: exception.path);
}
diff --git a/pkgs/test_core/lib/src/runner/loader.dart b/pkgs/test_core/lib/src/runner/loader.dart
index 6cd47d2..b3ec7e8 100644
--- a/pkgs/test_core/lib/src/runner/loader.dart
+++ b/pkgs/test_core/lib/src/runner/loader.dart
@@ -11,6 +11,7 @@
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/invoker.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
+import 'package:test_core/src/runner/compiler_selection.dart';
import 'package:yaml/yaml.dart';
import '../util/io.dart';
@@ -64,7 +65,7 @@
/// Creates a new loader that loads tests on platforms defined in
/// [Configuration.current].
Loader() {
- _registerPlatformPlugin([Runtime.vm], () => VMPlatform());
+ _registerPlatformPlugin([Runtime.vm], VMPlatform.new);
platformCallbacks.forEach((runtime, plugin) {
_registerPlatformPlugin([runtime], plugin);
@@ -182,60 +183,67 @@
for (var runtimeName in suiteConfig.runtimes) {
var runtime = findRuntime(runtimeName);
- assert(runtime != null, 'Unknown platform "$runtimeName".');
-
- var platform = currentPlatform(runtime!);
- if (!suiteConfig.metadata.testOn.evaluate(platform)) {
- continue;
+ if (runtime == null) {
+ throw ArgumentError.value(runtimeName, 'platform', 'Unknown platform');
}
+ final compilers = {
+ for (var selection
+ in suiteConfig.compilerSelections ?? <CompilerSelection>[])
+ if (runtime.supportedCompilers.contains(selection.compiler) &&
+ (selection.platformSelector == null ||
+ selection.platformSelector!
+ .evaluate(currentPlatform(runtime, selection.compiler))))
+ selection.compiler,
+ };
+ if (compilers.isEmpty) compilers.add(runtime.defaultCompiler);
- var platformConfig = suiteConfig.forPlatform(platform);
+ for (var compiler in compilers) {
+ var platform = currentPlatform(runtime, compiler);
+ if (!suiteConfig.metadata.testOn.evaluate(platform)) continue;
- // Don't load a skipped suite.
- if (platformConfig.metadata.skip && !platformConfig.runSkipped) {
- yield LoadSuite.forSuite(RunnerSuite(
- const PluginEnvironment(),
- platformConfig,
- Group.root([LocalTest('(suite)', platformConfig.metadata, () {})],
- metadata: platformConfig.metadata),
- platform,
- path: path));
- continue;
- }
+ var platformConfig = suiteConfig.forPlatform(platform);
- var name =
- (platform.runtime.isJS && platformConfig.precompiledPath == null
- ? 'compiling '
- : 'loading ') +
- path;
- yield LoadSuite(name, platformConfig, platform, () async {
- var memo = _platformPlugins[platform.runtime]!;
-
- var retriesLeft = suiteConfig.metadata.retry;
- while (true) {
- try {
- var plugin =
- await memo.runOnce(_platformCallbacks[platform.runtime]!);
- _customizePlatform(plugin, platform.runtime);
- var suite = await plugin.load(path, platform, platformConfig,
- {'platformVariables': _runtimeVariables.toList()});
- if (suite != null) _suites.add(suite);
- return suite;
- } on Object catch (error, stackTrace) {
- if (retriesLeft > 0) {
- retriesLeft--;
- print('Retrying load of $path in 1s ($retriesLeft remaining)');
- await Future.delayed(Duration(seconds: 1));
- continue;
- }
- if (error is LoadException) {
- rethrow;
- }
- await Future.error(LoadException(path, error), stackTrace);
- return null;
- }
+ // Don't load a skipped suite.
+ if (platformConfig.metadata.skip && !platformConfig.runSkipped) {
+ yield LoadSuite.forSuite(RunnerSuite(
+ const PluginEnvironment(),
+ platformConfig,
+ Group.root([LocalTest('(suite)', platformConfig.metadata, () {})],
+ metadata: platformConfig.metadata),
+ platform,
+ path: path));
+ continue;
}
- }, path: path);
+
+ yield LoadSuite('loading $path', platformConfig, platform, () async {
+ var memo = _platformPlugins[platform.runtime]!;
+
+ var retriesLeft = suiteConfig.metadata.retry;
+ while (true) {
+ try {
+ var plugin =
+ await memo.runOnce(_platformCallbacks[platform.runtime]!);
+ _customizePlatform(plugin, platform.runtime);
+ var suite = await plugin.load(path, platform, platformConfig,
+ {'platformVariables': _runtimeVariables.toList()});
+ if (suite != null) _suites.add(suite);
+ return suite;
+ } on Object catch (error, stackTrace) {
+ if (retriesLeft > 0) {
+ retriesLeft--;
+ print('Retrying load of $path in 1s ($retriesLeft remaining)');
+ await Future.delayed(Duration(seconds: 1));
+ continue;
+ }
+ if (error is LoadException) {
+ rethrow;
+ }
+ await Future.error(LoadException(path, error), stackTrace);
+ return null;
+ }
+ }
+ }, path: path);
+ }
}
}
diff --git a/pkgs/test_core/lib/src/runner/parse_metadata.dart b/pkgs/test_core/lib/src/runner/parse_metadata.dart
index 451f175..63b5e59 100644
--- a/pkgs/test_core/lib/src/runner/parse_metadata.dart
+++ b/pkgs/test_core/lib/src/runner/parse_metadata.dart
@@ -6,9 +6,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:path/path.dart' as p;
import 'package:source_span/source_span.dart';
-import 'package:test_api/scaffolding.dart' // ignore: deprecated_member_use
- show
- Timeout;
+import 'package:test_api/scaffolding.dart' show Timeout;
import 'package:test_api/src/backend/metadata.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/platform_selector.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/util/identifier_regex.dart'; // ignore: implementation_imports
@@ -200,9 +198,8 @@
///
/// [annotation] is the annotation.
Map<PlatformSelector, Metadata> _parseOnPlatform(Annotation annotation) {
- return _parseMap(annotation.arguments!.arguments.first, key: (key) {
- return _parsePlatformSelector(key);
- }, value: (value) {
+ return _parseMap(annotation.arguments!.arguments.first,
+ key: _parsePlatformSelector, value: (value) {
var expressions = <AstNode>[];
if (value is ListLiteral) {
expressions = _parseList(value);
@@ -219,10 +216,7 @@
Object? skip;
for (var expression in expressions) {
if (expression is InstanceCreationExpression) {
- var className = _resolveConstructor(
- expression.constructorName.type.name,
- expression.constructorName.name)
- .first;
+ var className = expression.constructorName.type.name2.lexeme;
if (className == 'Timeout') {
_assertSingle(timeout, 'Timeout', expression);
@@ -345,7 +339,7 @@
/// If [expression] is not an instantiation of a [className] throws.
String? _findConstructorName(Expression expression, String className) {
if (expression is InstanceCreationExpression) {
- return _findConstructornameFromInstantiation(expression, className);
+ return _findConstructorNameFromInstantiation(expression, className);
}
if (expression is MethodInvocation) {
return _findConstructorNameFromMethod(expression, className);
@@ -354,12 +348,10 @@
'Expected a $className.', _spanFor(expression));
}
- String? _findConstructornameFromInstantiation(
+ String? _findConstructorNameFromInstantiation(
InstanceCreationExpression constructor, String className) {
- var pair = _resolveConstructor(constructor.constructorName.type.name,
- constructor.constructorName.name);
- var actualClassName = pair.first;
- var constructorName = pair.last;
+ var actualClassName = constructor.constructorName.type.name2.lexeme;
+ var constructorName = constructor.constructorName.name?.name;
if (actualClassName != className) {
throw SourceSpanFormatException(
diff --git a/pkgs/test_core/lib/src/runner/plugin/platform_helpers.dart b/pkgs/test_core/lib/src/runner/plugin/platform_helpers.dart
index f40a71c..569ef60 100644
--- a/pkgs/test_core/lib/src/runner/plugin/platform_helpers.dart
+++ b/pkgs/test_core/lib/src/runner/plugin/platform_helpers.dart
@@ -7,7 +7,6 @@
import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/stream_channel.dart';
-// ignore: deprecated_member_use
import 'package:test_api/backend.dart'
show Metadata, RemoteException, SuitePlatform;
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
@@ -63,7 +62,7 @@
'foldTraceOnly': Configuration.current.foldTraceOnly.toList(),
'allowDuplicateTestNames': suiteConfig.allowDuplicateTestNames,
'ignoreTimeouts': suiteConfig.ignoreTimeouts,
- ...(message as Map<String, dynamic>),
+ ...message as Map<String, dynamic>,
});
var completer = Completer<Group>();
@@ -95,7 +94,8 @@
break;
case 'error':
- var asyncError = RemoteException.deserialize(response['error']);
+ var asyncError = RemoteException.deserialize(
+ response['error'] as Map<String, dynamic>);
handleError(
LoadException(path, asyncError.error), asyncError.stackTrace);
break;
@@ -156,7 +156,7 @@
var metadata = Metadata.deserialize(test['metadata']);
var trace =
test['trace'] == null ? null : Trace.parse(test['trace'] as String);
- var testChannel = _channel.virtualChannel(test['channel'] as int);
+ var testChannel = _channel.virtualChannel((test['channel'] as num).toInt());
return RunnerTest(test['name'] as String, metadata, trace, testChannel);
}
}
diff --git a/pkgs/test_core/lib/src/runner/plugin/remote_platform_helpers.dart b/pkgs/test_core/lib/src/runner/plugin/remote_platform_helpers.dart
index 7e50207..8eb2b76 100644
--- a/pkgs/test_core/lib/src/runner/plugin/remote_platform_helpers.dart
+++ b/pkgs/test_core/lib/src/runner/plugin/remote_platform_helpers.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:stream_channel/stream_channel.dart';
-// ignore: deprecated_member_use
import 'package:test_api/backend.dart'
show RemoteListener, StackTraceFormatter, StackTraceMapper;
diff --git a/pkgs/test_core/lib/src/runner/plugin/shared_platform_helpers.dart b/pkgs/test_core/lib/src/runner/plugin/shared_platform_helpers.dart
new file mode 100644
index 0000000..4fdcf23
--- /dev/null
+++ b/pkgs/test_core/lib/src/runner/plugin/shared_platform_helpers.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:async/async.dart';
+import 'package:stream_channel/stream_channel.dart';
+
+/// Converts a raw [Socket] into a [StreamChannel] of JSON objects.
+///
+/// JSON messages are separated by newlines.
+StreamChannel<Object?> jsonSocketStreamChannel(Socket socket) =>
+ StreamChannel.withGuarantees(socket, socket)
+ .cast<List<int>>()
+ .transform(StreamChannelTransformer.fromCodec(utf8))
+ .transformStream(const LineSplitter())
+ .transformSink(StreamSinkTransformer.fromHandlers(
+ handleData: (original, sink) => sink.add('$original\n')))
+ .transform(jsonDocument);
diff --git a/pkgs/test_core/lib/src/runner/reporter/compact.dart b/pkgs/test_core/lib/src/runner/reporter/compact.dart
index 6760a91..962213f 100644
--- a/pkgs/test_core/lib/src/runner/reporter/compact.dart
+++ b/pkgs/test_core/lib/src/runner/reporter/compact.dart
@@ -435,7 +435,8 @@
}
if (_printPlatform) {
- name = '[${liveTest.suite.platform.runtime.name}] $name';
+ name = '[${liveTest.suite.platform.runtime.name}, '
+ '${liveTest.suite.platform.compiler.name}] $name';
}
if (liveTest.suite is LoadSuite) name = '$_bold$_gray$name$_noColor';
diff --git a/pkgs/test_core/lib/src/runner/reporter/expanded.dart b/pkgs/test_core/lib/src/runner/reporter/expanded.dart
index 6ff2b6f..a654528 100644
--- a/pkgs/test_core/lib/src/runner/reporter/expanded.dart
+++ b/pkgs/test_core/lib/src/runner/reporter/expanded.dart
@@ -171,9 +171,9 @@
} else if (_engine.active.isEmpty &&
_engine.activeSuiteLoads.length == 1 &&
_engine.activeSuiteLoads.first == liveTest &&
- liveTest.test.name.startsWith('compiling ')) {
- // Print a progress line for load tests that come from compiling JS, since
- // that takes a long time.
+ liveTest.test.name.startsWith('loading ')) {
+ // Print a progress line for ongoing suite loading synthetic test since it
+ // may be slow (or stuck) depending on the platform.
_progressLine(_description(liveTest));
}
@@ -336,7 +336,8 @@
}
if (_printPlatform) {
- name = '[${liveTest.suite.platform.runtime.name}] $name';
+ name = '[${liveTest.suite.platform.runtime.name}, '
+ '${liveTest.suite.platform.compiler.name}] $name';
}
if (liveTest.suite is LoadSuite) name = '$_bold$_gray$name$_noColor';
diff --git a/pkgs/test_core/lib/src/runner/reporter/github.dart b/pkgs/test_core/lib/src/runner/reporter/github.dart
index ed9ab5a..5249817 100644
--- a/pkgs/test_core/lib/src/runner/reporter/github.dart
+++ b/pkgs/test_core/lib/src/runner/reporter/github.dart
@@ -152,7 +152,8 @@
}
}
if (_printPlatform) {
- name = '[${test.suite.platform.runtime.name}] $name';
+ name = '[${test.suite.platform.runtime.name}, '
+ '${test.suite.platform.compiler.name}] $name';
}
if (messages.isEmpty && errors.isEmpty) {
_sink.writeln('$prefix $name$statusSuffix');
@@ -184,7 +185,8 @@
}
}
if (_printPlatform) {
- name = '[${test.suite.platform.runtime.name}] $name';
+ name = '[${test.suite.platform.runtime.name}, '
+ '${test.suite.platform.compiler.name}] $name';
}
_sink.writeln(_GithubMarkup.startGroup('$prefix $name$statusSuffix'));
diff --git a/pkgs/test_core/lib/src/runner/reporter/json.dart b/pkgs/test_core/lib/src/runner/reporter/json.dart
index 5497817..0683b60 100644
--- a/pkgs/test_core/lib/src/runner/reporter/json.dart
+++ b/pkgs/test_core/lib/src/runner/reporter/json.dart
@@ -303,7 +303,7 @@
/// all be `null`.
Map<String, dynamic> _frameInfo(SuiteConfiguration suiteConfig, Trace? trace,
Runtime runtime, String suitePath) {
- var absoluteSuitePath = p.absolute(suitePath);
+ var absoluteSuitePath = p.canonicalize(p.absolute(suitePath));
var frame = trace?.frames.first;
if (frame == null || (suiteConfig.jsTrace && runtime.isJS)) {
return {'line': null, 'column': null, 'url': null};
@@ -311,7 +311,7 @@
var rootFrame = trace?.frames.firstWhereOrNull((frame) =>
frame.uri.scheme == 'file' &&
- frame.uri.toFilePath() == absoluteSuitePath);
+ p.canonicalize(frame.uri.toFilePath()) == absoluteSuitePath);
return {
'line': frame.line,
'column': frame.column,
diff --git a/pkgs/test_core/lib/src/runner/runner_test.dart b/pkgs/test_core/lib/src/runner/runner_test.dart
index 10ef8bc..f140c01 100644
--- a/pkgs/test_core/lib/src/runner/runner_test.dart
+++ b/pkgs/test_core/lib/src/runner/runner_test.dart
@@ -6,7 +6,6 @@
import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/stream_channel.dart';
-// ignore: deprecated_member_use
import 'package:test_api/backend.dart'
show Metadata, RemoteException, SuitePlatform;
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
@@ -46,7 +45,8 @@
testChannel.stream.listen((message) {
switch (message['type'] as String) {
case 'error':
- var asyncError = RemoteException.deserialize(message['error']);
+ var asyncError = RemoteException.deserialize(
+ message['error'] as Map<String, dynamic>);
var stackTrace = asyncError.stackTrace;
controller.addError(asyncError.error, stackTrace);
break;
@@ -71,7 +71,8 @@
// this virtual channel and cause the spawned isolate to close as
// well.
spawnHybridUri(message['url'] as String, message['message'], suite)
- .pipe(testChannel.virtualChannel(message['channel'] as int));
+ .pipe(testChannel
+ .virtualChannel((message['channel'] as num).toInt()));
break;
}
}, onDone: () {
diff --git a/pkgs/test_core/lib/src/runner/runtime_selection.dart b/pkgs/test_core/lib/src/runner/runtime_selection.dart
index e607400..7f64a5c 100644
--- a/pkgs/test_core/lib/src/runner/runtime_selection.dart
+++ b/pkgs/test_core/lib/src/runner/runtime_selection.dart
@@ -17,7 +17,8 @@
RuntimeSelection(this.name, [this.span]);
@override
- bool operator ==(other) => other is RuntimeSelection && other.name == name;
+ bool operator ==(Object other) =>
+ other is RuntimeSelection && other.name == name;
@override
int get hashCode => name.hashCode;
diff --git a/pkgs/test_core/lib/src/runner/spawn_hybrid.dart b/pkgs/test_core/lib/src/runner/spawn_hybrid.dart
index e21b8f8..e44e05d 100644
--- a/pkgs/test_core/lib/src/runner/spawn_hybrid.dart
+++ b/pkgs/test_core/lib/src/runner/spawn_hybrid.dart
@@ -10,7 +10,6 @@
import 'package:path/path.dart' as p;
import 'package:stream_channel/isolate_channel.dart';
import 'package:stream_channel/stream_channel.dart';
-// ignore: deprecated_member_use
import 'package:test_api/backend.dart' show RemoteException;
import 'package:test_api/src/backend/suite.dart'; // ignore: implementation_imports
@@ -160,15 +159,9 @@
return '';
}
-Future<String> _readUri(Uri uri) async {
- switch (uri.scheme) {
- case '':
- case 'file':
- return File.fromUri(uri).readAsString();
- case 'data':
- return uri.data!.contentAsString();
- default:
- throw ArgumentError.value(uri, 'uri',
- 'Only data and file uris (as well as relative paths) are supported');
- }
-}
+Future<String> _readUri(Uri uri) async => switch (uri.scheme) {
+ '' || 'file' => await File.fromUri(uri).readAsString(),
+ 'data' => uri.data!.contentAsString(),
+ _ => throw ArgumentError.value(uri, 'uri',
+ 'Only data and file uris (as well as relative paths) are supported'),
+ };
diff --git a/pkgs/test_core/lib/src/runner/suite.dart b/pkgs/test_core/lib/src/runner/suite.dart
index 138abee..b3561ab 100644
--- a/pkgs/test_core/lib/src/runner/suite.dart
+++ b/pkgs/test_core/lib/src/runner/suite.dart
@@ -5,14 +5,13 @@
import 'package:boolean_selector/boolean_selector.dart';
import 'package:collection/collection.dart';
import 'package:source_span/source_span.dart';
-import 'package:test_api/scaffolding.dart' // ignore: deprecated_member_use
- show
- Timeout;
+import 'package:test_api/scaffolding.dart' show Timeout;
import 'package:test_api/src/backend/metadata.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/platform_selector.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
+import 'compiler_selection.dart';
import 'runtime_selection.dart';
/// A filter on tests cases to run within a test suite.
@@ -22,7 +21,7 @@
/// matches any test selection.
///
/// An empty [TestSelection()] will run all tests in the suite.
-class TestSelection {
+final class TestSelection {
/// The patterns to check against test case names.
///
/// Only run tests which match all the patterns.
@@ -40,7 +39,7 @@
/// Suite-level configuration.
///
/// This tracks configuration that can differ from suite to suite.
-class SuiteConfiguration {
+final class SuiteConfiguration {
/// Empty configuration with only default values.
///
/// Using this is slightly more efficient than manually constructing a new
@@ -54,6 +53,7 @@
testSelections: const {},
precompiledPath: null,
runtimes: null,
+ compilerSelections: null,
tags: null,
onPlatform: null,
metadata: null,
@@ -104,6 +104,9 @@
/// [testSelections].
final Set<TestSelection> testSelections;
+ /// The set of compiler selections for running tests.
+ final List<CompilerSelection>? compilerSelections;
+
/// The set of runtimes on which to run tests.
List<String> get runtimes => _runtimes == null
? const ['vm']
@@ -153,6 +156,7 @@
required bool? runSkipped,
required Iterable<String>? dart2jsArgs,
required String? precompiledPath,
+ required Iterable<CompilerSelection>? compilerSelections,
required Iterable<RuntimeSelection>? runtimes,
required Map<BooleanSelector, SuiteConfiguration>? tags,
required Map<PlatformSelector, SuiteConfiguration>? onPlatform,
@@ -175,6 +179,7 @@
dart2jsArgs: dart2jsArgs,
testSelections: const {},
precompiledPath: precompiledPath,
+ compilerSelections: compilerSelections,
runtimes: runtimes,
tags: tags,
onPlatform: onPlatform,
@@ -202,6 +207,7 @@
bool? runSkipped,
Iterable<String>? dart2jsArgs,
String? precompiledPath,
+ Iterable<CompilerSelection>? compilerSelections,
Iterable<RuntimeSelection>? runtimes,
Map<BooleanSelector, SuiteConfiguration>? tags,
Map<PlatformSelector, SuiteConfiguration>? onPlatform,
@@ -223,6 +229,7 @@
runSkipped: runSkipped,
dart2jsArgs: dart2jsArgs,
precompiledPath: precompiledPath,
+ compilerSelections: compilerSelections,
runtimes: runtimes,
tags: tags,
onPlatform: onPlatform,
@@ -260,6 +267,7 @@
required Iterable<String>? dart2jsArgs,
required this.testSelections,
required this.precompiledPath,
+ required Iterable<CompilerSelection>? compilerSelections,
required Iterable<RuntimeSelection>? runtimes,
required Map<BooleanSelector, SuiteConfiguration>? tags,
required Map<PlatformSelector, SuiteConfiguration>? onPlatform,
@@ -271,6 +279,7 @@
_runSkipped = runSkipped,
dart2jsArgs = _list(dart2jsArgs) ?? const [],
_runtimes = _list(runtimes),
+ compilerSelections = _list(compilerSelections),
tags = _map(tags),
onPlatform = _map(onPlatform),
_ignoreTimeouts = ignoreTimeouts,
@@ -293,6 +302,7 @@
testSelections: const {},
precompiledPath: null,
runtimes: null,
+ compilerSelections: null,
ignoreTimeouts: null,
);
@@ -333,6 +343,7 @@
testSelections:
testSelections.isEmpty ? other.testSelections : testSelections,
precompiledPath: other.precompiledPath ?? precompiledPath,
+ compilerSelections: other.compilerSelections ?? compilerSelections,
runtimes: other._runtimes ?? _runtimes,
tags: _mergeConfigMaps(tags, other.tags),
onPlatform: _mergeConfigMaps(onPlatform, other.onPlatform),
@@ -352,6 +363,7 @@
bool? runSkipped,
Iterable<String>? dart2jsArgs,
String? precompiledPath,
+ Iterable<CompilerSelection>? compilerSelections,
Iterable<RuntimeSelection>? runtimes,
Map<BooleanSelector, SuiteConfiguration>? tags,
Map<PlatformSelector, SuiteConfiguration>? onPlatform,
@@ -376,6 +388,7 @@
dart2jsArgs: dart2jsArgs?.toList() ?? this.dart2jsArgs,
testSelections: testSelections,
precompiledPath: precompiledPath ?? this.precompiledPath,
+ compilerSelections: compilerSelections ?? this.compilerSelections,
runtimes: runtimes ?? _runtimes,
tags: tags ?? this.tags,
onPlatform: onPlatform ?? this.onPlatform,
@@ -410,6 +423,7 @@
runSkipped: _runSkipped,
dart2jsArgs: dart2jsArgs,
precompiledPath: precompiledPath,
+ compilerSelections: compilerSelections,
runtimes: _runtimes,
tags: tags,
onPlatform: onPlatform,
diff --git a/pkgs/test_core/lib/src/runner/vm/platform.dart b/pkgs/test_core/lib/src/runner/vm/platform.dart
index 2ea9483..2cb5a48 100644
--- a/pkgs/test_core/lib/src/runner/vm/platform.dart
+++ b/pkgs/test_core/lib/src/runner/vm/platform.dart
@@ -13,7 +13,7 @@
import 'package:path/path.dart' as p;
import 'package:stream_channel/isolate_channel.dart';
import 'package:stream_channel/stream_channel.dart';
-import 'package:test_api/backend.dart'; // ignore: deprecated_member_use
+import 'package:test_api/backend.dart';
import 'package:test_core/src/runner/vm/test_compiler.dart';
import 'package:vm_service/vm_service.dart' hide Isolate;
import 'package:vm_service/vm_service_io.dart';
@@ -23,9 +23,10 @@
import '../../runner/load_exception.dart';
import '../../runner/platform.dart';
import '../../runner/plugin/platform_helpers.dart';
+import '../../runner/plugin/shared_platform_helpers.dart';
import '../../runner/runner_suite.dart';
import '../../runner/suite.dart';
-import '../../util/dart.dart' as dart;
+import '../../util/io.dart';
import '../../util/package_config.dart';
import '../package_version.dart';
import 'environment.dart';
@@ -40,6 +41,7 @@
p.join(p.current, '.dart_tool', 'test', 'incremental_kernel'));
final _closeMemo = AsyncMemoizer<void>();
final _workingDirectory = Directory.current.uri;
+ final _tempDir = Directory.systemTemp.createTempSync('dart_test.vm.');
@override
Future<RunnerSuite?> load(String path, SuitePlatform platform,
@@ -48,23 +50,48 @@
_setupPauseAfterTests();
- var receivePort = ReceivePort();
+ MultiChannel outerChannel;
+ var cleanupCallbacks = <void Function()>[];
Isolate? isolate;
- try {
- isolate =
- await _spawnIsolate(path, receivePort.sendPort, suiteConfig.metadata);
- if (isolate == null) return null;
- } catch (error) {
- receivePort.close();
- rethrow;
+ if (platform.compiler == Compiler.exe) {
+ var serverSocket = await ServerSocket.bind('localhost', 0);
+ Process process;
+ try {
+ process =
+ await _spawnExecutable(path, suiteConfig.metadata, serverSocket);
+ } catch (error) {
+ serverSocket.close();
+ rethrow;
+ }
+ process.stdout.listen(stdout.add);
+ process.stderr.listen(stderr.add);
+ var socket = await serverSocket.first;
+ outerChannel = MultiChannel<Object?>(jsonSocketStreamChannel(socket));
+ cleanupCallbacks
+ ..add(serverSocket.close)
+ ..add(process.kill);
+ } else {
+ var receivePort = ReceivePort();
+ try {
+ isolate = await _spawnIsolate(path, receivePort.sendPort,
+ suiteConfig.metadata, platform.compiler);
+ if (isolate == null) return null;
+ } catch (error) {
+ receivePort.close();
+ rethrow;
+ }
+ outerChannel = MultiChannel(IsolateChannel.connectReceive(receivePort));
+ cleanupCallbacks
+ ..add(receivePort.close)
+ ..add(isolate.kill);
}
+ cleanupCallbacks.add(outerChannel.sink.close);
VmService? client;
StreamSubscription<Event>? eventSub;
// Typical test interaction will go across `channel`, `outerChannel` adds
// additional communication directly between the test bootstrapping and this
// platform to enable pausing after tests for debugging.
- var outerChannel = MultiChannel(IsolateChannel.connectReceive(receivePort));
var outerQueue = StreamQueue(outerChannel.stream);
var channelId = (await outerQueue.next) as int;
var channel = outerChannel.virtualChannel(channelId).transformStream(
@@ -73,8 +100,9 @@
outerChannel.sink.add('debug');
await outerQueue.next;
}
- receivePort.close();
- isolate!.kill();
+ for (var fn in cleanupCallbacks) {
+ fn();
+ }
eventSub?.cancel();
client?.dispose();
sink.close();
@@ -83,9 +111,15 @@
Environment? environment;
IsolateRef? isolateRef;
if (_config.debug) {
+ if (platform.compiler == Compiler.exe) {
+ throw UnsupportedError(
+ 'Unable to debug tests compiled to `exe` (tried to debug $path with '
+ 'the `exe` compiler).');
+ }
var info =
await Service.controlWebServer(enable: true, silenceOutput: true);
- var isolateID = Service.getIsolateID(isolate)!;
+ // ignore: deprecated_member_use, Remove when SDK constraint is at 3.2.0
+ var isolateID = Service.getIsolateID(isolate!)!;
var libraryPath = _absolute(path).toString();
var serverUri = info.serverUri!;
@@ -125,7 +159,10 @@
}
@override
- Future close() => _closeMemo.runOnce(_compiler.dispose);
+ Future close() => _closeMemo.runOnce(() => Future.wait([
+ _compiler.dispose(),
+ _tempDir.deleteWithRetry(),
+ ]));
Uri _absolute(String path) {
final uri = p.toUri(path);
@@ -133,63 +170,118 @@
return _workingDirectory.resolveUri(uri);
}
- /// Spawns an isolate and passes it [message].
+ /// Compiles [path] to a native executable and spawns it as a process.
+ ///
+ /// Sets up a communication channel as well by passing command line arguments
+ /// for the host and port of [socket].
+ Future<Process> _spawnExecutable(
+ String path, Metadata suiteMetadata, ServerSocket socket) async {
+ if (_config.suiteDefaults.precompiledPath != null) {
+ throw UnsupportedError(
+ 'Precompiled native executable tests are not supported at this time');
+ }
+ var executable = await _compileToNative(path, suiteMetadata);
+ return await Process.start(
+ executable, [socket.address.host, socket.port.toString()]);
+ }
+
+ /// Compiles [path] to a native executable using `dart compile exe`.
+ Future<String> _compileToNative(String path, Metadata suiteMetadata) async {
+ var bootstrapPath = _bootstrapNativeTestFile(
+ path,
+ suiteMetadata.languageVersionComment ??
+ await rootPackageLanguageVersionComment);
+ var output = File(p.setExtension(bootstrapPath, '.exe'));
+ var processResult = await Process.run(Platform.resolvedExecutable, [
+ 'compile',
+ 'exe',
+ bootstrapPath,
+ '--output',
+ output.path,
+ '--packages',
+ (await packageConfigUri).toFilePath(),
+ ]);
+ if (processResult.exitCode != 0 || !(await output.exists())) {
+ throw LoadException(path, '''
+exitCode: ${processResult.exitCode}
+stdout: ${processResult.stdout}
+stderr: ${processResult.stderr}''');
+ }
+ return output.path;
+ }
+
+ /// Spawns an isolate with the current configuration and passes it [message].
///
/// This isolate connects an [IsolateChannel] to [message] and sends the
/// serialized tests over that channel.
- Future<Isolate?> _spawnIsolate(
- String path, SendPort message, Metadata suiteMetadata) async {
+ ///
+ /// Returns `null` if an exception occurs but [close] has already been called.
+ Future<Isolate?> _spawnIsolate(String path, SendPort message,
+ Metadata suiteMetadata, Compiler compiler) async {
try {
var precompiledPath = _config.suiteDefaults.precompiledPath;
if (precompiledPath != null) {
- return _spawnPrecompiledIsolate(path, message, precompiledPath);
+ return _spawnPrecompiledIsolate(
+ path, message, precompiledPath, compiler);
} else if (_config.pubServeUrl != null) {
- return _spawnPubServeIsolate(path, message, _config.pubServeUrl!);
- } else if (_config.useDataIsolateStrategy) {
- return _spawnDataIsolate(path, message, suiteMetadata);
- } else {
- return _spawnKernelIsolate(path, message, suiteMetadata);
+ return _spawnPubServeIsolate(
+ path, message, _config.pubServeUrl!, compiler);
}
+ return switch (compiler) {
+ Compiler.kernel => _spawnIsolateWithUri(
+ await _compileToKernel(path, suiteMetadata), message),
+ Compiler.source => _spawnIsolateWithUri(
+ _bootstrapIsolateTestFile(
+ path,
+ suiteMetadata.languageVersionComment ??
+ await rootPackageLanguageVersionComment),
+ message),
+ _ => throw StateError(
+ 'Unsupported compiler $compiler for the VM platform'),
+ };
} catch (_) {
if (_closeMemo.hasRun) return null;
rethrow;
}
}
- /// Compiles [path] to kernel using [_compiler] and spawns that in an
- /// isolate.
- Future<Isolate> _spawnKernelIsolate(
- String path, SendPort message, Metadata suiteMetadata) async {
+ /// Compiles [path] to kernel and returns the uri to the compiled dill.
+ Future<Uri> _compileToKernel(String path, Metadata suiteMetadata) async {
final response = await _compiler.compile(_absolute(path), suiteMetadata);
var compiledDill = response.kernelOutputUri?.toFilePath();
if (compiledDill == null || response.errorCount > 0) {
throw LoadException(path, response.compilerOutput ?? 'unknown error');
}
- return await Isolate.spawnUri(p.toUri(compiledDill), [], message,
+ return _absolute(compiledDill);
+ }
+
+ /// Runs [uri] in an isolate, passing [message].
+ Future<Isolate> _spawnIsolateWithUri(Uri uri, SendPort message) async {
+ return await Isolate.spawnUri(uri, [], message,
packageConfig: await packageConfigUri, checked: true);
}
- Future<Isolate> _spawnDataIsolate(
- String path, SendPort message, Metadata suiteMetadata) async {
- return await dart.runInIsolate('''
- ${suiteMetadata.languageVersionComment ?? await rootPackageLanguageVersionComment}
- import "dart:isolate";
- import "package:test_core/src/bootstrap/vm.dart";
- import "${_absolute(path)}" as test;
- void main(_, SendPort sendPort) {
- internalBootstrapVmTest(() => test.main, sendPort);
- }
- ''', message);
- }
-
- Future<Isolate> _spawnPrecompiledIsolate(
- String testPath, SendPort message, String precompiledPath) async {
+ Future<Isolate> _spawnPrecompiledIsolate(String testPath, SendPort message,
+ String precompiledPath, Compiler compiler) async {
testPath =
_absolute('${p.join(precompiledPath, testPath)}.vm_test.dart').path;
- var dillTestpath =
- '${testPath.substring(0, testPath.length - '.dart'.length)}.vm.app.dill';
- if (await File(dillTestpath).exists()) {
- testPath = dillTestpath;
+ switch (compiler) {
+ case Compiler.kernel:
+ var dillTestpath =
+ '${testPath.substring(0, testPath.length - '.dart'.length)}'
+ '.vm.app.dill';
+ if (await File(dillTestpath).exists()) {
+ testPath = dillTestpath;
+ }
+ // TODO: Compile to kernel manually here? Otherwise we aren't compiling
+ // with kernel when we technically should be, based on the compiler
+ // setting.
+ break;
+ case Compiler.source:
+ // Just leave test path as is.
+ break;
+ default:
+ throw StateError('Unsupported compiler for the VM platform $compiler.');
}
File? packageConfig =
File(p.join(precompiledPath, '.dart_tool/package_config.json'));
@@ -202,8 +294,69 @@
return await Isolate.spawnUri(p.toUri(testPath), [], message,
packageConfig: packageConfig?.uri, checked: true);
}
+
+ /// Bootstraps the test at [testPath] and writes its contents to a temporary
+ /// file.
+ ///
+ /// Returns the [Uri] to the created file.
+ Uri _bootstrapIsolateTestFile(
+ String testPath, String languageVersionComment) {
+ var file = File(p.join(
+ _tempDir.path, p.setExtension(testPath, '.bootstrap.isolate.dart')));
+ if (!file.existsSync()) {
+ file
+ ..createSync(recursive: true)
+ ..writeAsStringSync(_bootstrapIsolateTestContents(
+ _absolute(testPath), languageVersionComment));
+ }
+ return file.uri;
+ }
+
+ /// Bootstraps the test at [testPath] for native execution and writes its
+ /// contents to a temporary file.
+ ///
+ /// Returns the path to the created file.
+ String _bootstrapNativeTestFile(
+ String testPath, String languageVersionComment) {
+ var file = File(p.join(
+ _tempDir.path, p.setExtension(testPath, '.bootstrap.native.dart')));
+ if (!file.existsSync()) {
+ file
+ ..createSync(recursive: true)
+ ..writeAsStringSync(_bootstrapNativeTestContents(
+ _absolute(testPath), languageVersionComment));
+ }
+ return file.path;
+ }
}
+/// Creates bootstrap file contents for running [testUri] in a VM isolate.
+String _bootstrapIsolateTestContents(
+ Uri testUri, String languageVersionComment) =>
+ '''
+ $languageVersionComment
+ import "dart:isolate";
+ import "package:test_core/src/bootstrap/vm.dart";
+ import "$testUri" as test;
+ void main(_, SendPort sendPort) {
+ internalBootstrapVmTest(() => test.main, sendPort);
+ }
+ ''';
+
+/// Creates bootstrap file contents for running [testUri] as a native
+/// executable.
+String _bootstrapNativeTestContents(
+ Uri testUri, String languageVersionComment) =>
+ '''
+ $languageVersionComment
+ import "dart:isolate";
+ import "package:test_core/src/bootstrap/vm.dart";
+ import "$testUri" as test;
+ void main(List<String> args) {
+ internalBootstrapNativeTest(() => test.main, args);
+ }
+ ''';
+
Future<Map<String, dynamic>> _gatherCoverage(Environment environment) async {
final isolateId = Uri.parse(environment.observatoryUrl!.fragment)
.queryParameters['isolateId'];
@@ -211,8 +364,13 @@
isolateIds: {isolateId!});
}
-Future<Isolate> _spawnPubServeIsolate(
- String testPath, SendPort message, Uri pubServeUrl) async {
+Future<Isolate> _spawnPubServeIsolate(String testPath, SendPort message,
+ Uri pubServeUrl, Compiler compiler) async {
+ if (compiler != Compiler.source) {
+ throw ArgumentError(
+ 'The --pub-serve option requires the `--compiler none` option but the '
+ 'compiler was $compiler');
+ }
var url = pubServeUrl.resolveUri(
p.toUri('${p.relative(testPath, from: 'test')}.vm_test.dart'));
diff --git a/pkgs/test_core/lib/src/runner/vm/test_compiler.dart b/pkgs/test_core/lib/src/runner/vm/test_compiler.dart
index 9533473..ba3c4b7 100644
--- a/pkgs/test_core/lib/src/runner/vm/test_compiler.dart
+++ b/pkgs/test_core/lib/src/runner/vm/test_compiler.dart
@@ -10,9 +10,10 @@
import 'package:frontend_server_client/frontend_server_client.dart';
import 'package:path/path.dart' as p;
import 'package:pool/pool.dart';
-import 'package:test_api/backend.dart'; // ignore: deprecated_member_use
+import 'package:test_api/backend.dart';
import '../../util/dart.dart';
+import '../../util/io.dart';
import '../../util/package_config.dart';
import '../package_version.dart';
@@ -72,7 +73,7 @@
late final _outputDill =
File(p.join(_outputDillDirectory.path, 'output.dill'));
final _outputDillDirectory =
- Directory.systemTemp.createTempSync('dart_test.');
+ Directory.systemTemp.createTempSync('dart_test.kernel.');
// Used to create unique file names for final kernel files.
int _compileNumber = 0;
// The largest incremental dill file we created, will be cached under
@@ -158,13 +159,25 @@
final platformDill = 'lib/_internal/vm_platform_strong.dill';
final sdkRoot =
p.relative(p.dirname(p.dirname(Platform.resolvedExecutable)));
+ final packageConfigUriAwaited = await packageConfigUri;
+
+ // If we have native assets for the host os in JIT mode, they are here.
+ Uri? nativeAssetsYaml;
+ if (enabledExperiments.contains('native-assets')) {
+ nativeAssetsYaml = packageConfigUriAwaited.resolve('native_assets.yaml');
+ if (!await File.fromUri(nativeAssetsYaml).exists()) {
+ nativeAssetsYaml = null;
+ }
+ }
+
var client = _frontendServerClient = await FrontendServerClient.start(
testUri.toString(),
_outputDill.path,
platformDill,
enabledExperiments: enabledExperiments,
sdkRoot: sdkRoot,
- packagesJson: (await packageConfigUri).toFilePath(),
+ packagesJson: packageConfigUriAwaited.toFilePath(),
+ nativeAssets: nativeAssetsYaml?.toFilePath(),
printIncrementalDependencies: false,
);
return client.compile();
@@ -182,7 +195,7 @@
_frontendServerClient?.kill();
_frontendServerClient = null;
if (_outputDillDirectory.existsSync()) {
- _outputDillDirectory.deleteSync(recursive: true);
+ await _outputDillDirectory.deleteWithRetry();
}
});
}
diff --git a/pkgs/test_core/lib/src/util/errors.dart b/pkgs/test_core/lib/src/util/errors.dart
index d528cac..7ebea6e 100644
--- a/pkgs/test_core/lib/src/util/errors.dart
+++ b/pkgs/test_core/lib/src/util/errors.dart
@@ -10,5 +10,5 @@
///
/// Many exceptions include the exception class name at the beginning of their
/// [toString], so we remove that if it exists.
-String getErrorMessage(error) =>
+String getErrorMessage(Object error) =>
error.toString().replaceFirst(_exceptionPrefix, '');
diff --git a/pkgs/test_core/lib/src/util/io.dart b/pkgs/test_core/lib/src/util/io.dart
index da9f072..59e613c 100644
--- a/pkgs/test_core/lib/src/util/io.dart
+++ b/pkgs/test_core/lib/src/util/io.dart
@@ -7,9 +7,11 @@
import 'dart:core' as core;
import 'dart:core';
import 'dart:io';
+import 'dart:math';
import 'package:async/async.dart';
import 'package:path/path.dart' as p;
+import 'package:test_api/src/backend/compiler.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/operating_system.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
@@ -46,9 +48,11 @@
/// [inGoogle] determined automatically.
///
/// If [runtime] is a browser, this will set [os] to [OperatingSystem.none].
-SuitePlatform currentPlatform(Runtime runtime) => SuitePlatform(runtime,
- os: runtime.isBrowser ? OperatingSystem.none : currentOS,
- inGoogle: inGoogle);
+SuitePlatform currentPlatform(Runtime runtime, Compiler? compiler) =>
+ SuitePlatform(runtime,
+ compiler: compiler,
+ os: runtime.isBrowser ? OperatingSystem.none : currentOS,
+ inGoogle: inGoogle);
/// A transformer that decodes bytes using UTF-8 and splits them on newlines.
final lineSplitter = StreamTransformer<List<int>, String>(
@@ -109,7 +113,7 @@
return Future.sync(() {
var tempDir = createTempDir();
return Future.sync(() => fn(tempDir))
- .whenComplete(() => Directory(tempDir).deleteSync(recursive: true));
+ .whenComplete(() => Directory(tempDir).deleteWithRetry());
});
}
@@ -223,3 +227,19 @@
return base;
}
}
+
+extension RetryDelete on FileSystemEntity {
+ Future<void> deleteWithRetry() async {
+ var attempt = 0;
+ while (true) {
+ try {
+ await delete(recursive: true);
+ return;
+ } on FileSystemException {
+ if (attempt == 2) rethrow;
+ attempt++;
+ await Future.delayed(Duration(milliseconds: pow(10, attempt).toInt()));
+ }
+ }
+ }
+}
diff --git a/pkgs/test_core/lib/src/util/io_stub.dart b/pkgs/test_core/lib/src/util/io_stub.dart
index eee35d4..7953877 100644
--- a/pkgs/test_core/lib/src/util/io_stub.dart
+++ b/pkgs/test_core/lib/src/util/io_stub.dart
@@ -2,8 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:test_api/src/backend/compiler.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
-SuitePlatform currentPlatform(Runtime runtime) => throw UnsupportedError(
- 'Getting the current platform is only supported where dart:io exists');
+SuitePlatform currentPlatform(Runtime runtime, Compiler? compiler) =>
+ throw UnsupportedError(
+ 'Getting the current platform is only supported where dart:io exists');
diff --git a/pkgs/test_core/lib/src/util/pair.dart b/pkgs/test_core/lib/src/util/pair.dart
index 61dcff7..89a3d14 100644
--- a/pkgs/test_core/lib/src/util/pair.dart
+++ b/pkgs/test_core/lib/src/util/pair.dart
@@ -13,7 +13,7 @@
String toString() => '($first, $last)';
@override
- bool operator ==(other) {
+ bool operator ==(Object other) {
if (other is! Pair) return false;
return other.first == first && other.last == last;
}
diff --git a/pkgs/test_core/lib/src/util/stack_trace_mapper.dart b/pkgs/test_core/lib/src/util/stack_trace_mapper.dart
index 9e8650a..9d4248d 100644
--- a/pkgs/test_core/lib/src/util/stack_trace_mapper.dart
+++ b/pkgs/test_core/lib/src/util/stack_trace_mapper.dart
@@ -4,11 +4,10 @@
import 'package:source_map_stack_trace/source_map_stack_trace.dart' as mapper;
import 'package:source_maps/source_maps.dart';
-// ignore: deprecated_member_use
import 'package:test_api/backend.dart' show StackTraceMapper;
/// A class for mapping JS stack traces to Dart stack traces using source maps.
-class JSStackTraceMapper extends StackTraceMapper {
+class JSStackTraceMapper implements StackTraceMapper {
/// The parsed source map.
///
/// This is initialized lazily in `mapStackTrace()`.
diff --git a/pkgs/test_core/lib/src/util/string_literal_iterator.dart b/pkgs/test_core/lib/src/util/string_literal_iterator.dart
index 2a8b118..d58f64a 100644
--- a/pkgs/test_core/lib/src/util/string_literal_iterator.dart
+++ b/pkgs/test_core/lib/src/util/string_literal_iterator.dart
@@ -36,7 +36,7 @@
///
/// In addition to exposing the values of the runes themselves, this also
/// exposes the offset of the current rune in the Dart source file.
-class StringLiteralIterator extends Iterator<int> {
+class StringLiteralIterator implements Iterator<int> {
@override
int get current => _current!;
int? _current;
diff --git a/pkgs/test_core/lib/test_core.dart b/pkgs/test_core/lib/test_core.dart
index c603586..01f4454 100644
--- a/pkgs/test_core/lib/test_core.dart
+++ b/pkgs/test_core/lib/test_core.dart
@@ -6,12 +6,6 @@
'Please use package:test.')
library test_core;
-export 'package:test_api/expect.dart';
export 'package:test_api/hooks.dart' show TestFailure;
-// Not yet deprecated, but not exposed through focused libraries.
-export 'package:test_api/test_api.dart' show registerException;
-// Deprecated exports not surfaced through focused libraries.
-export 'package:test_api/test_api.dart'
- show ErrorFormatter, expectAsync, throws, Throws;
export 'scaffolding.dart';
diff --git a/pkgs/test_core/pubspec.yaml b/pkgs/test_core/pubspec.yaml
index 1244a99..afffdcb 100644
--- a/pkgs/test_core/pubspec.yaml
+++ b/pkgs/test_core/pubspec.yaml
@@ -1,19 +1,19 @@
name: test_core
-version: 0.4.23-dev
+version: 0.5.7-wip
description: A basic library for writing tests and running them on the VM.
repository: https://github.com/dart-lang/test/tree/master/pkgs/test_core
environment:
- sdk: '>=2.18.0 <3.0.0'
+ sdk: ^3.0.0
dependencies:
- analyzer: '>=3.3.0 <6.0.0'
- async: ^2.5.0
+ analyzer: '>=3.3.0 <7.0.0'
args: ^2.0.0
+ async: ^2.5.0
boolean_selector: ^2.1.0
collection: ^1.15.0
coverage: ^1.0.0
- frontend_server_client: '>=2.1.0 <4.0.0'
+ frontend_server_client: '>=3.2.0 <4.0.0'
glob: ^2.0.0
io: ^1.0.0
meta: ^1.3.0
@@ -25,12 +25,10 @@
source_span: ^1.8.0
stack_trace: ^1.10.0
stream_channel: ^2.1.0
- vm_service: ">=6.0.0 <11.0.0"
- yaml: ^3.0.0
- # matcher is tightly constrained by test_api
- matcher: any
# Use an exact version until the test_api package is stable.
- test_api: 0.4.18
+ test_api: 0.6.1
+ vm_service: ">=6.0.0 <12.0.0"
+ yaml: ^3.0.0
dev_dependencies:
- lints: '>=1.0.0 <3.0.0'
+ dart_flutter_team_lints: ^1.0.0
diff --git a/tool/ci.sh b/tool/ci.sh
index e8dec9f..a16044e 100755
--- a/tool/ci.sh
+++ b/tool/ci.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Created with package:mono_repo v6.5.0
+# Created with package:mono_repo v6.5.7
# Support built in commands on windows out of the box.
# When it is a flutter repo (check the pubspec.yaml for "sdk: flutter")
@@ -76,50 +76,54 @@
dart analyze || EXIT_CODE=$?
;;
command_00)
+ echo 'pushd /tmp && wget https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb && sudo dpkg -i google-chrome-beta_current_amd64.deb && popd && which google-chrome-beta'
+ pushd /tmp && wget https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb && sudo dpkg -i google-chrome-beta_current_amd64.deb && popd && which google-chrome-beta || EXIT_CODE=$?
+ ;;
+ command_01)
echo 'dart test'
dart test || EXIT_CODE=$?
;;
- command_01)
+ command_02)
echo 'xvfb-run -s "-screen 0 1024x768x24" dart test --preset travis --total-shards 5 --shard-index 0'
xvfb-run -s "-screen 0 1024x768x24" dart test --preset travis --total-shards 5 --shard-index 0 || EXIT_CODE=$?
;;
- command_02)
+ command_03)
echo 'xvfb-run -s "-screen 0 1024x768x24" dart test --preset travis --total-shards 5 --shard-index 1'
xvfb-run -s "-screen 0 1024x768x24" dart test --preset travis --total-shards 5 --shard-index 1 || EXIT_CODE=$?
;;
- command_03)
+ command_04)
echo 'xvfb-run -s "-screen 0 1024x768x24" dart test --preset travis --total-shards 5 --shard-index 2'
xvfb-run -s "-screen 0 1024x768x24" dart test --preset travis --total-shards 5 --shard-index 2 || EXIT_CODE=$?
;;
- command_04)
+ command_05)
echo 'xvfb-run -s "-screen 0 1024x768x24" dart test --preset travis --total-shards 5 --shard-index 3'
xvfb-run -s "-screen 0 1024x768x24" dart test --preset travis --total-shards 5 --shard-index 3 || EXIT_CODE=$?
;;
- command_05)
+ command_06)
echo 'xvfb-run -s "-screen 0 1024x768x24" dart test --preset travis --total-shards 5 --shard-index 4'
xvfb-run -s "-screen 0 1024x768x24" dart test --preset travis --total-shards 5 --shard-index 4 || EXIT_CODE=$?
;;
- command_06)
+ command_07)
echo 'dart test --preset travis --total-shards 5 --shard-index 0'
dart test --preset travis --total-shards 5 --shard-index 0 || EXIT_CODE=$?
;;
- command_07)
+ command_08)
echo 'dart test --preset travis --total-shards 5 --shard-index 1'
dart test --preset travis --total-shards 5 --shard-index 1 || EXIT_CODE=$?
;;
- command_08)
+ command_09)
echo 'dart test --preset travis --total-shards 5 --shard-index 2'
dart test --preset travis --total-shards 5 --shard-index 2 || EXIT_CODE=$?
;;
- command_09)
+ command_10)
echo 'dart test --preset travis --total-shards 5 --shard-index 3'
dart test --preset travis --total-shards 5 --shard-index 3 || EXIT_CODE=$?
;;
- command_10)
+ command_11)
echo 'dart test --preset travis --total-shards 5 --shard-index 4'
dart test --preset travis --total-shards 5 --shard-index 4 || EXIT_CODE=$?
;;
- command_11)
+ command_12)
echo 'dart test --preset travis -x browser'
dart test --preset travis -x browser || EXIT_CODE=$?
;;
@@ -127,10 +131,14 @@
echo 'dart format --output=none --set-exit-if-changed .'
dart format --output=none --set-exit-if-changed . || EXIT_CODE=$?
;;
- test)
+ test_0)
echo 'dart test -p chrome,vm,node'
dart test -p chrome,vm,node || EXIT_CODE=$?
;;
+ test_1)
+ echo 'dart test --timeout=60s'
+ dart test --timeout=60s || EXIT_CODE=$?
+ ;;
*)
echo -e "\033[31mUnknown TASK '${TASK}' - TERMINATING JOB\033[0m"
exit 64