diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index 43505523..a9b6c2fa 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -19,4 +19,4 @@ jobs:
- run: npm ci
- run: npm run lint
- run: npm run build
- - run: npm run tap
+ - run: npm run test:node
diff --git a/.nvmrc b/.nvmrc
index 6f7f377b..a45fd52c 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v16
+24
diff --git a/package-lock.json b/package-lock.json
index afda7ac2..350d3310 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -56,7 +56,6 @@
"scratch-storage": "2.3.1",
"script-loader": "0.7.2",
"stats.js": "0.17.0",
- "tap": "16.2.0",
"tiny-worker": "2.3.0",
"uglifyjs-webpack-plugin": "1.2.7",
"webpack": "4.47.0",
@@ -1876,136 +1875,6 @@
"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
"dev": true
},
- "node_modules/@istanbuljs/load-nyc-config": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
- "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
- "dev": true,
- "dependencies": {
- "camelcase": "^5.3.1",
- "find-up": "^4.1.0",
- "get-package-type": "^0.1.0",
- "js-yaml": "^3.13.1",
- "resolve-from": "^5.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "dev": true,
- "bin": {
- "esparse": "bin/esparse.js",
- "esvalidate": "bin/esvalidate.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
- "dev": true,
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/schema": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
- "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
@@ -2522,19 +2391,6 @@
"node": ">=0.3.0"
}
},
- "node_modules/aggregate-error": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
- "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
- "dev": true,
- "dependencies": {
- "clean-stack": "^2.0.0",
- "indent-string": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -2621,7 +2477,7 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "devOptional": true,
+ "optional": true,
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
@@ -2630,18 +2486,6 @@
"node": ">= 8"
}
},
- "node_modules/append-transform": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz",
- "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==",
- "dev": true,
- "dependencies": {
- "default-require-extensions": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/aproba": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
@@ -2668,12 +2512,6 @@
"node": ">=4"
}
},
- "node_modules/archy": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
- "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==",
- "dev": true
- },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -2943,15 +2781,6 @@
}
]
},
- "node_modules/async-hook-domain": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-2.0.4.tgz",
- "integrity": "sha512-14LjCmlK1PK8eDtTezR6WX8TMaYNIzBIsd2D1sGoGjgx0BuNMMoSdk7i/drlbtamy0AWv9yv2tkB+ASdmeqFIw==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/async-limiter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
@@ -3308,20 +3137,11 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "devOptional": true,
+ "optional": true,
"engines": {
"node": ">=8"
}
},
- "node_modules/bind-obj-methods": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-3.0.0.tgz",
- "integrity": "sha512-nLEaaz3/sEzNSyPWRsN9HNsqwk1AUyECtGj+XwGdIi3xABnEqecvXtIJ0wehQXuuER5uZ/5fTs2usONgYjG+iw==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
@@ -3482,8 +3302,8 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"fill-range": "^7.1.1"
},
@@ -3848,21 +3668,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/caching-transform": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
- "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
- "dev": true,
- "dependencies": {
- "hasha": "^5.0.0",
- "make-dir": "^3.0.0",
- "package-hash": "^4.0.0",
- "write-file-atomic": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/call-bind": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
@@ -4020,13 +3825,13 @@
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
- "devOptional": true,
"funding": [
{
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
],
+ "optional": true,
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
@@ -4047,7 +3852,7 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "devOptional": true,
+ "optional": true,
"dependencies": {
"is-glob": "^4.0.1"
},
@@ -4121,15 +3926,6 @@
"node": ">= 0.4"
}
},
- "node_modules/clean-stack": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
- "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/cli-cursor": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
@@ -4148,17 +3944,6 @@
"integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
"dev": true
},
- "node_modules/cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^7.0.0"
- }
- },
"node_modules/clone-response": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
@@ -4214,15 +3999,6 @@
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
},
- "node_modules/color-support": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
- "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
- "dev": true,
- "bin": {
- "color-support": "bin.js"
- }
- },
"node_modules/colors": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
@@ -4959,21 +4735,6 @@
"node": ">=6"
}
},
- "node_modules/default-require-extensions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz",
- "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==",
- "dev": true,
- "dependencies": {
- "strip-bom": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/define-data-property": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
@@ -5121,15 +4882,6 @@
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
"dev": true
},
- "node_modules/diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
- "dev": true,
- "engines": {
- "node": ">=0.3.1"
- }
- },
"node_modules/diff-match-patch": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.4.tgz",
@@ -5480,12 +5232,6 @@
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
},
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
"node_modules/emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
@@ -5752,12 +5498,6 @@
"node": ">=0.10"
}
},
- "node_modules/es6-error": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
- "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
- "dev": true
- },
"node_modules/es6-iterator": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
@@ -6445,12 +6185,6 @@
"node": ">=0.8.x"
}
},
- "node_modules/events-to-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz",
- "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==",
- "dev": true
- },
"node_modules/eventsource": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz",
@@ -7062,8 +6796,8 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"to-regex-range": "^5.0.1"
},
@@ -7140,12 +6874,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/findit": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz",
- "integrity": "sha512-ENZS237/Hr8bjczn5eKuBohLgaD0JyUd0arxretR1f9RO46vZHA1b2y0VorgGV3WaOT3c+78P8h7v4JGJ1i/rg==",
- "dev": true
- },
"node_modules/findup": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/findup/-/findup-0.1.5.tgz",
@@ -7286,19 +7014,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/foreground-child": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
- "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
- "dev": true,
- "dependencies": {
- "cross-spawn": "^7.0.0",
- "signal-exit": "^3.0.2"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
"node_modules/forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
@@ -7990,38 +7705,12 @@
"safe-buffer": "~5.1.0"
}
},
- "node_modules/fromentries": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
- "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
"node_modules/fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
"dev": true
},
- "node_modules/fs-exists-cached": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz",
- "integrity": "sha512-kSxoARUDn4F2RPXX48UXnaFKwVU7Ivd/6qpzZL29MCDmr9sTvybv4gFCp+qaI4fM9m0z9fgz/yJvi56GAz+BZg==",
- "dev": true
- },
"node_modules/fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
@@ -8111,12 +7800,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/function-loop": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-2.0.1.tgz",
- "integrity": "sha512-ktIR+O6i/4h+j/ZhZJNdzeI4i9lEPeEK6UPR2EVyTVBqOwcU3Za9xYKLH64ZR9HmcROyRrOkizNyjjtWJzDDkQ==",
- "dev": true
- },
"node_modules/function.prototype.name": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
@@ -8205,15 +7888,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/get-package-type": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
- "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
- "dev": true,
- "engines": {
- "node": ">=8.0.0"
- }
- },
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
@@ -8693,34 +8367,6 @@
"minimalistic-assert": "^1.0.1"
}
},
- "node_modules/hasha": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz",
- "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==",
- "dev": true,
- "dependencies": {
- "is-stream": "^2.0.0",
- "type-fest": "^0.8.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/hasha/node_modules/is-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@@ -8812,12 +8458,6 @@
"integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==",
"dev": true
},
- "node_modules/html-escaper": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true
- },
"node_modules/htmlparser2": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz",
@@ -9118,15 +8758,6 @@
"not-in-publish": "not-in-publish.js"
}
},
- "node_modules/indent-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/infer-owner": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
@@ -9409,7 +9040,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "devOptional": true,
+ "optional": true,
"dependencies": {
"binary-extensions": "^2.0.0"
},
@@ -9535,15 +9166,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/is-generator-function": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
@@ -9624,8 +9246,8 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"engines": {
"node": ">=0.12.0"
}
@@ -9919,193 +9541,6 @@
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
"dev": true
},
- "node_modules/istanbul-lib-coverage": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
- "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-hook": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz",
- "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==",
- "dev": true,
- "dependencies": {
- "append-transform": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-instrument": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
- "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
- "dev": true,
- "dependencies": {
- "@babel/core": "^7.7.5",
- "@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-coverage": "^3.0.0",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-processinfo": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz",
- "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==",
- "dev": true,
- "dependencies": {
- "archy": "^1.0.0",
- "cross-spawn": "^7.0.3",
- "istanbul-lib-coverage": "^3.2.0",
- "p-map": "^3.0.0",
- "rimraf": "^3.0.0",
- "uuid": "^8.3.2"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-processinfo/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/istanbul-lib-report": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
- "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
- "dev": true,
- "dependencies": {
- "istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^4.0.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-lib-report/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-report/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-lib-report/node_modules/make-dir": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
- "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
- "dev": true,
- "dependencies": {
- "semver": "^7.5.3"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/istanbul-lib-report/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-lib-report/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-report/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
- "node_modules/istanbul-lib-source-maps": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
- "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
- "dev": true,
- "dependencies": {
- "debug": "^4.1.1",
- "istanbul-lib-coverage": "^3.0.0",
- "source-map": "^0.6.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-lib-source-maps/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/istanbul-reports": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz",
- "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==",
- "dev": true,
- "dependencies": {
- "html-escaper": "^2.0.0",
- "istanbul-lib-report": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/isurl": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
@@ -10133,18 +9568,6 @@
"set-function-name": "^2.0.1"
}
},
- "node_modules/jackspeak": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.2.tgz",
- "integrity": "sha512-GHeGTmnuaHnvS+ZctRB01bfxARuu9wW83ENbuiweu07SFcVlZrJpcshSre/keGT7YGBhLHg/+rXCNSrsEHKU4Q==",
- "dev": true,
- "dependencies": {
- "cliui": "^7.0.4"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/js-md5": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
@@ -10441,33 +9864,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/libtap": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.4.1.tgz",
- "integrity": "sha512-S9v19shLTigoMn3c02V7LZ4t09zxmVP3r3RbEAwuHFYeKgF+ESFJxoQ0PMFKW4XdgQhcjVBEwDoopG6WROq/gw==",
- "dev": true,
- "dependencies": {
- "async-hook-domain": "^2.0.4",
- "bind-obj-methods": "^3.0.0",
- "diff": "^4.0.2",
- "function-loop": "^2.0.1",
- "minipass": "^3.1.5",
- "own-or": "^1.0.0",
- "own-or-env": "^1.0.2",
- "signal-exit": "^3.0.4",
- "stack-utils": "^2.0.4",
- "tap-parser": "^11.0.0",
- "tap-yaml": "^1.0.0",
- "tcompare": "^5.0.6",
- "trivial-deferred": "^1.0.1"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/lie": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
@@ -10570,12 +9966,6 @@
"integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
"dev": true
},
- "node_modules/lodash.flattendeep": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
- "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==",
- "dev": true
- },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -11132,24 +10522,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minipass/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"node_modules/mississippi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz",
@@ -11530,18 +10902,6 @@
"safe-buffer": "~5.1.0"
}
},
- "node_modules/node-preload": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
- "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==",
- "dev": true,
- "dependencies": {
- "process-on-spawn": "^1.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/node-releases": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
@@ -11628,132 +10988,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/nyc": {
- "version": "15.1.0",
- "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz",
- "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==",
- "dev": true,
- "dependencies": {
- "@istanbuljs/load-nyc-config": "^1.0.0",
- "@istanbuljs/schema": "^0.1.2",
- "caching-transform": "^4.0.0",
- "convert-source-map": "^1.7.0",
- "decamelize": "^1.2.0",
- "find-cache-dir": "^3.2.0",
- "find-up": "^4.1.0",
- "foreground-child": "^2.0.0",
- "get-package-type": "^0.1.0",
- "glob": "^7.1.6",
- "istanbul-lib-coverage": "^3.0.0",
- "istanbul-lib-hook": "^3.0.0",
- "istanbul-lib-instrument": "^4.0.0",
- "istanbul-lib-processinfo": "^2.0.2",
- "istanbul-lib-report": "^3.0.0",
- "istanbul-lib-source-maps": "^4.0.0",
- "istanbul-reports": "^3.0.2",
- "make-dir": "^3.0.0",
- "node-preload": "^0.2.1",
- "p-map": "^3.0.0",
- "process-on-spawn": "^1.0.0",
- "resolve-from": "^5.0.0",
- "rimraf": "^3.0.0",
- "signal-exit": "^3.0.2",
- "spawn-wrap": "^2.0.0",
- "test-exclude": "^6.0.0",
- "yargs": "^15.0.2"
- },
- "bin": {
- "nyc": "bin/nyc.js"
- },
- "engines": {
- "node": ">=8.9"
- }
- },
- "node_modules/nyc/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/nyc/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/nyc/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/nyc/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/nyc/node_modules/p-try": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/nyc/node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/nyc/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@@ -12007,15 +11241,6 @@
"node": ">=4"
}
},
- "node_modules/opener": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
- "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
- "dev": true,
- "bin": {
- "opener": "bin/opener-bin.js"
- }
- },
"node_modules/opn": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
@@ -12082,21 +11307,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/own-or": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz",
- "integrity": "sha512-NfZr5+Tdf6MB8UI9GLvKRs4cXY8/yB0w3xtt84xFdWy8hkGjn+JFc60VhzS/hFRfbyxFcGYMTjnF4Me+RbbqrA==",
- "dev": true
- },
- "node_modules/own-or-env": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.2.tgz",
- "integrity": "sha512-NQ7v0fliWtK7Lkb+WdFqe6ky9XAzYmlkXthQrBbzlYbmFKoAYbDDcwmOm6q8kOuwSRXW8bdL5ORksploUJmWgw==",
- "dev": true,
- "dependencies": {
- "own-or": "^1.0.0"
- }
- },
"node_modules/p-cancelable": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
@@ -12187,18 +11397,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/p-map": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
- "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
- "dev": true,
- "dependencies": {
- "aggregate-error": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/p-retry": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz",
@@ -12232,21 +11430,6 @@
"node": ">=4"
}
},
- "node_modules/package-hash": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz",
- "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.15",
- "hasha": "^5.0.0",
- "lodash.flattendeep": "^4.4.0",
- "release-zalgo": "^1.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -12440,7 +11623,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "devOptional": true,
+ "optional": true,
"engines": {
"node": ">=8.6"
},
@@ -12628,18 +11811,6 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
- "node_modules/process-on-spawn": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
- "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==",
- "dev": true,
- "dependencies": {
- "fromentries": "^1.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/progress": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
@@ -12906,7 +12077,7 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "devOptional": true,
+ "optional": true,
"dependencies": {
"picomatch": "^2.2.1"
},
@@ -13076,18 +12247,6 @@
"jsesc": "bin/jsesc"
}
},
- "node_modules/release-zalgo": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
- "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==",
- "dev": true,
- "dependencies": {
- "es6-error": "^4.0.1"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -14494,38 +13653,6 @@
"integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
"deprecated": "See https://github.com/lydell/source-map-url#deprecated"
},
- "node_modules/spawn-wrap": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
- "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
- "dev": true,
- "dependencies": {
- "foreground-child": "^2.0.0",
- "is-windows": "^1.0.2",
- "make-dir": "^3.0.0",
- "rimraf": "^3.0.0",
- "signal-exit": "^3.0.2",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/spawn-wrap/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/spdx-correct": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
@@ -14639,27 +13766,6 @@
"safe-buffer": "^5.1.1"
}
},
- "node_modules/stack-utils": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
- "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
- "dev": true,
- "dependencies": {
- "escape-string-regexp": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/stack-utils/node_modules/escape-string-regexp": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
- "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/startaudiocontext": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/startaudiocontext/-/startaudiocontext-1.2.1.tgz",
@@ -14950,20 +14056,6 @@
"safe-buffer": "~5.2.0"
}
},
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/string.prototype.matchall": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz",
@@ -15045,15 +14137,6 @@
"node": ">=8"
}
},
- "node_modules/strip-bom": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
- "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/strip-dirs": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz",
@@ -15257,2011 +14340,6 @@
"integrity": "sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA==",
"dev": true
},
- "node_modules/tap": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/tap/-/tap-16.2.0.tgz",
- "integrity": "sha512-ikfNLy701p2+sH3R0pAXQ/Aen6ZByaguUY7UsoTLL4AXa2c9gYQL+pI21p13lq54R7/CEoLaViC1sexcWG32ig==",
- "bundleDependencies": [
- "ink",
- "treport",
- "@types/react",
- "@isaacs/import-jsx",
- "react"
- ],
- "dev": true,
- "dependencies": {
- "@isaacs/import-jsx": "^4.0.1",
- "@types/react": "^17",
- "chokidar": "^3.3.0",
- "findit": "^2.0.0",
- "foreground-child": "^2.0.0",
- "fs-exists-cached": "^1.0.0",
- "glob": "^7.1.6",
- "ink": "^3.2.0",
- "isexe": "^2.0.0",
- "istanbul-lib-processinfo": "^2.0.2",
- "jackspeak": "^1.4.1",
- "libtap": "^1.4.0",
- "minipass": "^3.1.1",
- "mkdirp": "^1.0.4",
- "nyc": "^15.1.0",
- "opener": "^1.5.1",
- "react": "^17.0.2",
- "rimraf": "^3.0.0",
- "signal-exit": "^3.0.6",
- "source-map-support": "^0.5.16",
- "tap-mocha-reporter": "^5.0.3",
- "tap-parser": "^11.0.1",
- "tap-yaml": "^1.0.0",
- "tcompare": "^5.0.7",
- "treport": "^3.0.3",
- "which": "^2.0.2"
- },
- "bin": {
- "tap": "bin/run.js"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- },
- "peerDependencies": {
- "coveralls": "^3.1.1",
- "flow-remove-types": ">=2.112.0",
- "ts-node": ">=8.5.2",
- "typescript": ">=3.7.2"
- },
- "peerDependenciesMeta": {
- "coveralls": {
- "optional": true
- },
- "flow-remove-types": {
- "optional": true
- },
- "ts-node": {
- "optional": true
- },
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/tap-mocha-reporter": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.4.tgz",
- "integrity": "sha512-J+YMO8B7lq1O6Zxd/jeuG27vJ+Y4tLiRMKPSb7KR6FVh86k3Rq1TwYc2GKPyIjCbzzdMdReh3Vfz9L5cg1Z2Bw==",
- "dev": true,
- "dependencies": {
- "color-support": "^1.1.0",
- "debug": "^4.1.1",
- "diff": "^4.0.1",
- "escape-string-regexp": "^2.0.0",
- "glob": "^7.0.5",
- "tap-parser": "^11.0.0",
- "tap-yaml": "^1.0.0",
- "unicode-length": "^2.0.2"
- },
- "bin": {
- "tap-mocha-reporter": "index.js"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/tap-mocha-reporter/node_modules/escape-string-regexp": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
- "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap-parser": {
- "version": "11.0.2",
- "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-11.0.2.tgz",
- "integrity": "sha512-6qGlC956rcORw+fg7Fv1iCRAY8/bU9UabUAhs3mXRH6eRmVZcNPLheSXCYaVaYeSwx5xa/1HXZb1537YSvwDZg==",
- "dev": true,
- "dependencies": {
- "events-to-array": "^1.0.1",
- "minipass": "^3.1.6",
- "tap-yaml": "^1.0.0"
- },
- "bin": {
- "tap-parser": "bin/cmd.js"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/tap-yaml": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.2.tgz",
- "integrity": "sha512-GegASpuqBnRNdT1U+yuUPZ8rEU64pL35WPBpCISWwff4dErS2/438barz7WFJl4Nzh3Y05tfPidZnH+GaV1wMg==",
- "dev": true,
- "dependencies": {
- "yaml": "^1.10.2"
- }
- },
- "node_modules/tap/node_modules/@ampproject/remapping": {
- "version": "2.1.2",
- "dev": true,
- "inBundle": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.0"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/tap/node_modules/@babel/code-frame": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/highlight": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/compat-data": {
- "version": "7.17.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/core": {
- "version": "7.17.8",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@ampproject/remapping": "^2.1.0",
- "@babel/code-frame": "^7.16.7",
- "@babel/generator": "^7.17.7",
- "@babel/helper-compilation-targets": "^7.17.7",
- "@babel/helper-module-transforms": "^7.17.7",
- "@babel/helpers": "^7.17.8",
- "@babel/parser": "^7.17.8",
- "@babel/template": "^7.16.7",
- "@babel/traverse": "^7.17.3",
- "@babel/types": "^7.17.0",
- "convert-source-map": "^1.7.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.1.2",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/tap/node_modules/@babel/generator": {
- "version": "7.17.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.17.0",
- "jsesc": "^2.5.1",
- "source-map": "^0.5.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-compilation-targets": {
- "version": "7.17.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.17.7",
- "@babel/helper-validator-option": "^7.16.7",
- "browserslist": "^4.17.5",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-environment-visitor": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-function-name": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-get-function-arity": "^7.16.7",
- "@babel/template": "^7.16.7",
- "@babel/types": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-get-function-arity": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-hoist-variables": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-module-imports": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-module-transforms": {
- "version": "7.17.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-environment-visitor": "^7.16.7",
- "@babel/helper-module-imports": "^7.16.7",
- "@babel/helper-simple-access": "^7.17.7",
- "@babel/helper-split-export-declaration": "^7.16.7",
- "@babel/helper-validator-identifier": "^7.16.7",
- "@babel/template": "^7.16.7",
- "@babel/traverse": "^7.17.3",
- "@babel/types": "^7.17.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-plugin-utils": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-simple-access": {
- "version": "7.17.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.17.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-split-export-declaration": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-validator-identifier": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helper-validator-option": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/helpers": {
- "version": "7.17.8",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.16.7",
- "@babel/traverse": "^7.17.3",
- "@babel/types": "^7.17.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/highlight": {
- "version": "7.16.10",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.16.7",
- "chalk": "^2.0.0",
- "js-tokens": "^4.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/parser": {
- "version": "7.17.8",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/tap/node_modules/@babel/plugin-proposal-object-rest-spread": {
- "version": "7.17.3",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.17.0",
- "@babel/helper-compilation-targets": "^7.16.7",
- "@babel/helper-plugin-utils": "^7.16.7",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-transform-parameters": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/tap/node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/tap/node_modules/@babel/plugin-syntax-object-rest-spread": {
- "version": "7.8.3",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/tap/node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.17.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/tap/node_modules/@babel/plugin-transform-parameters": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/tap/node_modules/@babel/plugin-transform-react-jsx": {
- "version": "7.17.3",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.16.7",
- "@babel/helper-module-imports": "^7.16.7",
- "@babel/helper-plugin-utils": "^7.16.7",
- "@babel/plugin-syntax-jsx": "^7.16.7",
- "@babel/types": "^7.17.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/tap/node_modules/@babel/template": {
- "version": "7.16.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.16.7",
- "@babel/parser": "^7.16.7",
- "@babel/types": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/traverse": {
- "version": "7.17.3",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.16.7",
- "@babel/generator": "^7.17.3",
- "@babel/helper-environment-visitor": "^7.16.7",
- "@babel/helper-function-name": "^7.16.7",
- "@babel/helper-hoist-variables": "^7.16.7",
- "@babel/helper-split-export-declaration": "^7.16.7",
- "@babel/parser": "^7.17.3",
- "@babel/types": "^7.17.0",
- "debug": "^4.1.0",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@babel/types": {
- "version": "7.17.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.16.7",
- "to-fast-properties": "^2.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/@isaacs/import-jsx": {
- "version": "4.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.5.5",
- "@babel/plugin-proposal-object-rest-spread": "^7.5.5",
- "@babel/plugin-transform-destructuring": "^7.5.0",
- "@babel/plugin-transform-react-jsx": "^7.3.0",
- "caller-path": "^3.0.1",
- "find-cache-dir": "^3.2.0",
- "make-dir": "^3.0.2",
- "resolve-from": "^3.0.0",
- "rimraf": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/tap/node_modules/@jridgewell/resolve-uri": {
- "version": "3.0.5",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/tap/node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.11",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.4",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.0.3",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- }
- },
- "node_modules/tap/node_modules/@types/prop-types": {
- "version": "15.7.4",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/@types/react": {
- "version": "17.0.41",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@types/prop-types": "*",
- "@types/scheduler": "*",
- "csstype": "^3.0.2"
- }
- },
- "node_modules/tap/node_modules/@types/scheduler": {
- "version": "0.16.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/@types/yoga-layout": {
- "version": "1.9.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/ansi-escapes": {
- "version": "4.3.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "type-fest": "^0.21.3"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/tap/node_modules/ansi-escapes/node_modules/type-fest": {
- "version": "0.21.3",
- "dev": true,
- "inBundle": true,
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/tap/node_modules/ansi-regex": {
- "version": "5.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/ansi-styles": {
- "version": "3.2.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tap/node_modules/ansicolors": {
- "version": "0.3.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/astral-regex": {
- "version": "2.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/auto-bind": {
- "version": "4.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/tap/node_modules/balanced-match": {
- "version": "1.0.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/brace-expansion": {
- "version": "1.1.11",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/tap/node_modules/browserslist": {
- "version": "4.20.2",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- }
- ],
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "caniuse-lite": "^1.0.30001317",
- "electron-to-chromium": "^1.4.84",
- "escalade": "^3.1.1",
- "node-releases": "^2.0.2",
- "picocolors": "^1.0.0"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/tap/node_modules/caller-callsite": {
- "version": "4.1.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "callsites": "^3.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/caller-path": {
- "version": "3.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "caller-callsite": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/callsites": {
- "version": "3.1.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tap/node_modules/caniuse-lite": {
- "version": "1.0.30001319",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- }
- ],
- "inBundle": true,
- "license": "CC-BY-4.0"
- },
- "node_modules/tap/node_modules/cardinal": {
- "version": "2.1.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansicolors": "~0.3.2",
- "redeyed": "~2.1.0"
- },
- "bin": {
- "cdl": "bin/cdl.js"
- }
- },
- "node_modules/tap/node_modules/chalk": {
- "version": "2.4.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tap/node_modules/ci-info": {
- "version": "2.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/cli-boxes": {
- "version": "2.2.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/tap/node_modules/cli-cursor": {
- "version": "3.1.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "restore-cursor": "^3.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/cli-truncate": {
- "version": "2.1.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "slice-ansi": "^3.0.0",
- "string-width": "^4.2.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/tap/node_modules/code-excerpt": {
- "version": "3.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "convert-to-spaces": "^1.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/tap/node_modules/color-convert": {
- "version": "1.9.3",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/tap/node_modules/color-name": {
- "version": "1.1.3",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/commondir": {
- "version": "1.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/concat-map": {
- "version": "0.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/convert-source-map": {
- "version": "1.8.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "~5.1.1"
- }
- },
- "node_modules/tap/node_modules/convert-to-spaces": {
- "version": "1.0.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/tap/node_modules/csstype": {
- "version": "3.0.11",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/debug": {
- "version": "4.3.4",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/tap/node_modules/electron-to-chromium": {
- "version": "1.4.89",
- "dev": true,
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/tap/node_modules/emoji-regex": {
- "version": "8.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/escalade": {
- "version": "3.1.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tap/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/tap/node_modules/esprima": {
- "version": "4.0.1",
- "dev": true,
- "inBundle": true,
- "license": "BSD-2-Clause",
- "bin": {
- "esparse": "bin/esparse.js",
- "esvalidate": "bin/esvalidate.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tap/node_modules/events-to-array": {
- "version": "1.1.2",
- "dev": true,
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/tap/node_modules/find-cache-dir": {
- "version": "3.3.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "commondir": "^1.0.1",
- "make-dir": "^3.0.2",
- "pkg-dir": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
- }
- },
- "node_modules/tap/node_modules/find-up": {
- "version": "4.1.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/fs.realpath": {
- "version": "1.0.0",
- "dev": true,
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/tap/node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/tap/node_modules/glob": {
- "version": "7.2.0",
- "dev": true,
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/tap/node_modules/globals": {
- "version": "11.12.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tap/node_modules/has-flag": {
- "version": "3.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tap/node_modules/indent-string": {
- "version": "4.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/inflight": {
- "version": "1.0.6",
- "dev": true,
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/tap/node_modules/inherits": {
- "version": "2.0.4",
- "dev": true,
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/tap/node_modules/ink": {
- "version": "3.2.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-escapes": "^4.2.1",
- "auto-bind": "4.0.0",
- "chalk": "^4.1.0",
- "cli-boxes": "^2.2.0",
- "cli-cursor": "^3.1.0",
- "cli-truncate": "^2.1.0",
- "code-excerpt": "^3.0.0",
- "indent-string": "^4.0.0",
- "is-ci": "^2.0.0",
- "lodash": "^4.17.20",
- "patch-console": "^1.0.0",
- "react-devtools-core": "^4.19.1",
- "react-reconciler": "^0.26.2",
- "scheduler": "^0.20.2",
- "signal-exit": "^3.0.2",
- "slice-ansi": "^3.0.0",
- "stack-utils": "^2.0.2",
- "string-width": "^4.2.2",
- "type-fest": "^0.12.0",
- "widest-line": "^3.1.0",
- "wrap-ansi": "^6.2.0",
- "ws": "^7.5.5",
- "yoga-layout-prebuilt": "^1.9.6"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "@types/react": ">=16.8.0",
- "react": ">=16.8.0"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/tap/node_modules/ink/node_modules/ansi-styles": {
- "version": "4.3.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/tap/node_modules/ink/node_modules/chalk": {
- "version": "4.1.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/tap/node_modules/ink/node_modules/color-convert": {
- "version": "2.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/tap/node_modules/ink/node_modules/color-name": {
- "version": "1.1.4",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/ink/node_modules/has-flag": {
- "version": "4.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/ink/node_modules/supports-color": {
- "version": "7.2.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/is-ci": {
- "version": "2.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ci-info": "^2.0.0"
- },
- "bin": {
- "is-ci": "bin.js"
- }
- },
- "node_modules/tap/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/js-tokens": {
- "version": "4.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/jsesc": {
- "version": "2.5.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tap/node_modules/json5": {
- "version": "2.2.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tap/node_modules/locate-path": {
- "version": "5.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/lodash": {
- "version": "4.17.21",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/loose-envify": {
- "version": "1.4.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "loose-envify": "cli.js"
- }
- },
- "node_modules/tap/node_modules/make-dir": {
- "version": "3.1.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/tap/node_modules/mimic-fn": {
- "version": "2.1.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tap/node_modules/minimatch": {
- "version": "3.1.2",
- "dev": true,
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/tap/node_modules/minipass": {
- "version": "3.1.6",
- "dev": true,
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "dev": true,
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/tap/node_modules/ms": {
- "version": "2.1.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/node-releases": {
- "version": "2.0.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/object-assign": {
- "version": "4.1.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tap/node_modules/once": {
- "version": "1.4.0",
- "dev": true,
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/tap/node_modules/onetime": {
- "version": "5.1.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "mimic-fn": "^2.1.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/tap/node_modules/p-limit": {
- "version": "2.3.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/tap/node_modules/p-locate": {
- "version": "4.1.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/p-try": {
- "version": "2.2.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tap/node_modules/patch-console": {
- "version": "1.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/tap/node_modules/path-exists": {
- "version": "4.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/path-is-absolute": {
- "version": "1.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tap/node_modules/picocolors": {
- "version": "1.0.0",
- "dev": true,
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/tap/node_modules/pkg-dir": {
- "version": "4.2.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "find-up": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/punycode": {
- "version": "2.1.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tap/node_modules/react": {
- "version": "17.0.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tap/node_modules/react-devtools-core": {
- "version": "4.24.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "shell-quote": "^1.6.1",
- "ws": "^7"
- }
- },
- "node_modules/tap/node_modules/react-reconciler": {
- "version": "0.26.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1",
- "scheduler": "^0.20.2"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "peerDependencies": {
- "react": "^17.0.2"
- }
- },
- "node_modules/tap/node_modules/redeyed": {
- "version": "2.1.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "esprima": "~4.0.0"
- }
- },
- "node_modules/tap/node_modules/resolve-from": {
- "version": "3.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tap/node_modules/restore-cursor": {
- "version": "3.1.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "onetime": "^5.1.0",
- "signal-exit": "^3.0.2"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/rimraf": {
- "version": "3.0.2",
- "dev": true,
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/tap/node_modules/safe-buffer": {
- "version": "5.1.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/scheduler": {
- "version": "0.20.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1"
- }
- },
- "node_modules/tap/node_modules/semver": {
- "version": "6.3.0",
- "dev": true,
- "inBundle": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/tap/node_modules/shell-quote": {
- "version": "1.7.3",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/signal-exit": {
- "version": "3.0.7",
- "dev": true,
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/tap/node_modules/slice-ansi": {
- "version": "3.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/slice-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/tap/node_modules/slice-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/tap/node_modules/slice-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/source-map": {
- "version": "0.5.7",
- "dev": true,
- "inBundle": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tap/node_modules/stack-utils": {
- "version": "2.0.5",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "escape-string-regexp": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/tap/node_modules/stack-utils/node_modules/escape-string-regexp": {
- "version": "2.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/string-width": {
- "version": "4.2.3",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/strip-ansi": {
- "version": "6.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/supports-color": {
- "version": "5.5.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tap/node_modules/tap-parser": {
- "version": "11.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "events-to-array": "^1.0.1",
- "minipass": "^3.1.6",
- "tap-yaml": "^1.0.0"
- },
- "bin": {
- "tap-parser": "bin/cmd.js"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/tap/node_modules/tap-yaml": {
- "version": "1.0.0",
- "dev": true,
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "yaml": "^1.5.0"
- }
- },
- "node_modules/tap/node_modules/to-fast-properties": {
- "version": "2.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tap/node_modules/treport": {
- "version": "3.0.3",
- "dev": true,
- "inBundle": true,
- "license": "ISC",
- "dependencies": {
- "@isaacs/import-jsx": "^4.0.1",
- "cardinal": "^2.1.1",
- "chalk": "^3.0.0",
- "ink": "^3.2.0",
- "ms": "^2.1.2",
- "tap-parser": "^11.0.0",
- "unicode-length": "^2.0.2"
- },
- "peerDependencies": {
- "react": "^17.0.2"
- }
- },
- "node_modules/tap/node_modules/treport/node_modules/ansi-styles": {
- "version": "4.3.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/tap/node_modules/treport/node_modules/chalk": {
- "version": "3.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/treport/node_modules/color-convert": {
- "version": "2.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/tap/node_modules/treport/node_modules/color-name": {
- "version": "1.1.4",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/treport/node_modules/has-flag": {
- "version": "4.0.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/treport/node_modules/supports-color": {
- "version": "7.2.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/type-fest": {
- "version": "0.12.0",
- "dev": true,
- "inBundle": true,
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/tap/node_modules/unicode-length": {
- "version": "2.0.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "punycode": "^2.0.0",
- "strip-ansi": "^3.0.1"
- }
- },
- "node_modules/tap/node_modules/unicode-length/node_modules/ansi-regex": {
- "version": "2.1.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tap/node_modules/unicode-length/node_modules/strip-ansi": {
- "version": "3.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^2.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tap/node_modules/widest-line": {
- "version": "3.1.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "string-width": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/wrap-ansi": {
- "version": "6.2.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tap/node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/tap/node_modules/wrap-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/tap/node_modules/wrap-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "dev": true,
- "inBundle": true,
- "license": "MIT"
- },
- "node_modules/tap/node_modules/wrappy": {
- "version": "1.0.2",
- "dev": true,
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/tap/node_modules/ws": {
- "version": "7.5.7",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.3.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": "^5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
- }
- },
- "node_modules/tap/node_modules/yallist": {
- "version": "4.0.0",
- "dev": true,
- "inBundle": true,
- "license": "ISC"
- },
- "node_modules/tap/node_modules/yaml": {
- "version": "1.10.2",
- "dev": true,
- "inBundle": true,
- "license": "ISC",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/tap/node_modules/yoga-layout-prebuilt": {
- "version": "1.10.0",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "dependencies": {
- "@types/yoga-layout": "1.9.2"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/tapable": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
@@ -17324,18 +14402,6 @@
"safe-buffer": "~5.1.0"
}
},
- "node_modules/tcompare": {
- "version": "5.0.7",
- "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.7.tgz",
- "integrity": "sha512-d9iddt6YYGgyxJw5bjsN7UJUO1kGOtjSlNy/4PoGYAjQS5pAT/hzIoLf1bZCw+uUxRmZJh7Yy1aA7xKVRT9B4w==",
- "dev": true,
- "dependencies": {
- "diff": "^4.0.2"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/terser": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz",
@@ -17587,20 +14653,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/test-exclude": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
- "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
- "dev": true,
- "dependencies": {
- "@istanbuljs/schema": "^0.1.2",
- "glob": "^7.1.4",
- "minimatch": "^3.0.4"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/text-encoding": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz",
@@ -17773,8 +14825,8 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"is-number": "^7.0.0"
},
@@ -17848,15 +14900,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/trivial-deferred": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.1.2.tgz",
- "integrity": "sha512-vDPiDBC3hyP6O4JrJYMImW3nl3c03Tsj9fEXc7Qc/XKa1O7gf5ZtFfIR/E0dun9SnDHdwjna1Z2rSzYgqpxh/g==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
"node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -17910,15 +14953,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -18007,15 +15041,6 @@
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
},
- "node_modules/typedarray-to-buffer": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
- "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
- "dev": true,
- "dependencies": {
- "is-typedarray": "^1.0.0"
- }
- },
"node_modules/uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
@@ -18229,15 +15254,6 @@
"node": ">=4"
}
},
- "node_modules/unicode-length": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.1.0.tgz",
- "integrity": "sha512-4bV582zTV9Q02RXBxSUMiuN/KHo5w4aTojuKTNT96DIKps/SIawFp7cS5Mu25VuY1AioGXrmYyzKZUzh8OqoUw==",
- "dev": true,
- "dependencies": {
- "punycode": "^2.0.0"
- }
- },
"node_modules/unicode-match-property-ecmascript": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
@@ -20155,56 +17171,6 @@
"node": ">= 4"
}
},
- "node_modules/wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -20222,18 +17188,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/write-file-atomic": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
- "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
- "dev": true,
- "dependencies": {
- "imurmurhash": "^0.1.4",
- "is-typedarray": "^1.0.0",
- "signal-exit": "^3.0.2",
- "typedarray-to-buffer": "^3.1.5"
- }
- },
"node_modules/ws": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
@@ -20268,169 +17222,6 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
},
- "node_modules/yaml": {
- "version": "1.10.2",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
- "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
- "dev": true,
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/yargs": {
- "version": "15.4.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
- "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
- "dev": true,
- "dependencies": {
- "cliui": "^6.0.0",
- "decamelize": "^1.2.0",
- "find-up": "^4.1.0",
- "get-caller-file": "^2.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^2.0.0",
- "set-blocking": "^2.0.0",
- "string-width": "^4.2.0",
- "which-module": "^2.0.0",
- "y18n": "^4.0.0",
- "yargs-parser": "^18.1.2"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yargs-parser": {
- "version": "18.1.3",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
- "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
- "dev": true,
- "dependencies": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/yargs/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/yargs/node_modules/cliui": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
- "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^6.2.0"
- }
- },
- "node_modules/yargs/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/yargs/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/yargs/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yargs/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yargs/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/yargs/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yargs/node_modules/p-try": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/yargs/node_modules/wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
diff --git a/package.json b/package.json
index 3155445d..5c93e5d5 100644
--- a/package.json
+++ b/package.json
@@ -13,26 +13,19 @@
"browser": "./src/index.js",
"scripts": {
"build": "webpack --progress --colors --bail",
- "coverage": "tap ./test/{unit,integration}/*.js --coverage --coverage-report=lcov",
"docs": "jsdoc -c .jsdoc.json",
"i18n:src": "mkdirp translations/core && format-message extract --out-file translations/core/en.json src/extensions/**/index.js",
"i18n:push": "tx-push-src scratch-editor extensions translations/core/en.json",
"lint": "eslint .",
"prepublish": "in-publish && npm run build || not-in-publish",
"start": "webpack-dev-server",
- "tap": "tap ./test/{unit,integration}/*.js",
- "tap:unit": "tap ./test/unit/*.js",
- "tap:integration": "tap ./test/integration/*.js",
- "test": "npm run lint && npm run tap",
+ "test": "npm run lint && npm run test:node",
+ "test:node": "node --test --test-force-exit --test-timeout=30000 test/unit/*.js test/integration/*.js",
+ "test:unit": "node --test --test-force-exit --test-timeout=30000 test/unit/*.js",
+ "test:integration": "node --test --test-force-exit --test-timeout=30000 test/integration/*.js",
"watch": "webpack --progress --colors --watch",
"version": "json -f package.json -I -e \"this.repository.sha = '$(git log -n1 --pretty=format:%H)'\""
},
- "tap": {
- "branches": 60,
- "functions": 70,
- "lines": 70,
- "statements": 70
- },
"dependencies": {
"@turbowarp/json": "^0.1.2",
"@turbowarp/jszip": "^3.11.0",
@@ -84,7 +77,6 @@
"scratch-storage": "2.3.1",
"script-loader": "0.7.2",
"stats.js": "0.17.0",
- "tap": "16.2.0",
"tiny-worker": "2.3.0",
"uglifyjs-webpack-plugin": "1.2.7",
"webpack": "4.47.0",
diff --git a/test/fixtures/test-compare.js b/test/fixtures/test-compare.js
index 4aa625ea..23ae020f 100644
--- a/test/fixtures/test-compare.js
+++ b/test/fixtures/test-compare.js
@@ -1,14 +1,15 @@
-const testCompare = (t, lhs, op, rhs, message) => {
- const details = `Expected: ${lhs} ${op} ${rhs}`;
- const extra = {details};
+const assert = require('node:assert');
+
+const testCompare = (lhs, op, rhs, message) => {
+ const details = `${message}. Expected: ${lhs} ${op} ${rhs}`;
switch (op) {
- case '<': return t.ok(lhs < rhs, message, extra);
- case '<=': return t.ok(lhs <= rhs, message, extra);
- case '===': return t.ok(lhs === rhs, message, extra);
- case '!==': return t.ok(lhs !== rhs, message, extra);
- case '>=': return t.ok(lhs >= rhs, message, extra);
- case '>': return t.ok(lhs > rhs, message, extra);
- default: return t.fail(`Unrecognized op: ${op}`);
+ case '<': return assert.ok(lhs < rhs, details);
+ case '<=': return assert.ok(lhs <= rhs, details);
+ case '===': return assert.ok(lhs === rhs, details);
+ case '!==': return assert.ok(lhs !== rhs, details);
+ case '>=': return assert.ok(lhs >= rhs, details);
+ case '>': return assert.ok(lhs > rhs, details);
+ default: return assert.fail(`Unrecognized op: ${op}`);
}
};
diff --git a/test/integration/addSprite.js b/test/integration/addSprite.js
index 75024156..aa8eb628 100644
--- a/test/integration/addSprite.js
+++ b/test/integration/addSprite.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
@@ -11,12 +12,11 @@ const project = readFileToBuffer(projectUri);
const vm = new VirtualMachine();
-test('spec', t => {
- t.type(vm.addSprite, 'function');
- t.end();
+test('spec', () => {
+ assert.strictEqual(typeof vm.addSprite, 'function');
});
-test('default cat', t => {
+test('default cat', (t, done) => {
// Get default cat from .sprite2
const uri = path.resolve(__dirname, '../fixtures/example_sprite.sprite2');
const sprite = readFileToBuffer(uri);
@@ -26,50 +26,50 @@ test('default cat', t => {
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length === 0);
+ assert.ok(threads.length === 0);
vm.quit();
- t.end();
+ done();
});
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.loadProject(project).then(() => {
- t.equal(vm.runtime.targets.length, 2); // stage and default sprite
+ assert.strictEqual(vm.runtime.targets.length, 2); // stage and default sprite
// Add another sprite
vm.addSprite(sprite).then(() => {
const targets = vm.runtime.targets;
// Test
- t.type(targets, 'object');
- t.equal(targets.length, 3);
+ assert.strictEqual(typeof targets, 'object');
+ assert.strictEqual(targets.length, 3);
const newTarget = targets[2];
- t.ok(newTarget instanceof RenderedTarget);
- t.type(newTarget.id, 'string');
- t.type(newTarget.blocks, 'object');
- t.type(newTarget.variables, 'object');
+ assert.ok(newTarget instanceof RenderedTarget);
+ assert.strictEqual(typeof newTarget.id, 'string');
+ assert.strictEqual(typeof newTarget.blocks, 'object');
+ assert.strictEqual(typeof newTarget.variables, 'object');
const varIds = Object.keys(newTarget.variables);
- t.type(varIds.length, 1);
+ assert.strictEqual(varIds.length, 1);
const variable = newTarget.variables[varIds[0]];
- t.equal(variable.name, 'foo');
- t.equal(variable.value, 0);
+ assert.strictEqual(variable.name, 'foo');
+ assert.strictEqual(variable.value, 0);
- t.equal(newTarget.isOriginal, true);
- t.equal(newTarget.currentCostume, 0);
- t.equal(newTarget.isOriginal, true);
- t.equal(newTarget.isStage, false);
- t.equal(newTarget.sprite.name, 'Apple');
+ assert.strictEqual(newTarget.isOriginal, true);
+ assert.strictEqual(newTarget.currentCostume, 0);
+ assert.strictEqual(newTarget.isOriginal, true);
+ assert.strictEqual(newTarget.isStage, false);
+ assert.strictEqual(newTarget.sprite.name, 'Apple');
vm.greenFlag();
setTimeout(() => {
- t.equal(variable.value, 10);
+ assert.strictEqual(variable.value, 10);
vm.getPlaygroundData();
vm.stopAll();
}, 1000);
diff --git a/test/integration/block_to_workspace_comment_import.js b/test/integration/block_to_workspace_comment_import.js
index daea35a5..366ba6c4 100644
--- a/test/integration/block_to_workspace_comment_import.js
+++ b/test/integration/block_to_workspace_comment_import.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,38 +8,38 @@ const VirtualMachine = require('../../src/index');
const projectUri = path.resolve(__dirname, '../fixtures/block-to-workspace-comments.sb2');
const project = readFileToBuffer(projectUri);
-test('importing sb2 project where block comment is converted to workspace comment and block is deleted', t => {
+test('importing sb2 project where block comment is converted to workspace comment and block is deleted', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.equal(threads.length, 0);
+ assert.strictEqual(threads.length, 0);
const target = vm.runtime.targets[1];
// Sprite 1 has 3 Comments, 1 block comment and 2 workspace comments (which were
// originally created via a block comment to workspace comment conversion in Scratch 2.0).
const targetComments = Object.values(target.comments);
- t.equal(targetComments.length, 3);
+ assert.strictEqual(targetComments.length, 3);
const spriteWorkspaceComments = targetComments.filter(comment => comment.blockId === null);
- t.equal(spriteWorkspaceComments.length, 2);
+ assert.strictEqual(spriteWorkspaceComments.length, 2);
// Test the sprite block comments
const blockComments = targetComments.filter(comment => !!comment.blockId);
- t.equal(blockComments.length, 1);
+ assert.strictEqual(blockComments.length, 1);
// There should not be any comments where blockId is a number
const invalidComments = targetComments.filter(comment => typeof comment.blockId === 'number');
- t.equal(invalidComments.length, 0);
+ assert.strictEqual(invalidComments.length, 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/block_to_workspace_comment_import_no_scripts.js b/test/integration/block_to_workspace_comment_import_no_scripts.js
index f3dec670..fb8f1266 100644
--- a/test/integration/block_to_workspace_comment_import_no_scripts.js
+++ b/test/integration/block_to_workspace_comment_import_no_scripts.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -8,14 +9,14 @@ const projectUri = path.resolve(__dirname, '../fixtures/block-to-workspace-comme
const project = readFileToBuffer(projectUri);
/* eslint-disable-next-line max-len */
-test('importing sb2 project where block comment is converted to workspace comment and block is deleted, and there are no scripts on the workspace', t => {
+test('importing sb2 project where block comment is converted to workspace comment and block is deleted, and there are no scripts on the workspace', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.equal(threads.length, 0);
+ assert.strictEqual(threads.length, 0);
const target = vm.runtime.targets[1];
@@ -23,27 +24,27 @@ test('importing sb2 project where block comment is converted to workspace commen
// originally created via a block comment to workspace comment conversion in Scratch 2.0.
// What differentiates this test from above is that there are no scripts in this project.
const targetComments = Object.values(target.comments);
- t.equal(targetComments.length, 1);
+ assert.strictEqual(targetComments.length, 1);
const spriteWorkspaceComments = targetComments.filter(comment => comment.blockId === null);
- t.equal(spriteWorkspaceComments.length, 1);
+ assert.strictEqual(spriteWorkspaceComments.length, 1);
// Test the sprite block comments
const blockComments = targetComments.filter(comment => !!comment.blockId);
- t.equal(blockComments.length, 0);
+ assert.strictEqual(blockComments.length, 0);
// There should not be any comments where blockId is a number
const invalidComments = targetComments.filter(comment => typeof comment.blockId === 'number');
- t.equal(invalidComments.length, 0);
+ assert.strictEqual(invalidComments.length, 0);
const targetBlocks = Object.values(target.blocks._blocks);
- t.equal(targetBlocks.length, 0);
+ assert.strictEqual(targetBlocks.length, 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/broadcast_special_chars_sb2.js b/test/integration/broadcast_special_chars_sb2.js
index 24988f40..eeb605cc 100644
--- a/test/integration/broadcast_special_chars_sb2.js
+++ b/test/integration/broadcast_special_chars_sb2.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -10,16 +11,16 @@ const VariableUtil = require('../../src/util/variable-util');
const projectUri = path.resolve(__dirname, '../fixtures/broadcast_special_chars.sb2');
const project = readFileToBuffer(projectUri);
-test('importing sb2 project with special chars in message names', t => {
+test('importing sb2 project with special chars in message names', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.equal(threads.length, 0);
+ assert.strictEqual(threads.length, 0);
- t.equal(vm.runtime.targets.length, 2);
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
const cat = vm.runtime.targets[1];
@@ -31,13 +32,13 @@ test('importing sb2 project with special chars in message names', t => {
// Check for unsafe characters, replaceUnsafeChars should just result in the original string
// (e.g. there was nothing to replace)
// Check that the message ID does not have any unsafe characters
- t.equal(StringUtil.replaceUnsafeChars(abMessageId), abMessageId);
+ assert.strictEqual(StringUtil.replaceUnsafeChars(abMessageId), abMessageId);
// Check that the message still has the correct info
- t.equal(StringUtil.replaceUnsafeChars(abMessage.id), abMessage.id);
- t.equal(abMessage.id, abMessageId);
- t.equal(abMessage.type, Variable.BROADCAST_MESSAGE_TYPE);
- t.equal(abMessage.value, 'a&b');
+ assert.strictEqual(StringUtil.replaceUnsafeChars(abMessage.id), abMessage.id);
+ assert.strictEqual(abMessage.id, abMessageId);
+ assert.strictEqual(abMessage.type, Variable.BROADCAST_MESSAGE_TYPE);
+ assert.strictEqual(abMessage.value, 'a&b');
const ltPerfectMessageId = Object.keys(stage.variables).filter(k => stage.variables[k].name === '< perfect')[0];
@@ -45,31 +46,31 @@ test('importing sb2 project with special chars in message names', t => {
// Check for unsafe characters, replaceUnsafeChars should just result in the original string
// (e.g. there was nothing to replace)
// Check that the message ID does not have any unsafe characters
- t.equal(StringUtil.replaceUnsafeChars(ltPerfectMessageId), ltPerfectMessageId);
+ assert.strictEqual(StringUtil.replaceUnsafeChars(ltPerfectMessageId), ltPerfectMessageId);
// Check that the message still has the correct info
- t.equal(StringUtil.replaceUnsafeChars(ltPerfectMessage.id), ltPerfectMessage.id);
- t.equal(ltPerfectMessage.id, ltPerfectMessageId);
- t.equal(ltPerfectMessage.type, Variable.BROADCAST_MESSAGE_TYPE);
- t.equal(ltPerfectMessage.value, '< perfect');
+ assert.strictEqual(StringUtil.replaceUnsafeChars(ltPerfectMessage.id), ltPerfectMessage.id);
+ assert.strictEqual(ltPerfectMessage.id, ltPerfectMessageId);
+ assert.strictEqual(ltPerfectMessage.type, Variable.BROADCAST_MESSAGE_TYPE);
+ assert.strictEqual(ltPerfectMessage.value, '< perfect');
// Find all the references for these messages, and verify they have the correct ID
- t.equal(allBroadcastFields[ltPerfectMessageId].length, 1);
- t.equal(allBroadcastFields[abMessageId].length, 1);
+ assert.strictEqual(allBroadcastFields[ltPerfectMessageId].length, 1);
+ assert.strictEqual(allBroadcastFields[abMessageId].length, 1);
const catBlocks = Object.keys(cat.blocks._blocks).map(blockId => cat.blocks._blocks[blockId]);
const catMessageBlocks = catBlocks.filter(
block => Object.prototype.hasOwnProperty.call(block.fields, 'BROADCAST_OPTION')
);
- t.equal(catMessageBlocks.length, 2);
- t.equal(catMessageBlocks[0].fields.BROADCAST_OPTION.id, ltPerfectMessageId);
- t.equal(catMessageBlocks[1].fields.BROADCAST_OPTION.id, abMessageId);
+ assert.strictEqual(catMessageBlocks.length, 2);
+ assert.strictEqual(catMessageBlocks[0].fields.BROADCAST_OPTION.id, ltPerfectMessageId);
+ assert.strictEqual(catMessageBlocks[1].fields.BROADCAST_OPTION.id, abMessageId);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/broadcast_special_chars_sb3.js b/test/integration/broadcast_special_chars_sb3.js
index 91050e59..a08d535f 100644
--- a/test/integration/broadcast_special_chars_sb3.js
+++ b/test/integration/broadcast_special_chars_sb3.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -10,16 +11,16 @@ const VariableUtil = require('../../src/util/variable-util');
const projectUri = path.resolve(__dirname, '../fixtures/broadcast_special_chars.sb3');
const project = readFileToBuffer(projectUri);
-test('importing sb3 project with special chars in message names', t => {
+test('importing sb3 project with special chars in message names', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.equal(threads.length, 0);
+ assert.strictEqual(threads.length, 0);
- t.equal(vm.runtime.targets.length, 2);
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
const cat = vm.runtime.targets[1];
@@ -31,13 +32,13 @@ test('importing sb3 project with special chars in message names', t => {
// Check for unsafe characters, replaceUnsafeChars should just result in the original string
// (e.g. there was nothing to replace)
// Check that the message ID does not have any unsafe characters
- t.equal(StringUtil.replaceUnsafeChars(abMessageId), abMessageId);
+ assert.strictEqual(StringUtil.replaceUnsafeChars(abMessageId), abMessageId);
// Check that the message still has the correct info
- t.equal(StringUtil.replaceUnsafeChars(abMessage.id), abMessage.id);
- t.equal(abMessage.id, abMessageId);
- t.equal(abMessage.type, Variable.BROADCAST_MESSAGE_TYPE);
- t.equal(abMessage.value, 'a&b');
+ assert.strictEqual(StringUtil.replaceUnsafeChars(abMessage.id), abMessage.id);
+ assert.strictEqual(abMessage.id, abMessageId);
+ assert.strictEqual(abMessage.type, Variable.BROADCAST_MESSAGE_TYPE);
+ assert.strictEqual(abMessage.value, 'a&b');
const ltPerfectMessageId = Object.keys(stage.variables).filter(k => stage.variables[k].name === '< perfect')[0];
@@ -45,31 +46,31 @@ test('importing sb3 project with special chars in message names', t => {
// Check for unsafe characters, replaceUnsafeChars should just result in the original string
// (e.g. there was nothing to replace)
// Check that the message ID does not have any unsafe characters
- t.equal(StringUtil.replaceUnsafeChars(ltPerfectMessageId), ltPerfectMessageId);
+ assert.strictEqual(StringUtil.replaceUnsafeChars(ltPerfectMessageId), ltPerfectMessageId);
// Check that the message still has the correct info
- t.equal(StringUtil.replaceUnsafeChars(ltPerfectMessage.id), ltPerfectMessage.id);
- t.equal(ltPerfectMessage.id, ltPerfectMessageId);
- t.equal(ltPerfectMessage.type, Variable.BROADCAST_MESSAGE_TYPE);
- t.equal(ltPerfectMessage.value, '< perfect');
+ assert.strictEqual(StringUtil.replaceUnsafeChars(ltPerfectMessage.id), ltPerfectMessage.id);
+ assert.strictEqual(ltPerfectMessage.id, ltPerfectMessageId);
+ assert.strictEqual(ltPerfectMessage.type, Variable.BROADCAST_MESSAGE_TYPE);
+ assert.strictEqual(ltPerfectMessage.value, '< perfect');
// Find all the references for these messages, and verify they have the correct ID
- t.equal(allBroadcastFields[ltPerfectMessageId].length, 1);
- t.equal(allBroadcastFields[abMessageId].length, 1);
+ assert.strictEqual(allBroadcastFields[ltPerfectMessageId].length, 1);
+ assert.strictEqual(allBroadcastFields[abMessageId].length, 1);
const catBlocks = Object.keys(cat.blocks._blocks).map(blockId => cat.blocks._blocks[blockId]);
const catMessageBlocks = catBlocks.filter(
block => Object.prototype.hasOwnProperty.call(block.fields, 'BROADCAST_OPTION')
);
- t.equal(catMessageBlocks.length, 2);
- t.equal(catMessageBlocks[0].fields.BROADCAST_OPTION.id, ltPerfectMessageId);
- t.equal(catMessageBlocks[1].fields.BROADCAST_OPTION.id, abMessageId);
+ assert.strictEqual(catMessageBlocks.length, 2);
+ assert.strictEqual(catMessageBlocks[0].fields.BROADCAST_OPTION.id, ltPerfectMessageId);
+ assert.strictEqual(catMessageBlocks[1].fields.BROADCAST_OPTION.id, abMessageId);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/clone-cleanup.js b/test/integration/clone-cleanup.js
index af6707ec..100c524d 100644
--- a/test/integration/clone-cleanup.js
+++ b/test/integration/clone-cleanup.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,7 +8,7 @@ const VirtualMachine = require('../../src/index');
const projectUri = path.resolve(__dirname, '../fixtures/clone-cleanup.sb2');
const project = readFileToBuffer(projectUri);
-test('clone-cleanup', t => {
+test('clone-cleanup', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -19,19 +20,19 @@ test('clone-cleanup', t => {
const verifyCounts = (expectedClones, extraThreads) => {
// stage plus one sprite, plus clones
- t.strictEqual(vm.runtime.targets.length, 2 + expectedClones,
+ assert.strictEqual(vm.runtime.targets.length, 2 + expectedClones,
`target count at step ${testStep}`);
// the stage should never have any clones
- t.strictEqual(vm.runtime.targets[0].sprite.clones.length, 1,
+ assert.strictEqual(vm.runtime.targets[0].sprite.clones.length, 1,
`stage clone count at step ${testStep}`);
// check sprite clone count (+1 for original)
- t.strictEqual(vm.runtime.targets[1].sprite.clones.length, 1 + expectedClones,
+ assert.strictEqual(vm.runtime.targets[1].sprite.clones.length, 1 + expectedClones,
`sprite clone count at step ${testStep}`);
// thread count isn't directly tied to clone count since threads can end
- t.strictEqual(vm.runtime.threads.length, extraThreads + (2 * expectedClones),
+ assert.strictEqual(vm.runtime.threads.length, extraThreads + (2 * expectedClones),
`thread count at step ${testStep}`);
};
@@ -66,13 +67,13 @@ test('clone-cleanup', t => {
verifyCounts(0, 0);
vm.quit();
- t.end();
+ done();
break;
}
};
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/cloud_variables_sb2.js b/test/integration/cloud_variables_sb2.js
index 0b2e0a3a..16643cd7 100644
--- a/test/integration/cloud_variables_sb2.js
+++ b/test/integration/cloud_variables_sb2.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -14,7 +15,7 @@ const cloudVarLimit = readFileToBuffer(cloudVarLimitUri);
const cloudVarExceededLimit = readFileToBuffer(cloudVarExceededLimitUri);
const cloudVarLocal = readFileToBuffer(cloudVarLocalUri);
-test('importing an sb2 project with cloud variables', t => {
+test('importing an sb2 project with cloud variables', async () => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -23,26 +24,24 @@ test('importing an sb2 project with cloud variables', t => {
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(cloudVarSimple).then(() => {
- t.equal(vm.runtime.hasCloudData(), true);
+ await vm.loadProject(cloudVarSimple);
+ assert.strictEqual(vm.runtime.hasCloudData(), true);
- const stage = vm.runtime.targets[0];
- const stageVars = Object.values(stage.variables);
- t.equal(stageVars.length, 1);
+ const stage = vm.runtime.targets[0];
+ const stageVars = Object.values(stage.variables);
+ assert.strictEqual(stageVars.length, 1);
- const variable = stageVars[0];
- t.equal(variable.name, '☁ firstCloud');
- t.equal(Number(variable.value), 100); // Though scratch 2 requires
- // cloud variables to be numbers, this is something that happens
- // when the message is being sent to the server rather than on the client
- t.equal(variable.isCloud, true);
+ const variable = stageVars[0];
+ assert.strictEqual(variable.name, '☁ firstCloud');
+ assert.strictEqual(Number(variable.value), 100); // Though scratch 2 requires
+ // cloud variables to be numbers, this is something that happens
+ // when the message is being sent to the server rather than on the client
+ assert.strictEqual(variable.isCloud, true);
- vm.quit();
- t.end();
- });
+ vm.quit();
});
-test('importing an sb2 project with cloud variables at the limit for a project', t => {
+test('importing an sb2 project with cloud variables at the limit for a project', async () => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -51,22 +50,20 @@ test('importing an sb2 project with cloud variables at the limit for a project',
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(cloudVarLimit).then(() => {
- t.equal(vm.runtime.hasCloudData(), true);
+ await vm.loadProject(cloudVarLimit);
+ assert.strictEqual(vm.runtime.hasCloudData(), true);
- const stage = vm.runtime.targets[0];
- const stageVars = Object.values(stage.variables);
+ const stage = vm.runtime.targets[0];
+ const stageVars = Object.values(stage.variables);
- t.equal(stageVars.length, 10);
- // All of the 8 stage variables should be cloud variables
- t.equal(stageVars.filter(v => v.isCloud).length, 10);
+ assert.strictEqual(stageVars.length, 10);
+ // All of the 8 stage variables should be cloud variables
+ assert.strictEqual(stageVars.filter(v => v.isCloud).length, 10);
- vm.quit();
- t.end();
- });
+ vm.quit();
});
-test('importing an sb2 project with cloud variables exceeding the limit for a project', t => {
+test('importing an sb2 project with cloud variables exceeding the limit for a project', async () => {
// This tests a hacked project where additional cloud variables exceeding
// the project limit have been added.
const vm = new VirtualMachine();
@@ -77,22 +74,20 @@ test('importing an sb2 project with cloud variables exceeding the limit for a pr
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(cloudVarExceededLimit).then(() => {
- t.equal(vm.runtime.hasCloudData(), true);
+ await vm.loadProject(cloudVarExceededLimit);
+ assert.strictEqual(vm.runtime.hasCloudData(), true);
- const stage = vm.runtime.targets[0];
- const stageVars = Object.values(stage.variables);
+ const stage = vm.runtime.targets[0];
+ const stageVars = Object.values(stage.variables);
- t.equal(stageVars.length, 15);
- // Only 8 of the variables should have the isCloud flag set to true
- t.equal(stageVars.filter(v => v.isCloud).length, 10);
+ assert.strictEqual(stageVars.length, 15);
+ // Only 8 of the variables should have the isCloud flag set to true
+ assert.strictEqual(stageVars.filter(v => v.isCloud).length, 10);
- vm.quit();
- t.end();
- });
+ vm.quit();
});
-test('importing one project after the other resets cloud variable limit', t => {
+test('importing one project after the other resets cloud variable limit', async () => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -101,30 +96,27 @@ test('importing one project after the other resets cloud variable limit', t => {
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(cloudVarExceededLimit).then(() => {
- t.equal(vm.runtime.canAddCloudVariable(), false);
+ await vm.loadProject(cloudVarExceededLimit);
+ assert.strictEqual(vm.runtime.canAddCloudVariable(), false);
- vm.loadProject(cloudVarSimple).then(() => {
- const stage = vm.runtime.targets[0];
- const stageVars = Object.values(stage.variables);
- t.equal(stageVars.length, 1);
+ await vm.loadProject(cloudVarSimple);
+ const stage = vm.runtime.targets[0];
+ const stageVars = Object.values(stage.variables);
+ assert.strictEqual(stageVars.length, 1);
- const variable = stageVars[0];
- t.equal(variable.name, '☁ firstCloud');
- t.equal(Number(variable.value), 100); // Though scratch 2 requires
- // cloud variables to be numbers, this is something that happens
- // when the message is being sent to the server rather than on the client
- t.equal(variable.isCloud, true);
+ const variable = stageVars[0];
+ assert.strictEqual(variable.name, '☁ firstCloud');
+ assert.strictEqual(Number(variable.value), 100); // Though scratch 2 requires
+ // cloud variables to be numbers, this is something that happens
+ // when the message is being sent to the server rather than on the client
+ assert.strictEqual(variable.isCloud, true);
- t.equal(vm.runtime.canAddCloudVariable(), true);
+ assert.strictEqual(vm.runtime.canAddCloudVariable(), true);
- vm.quit();
- t.end();
- });
- });
+ vm.quit();
});
-test('local cloud variables get imported as regular variables', t => {
+test('local cloud variables get imported as regular variables', async () => {
// This tests a hacked project where a sprite-local variable is
// has the cloud variable flag set.
const vm = new VirtualMachine();
@@ -135,21 +127,19 @@ test('local cloud variables get imported as regular variables', t => {
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(cloudVarLocal).then(() => {
- t.equal(vm.runtime.hasCloudData(), false);
+ await vm.loadProject(cloudVarLocal);
+ assert.strictEqual(vm.runtime.hasCloudData(), false);
- const stage = vm.runtime.targets[0];
- const stageVars = Object.values(stage.variables);
+ const stage = vm.runtime.targets[0];
+ const stageVars = Object.values(stage.variables);
- t.equal(stageVars.length, 0);
+ assert.strictEqual(stageVars.length, 0);
- const sprite = vm.runtime.targets[1];
- const spriteVars = Object.values(sprite.variables);
+ const sprite = vm.runtime.targets[1];
+ const spriteVars = Object.values(sprite.variables);
- t.equal(spriteVars.length, 1);
- t.equal(spriteVars[0].isCloud, false);
+ assert.strictEqual(spriteVars.length, 1);
+ assert.strictEqual(spriteVars[0].isCloud, false);
- vm.quit();
- t.end();
- });
+ vm.quit();
});
diff --git a/test/integration/cloud_variables_sb3.js b/test/integration/cloud_variables_sb3.js
index 7caab31e..a7d5630c 100644
--- a/test/integration/cloud_variables_sb3.js
+++ b/test/integration/cloud_variables_sb3.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -14,7 +15,7 @@ const cloudVarLimit = readFileToBuffer(cloudVarLimitUri);
const cloudVarExceededLimit = readFileToBuffer(cloudVarExceededLimitUri);
const cloudVarLocal = readFileToBuffer(cloudVarLocalUri);
-test('importing an sb3 project with cloud variables', t => {
+test('importing an sb3 project with cloud variables', async () => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -23,24 +24,22 @@ test('importing an sb3 project with cloud variables', t => {
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(cloudVarSimple).then(() => {
- t.equal(vm.runtime.hasCloudData(), true);
+ await vm.loadProject(cloudVarSimple);
+ assert.strictEqual(vm.runtime.hasCloudData(), true);
- const stage = vm.runtime.targets[0];
- const stageVars = Object.values(stage.variables);
- t.equal(stageVars.length, 1);
+ const stage = vm.runtime.targets[0];
+ const stageVars = Object.values(stage.variables);
+ assert.strictEqual(stageVars.length, 1);
- const variable = stageVars[0];
- t.equal(variable.name, '☁ firstCloud');
- t.equal(Number(variable.value), 100);
- t.equal(variable.isCloud, true);
+ const variable = stageVars[0];
+ assert.strictEqual(variable.name, '☁ firstCloud');
+ assert.strictEqual(Number(variable.value), 100);
+ assert.strictEqual(variable.isCloud, true);
- vm.quit();
- t.end();
- });
+ vm.quit();
});
-test('importing an sb3 project with cloud variables at the limit for a project', t => {
+test('importing an sb3 project with cloud variables at the limit for a project', async () => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -49,22 +48,20 @@ test('importing an sb3 project with cloud variables at the limit for a project',
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(cloudVarLimit).then(() => {
- t.equal(vm.runtime.hasCloudData(), true);
+ await vm.loadProject(cloudVarLimit);
+ assert.strictEqual(vm.runtime.hasCloudData(), true);
- const stage = vm.runtime.targets[0];
- const stageVars = Object.values(stage.variables);
+ const stage = vm.runtime.targets[0];
+ const stageVars = Object.values(stage.variables);
- t.equal(stageVars.length, 10);
- // All of the 10 stage variables should be cloud variables
- t.equal(stageVars.filter(v => v.isCloud).length, 10);
+ assert.strictEqual(stageVars.length, 10);
+ // All of the 10 stage variables should be cloud variables
+ assert.strictEqual(stageVars.filter(v => v.isCloud).length, 10);
- vm.quit();
- t.end();
- });
+ vm.quit();
});
-test('importing an sb3 project with cloud variables exceeding the limit for a project', t => {
+test('importing an sb3 project with cloud variables exceeding the limit for a project', async () => {
// This tests a hacked project where additional cloud variables exceeding
// the project limit have been added.
const vm = new VirtualMachine();
@@ -75,22 +72,20 @@ test('importing an sb3 project with cloud variables exceeding the limit for a pr
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(cloudVarExceededLimit).then(() => {
- t.equal(vm.runtime.hasCloudData(), true);
+ await vm.loadProject(cloudVarExceededLimit);
+ assert.strictEqual(vm.runtime.hasCloudData(), true);
- const stage = vm.runtime.targets[0];
- const stageVars = Object.values(stage.variables);
+ const stage = vm.runtime.targets[0];
+ const stageVars = Object.values(stage.variables);
- t.equal(stageVars.length, 15);
- // Only 8 of the variables should have the isCloud flag set to true
- t.equal(stageVars.filter(v => v.isCloud).length, 10);
+ assert.strictEqual(stageVars.length, 15);
+ // Only 8 of the variables should have the isCloud flag set to true
+ assert.strictEqual(stageVars.filter(v => v.isCloud).length, 10);
- vm.quit();
- t.end();
- });
+ vm.quit();
});
-test('importing one project after the other resets cloud variable limit', t => {
+test('importing one project after the other resets cloud variable limit', async () => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -99,28 +94,25 @@ test('importing one project after the other resets cloud variable limit', t => {
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(cloudVarExceededLimit).then(() => {
- t.equal(vm.runtime.canAddCloudVariable(), false);
+ await vm.loadProject(cloudVarExceededLimit);
+ assert.strictEqual(vm.runtime.canAddCloudVariable(), false);
- vm.loadProject(cloudVarSimple).then(() => {
- const stage = vm.runtime.targets[0];
- const stageVars = Object.values(stage.variables);
- t.equal(stageVars.length, 1);
+ await vm.loadProject(cloudVarSimple);
+ const stage = vm.runtime.targets[0];
+ const stageVars = Object.values(stage.variables);
+ assert.strictEqual(stageVars.length, 1);
- const variable = stageVars[0];
- t.equal(variable.name, '☁ firstCloud');
- t.equal(Number(variable.value), 100);
- t.equal(variable.isCloud, true);
+ const variable = stageVars[0];
+ assert.strictEqual(variable.name, '☁ firstCloud');
+ assert.strictEqual(Number(variable.value), 100);
+ assert.strictEqual(variable.isCloud, true);
- t.equal(vm.runtime.canAddCloudVariable(), true);
+ assert.strictEqual(vm.runtime.canAddCloudVariable(), true);
- vm.quit();
- t.end();
- });
- });
+ vm.quit();
});
-test('local cloud variables get imported as regular variables', t => {
+test('local cloud variables get imported as regular variables', async () => {
// This tests a hacked project where a sprite-local variable is
// has the cloud variable flag set.
const vm = new VirtualMachine();
@@ -131,21 +123,19 @@ test('local cloud variables get imported as regular variables', t => {
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(cloudVarLocal).then(() => {
- t.equal(vm.runtime.hasCloudData(), false);
+ await vm.loadProject(cloudVarLocal);
+ assert.strictEqual(vm.runtime.hasCloudData(), false);
- const stage = vm.runtime.targets[0];
- const stageVars = Object.values(stage.variables);
+ const stage = vm.runtime.targets[0];
+ const stageVars = Object.values(stage.variables);
- t.equal(stageVars.length, 0);
+ assert.strictEqual(stageVars.length, 0);
- const sprite = vm.runtime.targets[1];
- const spriteVars = Object.values(sprite.variables);
+ const sprite = vm.runtime.targets[1];
+ const spriteVars = Object.values(sprite.variables);
- t.equal(spriteVars.length, 1);
- t.equal(spriteVars[0].isCloud, false);
+ assert.strictEqual(spriteVars.length, 1);
+ assert.strictEqual(spriteVars[0].isCloud, false);
- vm.quit();
- t.end();
- });
+ vm.quit();
});
diff --git a/test/integration/comments.js b/test/integration/comments.js
index 14304ab8..a1b0656c 100644
--- a/test/integration/comments.js
+++ b/test/integration/comments.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,14 +8,14 @@ const VirtualMachine = require('../../src/index');
const projectUri = path.resolve(__dirname, '../fixtures/comments.sb2');
const project = readFileToBuffer(projectUri);
-test('importing sb2 project with comments', t => {
+test('importing sb2 project with comments', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.equal(threads.length, 0);
+ assert.strictEqual(threads.length, 0);
const stage = vm.runtime.targets[0];
const target = vm.runtime.targets[1];
@@ -22,60 +23,60 @@ test('importing sb2 project with comments', t => {
const stageComments = Object.values(stage.comments);
// Stage has 1 comment, and it is minimized.
- t.equal(stageComments.length, 1);
- t.equal(stageComments[0].minimized, true);
- t.equal(stageComments[0].text, 'A minimized stage comment.');
+ assert.strictEqual(stageComments.length, 1);
+ assert.strictEqual(stageComments[0].minimized, true);
+ assert.strictEqual(stageComments[0].text, 'A minimized stage comment.');
// The stage comment is a workspace comment
- t.equal(stageComments[0].blockId, null);
+ assert.strictEqual(stageComments[0].blockId, null);
// Sprite 1 has 6 Comments, 1 workspace comment, and 5 block comments
const targetComments = Object.values(target.comments);
- t.equal(targetComments.length, 6);
+ assert.strictEqual(targetComments.length, 6);
const spriteWorkspaceComments = targetComments.filter(comment => comment.blockId === null);
- t.equal(spriteWorkspaceComments.length, 1);
- t.equal(spriteWorkspaceComments[0].minimized, false);
- t.equal(spriteWorkspaceComments[0].text, 'This is a workspace comment.');
+ assert.strictEqual(spriteWorkspaceComments.length, 1);
+ assert.strictEqual(spriteWorkspaceComments[0].minimized, false);
+ assert.strictEqual(spriteWorkspaceComments[0].text, 'This is a workspace comment.');
// Test the sprite block comments
const blockComments = targetComments.filter(comment => !!comment.blockId);
- t.equal(blockComments.length, 5);
+ assert.strictEqual(blockComments.length, 5);
- t.equal(blockComments[0].minimized, true);
- t.equal(blockComments[0].text, '1. Green Flag Comment.');
+ assert.strictEqual(blockComments[0].minimized, true);
+ assert.strictEqual(blockComments[0].text, '1. Green Flag Comment.');
const greenFlagBlock = target.blocks.getBlock(blockComments[0].blockId);
- t.equal(greenFlagBlock.comment, blockComments[0].id);
- t.equal(greenFlagBlock.opcode, 'event_whenflagclicked');
+ assert.strictEqual(greenFlagBlock.comment, blockComments[0].id);
+ assert.strictEqual(greenFlagBlock.opcode, 'event_whenflagclicked');
- t.equal(blockComments[1].minimized, true);
- t.equal(blockComments[1].text, '2. Turn 15 Degrees Comment.');
+ assert.strictEqual(blockComments[1].minimized, true);
+ assert.strictEqual(blockComments[1].text, '2. Turn 15 Degrees Comment.');
const turnRightBlock = target.blocks.getBlock(blockComments[1].blockId);
- t.equal(turnRightBlock.comment, blockComments[1].id);
- t.equal(turnRightBlock.opcode, 'motion_turnright');
+ assert.strictEqual(turnRightBlock.comment, blockComments[1].id);
+ assert.strictEqual(turnRightBlock.opcode, 'motion_turnright');
- t.equal(blockComments[2].minimized, false);
- t.equal(blockComments[2].text, '3. Comment for a loop.');
+ assert.strictEqual(blockComments[2].minimized, false);
+ assert.strictEqual(blockComments[2].text, '3. Comment for a loop.');
const repeatBlock = target.blocks.getBlock(blockComments[2].blockId);
- t.equal(repeatBlock.comment, blockComments[2].id);
- t.equal(repeatBlock.opcode, 'control_repeat');
+ assert.strictEqual(repeatBlock.comment, blockComments[2].id);
+ assert.strictEqual(repeatBlock.opcode, 'control_repeat');
- t.equal(blockComments[3].minimized, false);
- t.equal(blockComments[3].text, '4. Comment for a block nested in a loop.');
+ assert.strictEqual(blockComments[3].minimized, false);
+ assert.strictEqual(blockComments[3].text, '4. Comment for a block nested in a loop.');
const changeColorBlock = target.blocks.getBlock(blockComments[3].blockId);
- t.equal(changeColorBlock.comment, blockComments[3].id);
- t.equal(changeColorBlock.opcode, 'looks_changeeffectby');
+ assert.strictEqual(changeColorBlock.comment, blockComments[3].id);
+ assert.strictEqual(changeColorBlock.opcode, 'looks_changeeffectby');
- t.equal(blockComments[4].minimized, false);
- t.equal(blockComments[4].text, '5. Comment for a block outside of a loop.');
+ assert.strictEqual(blockComments[4].minimized, false);
+ assert.strictEqual(blockComments[4].text, '5. Comment for a block outside of a loop.');
const stopAllBlock = target.blocks.getBlock(blockComments[4].blockId);
- t.equal(stopAllBlock.comment, blockComments[4].id);
- t.equal(stopAllBlock.opcode, 'control_stop');
+ assert.strictEqual(stopAllBlock.comment, blockComments[4].id);
+ assert.strictEqual(stopAllBlock.opcode, 'control_stop');
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/comments_sb3.js b/test/integration/comments_sb3.js
index ceebfb2c..7350439c 100644
--- a/test/integration/comments_sb3.js
+++ b/test/integration/comments_sb3.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,14 +8,14 @@ const VirtualMachine = require('../../src/index');
const projectUri = path.resolve(__dirname, '../fixtures/comments.sb3');
const project = readFileToBuffer(projectUri);
-test('load an sb3 project with comments', t => {
+test('load an sb3 project with comments', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.equal(threads.length, 0);
+ assert.strictEqual(threads.length, 0);
const stage = vm.runtime.targets[0];
const target = vm.runtime.targets[1];
@@ -22,60 +23,60 @@ test('load an sb3 project with comments', t => {
const stageComments = Object.values(stage.comments);
// Stage has 1 comment, and it is minimized.
- t.equal(stageComments.length, 1);
- t.equal(stageComments[0].minimized, true);
- t.equal(stageComments[0].text, 'A minimized stage comment.');
+ assert.strictEqual(stageComments.length, 1);
+ assert.strictEqual(stageComments[0].minimized, true);
+ assert.strictEqual(stageComments[0].text, 'A minimized stage comment.');
// The stage comment is a workspace comment
- t.equal(stageComments[0].blockId, null);
+ assert.strictEqual(stageComments[0].blockId, null);
// Sprite 1 has 6 Comments, 1 workspace comment, and 5 block comments
const targetComments = Object.values(target.comments);
- t.equal(targetComments.length, 6);
+ assert.strictEqual(targetComments.length, 6);
const spriteWorkspaceComments = targetComments.filter(comment => comment.blockId === null);
- t.equal(spriteWorkspaceComments.length, 1);
- t.equal(spriteWorkspaceComments[0].minimized, false);
- t.equal(spriteWorkspaceComments[0].text, 'This is a workspace comment.');
+ assert.strictEqual(spriteWorkspaceComments.length, 1);
+ assert.strictEqual(spriteWorkspaceComments[0].minimized, false);
+ assert.strictEqual(spriteWorkspaceComments[0].text, 'This is a workspace comment.');
// Test the sprite block comments
const blockComments = targetComments.filter(comment => !!comment.blockId);
- t.equal(blockComments.length, 5);
+ assert.strictEqual(blockComments.length, 5);
- t.equal(blockComments[0].minimized, true);
- t.equal(blockComments[0].text, '1. Green Flag Comment.');
+ assert.strictEqual(blockComments[0].minimized, true);
+ assert.strictEqual(blockComments[0].text, '1. Green Flag Comment.');
const greenFlagBlock = target.blocks.getBlock(blockComments[0].blockId);
- t.equal(greenFlagBlock.comment, blockComments[0].id);
- t.equal(greenFlagBlock.opcode, 'event_whenflagclicked');
+ assert.strictEqual(greenFlagBlock.comment, blockComments[0].id);
+ assert.strictEqual(greenFlagBlock.opcode, 'event_whenflagclicked');
- t.equal(blockComments[1].minimized, true);
- t.equal(blockComments[1].text, '2. Turn 15 Degrees Comment.');
+ assert.strictEqual(blockComments[1].minimized, true);
+ assert.strictEqual(blockComments[1].text, '2. Turn 15 Degrees Comment.');
const turnRightBlock = target.blocks.getBlock(blockComments[1].blockId);
- t.equal(turnRightBlock.comment, blockComments[1].id);
- t.equal(turnRightBlock.opcode, 'motion_turnright');
+ assert.strictEqual(turnRightBlock.comment, blockComments[1].id);
+ assert.strictEqual(turnRightBlock.opcode, 'motion_turnright');
- t.equal(blockComments[2].minimized, false);
- t.equal(blockComments[2].text, '3. Comment for a loop.');
+ assert.strictEqual(blockComments[2].minimized, false);
+ assert.strictEqual(blockComments[2].text, '3. Comment for a loop.');
const repeatBlock = target.blocks.getBlock(blockComments[2].blockId);
- t.equal(repeatBlock.comment, blockComments[2].id);
- t.equal(repeatBlock.opcode, 'control_repeat');
+ assert.strictEqual(repeatBlock.comment, blockComments[2].id);
+ assert.strictEqual(repeatBlock.opcode, 'control_repeat');
- t.equal(blockComments[3].minimized, false);
- t.equal(blockComments[3].text, '4. Comment for a block nested in a loop.');
+ assert.strictEqual(blockComments[3].minimized, false);
+ assert.strictEqual(blockComments[3].text, '4. Comment for a block nested in a loop.');
const changeColorBlock = target.blocks.getBlock(blockComments[3].blockId);
- t.equal(changeColorBlock.comment, blockComments[3].id);
- t.equal(changeColorBlock.opcode, 'looks_changeeffectby');
+ assert.strictEqual(changeColorBlock.comment, blockComments[3].id);
+ assert.strictEqual(changeColorBlock.opcode, 'looks_changeeffectby');
- t.equal(blockComments[4].minimized, false);
- t.equal(blockComments[4].text, '5. Comment for a block outside of a loop.');
+ assert.strictEqual(blockComments[4].minimized, false);
+ assert.strictEqual(blockComments[4].text, '5. Comment for a block outside of a loop.');
const stopAllBlock = target.blocks.getBlock(blockComments[4].blockId);
- t.equal(stopAllBlock.comment, blockComments[4].id);
- t.equal(stopAllBlock.opcode, 'control_stop');
+ assert.strictEqual(stopAllBlock.comment, blockComments[4].id);
+ assert.strictEqual(stopAllBlock.opcode, 'control_stop');
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/complex.js b/test/integration/complex.js
index de22faef..cb5e2623 100644
--- a/test/integration/complex.js
+++ b/test/integration/complex.js
@@ -1,6 +1,7 @@
const fs = require('fs');
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -11,16 +12,16 @@ const project = readFileToBuffer(projectUri);
const spriteUri = path.resolve(__dirname, '../fixtures/sprite.json');
const sprite = fs.readFileSync(spriteUri, 'utf8');
-test('complex', t => {
+test('complex', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length === 0);
+ assert.ok(threads.length === 0);
vm.quit();
- t.end();
+ done();
});
// Manipulate each target
@@ -55,7 +56,7 @@ test('complex', t => {
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/control.js b/test/integration/control.js
index 3a3ad7d0..16c6998a 100644
--- a/test/integration/control.js
+++ b/test/integration/control.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,20 +8,20 @@ const VirtualMachine = require('../../src/index');
const uri = path.resolve(__dirname, '../fixtures/control.sb2');
const project = readFileToBuffer(uri);
-test('control', t => {
+test('control', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length > 0);
+ assert.ok(threads.length > 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/data.js b/test/integration/data.js
index 65e50c4a..7f021da7 100644
--- a/test/integration/data.js
+++ b/test/integration/data.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,7 +8,7 @@ const VirtualMachine = require('../../src/index');
const uri = path.resolve(__dirname, '../fixtures/data.sb2');
const project = readFileToBuffer(uri);
-test('data', t => {
+test('data', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -15,11 +16,11 @@ test('data', t => {
vm.on('playgroundData', () => {
// @todo Additional tests
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/delete-and-restore-sprite.js b/test/integration/delete-and-restore-sprite.js
index 80352cd0..1cc19cf4 100644
--- a/test/integration/delete-and-restore-sprite.js
+++ b/test/integration/delete-and-restore-sprite.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
@@ -11,12 +12,11 @@ const project = readFileToBuffer(projectUri);
const vm = new VirtualMachine();
-test('spec', t => {
- t.type(vm.deleteSprite, 'function');
- t.end();
+test('spec', () => {
+ assert.strictEqual(typeof vm.deleteSprite, 'function');
});
-test('default cat', t => {
+test('default cat', (t, done) => {
// Get default cat from .sprite2
// const uri = path.resolve(__dirname, '../fixtures/example_sprite.sprite2');
// const sprite = readFileToBuffer(uri);
@@ -26,32 +26,32 @@ test('default cat', t => {
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length === 0);
+ assert.ok(threads.length === 0);
vm.quit();
- t.end();
+ done();
});
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.loadProject(project).then(() => {
- t.equal(vm.runtime.targets.length, 2); // stage and default sprite
+ assert.strictEqual(vm.runtime.targets.length, 2); // stage and default sprite
const defaultSprite = vm.runtime.targets[1];
// Delete the sprite
const addSpriteBack = vm.deleteSprite(vm.runtime.targets[1].id);
- t.equal(vm.runtime.targets.length, 1);
+ assert.strictEqual(vm.runtime.targets.length, 1);
- t.type(addSpriteBack, 'function');
+ assert.strictEqual(typeof addSpriteBack, 'function');
addSpriteBack().then(() => {
- t.equal(vm.runtime.targets.length, 2);
- t.equal(vm.runtime.targets[1].getName(), defaultSprite.getName());
+ assert.strictEqual(vm.runtime.targets.length, 2);
+ assert.strictEqual(vm.runtime.targets[1].getName(), defaultSprite.getName());
vm.greenFlag();
diff --git a/test/integration/event.js b/test/integration/event.js
index 886bca2e..6eced037 100644
--- a/test/integration/event.js
+++ b/test/integration/event.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,20 +8,20 @@ const VirtualMachine = require('../../src/index');
const uri = path.resolve(__dirname, '../fixtures/event.sb2');
const project = readFileToBuffer(uri);
-test('event', t => {
+test('event', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length > 0);
+ assert.ok(threads.length > 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/execute.js b/test/integration/execute.js
index 88d9e7d4..ee9cea48 100644
--- a/test/integration/execute.js
+++ b/test/integration/execute.js
@@ -1,7 +1,7 @@
const fs = require('fs');
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
@@ -14,15 +14,15 @@ const VirtualMachine = require('../../src/index');
* or did "fail". Four keywords can be set at the beginning of a SAY messaage
* to indicate a test primitive.
*
- * - "pass MESSAGE" will t.pass(MESSAGE).
- * - "fail MESSAGE" will t.fail(MESSAGE).
+ * - "pass MESSAGE" will pass an assertion with MESSAGE.
+ * - "fail MESSAGE" will fail the test with MESSAGE once the project finishes.
* - "plan NUMBER_OF_TESTS" will t.plan(Number(NUMBER_OF_TESTS)).
- * - "end" will t.end().
+ * - "end" marks the test as having reached its end.
*
* A good strategy to follow is to SAY "plan NUMBER_OF_TESTS" first. Then
* "pass" and "fail" depending on expected scratch results in conditions, event
* scripts, or what is best for testing the target block or group of blocks.
- * When its done you must SAY "end" so the test and tap know that the end has
+ * When its done you must SAY "end" so the test knows that the end has
* been reached.
*/
@@ -43,16 +43,15 @@ const whenThreadsComplete = (t, vm, uri, timeLimit = 5000) =>
}, 50);
const timeoutId = setTimeout(() => {
- t.fail(`Timeout waiting for threads to complete: ${uri}`);
- reject(new Error('time limit reached'));
-
// Attempt to stop the lingering VM from interfering with other tests.
vm.quit();
+
+ reject(new Error(`Timeout waiting for threads to complete: ${uri}`));
}, timeLimit);
// Clear the interval to allow the process to exit
// naturally.
- t.tearDown(() => {
+ t.after(() => {
clearInterval(intervalId);
clearTimeout(timeoutId);
});
@@ -66,22 +65,25 @@ const fileFilter = /\.sb[23]?$/i;
fs.readdirSync(executeDir)
.filter(uri => fileFilter.test(uri))
.forEach(uri => {
- const run = (t, enableCompiler) => {
+ const run = async (t, enableCompiler) => {
const vm = new VirtualMachine();
+ // Stop a VM left running by a failed test from leaking into later tests.
+ t.after(() => vm.quit());
- // Map string messages to tap reporting methods. This will be used
+ // Map string messages to test reporting methods. This will be used
// with events from scratch's runtime emitted on block instructions.
let didPlan;
let didEnd;
+ const failures = [];
const reporters = {
comment (message) {
- t.comment(message);
+ t.diagnostic(message);
},
pass (reason) {
- t.pass(reason);
+ t.assert.ok(true, reason);
},
fail (reason) {
- t.fail(reason);
+ failures.push(reason);
},
plan (count) {
didPlan = true;
@@ -90,7 +92,6 @@ fs.readdirSync(executeDir)
end () {
didEnd = true;
vm.quit();
- t.end();
}
};
const reportVmResult = text => {
@@ -128,25 +129,26 @@ fs.readdirSync(executeDir)
// Load the project and once all threads are complete ensure that
// the scratch project sent us a "end" message.
- return vm.loadProject(project)
- .then(() => vm.greenFlag())
- .then(() => whenThreadsComplete(t, vm, uri))
- .then(() => {
- // Setting a plan is not required but is a good idea.
- if (!didPlan) {
- t.comment('did not say "plan NUMBER_OF_TESTS"');
- }
+ await vm.loadProject(project);
+ await vm.greenFlag();
+ await whenThreadsComplete(t, vm, uri);
+ // Setting a plan is not required but is a good idea.
+ if (!didPlan) {
+ t.diagnostic('did not say "plan NUMBER_OF_TESTS"');
+ }
- // End must be called so that tap knows the test is done. If
- // the test has an SAY "end" block but that block did not
- // execute, this explicit failure will raise that issue so
- // it can be resolved.
- if (!didEnd) {
- t.fail('did not say "end"');
- vm.quit();
- t.end();
- }
- });
+ // If the test has an SAY "end" block but that block did not
+ // execute, this explicit failure will raise that issue so
+ // it can be resolved.
+ if (!didEnd) {
+ vm.quit();
+ failures.push('did not say "end"');
+ }
+
+ // Not an assertion, as it would count towards the project's plan.
+ if (failures.length) {
+ throw new Error(failures.join('\n'));
+ }
};
test(`${uri} (interpreted)`, t => run(t, false));
test(`${uri} (compiled)`, t => run(t, true));
diff --git a/test/integration/hat-execution-order.js b/test/integration/hat-execution-order.js
index 89788d8c..bbe9b636 100644
--- a/test/integration/hat-execution-order.js
+++ b/test/integration/hat-execution-order.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -8,19 +9,15 @@ const projectUri = path.resolve(__dirname, '../fixtures/hat-execution-order.sb2'
const project = readFileToBuffer(projectUri);
const compilerAndInterpreter = (name, callback) => {
- test(`${name} - interpreted`, t => {
- callback(t, {
- enabled: false
- });
- });
- test(`${name} - compiled`, t => {
- callback(t, {
- enabled: true
- });
- });
+ test(`${name} - interpreted`, (t, done) => callback(done, {
+ enabled: false
+ }));
+ test(`${name} - compiled`, (t, done) => callback(done, {
+ enabled: true
+ }));
};
-compilerAndInterpreter('complex', (t, co) => {
+compilerAndInterpreter('complex', (done, co) => {
const vm = new VirtualMachine();
vm.setCompilerOptions(co);
vm.attachStorage(makeTestStorage());
@@ -28,18 +25,18 @@ compilerAndInterpreter('complex', (t, co) => {
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length === 0);
+ assert.ok(threads.length === 0);
const resultKey = Object.keys(vm.runtime.targets[0].variables)[0];
const results = vm.runtime.targets[0].variables[resultKey].value;
- t.deepEqual(results, ['3', '2', '1', 'stage']);
+ assert.deepEqual(results, ['3', '2', '1', 'stage']);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/hat-threads-run-every-frame.js b/test/integration/hat-threads-run-every-frame.js
index 9772ea5a..b328075f 100644
--- a/test/integration/hat-threads-run-every-frame.js
+++ b/test/integration/hat-threads-run-every-frame.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -8,32 +9,28 @@ const Runtime = require('../../src/engine/runtime');
const execute = require('../../src/engine/execute.js');
const compilerAndInterpreter = (name, callback) => {
- test(`${name} - interpreted`, t => {
- callback(t, {
- enabled: false
- });
- });
- test(`${name} - compiled`, t => {
- callback(t, {
- enabled: true
- });
- });
+ test(`${name} - interpreted`, (t, done) => callback(done, {
+ enabled: false
+ }));
+ test(`${name} - compiled`, (t, done) => callback(done, {
+ enabled: true
+ }));
};
const projectUri = path.resolve(__dirname, '../fixtures/timer-greater-than-hat.sb2');
const project = readFileToBuffer(projectUri);
-const checkIsHatThread = (t, vm, hatThread) => {
- t.equal(hatThread.stackClick, false);
- t.equal(hatThread.updateMonitor, false);
+const checkIsHatThread = (vm, hatThread) => {
+ assert.strictEqual(hatThread.stackClick, false);
+ assert.strictEqual(hatThread.updateMonitor, false);
const blockContainer = hatThread.target.blocks;
const opcode = blockContainer.getOpcode(blockContainer.getBlock(hatThread.topBlock));
- t.assert(vm.runtime.getIsEdgeActivatedHat(opcode));
+ assert.ok(vm.runtime.getIsEdgeActivatedHat(opcode));
};
-const checkIsStackClickThread = (t, vm, stackClickThread) => {
- t.equal(stackClickThread.stackClick, true);
- t.equal(stackClickThread.updateMonitor, false);
+const checkIsStackClickThread = (vm, stackClickThread) => {
+ assert.strictEqual(stackClickThread.stackClick, true);
+ assert.strictEqual(stackClickThread.updateMonitor, false);
};
/**
@@ -43,13 +40,13 @@ const checkIsStackClickThread = (t, vm, stackClickThread) => {
* The intention is to make sure that the hat block condition is evaluated
* on each frame.
*/
-compilerAndInterpreter('edge activated hat thread runs once every frame', (t, co) => {
+compilerAndInterpreter('edge activated hat thread runs once every frame', (done, co) => {
const vm = new VirtualMachine();
vm.setCompilerOptions(co);
vm.attachStorage(makeTestStorage());
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
// Note: don't run vm.start(), we handle calling _step() manually in this test
vm.runtime.currentStepTime = Runtime.THREAD_STEP_INTERVAL;
vm.clear();
@@ -57,23 +54,23 @@ compilerAndInterpreter('edge activated hat thread runs once every frame', (t, co
vm.setTurboMode(false);
vm.loadProject(project).then(() => {
- t.equal(vm.runtime.threads.length, 0);
+ assert.strictEqual(vm.runtime.threads.length, 0);
vm.runtime._step();
let threads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 0);
- t.equal(threads.length, 1);
- checkIsHatThread(t, vm, threads[0]);
- t.assert(threads[0].status === Thread.STATUS_DONE);
+ assert.strictEqual(vm.runtime.threads.length, 0);
+ assert.strictEqual(threads.length, 1);
+ checkIsHatThread(vm, threads[0]);
+ assert.ok(threads[0].status === Thread.STATUS_DONE);
// Check that the hat thread is added again when another step is taken
vm.runtime._step();
threads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 0);
- t.equal(threads.length, 1);
- checkIsHatThread(t, vm, threads[0]);
- t.assert(threads[0].status === Thread.STATUS_DONE);
- t.end();
+ assert.strictEqual(vm.runtime.threads.length, 0);
+ assert.strictEqual(threads.length, 1);
+ checkIsHatThread(vm, threads[0]);
+ assert.ok(threads[0].status === Thread.STATUS_DONE);
+ done();
});
});
});
@@ -83,13 +80,13 @@ compilerAndInterpreter('edge activated hat thread runs once every frame', (t, co
* caching should be reset.
*/
// eslint-disable-next-line max-len
-compilerAndInterpreter('edge activated hat thread runs after being added to previously executed target', (t, co) => {
+compilerAndInterpreter('edge activated hat thread runs after being added to previously executed target', (done, co) => {
const vm = new VirtualMachine();
vm.setCompilerOptions(co);
vm.attachStorage(makeTestStorage());
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
// Note: don't run vm.start(), we handle calling _step() manually in this test
vm.runtime.currentStepTime = Runtime.THREAD_STEP_INTERVAL;
vm.clear();
@@ -97,14 +94,14 @@ compilerAndInterpreter('edge activated hat thread runs after being added to prev
vm.setTurboMode(false);
vm.loadProject(project).then(() => {
- t.equal(vm.runtime.threads.length, 0);
+ assert.strictEqual(vm.runtime.threads.length, 0);
vm.runtime._step();
let threads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 0);
- t.equal(threads.length, 1);
- checkIsHatThread(t, vm, threads[0]);
- t.assert(threads[0].status === Thread.STATUS_DONE);
+ assert.strictEqual(vm.runtime.threads.length, 0);
+ assert.strictEqual(threads.length, 1);
+ checkIsHatThread(vm, threads[0]);
+ assert.ok(threads[0].status === Thread.STATUS_DONE);
// Add a second hat that should create a second thread
const hatBlock = threads[0].target.blocks.getBlock(threads[0].topBlock);
@@ -115,13 +112,13 @@ compilerAndInterpreter('edge activated hat thread runs after being added to prev
// Check that the hat thread is added again when another step is taken
vm.runtime._step();
threads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 0);
- t.equal(threads.length, 2);
- checkIsHatThread(t, vm, threads[0]);
- checkIsHatThread(t, vm, threads[1]);
- t.assert(threads[0].status === Thread.STATUS_DONE);
- t.assert(threads[1].status === Thread.STATUS_DONE);
- t.end();
+ assert.strictEqual(vm.runtime.threads.length, 0);
+ assert.strictEqual(threads.length, 2);
+ checkIsHatThread(vm, threads[0]);
+ checkIsHatThread(vm, threads[1]);
+ assert.ok(threads[0].status === Thread.STATUS_DONE);
+ assert.ok(threads[1].status === Thread.STATUS_DONE);
+ done();
});
});
});
@@ -130,13 +127,13 @@ compilerAndInterpreter('edge activated hat thread runs after being added to prev
* If the hat doesn't finish evaluating within one frame, it shouldn't be added again
* on the next frame. (We skip execution by setting the step time to 0)
*/
-compilerAndInterpreter('edge activated hat thread not added twice', (t, co) => {
+compilerAndInterpreter('edge activated hat thread not added twice', (done, co) => {
const vm = new VirtualMachine();
vm.setCompilerOptions(co);
vm.attachStorage(makeTestStorage());
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
// Note: don't run vm.start(), we handle calling _step() manually in this test
vm.runtime.currentStepTime = 0;
vm.clear();
@@ -144,25 +141,25 @@ compilerAndInterpreter('edge activated hat thread not added twice', (t, co) => {
vm.setTurboMode(false);
vm.loadProject(project).then(() => {
- t.equal(vm.runtime.threads.length, 0);
+ assert.strictEqual(vm.runtime.threads.length, 0);
vm.runtime._step();
let doneThreads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 1);
- t.equal(doneThreads.length, 0);
+ assert.strictEqual(vm.runtime.threads.length, 1);
+ assert.strictEqual(doneThreads.length, 0);
const prevThread = vm.runtime.threads[0];
- checkIsHatThread(t, vm, vm.runtime.threads[0]);
- t.assert(vm.runtime.threads[0].status === Thread.STATUS_RUNNING);
+ checkIsHatThread(vm, vm.runtime.threads[0]);
+ assert.ok(vm.runtime.threads[0].status === Thread.STATUS_RUNNING);
// Check that no new threads are added when another step is taken
vm.runtime._step();
doneThreads = vm.runtime._lastStepDoneThreads;
// There should now be one done hat thread and one new hat thread to run
- t.equal(vm.runtime.threads.length, 1);
- t.equal(doneThreads.length, 0);
- checkIsHatThread(t, vm, vm.runtime.threads[0]);
- t.assert(vm.runtime.threads[0] === prevThread);
- t.end();
+ assert.strictEqual(vm.runtime.threads.length, 1);
+ assert.strictEqual(doneThreads.length, 0);
+ checkIsHatThread(vm, vm.runtime.threads[0]);
+ assert.ok(vm.runtime.threads[0] === prevThread);
+ done();
});
});
});
@@ -172,7 +169,7 @@ compilerAndInterpreter('edge activated hat thread not added twice', (t, co) => {
* Duplicating a sprite should also track duplicated edge activated hat in
* runtime's _edgeActivatedHatValues map.
*/
-compilerAndInterpreter('edge activated hat should trigger for both sprites when sprite is duplicated', (t, co) => {
+compilerAndInterpreter('edge activated hat should trigger for both sprites when sprite is duplicated', (done, co) => {
// Project that is similar to timer-greater-than-hat.sb2, but has code on the sprite so that
// the sprite can be duplicated
@@ -184,7 +181,7 @@ compilerAndInterpreter('edge activated hat should trigger for both sprites when
vm.attachStorage(makeTestStorage());
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
// Note: don't run vm.start(), we handle calling _step() manually in this test
vm.runtime.currentStepTime = 0;
vm.clear();
@@ -192,15 +189,15 @@ compilerAndInterpreter('edge activated hat should trigger for both sprites when
vm.setTurboMode(false);
vm.loadProject(projectWithSprite).then(() => {
- t.equal(vm.runtime.threads.length, 0);
+ assert.strictEqual(vm.runtime.threads.length, 0);
vm.runtime._step();
- t.equal(vm.runtime.threads.length, 1);
- checkIsHatThread(t, vm, vm.runtime.threads[0]);
- t.assert(vm.runtime.threads[0].status === Thread.STATUS_RUNNING);
+ assert.strictEqual(vm.runtime.threads.length, 1);
+ checkIsHatThread(vm, vm.runtime.threads[0]);
+ assert.ok(vm.runtime.threads[0].status === Thread.STATUS_RUNNING);
let numTargetEdgeHats = vm.runtime.targets.reduce((val, target) =>
val + Object.keys(target._edgeActivatedHatValues).length, 0);
- t.equal(numTargetEdgeHats, 1);
+ assert.strictEqual(numTargetEdgeHats, 1);
vm.duplicateSprite(vm.runtime.targets[1].id).then(() => {
vm.runtime._step();
@@ -208,8 +205,8 @@ compilerAndInterpreter('edge activated hat should trigger for both sprites when
// after execute is run on each thread
numTargetEdgeHats = vm.runtime.targets.reduce((val, target) =>
val + Object.keys(target._edgeActivatedHatValues).length, 0);
- t.equal(numTargetEdgeHats, 2);
- t.end();
+ assert.strictEqual(numTargetEdgeHats, 2);
+ done();
});
});
@@ -220,7 +217,7 @@ compilerAndInterpreter('edge activated hat should trigger for both sprites when
* Cloning a sprite should also track cloned edge activated hat separately
* runtime's _edgeActivatedHatValues map.
*/
-compilerAndInterpreter('edge activated hat should trigger for both sprites when sprite is cloned', (t, co) => {
+compilerAndInterpreter('edge activated hat should trigger for both sprites when sprite is cloned', (done, co) => {
// Project that is similar to loudness-hat-block.sb2, but has code on the sprite so that
// the sprite can be duplicated
@@ -232,7 +229,7 @@ compilerAndInterpreter('edge activated hat should trigger for both sprites when
vm.attachStorage(makeTestStorage());
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
// Note: don't run vm.start(), we handle calling _step() manually in this test
vm.runtime.currentStepTime = 0;
vm.clear();
@@ -240,18 +237,18 @@ compilerAndInterpreter('edge activated hat should trigger for both sprites when
vm.setTurboMode(false);
vm.loadProject(projectWithSprite).then(() => {
- t.equal(vm.runtime.threads.length, 0);
+ assert.strictEqual(vm.runtime.threads.length, 0);
vm.runtime._step();
- t.equal(vm.runtime.threads.length, 1);
- checkIsHatThread(t, vm, vm.runtime.threads[0]);
- t.assert(vm.runtime.threads[0].status === Thread.STATUS_RUNNING);
+ assert.strictEqual(vm.runtime.threads.length, 1);
+ checkIsHatThread(vm, vm.runtime.threads[0]);
+ assert.ok(vm.runtime.threads[0].status === Thread.STATUS_RUNNING);
// Run execute on the thread to populate the runtime's
// _edgeActivatedHatValues object
execute(vm.runtime.sequencer, vm.runtime.threads[0]);
let numTargetEdgeHats = vm.runtime.targets.reduce((val, target) =>
val + Object.keys(target._edgeActivatedHatValues).length, 0);
- t.equal(numTargetEdgeHats, 1);
+ assert.strictEqual(numTargetEdgeHats, 1);
const cloneTarget = vm.runtime.targets[1].makeClone();
vm.runtime.addTarget(cloneTarget);
@@ -262,8 +259,8 @@ compilerAndInterpreter('edge activated hat should trigger for both sprites when
vm.runtime.threads.forEach(thread => execute(vm.runtime.sequencer, thread));
numTargetEdgeHats = vm.runtime.targets.reduce((val, target) =>
val + Object.keys(target._edgeActivatedHatValues).length, 0);
- t.equal(numTargetEdgeHats, 2);
- t.end();
+ assert.strictEqual(numTargetEdgeHats, 2);
+ done();
});
});
});
@@ -272,13 +269,13 @@ compilerAndInterpreter('edge activated hat should trigger for both sprites when
* When adding a stack click thread first, make sure that the edge activated hat thread and
* the stack click thread are both pushed and run (despite having the same top block)
*/
-compilerAndInterpreter('edge activated hat thread does not interrupt stack click thread', (t, co) => {
+compilerAndInterpreter('edge activated hat thread does not interrupt stack click thread', (done, co) => {
const vm = new VirtualMachine();
vm.setCompilerOptions(co);
vm.attachStorage(makeTestStorage());
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
// Note: don't run vm.start(), we handle calling _step() manually in this test
vm.runtime.currentStepTime = Runtime.THREAD_STEP_INTERVAL;
vm.clear();
@@ -286,14 +283,14 @@ compilerAndInterpreter('edge activated hat thread does not interrupt stack click
vm.setTurboMode(false);
vm.loadProject(project).then(() => {
- t.equal(vm.runtime.threads.length, 0);
+ assert.strictEqual(vm.runtime.threads.length, 0);
vm.runtime._step();
let doneThreads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 0);
- t.equal(doneThreads.length, 1);
- checkIsHatThread(t, vm, doneThreads[0]);
- t.assert(doneThreads[0].status === Thread.STATUS_DONE);
+ assert.strictEqual(vm.runtime.threads.length, 0);
+ assert.strictEqual(doneThreads.length, 1);
+ checkIsHatThread(vm, doneThreads[0]);
+ assert.ok(doneThreads[0].status === Thread.STATUS_DONE);
// Add stack click thread on this hat
vm.runtime.toggleScript(doneThreads[0].topBlock, {stackClick: true});
@@ -301,8 +298,8 @@ compilerAndInterpreter('edge activated hat thread does not interrupt stack click
// Check that the hat thread is added again when another step is taken
vm.runtime._step();
doneThreads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 0);
- t.equal(doneThreads.length, 2);
+ assert.strictEqual(vm.runtime.threads.length, 0);
+ assert.strictEqual(doneThreads.length, 2);
let hatThread;
let stackClickThread;
if (doneThreads[0].stackClick) {
@@ -312,11 +309,11 @@ compilerAndInterpreter('edge activated hat thread does not interrupt stack click
stackClickThread = doneThreads[1];
hatThread = doneThreads[0];
}
- checkIsHatThread(t, vm, hatThread);
- checkIsStackClickThread(t, vm, stackClickThread);
- t.assert(doneThreads[0].status === Thread.STATUS_DONE);
- t.assert(doneThreads[1].status === Thread.STATUS_DONE);
- t.end();
+ checkIsHatThread(vm, hatThread);
+ checkIsStackClickThread(vm, stackClickThread);
+ assert.ok(doneThreads[0].status === Thread.STATUS_DONE);
+ assert.ok(doneThreads[1].status === Thread.STATUS_DONE);
+ done();
});
});
});
@@ -325,13 +322,13 @@ compilerAndInterpreter('edge activated hat thread does not interrupt stack click
* When adding the hat thread first, make sure that the edge activated hat thread and
* the stack click thread are both pushed and run (despite having the same top block)
*/
-compilerAndInterpreter('edge activated hat thread does not interrupt stack click thread', (t, co) => {
+compilerAndInterpreter('edge activated hat thread does not interrupt stack click thread', (done, co) => {
const vm = new VirtualMachine();
vm.setCompilerOptions(co);
vm.attachStorage(makeTestStorage());
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
// Note: don't run vm.start(), we handle calling _step() manually in this test
vm.runtime.currentStepTime = 0;
vm.clear();
@@ -339,14 +336,14 @@ compilerAndInterpreter('edge activated hat thread does not interrupt stack click
vm.setTurboMode(false);
vm.loadProject(project).then(() => {
- t.equal(vm.runtime.threads.length, 0);
+ assert.strictEqual(vm.runtime.threads.length, 0);
vm.runtime._step();
let doneThreads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 1);
- t.equal(doneThreads.length, 0);
- checkIsHatThread(t, vm, vm.runtime.threads[0]);
- t.assert(vm.runtime.threads[0].status === Thread.STATUS_RUNNING);
+ assert.strictEqual(vm.runtime.threads.length, 1);
+ assert.strictEqual(doneThreads.length, 0);
+ checkIsHatThread(vm, vm.runtime.threads[0]);
+ assert.ok(vm.runtime.threads[0].status === Thread.STATUS_RUNNING);
vm.runtime.currentStepTime = Runtime.THREAD_STEP_INTERVAL;
@@ -356,8 +353,8 @@ compilerAndInterpreter('edge activated hat thread does not interrupt stack click
// Check that the hat thread is added again when another step is taken
vm.runtime._step();
doneThreads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 0);
- t.equal(doneThreads.length, 2);
+ assert.strictEqual(vm.runtime.threads.length, 0);
+ assert.strictEqual(doneThreads.length, 2);
let hatThread;
let stackClickThread;
if (doneThreads[0].stackClick) {
@@ -367,11 +364,11 @@ compilerAndInterpreter('edge activated hat thread does not interrupt stack click
stackClickThread = doneThreads[1];
hatThread = doneThreads[0];
}
- checkIsHatThread(t, vm, hatThread);
- checkIsStackClickThread(t, vm, stackClickThread);
- t.assert(doneThreads[0].status === Thread.STATUS_DONE);
- t.assert(doneThreads[1].status === Thread.STATUS_DONE);
- t.end();
+ checkIsHatThread(vm, hatThread);
+ checkIsStackClickThread(vm, stackClickThread);
+ assert.ok(doneThreads[0].status === Thread.STATUS_DONE);
+ assert.ok(doneThreads[1].status === Thread.STATUS_DONE);
+ done();
});
});
});
diff --git a/test/integration/import-sb.js b/test/integration/import-sb.js
index b58afa06..05983340 100644
--- a/test/integration/import-sb.js
+++ b/test/integration/import-sb.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,20 +8,20 @@ const VirtualMachine = require('../../src/index');
const uri = path.resolve(__dirname, '../fixtures/single_sound.sb');
const project = readFileToBuffer(uri);
-test('default', t => {
+test('default', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length === 0);
+ assert.ok(threads.length === 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
@@ -33,7 +34,7 @@ test('default', t => {
// Check that the sound has the correct md5
// This md5 was obtained from the asset server
- t.equal(firstSound.md5, 'edb9713dedbe9a2e05c09e0540182ef1.wav');
+ assert.strictEqual(firstSound.md5, 'edb9713dedbe9a2e05c09e0540182ef1.wav');
// After two seconds, get playground data and stop
setTimeout(() => {
diff --git a/test/integration/import-sb2-from-object.js b/test/integration/import-sb2-from-object.js
index 63b7ae9b..e3414b8f 100644
--- a/test/integration/import-sb2-from-object.js
+++ b/test/integration/import-sb2-from-object.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const extractProjectJson = require('../fixtures/readProjectFile').extractProjectJson;
const VirtualMachine = require('../../src/index');
@@ -7,20 +8,20 @@ const VirtualMachine = require('../../src/index');
const uri = path.resolve(__dirname, '../fixtures/default.sb2');
const project = extractProjectJson(uri);
-test('default', t => {
+test('default', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length === 0);
+ assert.ok(threads.length === 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/import_nested_sb2.js b/test/integration/import_nested_sb2.js
index 38104669..df6f258a 100644
--- a/test/integration/import_nested_sb2.js
+++ b/test/integration/import_nested_sb2.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const extractProjectJson = require('../fixtures/readProjectFile').extractProjectJson;
@@ -7,12 +8,11 @@ const renderedTarget = require('../../src/sprites/rendered-target');
const runtime = require('../../src/engine/runtime');
const sb2 = require('../../src/serialization/sb2');
-test('spec', t => {
- t.type(sb2.deserialize, 'function');
- t.end();
+test('spec', () => {
+ assert.strictEqual(typeof sb2.deserialize, 'function');
});
-test('nested default/*', t => {
+test('nested default/*', async () => {
// Get SB2 JSON (string)
const uri = path.resolve(__dirname, '../fixtures/default_nested.sb2');
const json = extractProjectJson(uri, 'default');
@@ -20,33 +20,31 @@ test('nested default/*', t => {
// Create runtime instance & load SB2 into it
const rt = new runtime();
rt.attachStorage(makeTestStorage());
- sb2.deserialize(json, rt).then(({targets}) => {
- // Test
- t.type(json, 'object');
- t.type(rt, 'object');
- t.type(targets, 'object');
+ const {targets} = await sb2.deserialize(json, rt);
+ // Test
+ assert.strictEqual(typeof json, 'object');
+ assert.strictEqual(typeof rt, 'object');
+ assert.strictEqual(typeof targets, 'object');
- t.ok(targets[0] instanceof renderedTarget);
- t.type(targets[0].id, 'string');
- t.type(targets[0].blocks, 'object');
- t.type(targets[0].variables, 'object');
- t.type(targets[0].comments, 'object');
+ assert.ok(targets[0] instanceof renderedTarget);
+ assert.strictEqual(typeof targets[0].id, 'string');
+ assert.strictEqual(typeof targets[0].blocks, 'object');
+ assert.strictEqual(typeof targets[0].variables, 'object');
+ assert.strictEqual(typeof targets[0].comments, 'object');
- t.equal(targets[0].isOriginal, true);
- t.equal(targets[0].currentCostume, 0);
- t.equal(targets[0].isOriginal, true);
- t.equal(targets[0].isStage, true);
+ assert.strictEqual(targets[0].isOriginal, true);
+ assert.strictEqual(targets[0].currentCostume, 0);
+ assert.strictEqual(targets[0].isOriginal, true);
+ assert.strictEqual(targets[0].isStage, true);
- t.ok(targets[1] instanceof renderedTarget);
- t.type(targets[1].id, 'string');
- t.type(targets[1].blocks, 'object');
- t.type(targets[1].variables, 'object');
- t.type(targets[1].comments, 'object');
+ assert.ok(targets[1] instanceof renderedTarget);
+ assert.strictEqual(typeof targets[1].id, 'string');
+ assert.strictEqual(typeof targets[1].blocks, 'object');
+ assert.strictEqual(typeof targets[1].variables, 'object');
+ assert.strictEqual(typeof targets[1].comments, 'object');
- t.equal(targets[1].isOriginal, true);
- t.equal(targets[1].currentCostume, 0);
- t.equal(targets[1].isOriginal, true);
- t.equal(targets[1].isStage, false);
- t.end();
- });
+ assert.strictEqual(targets[1].isOriginal, true);
+ assert.strictEqual(targets[1].currentCostume, 0);
+ assert.strictEqual(targets[1].isOriginal, true);
+ assert.strictEqual(targets[1].isStage, false);
});
diff --git a/test/integration/import_sb2.js b/test/integration/import_sb2.js
index fb6fe850..2c6ff823 100644
--- a/test/integration/import_sb2.js
+++ b/test/integration/import_sb2.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const extractProjectJson = require('../fixtures/readProjectFile').extractProjectJson;
@@ -7,12 +8,11 @@ const renderedTarget = require('../../src/sprites/rendered-target');
const runtime = require('../../src/engine/runtime');
const sb2 = require('../../src/serialization/sb2');
-test('spec', t => {
- t.type(sb2.deserialize, 'function');
- t.end();
+test('spec', () => {
+ assert.strictEqual(typeof sb2.deserialize, 'function');
});
-test('default', t => {
+test('default', async () => {
// Get SB2 JSON (string)
const uri = path.resolve(__dirname, '../fixtures/default.sb2');
const json = extractProjectJson(uri);
@@ -20,33 +20,31 @@ test('default', t => {
// Create runtime instance & load SB2 into it
const rt = new runtime();
rt.attachStorage(makeTestStorage());
- sb2.deserialize(json, rt).then(({targets}) => {
- // Test
- t.type(json, 'object');
- t.type(rt, 'object');
- t.type(targets, 'object');
+ const {targets} = await sb2.deserialize(json, rt);
+ // Test
+ assert.strictEqual(typeof json, 'object');
+ assert.strictEqual(typeof rt, 'object');
+ assert.strictEqual(typeof targets, 'object');
- t.ok(targets[0] instanceof renderedTarget);
- t.type(targets[0].id, 'string');
- t.type(targets[0].blocks, 'object');
- t.type(targets[0].variables, 'object');
- t.type(targets[0].comments, 'object');
+ assert.ok(targets[0] instanceof renderedTarget);
+ assert.strictEqual(typeof targets[0].id, 'string');
+ assert.strictEqual(typeof targets[0].blocks, 'object');
+ assert.strictEqual(typeof targets[0].variables, 'object');
+ assert.strictEqual(typeof targets[0].comments, 'object');
- t.equal(targets[0].isOriginal, true);
- t.equal(targets[0].currentCostume, 0);
- t.equal(targets[0].isOriginal, true);
- t.equal(targets[0].isStage, true);
+ assert.strictEqual(targets[0].isOriginal, true);
+ assert.strictEqual(targets[0].currentCostume, 0);
+ assert.strictEqual(targets[0].isOriginal, true);
+ assert.strictEqual(targets[0].isStage, true);
- t.ok(targets[1] instanceof renderedTarget);
- t.type(targets[1].id, 'string');
- t.type(targets[1].blocks, 'object');
- t.type(targets[1].variables, 'object');
- t.type(targets[1].comments, 'object');
+ assert.ok(targets[1] instanceof renderedTarget);
+ assert.strictEqual(typeof targets[1].id, 'string');
+ assert.strictEqual(typeof targets[1].blocks, 'object');
+ assert.strictEqual(typeof targets[1].variables, 'object');
+ assert.strictEqual(typeof targets[1].comments, 'object');
- t.equal(targets[1].isOriginal, true);
- t.equal(targets[1].currentCostume, 0);
- t.equal(targets[1].isOriginal, true);
- t.equal(targets[1].isStage, false);
- t.end();
- });
+ assert.strictEqual(targets[1].isOriginal, true);
+ assert.strictEqual(targets[1].currentCostume, 0);
+ assert.strictEqual(targets[1].isOriginal, true);
+ assert.strictEqual(targets[1].isStage, false);
});
diff --git a/test/integration/internal-extension.js b/test/integration/internal-extension.js
index 51540e18..1460282e 100644
--- a/test/integration/internal-extension.js
+++ b/test/integration/internal-extension.js
@@ -1,4 +1,5 @@
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const Worker = require('tiny-worker');
const BlockType = require('../../src/extension-support/block-type');
@@ -51,22 +52,22 @@ class TestInternalExtension {
}
}
-test('internal extension', t => {
+test('internal extension', () => {
const vm = new VirtualMachine();
const extension = new TestInternalExtension();
- t.ok(extension.status.constructorCalled);
+ assert.ok(extension.status.constructorCalled);
- t.notOk(extension.status.getInfoCalled);
+ assert.ok(!extension.status.getInfoCalled);
vm.extensionManager._registerInternalExtension(extension);
- t.ok(extension.status.getInfoCalled);
+ assert.ok(extension.status.getInfoCalled);
const func = vm.runtime.getOpcodeFunction('testInternalExtension_go');
- t.type(func, 'function');
+ assert.strictEqual(typeof func, 'function');
- t.notOk(extension.status.goCalled);
+ assert.ok(!extension.status.goCalled);
const goBlockInfo = func();
- t.ok(extension.status.goCalled);
+ assert.ok(extension.status.goCalled);
// The 'go' block returns its own blockInfo. Make sure it matches the expected info.
// Note that the extension parser fills in missing fields so there are more fields here than in `getInfo`.
@@ -79,41 +80,38 @@ test('internal extension', t => {
terminal: false,
text: 'go'
};
- t.deepEqual(goBlockInfo, expectedBlockInfo);
+ assert.deepEqual(goBlockInfo, expectedBlockInfo);
// There should be 2 menus - one is an array, one is the function to call.
- t.equal(vm.runtime._blockInfo[0].menus.length, 2);
+ assert.strictEqual(vm.runtime._blockInfo[0].menus.length, 2);
// First menu has 3 items.
- t.equal(
+ assert.strictEqual(
vm.runtime._blockInfo[0].menus[0].json.args0[0].options.length, 3);
// Second menu is a dynamic menu and therefore should be a function.
- t.type(
- vm.runtime._blockInfo[0].menus[1].json.args0[0].options, 'function');
-
- t.end();
+ assert.strictEqual(typeof vm.runtime._blockInfo[0].menus[1].json.args0[0].options, 'function');
});
-test('load sync', t => {
+test('load sync', () => {
const vm = new VirtualMachine();
vm.extensionManager.loadExtensionIdSync('coreExample');
- t.ok(vm.extensionManager.isExtensionLoaded('coreExample'));
+ assert.ok(vm.extensionManager.isExtensionLoaded('coreExample'));
- t.equal(vm.runtime._blockInfo.length, 1);
+ assert.strictEqual(vm.runtime._blockInfo.length, 1);
// blocks should be an array of two items: a button pseudo-block and a reporter block.
- t.equal(vm.runtime._blockInfo[0].blocks.length, 3);
- t.type(vm.runtime._blockInfo[0].blocks[0].info, 'object');
- t.type(vm.runtime._blockInfo[0].blocks[0].info.func, 'MAKE_A_VARIABLE');
- t.equal(vm.runtime._blockInfo[0].blocks[0].info.blockType, 'button');
- t.type(vm.runtime._blockInfo[0].blocks[1].info, 'object');
- t.equal(vm.runtime._blockInfo[0].blocks[1].info.opcode, 'exampleOpcode');
- t.equal(vm.runtime._blockInfo[0].blocks[1].info.blockType, 'reporter');
- t.type(vm.runtime._blockInfo[0].blocks[2].info, 'object');
- t.equal(vm.runtime._blockInfo[0].blocks[2].info.opcode, 'exampleWithInlineImage');
- t.equal(vm.runtime._blockInfo[0].blocks[2].info.blockType, 'command');
+ assert.strictEqual(vm.runtime._blockInfo[0].blocks.length, 3);
+ assert.strictEqual(typeof vm.runtime._blockInfo[0].blocks[0].info, 'object');
+ assert.strictEqual(vm.runtime._blockInfo[0].blocks[0].info.func, 'MAKE_A_VARIABLE');
+ assert.strictEqual(vm.runtime._blockInfo[0].blocks[0].info.blockType, 'button');
+ assert.strictEqual(typeof vm.runtime._blockInfo[0].blocks[1].info, 'object');
+ assert.strictEqual(vm.runtime._blockInfo[0].blocks[1].info.opcode, 'exampleOpcode');
+ assert.strictEqual(vm.runtime._blockInfo[0].blocks[1].info.blockType, 'reporter');
+ assert.strictEqual(typeof vm.runtime._blockInfo[0].blocks[2].info, 'object');
+ assert.strictEqual(vm.runtime._blockInfo[0].blocks[2].info.opcode, 'exampleWithInlineImage');
+ assert.strictEqual(vm.runtime._blockInfo[0].blocks[2].info.blockType, 'command');
// Test the opcode function
- t.equal(vm.runtime._blockInfo[0].blocks[1].info.func(), 'no stage yet');
+ assert.strictEqual(vm.runtime._blockInfo[0].blocks[1].info.func(), 'no stage yet');
const sprite = new Sprite(null, vm.runtime);
sprite.name = 'Stage';
@@ -121,7 +119,5 @@ test('load sync', t => {
stage.isStage = true;
vm.runtime.targets = [stage];
- t.equal(vm.runtime._blockInfo[0].blocks[1].info.func(), 'Stage');
-
- t.end();
+ assert.strictEqual(vm.runtime._blockInfo[0].blocks[1].info.func(), 'Stage');
});
diff --git a/test/integration/list-monitor-rename.js b/test/integration/list-monitor-rename.js
index 286f861a..97e9f514 100644
--- a/test/integration/list-monitor-rename.js
+++ b/test/integration/list-monitor-rename.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,7 +8,7 @@ const VirtualMachine = require('../../src/index');
const projectUri = path.resolve(__dirname, '../fixtures/list-monitor-rename.sb3');
const project = readFileToBuffer(projectUri);
-test('importing sb3 project with incorrect list monitor name', t => {
+test('importing sb3 project with incorrect list monitor name', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -24,19 +25,19 @@ test('importing sb3 project with incorrect list monitor name', t => {
const monitorRecord = vm.runtime._monitorState.get(listId);
const monitorBlock = vm.runtime.monitorBlocks.getBlock(listId);
- t.equal(monitorRecord.opcode, 'data_listcontents');
+ assert.strictEqual(monitorRecord.opcode, 'data_listcontents');
// The list name should be properly renamed
- t.equal(monitorRecord.params.LIST, renamedListName);
- t.equal(monitorBlock.fields.LIST.value, renamedListName);
+ assert.strictEqual(monitorRecord.params.LIST, renamedListName);
+ assert.strictEqual(monitorBlock.fields.LIST.value, renamedListName);
}
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/load-extensions.js b/test/integration/load-extensions.js
index dfddb8de..ad52a2fc 100644
--- a/test/integration/load-extensions.js
+++ b/test/integration/load-extensions.js
@@ -1,6 +1,6 @@
const path = require('path');
-const tap = require('tap');
-const {test} = tap;
+const {test} = require('node:test');
+const assert = require('node:assert');
const fs = require('fs');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const dispatch = require('../../src/dispatch/central-dispatch');
@@ -27,21 +27,17 @@ test('Load external extensions', async t => {
const uri = path.resolve(__dirname, `../fixtures/load-extensions/confirm-load/${file}`);
const project = readFileToBuffer(uri);
- await t.test('Confirm expected extension is installed in example sb2 and sb3 projects', extTest => {
- vm.loadProject(project)
- .then(() => {
- extTest.ok(vm.extensionManager.isExtensionLoaded(ext));
- extTest.end();
- });
+ await t.test('Confirm expected extension is installed in example sb2 and sb3 projects', async () => {
+ await vm.loadProject(project);
+ assert.ok(vm.extensionManager.isExtensionLoaded(ext));
});
}
stopVideoLoop(vm);
vm.quit();
- t.end();
});
-test('Load video sensing extension and video properties', async t => {
+test('Load video sensing extension and video properties', async () => {
const vm = new VirtualMachine();
// An array of test projects and their expected video state values
const testProjects = [
@@ -66,18 +62,17 @@ test('Load video sensing extension and video properties', async t => {
const stage = vm.runtime.getTargetForStage();
- t.ok(vm.extensionManager.isExtensionLoaded('videoSensing'));
+ assert.ok(vm.extensionManager.isExtensionLoaded('videoSensing'));
// Check that the stage target has the video state values we expect
// based on the test project files, then check that the video io device
// has the expected state as well
- t.equal(stage.videoState, project.videoState);
- t.equal(vm.runtime.ioDevices.video.mirror, project.mirror);
- t.equal(stage.videoTransparency, project.videoTransparency);
- t.equal(vm.runtime.ioDevices.video._ghost, project.videoTransparency);
+ assert.strictEqual(stage.videoState, project.videoState);
+ assert.strictEqual(vm.runtime.ioDevices.video.mirror, project.mirror);
+ assert.strictEqual(stage.videoTransparency, project.videoTransparency);
+ assert.strictEqual(vm.runtime.ioDevices.video._ghost, project.videoTransparency);
}
stopVideoLoop(vm);
vm.quit();
- t.end();
});
diff --git a/test/integration/load-sb2-originally-sb1-without-backdrop-image.js b/test/integration/load-sb2-originally-sb1-without-backdrop-image.js
index d1211e24..bd467800 100644
--- a/test/integration/load-sb2-originally-sb1-without-backdrop-image.js
+++ b/test/integration/load-sb2-originally-sb1-without-backdrop-image.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
@@ -10,25 +11,25 @@ const project = readFileToBuffer(projectUri);
const vm = new VirtualMachine();
-test('sb2 project (originally from Scratch 1.4) with missing backdrop image should load', t => {
+test('sb2 project (originally from Scratch 1.4) with missing backdrop image should load', (t, done) => {
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length === 0);
+ assert.ok(threads.length === 0);
vm.quit();
- t.end();
+ done();
});
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.loadProject(project).then(() => {
- t.equal(vm.runtime.targets.length, 2); // stage and default sprite
+ assert.strictEqual(vm.runtime.targets.length, 2); // stage and default sprite
vm.greenFlag();
diff --git a/test/integration/looks.js b/test/integration/looks.js
index 869c7fb0..38e5eae3 100644
--- a/test/integration/looks.js
+++ b/test/integration/looks.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,20 +8,20 @@ const VirtualMachine = require('../../src/index');
const uri = path.resolve(__dirname, '../fixtures/looks.sb2');
const project = readFileToBuffer(uri);
-test('looks', t => {
+test('looks', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length === 0);
+ assert.ok(threads.length === 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/monitor-threads-run-every-frame.js b/test/integration/monitor-threads-run-every-frame.js
index 089beafd..de60ae4f 100644
--- a/test/integration/monitor-threads-run-every-frame.js
+++ b/test/integration/monitor-threads-run-every-frame.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -9,23 +10,23 @@ const Runtime = require('../../src/engine/runtime');
const projectUri = path.resolve(__dirname, '../fixtures/timer-monitor.sb3');
const project = readFileToBuffer(projectUri);
-const checkMonitorThreadPresent = (t, threads) => {
- t.equal(threads.length, 1);
+const checkMonitorThreadPresent = threads => {
+ assert.strictEqual(threads.length, 1);
const monitorThread = threads[0];
- t.equal(monitorThread.stackClick, false);
- t.equal(monitorThread.updateMonitor, true);
- t.equal(monitorThread.topBlock.toString(), 'timer');
+ assert.strictEqual(monitorThread.stackClick, false);
+ assert.strictEqual(monitorThread.updateMonitor, true);
+ assert.strictEqual(monitorThread.topBlock.toString(), 'timer');
};
/**
* Creates a monitor and then checks if it gets run every frame.
*/
-test('monitor thread runs every frame', t => {
+test('monitor thread runs every frame', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
// Note: don't run vm.start(), we handle calling _step() manually in this test
vm.runtime.currentStepTime = Runtime.THREAD_STEP_INTERVAL;
vm.clear();
@@ -33,23 +34,23 @@ test('monitor thread runs every frame', t => {
vm.setTurboMode(false);
vm.loadProject(project).then(() => {
- t.equal(vm.runtime.threads.length, 0);
+ assert.strictEqual(vm.runtime.threads.length, 0);
vm.runtime._step();
let doneThreads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 0);
- t.equal(doneThreads.length, 1);
- checkMonitorThreadPresent(t, doneThreads);
- t.assert(doneThreads[0].status === Thread.STATUS_DONE);
+ assert.strictEqual(vm.runtime.threads.length, 0);
+ assert.strictEqual(doneThreads.length, 1);
+ checkMonitorThreadPresent(doneThreads);
+ assert.ok(doneThreads[0].status === Thread.STATUS_DONE);
// Check that both are added again when another step is taken
vm.runtime._step();
doneThreads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 0);
- t.equal(doneThreads.length, 1);
- checkMonitorThreadPresent(t, doneThreads);
- t.assert(doneThreads[0].status === Thread.STATUS_DONE);
- t.end();
+ assert.strictEqual(vm.runtime.threads.length, 0);
+ assert.strictEqual(doneThreads.length, 1);
+ checkMonitorThreadPresent(doneThreads);
+ assert.ok(doneThreads[0].status === Thread.STATUS_DONE);
+ done();
});
});
});
@@ -58,12 +59,12 @@ test('monitor thread runs every frame', t => {
* If the monitor doesn't finish evaluating within one frame, it shouldn't be added again
* on the next frame. (We skip execution by setting the step time to 0)
*/
-test('monitor thread not added twice', t => {
+test('monitor thread not added twice', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
// Note: don't run vm.start(), we handle calling _step() manually in this test
vm.runtime.currentStepTime = 0;
@@ -72,24 +73,24 @@ test('monitor thread not added twice', t => {
vm.setTurboMode(false);
vm.loadProject(project).then(() => {
- t.equal(vm.runtime.threads.length, 0);
+ assert.strictEqual(vm.runtime.threads.length, 0);
vm.runtime._step();
let doneThreads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 1);
- t.equal(doneThreads.length, 0);
- checkMonitorThreadPresent(t, vm.runtime.threads);
- t.assert(vm.runtime.threads[0].status === Thread.STATUS_RUNNING);
+ assert.strictEqual(vm.runtime.threads.length, 1);
+ assert.strictEqual(doneThreads.length, 0);
+ checkMonitorThreadPresent(vm.runtime.threads);
+ assert.ok(vm.runtime.threads[0].status === Thread.STATUS_RUNNING);
const prevThread = vm.runtime.threads[0];
// Check that both are added again when another step is taken
vm.runtime._step();
doneThreads = vm.runtime._lastStepDoneThreads;
- t.equal(vm.runtime.threads.length, 1);
- t.equal(doneThreads.length, 0);
- checkMonitorThreadPresent(t, vm.runtime.threads);
- t.equal(vm.runtime.threads[0], prevThread);
- t.end();
+ assert.strictEqual(vm.runtime.threads.length, 1);
+ assert.strictEqual(doneThreads.length, 0);
+ checkMonitorThreadPresent(vm.runtime.threads);
+ assert.strictEqual(vm.runtime.threads[0], prevThread);
+ done();
});
});
});
diff --git a/test/integration/monitors_sb2.js b/test/integration/monitors_sb2.js
index e98ac40f..de2f9998 100644
--- a/test/integration/monitors_sb2.js
+++ b/test/integration/monitors_sb2.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,7 +8,7 @@ const VirtualMachine = require('../../src/index');
const projectUri = path.resolve(__dirname, '../fixtures/monitors.sb2');
const project = readFileToBuffer(projectUri);
-test('importing sb2 project with monitors', t => {
+test('importing sb2 project with monitors', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -16,16 +17,16 @@ test('importing sb2 project with monitors', t => {
const threads = JSON.parse(e.threads);
// All monitors should create threads that finish during the step and
// are revoved from runtime.threads.
- t.equal(threads.length, 0);
+ assert.strictEqual(threads.length, 0);
// we care that the last step updated the right number of monitors
// we don't care whether the last step ran other threads or not
const lastStepUpdatedMonitorThreads = vm.runtime._lastStepDoneThreads.filter(thread => thread.updateMonitor);
- t.equal(lastStepUpdatedMonitorThreads.length, 8);
+ assert.strictEqual(lastStepUpdatedMonitorThreads.length, 8);
// There should be one additional hidden monitor that is in the monitorState but
// does not start a thread.
- t.equal(vm.runtime._monitorState.size, 9);
+ assert.strictEqual(vm.runtime._monitorState.size, 9);
const stage = vm.runtime.targets[0];
const target = vm.runtime.targets[1];
@@ -33,55 +34,55 @@ test('importing sb2 project with monitors', t => {
// Global variable named "global" is a slider
let variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'global')[0];
let monitorRecord = vm.runtime._monitorState.get(variableId);
- t.equal(monitorRecord.opcode, 'data_variable');
- t.equal(monitorRecord.mode, 'slider');
- t.equal(monitorRecord.sliderMin, -200); // Make sure these are imported for sliders.
- t.equal(monitorRecord.sliderMax, 30);
- t.equal(monitorRecord.isDiscrete, false);
- t.equal(monitorRecord.x, 5); // These are imported for all monitors, just check once.
- t.equal(monitorRecord.y, 59);
- t.equal(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.opcode, 'data_variable');
+ assert.strictEqual(monitorRecord.mode, 'slider');
+ assert.strictEqual(monitorRecord.sliderMin, -200); // Make sure these are imported for sliders.
+ assert.strictEqual(monitorRecord.sliderMax, 30);
+ assert.strictEqual(monitorRecord.isDiscrete, false);
+ assert.strictEqual(monitorRecord.x, 5); // These are imported for all monitors, just check once.
+ assert.strictEqual(monitorRecord.y, 59);
+ assert.strictEqual(monitorRecord.visible, true);
// Global variable named "global list" is a list
variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'global list')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
- t.equal(monitorRecord.opcode, 'data_listcontents');
- t.equal(monitorRecord.mode, 'list');
- t.equal(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.opcode, 'data_listcontents');
+ assert.strictEqual(monitorRecord.mode, 'list');
+ assert.strictEqual(monitorRecord.visible, true);
// Local variable named "local" is hidden
variableId = Object.keys(target.variables).filter(k => target.variables[k].name === 'local')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
- t.equal(monitorRecord.opcode, 'data_variable');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, false);
+ assert.strictEqual(monitorRecord.opcode, 'data_variable');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, false);
// Local list named "local list" is visible
variableId = Object.keys(target.variables).filter(k => target.variables[k].name === 'local list')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
- t.equal(monitorRecord.opcode, 'data_listcontents');
- t.equal(monitorRecord.mode, 'list');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.width, 106); // Make sure these are imported from lists.
- t.equal(monitorRecord.height, 206);
+ assert.strictEqual(monitorRecord.opcode, 'data_listcontents');
+ assert.strictEqual(monitorRecord.mode, 'list');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.width, 106); // Make sure these are imported from lists.
+ assert.strictEqual(monitorRecord.height, 206);
// Backdrop name monitor is visible, not sprite specific
// should get imported with id that references the name parameter
// via '_name' at the end since the 3.0 block has a dropdown.
monitorRecord = vm.runtime._monitorState.get('backdropnumbername_name');
- t.equal(monitorRecord.opcode, 'looks_backdropnumbername');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorRecord.opcode, 'looks_backdropnumbername');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
// x position monitor is in large mode, specific to sprite 1
monitorRecord = vm.runtime._monitorState.get(`${target.id}_xposition`);
- t.equal(monitorRecord.opcode, 'motion_xposition');
- t.equal(monitorRecord.mode, 'large');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, 'Sprite1');
- t.equal(monitorRecord.targetId, target.id);
+ assert.strictEqual(monitorRecord.opcode, 'motion_xposition');
+ assert.strictEqual(monitorRecord.mode, 'large');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, 'Sprite1');
+ assert.strictEqual(monitorRecord.targetId, target.id);
let monitorId;
@@ -94,40 +95,40 @@ test('importing sb2 project with monitors', t => {
monitorId = 'current_date';
monitorRecord = vm.runtime._monitorState.get(monitorId);
- t.equal(monitorRecord.opcode, 'sensing_current');
+ assert.strictEqual(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorBlock.fields.CURRENTMENU.value, 'DATE');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorBlock.fields.CURRENTMENU.value, 'DATE');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
monitorId = 'current_minute';
monitorRecord = vm.runtime._monitorState.get(monitorId);
- t.equal(monitorRecord.opcode, 'sensing_current');
+ assert.strictEqual(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorBlock.fields.CURRENTMENU.value, 'MINUTE');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorBlock.fields.CURRENTMENU.value, 'MINUTE');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
monitorId = 'current_dayofweek';
monitorRecord = vm.runtime._monitorState.get(monitorId);
- t.equal(monitorRecord.opcode, 'sensing_current');
+ assert.strictEqual(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorBlock.fields.CURRENTMENU.value, 'DAYOFWEEK');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorBlock.fields.CURRENTMENU.value, 'DAYOFWEEK');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/monitors_sb2_to_sb3.js b/test/integration/monitors_sb2_to_sb3.js
index 77b67bce..1d016c49 100644
--- a/test/integration/monitors_sb2_to_sb3.js
+++ b/test/integration/monitors_sb2_to_sb3.js
@@ -1,12 +1,13 @@
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
let vm;
-tap.beforeEach(() => {
+beforeEach(() => {
const projectUri = path.resolve(__dirname, '../fixtures/monitors.sb2');
const project = readFileToBuffer(projectUri);
@@ -21,9 +22,8 @@ tap.beforeEach(() => {
return vm.loadProject(project);
});
-const test = tap.test;
-test('saving and loading sb2 project with monitors preserves sliderMin and sliderMax', t => {
+test('saving and loading sb2 project with monitors preserves sliderMin and sliderMax', (t, done) => {
vm.on('playgroundData', e /* eslint-disable-line no-unused-vars */ => {
// TODO related to above TODO, comment these back in when we figure out
@@ -41,7 +41,7 @@ test('saving and loading sb2 project with monitors preserves sliderMin and slide
// There should be one additional hidden monitor that is in the monitorState but
// does not start a thread.
- t.equal(vm.runtime._monitorState.size, 9);
+ assert.strictEqual(vm.runtime._monitorState.size, 9);
const stage = vm.runtime.targets[0];
const target = vm.runtime.targets[1];
@@ -50,55 +50,55 @@ test('saving and loading sb2 project with monitors preserves sliderMin and slide
let variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'global')[0];
// Used later when checking save and load of slider min/max
let monitorRecord = vm.runtime._monitorState.get(variableId);
- t.equal(monitorRecord.opcode, 'data_variable');
- t.equal(monitorRecord.mode, 'slider');
- t.equal(monitorRecord.sliderMin, -200); // Make sure these are imported for sliders.
- t.equal(monitorRecord.sliderMax, 30);
- t.equal(monitorRecord.isDiscrete, false);
- t.equal(monitorRecord.x, 5); // These are imported for all monitors, just check once.
- t.equal(monitorRecord.y, 59);
- t.equal(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.opcode, 'data_variable');
+ assert.strictEqual(monitorRecord.mode, 'slider');
+ assert.strictEqual(monitorRecord.sliderMin, -200); // Make sure these are imported for sliders.
+ assert.strictEqual(monitorRecord.sliderMax, 30);
+ assert.strictEqual(monitorRecord.isDiscrete, false);
+ assert.strictEqual(monitorRecord.x, 5); // These are imported for all monitors, just check once.
+ assert.strictEqual(monitorRecord.y, 59);
+ assert.strictEqual(monitorRecord.visible, true);
// Global variable named "global list" is a list
variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'global list')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
- t.equal(monitorRecord.opcode, 'data_listcontents');
- t.equal(monitorRecord.mode, 'list');
- t.equal(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.opcode, 'data_listcontents');
+ assert.strictEqual(monitorRecord.mode, 'list');
+ assert.strictEqual(monitorRecord.visible, true);
// Local variable named "local" is hidden
variableId = Object.keys(target.variables).filter(k => target.variables[k].name === 'local')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
- t.equal(monitorRecord.opcode, 'data_variable');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, false);
+ assert.strictEqual(monitorRecord.opcode, 'data_variable');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, false);
// Local list named "local list" is visible
variableId = Object.keys(target.variables).filter(k => target.variables[k].name === 'local list')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
- t.equal(monitorRecord.opcode, 'data_listcontents');
- t.equal(monitorRecord.mode, 'list');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.width, 106); // Make sure these are imported from lists.
- t.equal(monitorRecord.height, 206);
+ assert.strictEqual(monitorRecord.opcode, 'data_listcontents');
+ assert.strictEqual(monitorRecord.mode, 'list');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.width, 106); // Make sure these are imported from lists.
+ assert.strictEqual(monitorRecord.height, 206);
// Backdrop name monitor is visible, not sprite specific
// should get imported with id that references the name parameter
// via '_name' at the end since the 3.0 block has a dropdown.
monitorRecord = vm.runtime._monitorState.get('backdropnumbername_name');
- t.equal(monitorRecord.opcode, 'looks_backdropnumbername');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorRecord.opcode, 'looks_backdropnumbername');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
// x position monitor is in large mode, specific to sprite 1
monitorRecord = vm.runtime._monitorState.get(`${target.id}_xposition`);
- t.equal(monitorRecord.opcode, 'motion_xposition');
- t.equal(monitorRecord.mode, 'large');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, 'Sprite1');
- t.equal(monitorRecord.targetId, target.id);
+ assert.strictEqual(monitorRecord.opcode, 'motion_xposition');
+ assert.strictEqual(monitorRecord.mode, 'large');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, 'Sprite1');
+ assert.strictEqual(monitorRecord.targetId, target.id);
let monitorId;
@@ -111,45 +111,44 @@ test('saving and loading sb2 project with monitors preserves sliderMin and slide
monitorId = 'current_date';
monitorRecord = vm.runtime._monitorState.get(monitorId);
- t.equal(monitorRecord.opcode, 'sensing_current');
+ assert.strictEqual(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorBlock.fields.CURRENTMENU.value, 'DATE');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorBlock.fields.CURRENTMENU.value, 'DATE');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
monitorId = 'current_minute';
monitorRecord = vm.runtime._monitorState.get(monitorId);
- t.equal(monitorRecord.opcode, 'sensing_current');
+ assert.strictEqual(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorBlock.fields.CURRENTMENU.value, 'MINUTE');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorBlock.fields.CURRENTMENU.value, 'MINUTE');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
monitorId = 'current_dayofweek';
monitorRecord = vm.runtime._monitorState.get(monitorId);
- t.equal(monitorRecord.opcode, 'sensing_current');
+ assert.strictEqual(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorBlock.fields.CURRENTMENU.value, 'DAYOFWEEK');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorBlock.fields.CURRENTMENU.value, 'DAYOFWEEK');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(async () => {
const sb3ProjectJson = vm.toJSON();
- return vm.loadProject(sb3ProjectJson).then(() => {
- setTimeout(() => {
- vm.getPlaygroundData();
- vm.stopAll();
- }, 100);
- });
+ await vm.loadProject(sb3ProjectJson);
+ setTimeout(() => {
+ vm.getPlaygroundData();
+ vm.stopAll();
+ }, 100);
});
});
diff --git a/test/integration/monitors_sb3.js b/test/integration/monitors_sb3.js
index f688d79c..f899f3e4 100644
--- a/test/integration/monitors_sb3.js
+++ b/test/integration/monitors_sb3.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -8,7 +9,7 @@ const Variable = require('../../src/engine/variable');
const projectUri = path.resolve(__dirname, '../fixtures/monitors.sb3');
const project = readFileToBuffer(projectUri);
-test('importing sb3 project with monitors', t => {
+test('importing sb3 project with monitors', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -17,16 +18,16 @@ test('importing sb3 project with monitors', t => {
const threads = JSON.parse(e.threads);
// All monitors should create threads that finish during the step and
// are revoved from runtime.threads.
- t.equal(threads.length, 0);
+ assert.strictEqual(threads.length, 0);
// we care that the last step updated the right number of monitors
// we don't care whether the last step ran other threads or not
const lastStepUpdatedMonitorThreads = vm.runtime._lastStepDoneThreads.filter(thread => thread.updateMonitor);
- t.equal(lastStepUpdatedMonitorThreads.length, 17);
+ assert.strictEqual(lastStepUpdatedMonitorThreads.length, 17);
// There should be one additional hidden monitor that is in the monitorState but
// does not start a thread.
- t.equal(vm.runtime._monitorState.size, 18);
+ assert.strictEqual(vm.runtime._monitorState.size, 18);
const stage = vm.runtime.targets[0];
const shirtSprite = vm.runtime.targets[1];
@@ -36,94 +37,96 @@ test('importing sb3 project with monitors', t => {
let variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'my variable')[0];
let monitorRecord = vm.runtime._monitorState.get(variableId);
let monitorBlock = vm.runtime.monitorBlocks.getBlock(variableId);
- t.equal(monitorRecord.opcode, 'data_variable');
- t.equal(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.opcode, 'data_variable');
+ assert.strictEqual(monitorRecord.mode, 'default');
// The following few properties are imported for all monitors, just check once.
- t.equal(monitorRecord.sliderMin, 0);
- t.equal(monitorRecord.sliderMax, 100);
- t.equal(monitorRecord.isDiscrete, true); // The default if not present
- t.equal(monitorRecord.x, 10);
- t.equal(monitorRecord.y, 62);
+ assert.strictEqual(monitorRecord.sliderMin, 0);
+ assert.strictEqual(monitorRecord.sliderMax, 100);
+ assert.strictEqual(monitorRecord.isDiscrete, true); // The default if not present
+ assert.strictEqual(monitorRecord.x, 10);
+ assert.strictEqual(monitorRecord.y, 62);
// Height and width are only used for list monitors and should default to 0
// for all other monitors
- t.equal(monitorRecord.width, 0);
- t.equal(monitorRecord.height, 0);
- t.equal(monitorRecord.visible, true);
- t.type(monitorRecord.params, 'object');
+ assert.strictEqual(monitorRecord.width, 0);
+ assert.strictEqual(monitorRecord.height, 0);
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(typeof monitorRecord.params, 'object');
// The variable name should be stored in the monitor params
- t.equal(monitorRecord.params.VARIABLE, 'my variable');
+ assert.strictEqual(monitorRecord.params.VARIABLE, 'my variable');
// Test that the monitor block and its fields were constructed correctly
- t.equal(monitorBlock.fields.VARIABLE.value, 'my variable');
- t.equal(monitorBlock.fields.VARIABLE.name, 'VARIABLE');
- t.equal(monitorBlock.fields.VARIABLE.id, variableId);
- t.equal(monitorBlock.fields.VARIABLE.variableType, Variable.SCALAR_TYPE);
+ assert.strictEqual(monitorBlock.fields.VARIABLE.value, 'my variable');
+ assert.strictEqual(monitorBlock.fields.VARIABLE.name, 'VARIABLE');
+ assert.strictEqual(monitorBlock.fields.VARIABLE.id, variableId);
+ assert.strictEqual(monitorBlock.fields.VARIABLE.variableType, Variable.SCALAR_TYPE);
// There is a global variable named 'secret_slide' which has a hidden monitor
variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'secret_slide')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
monitorBlock = vm.runtime.monitorBlocks.getBlock(variableId);
- t.equal(monitorRecord.opcode, 'data_variable');
- t.equal(monitorRecord.mode, 'slider');
- t.equal(monitorRecord.visible, false);
- t.equal(monitorRecord.sliderMin, 0);
- t.equal(monitorRecord.sliderMax, 100);
- t.type(monitorRecord.params, 'object');
- t.equal(monitorRecord.params.VARIABLE, 'secret_slide');
+ assert.strictEqual(monitorRecord.opcode, 'data_variable');
+ assert.strictEqual(monitorRecord.mode, 'slider');
+ assert.strictEqual(monitorRecord.visible, false);
+ assert.strictEqual(monitorRecord.sliderMin, 0);
+ assert.strictEqual(monitorRecord.sliderMax, 100);
+ assert.strictEqual(typeof monitorRecord.params, 'object');
+ assert.strictEqual(monitorRecord.params.VARIABLE, 'secret_slide');
// Test that the monitor block and its fields were constructed correctly
- t.equal(monitorBlock.fields.VARIABLE.value, 'secret_slide');
- t.equal(monitorBlock.fields.VARIABLE.name, 'VARIABLE');
- t.equal(monitorBlock.fields.VARIABLE.id, variableId);
- t.equal(monitorBlock.fields.VARIABLE.variableType, Variable.SCALAR_TYPE);
+ assert.strictEqual(monitorBlock.fields.VARIABLE.value, 'secret_slide');
+ assert.strictEqual(monitorBlock.fields.VARIABLE.name, 'VARIABLE');
+ assert.strictEqual(monitorBlock.fields.VARIABLE.id, variableId);
+ assert.strictEqual(monitorBlock.fields.VARIABLE.variableType, Variable.SCALAR_TYPE);
// Shirt sprite has a local list named "fashion"
variableId = Object.keys(shirtSprite.variables).filter(k => shirtSprite.variables[k].name === 'fashion')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
monitorBlock = vm.runtime.monitorBlocks.getBlock(variableId);
- t.equal(monitorRecord.opcode, 'data_listcontents');
- t.equal(monitorRecord.mode, 'list');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.height, 122);
- t.equal(monitorRecord.width, 104);
- t.type(monitorRecord.params, 'object');
- t.equal(monitorRecord.params.LIST, 'fashion'); // The list name should be stored in the monitor params
+ assert.strictEqual(monitorRecord.opcode, 'data_listcontents');
+ assert.strictEqual(monitorRecord.mode, 'list');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.height, 122);
+ assert.strictEqual(monitorRecord.width, 104);
+ assert.strictEqual(typeof monitorRecord.params, 'object');
+ // The list name should be stored in the monitor params
+ assert.strictEqual(monitorRecord.params.LIST, 'fashion');
// Test that the monitor block and its fields were constructed correctly
- t.equal(monitorBlock.fields.LIST.value, 'fashion');
- t.equal(monitorBlock.fields.LIST.name, 'LIST');
- t.equal(monitorBlock.fields.LIST.id, variableId);
- t.equal(monitorBlock.fields.LIST.variableType, Variable.LIST_TYPE);
+ assert.strictEqual(monitorBlock.fields.LIST.value, 'fashion');
+ assert.strictEqual(monitorBlock.fields.LIST.name, 'LIST');
+ assert.strictEqual(monitorBlock.fields.LIST.id, variableId);
+ assert.strictEqual(monitorBlock.fields.LIST.variableType, Variable.LIST_TYPE);
// Shirt sprite has a local variable named "tee"
variableId = Object.keys(shirtSprite.variables).filter(k => shirtSprite.variables[k].name === 'tee')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
monitorBlock = vm.runtime.monitorBlocks.getBlock(variableId);
- t.equal(monitorRecord.opcode, 'data_variable');
- t.equal(monitorRecord.mode, 'slider');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.sliderMin, 0);
- t.equal(monitorRecord.sliderMax, 100);
- t.type(monitorRecord.params, 'object');
- t.equal(monitorRecord.params.VARIABLE, 'tee');
+ assert.strictEqual(monitorRecord.opcode, 'data_variable');
+ assert.strictEqual(monitorRecord.mode, 'slider');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.sliderMin, 0);
+ assert.strictEqual(monitorRecord.sliderMax, 100);
+ assert.strictEqual(typeof monitorRecord.params, 'object');
+ assert.strictEqual(monitorRecord.params.VARIABLE, 'tee');
// Test that the monitor block and its fields were constructed correctly
- t.equal(monitorBlock.fields.VARIABLE.value, 'tee');
- t.equal(monitorBlock.fields.VARIABLE.name, 'VARIABLE');
- t.equal(monitorBlock.fields.VARIABLE.id, variableId);
- t.equal(monitorBlock.fields.VARIABLE.variableType, Variable.SCALAR_TYPE);
+ assert.strictEqual(monitorBlock.fields.VARIABLE.value, 'tee');
+ assert.strictEqual(monitorBlock.fields.VARIABLE.name, 'VARIABLE');
+ assert.strictEqual(monitorBlock.fields.VARIABLE.id, variableId);
+ assert.strictEqual(monitorBlock.fields.VARIABLE.variableType, Variable.SCALAR_TYPE);
// Heart sprite has a local list named "hearty"
variableId = Object.keys(heartSprite.variables).filter(k => heartSprite.variables[k].name === 'hearty')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
monitorBlock = vm.runtime.monitorBlocks.getBlock(variableId);
- t.equal(monitorRecord.opcode, 'data_variable');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.type(monitorRecord.params, 'object');
- t.equal(monitorRecord.params.VARIABLE, 'hearty'); // The variable name should be stored in the monitor params
+ assert.strictEqual(monitorRecord.opcode, 'data_variable');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(typeof monitorRecord.params, 'object');
+ // The variable name should be stored in the monitor params
+ assert.strictEqual(monitorRecord.params.VARIABLE, 'hearty');
// Test that the monitor block and its fields were constructed correctly
- t.equal(monitorBlock.fields.VARIABLE.value, 'hearty');
- t.equal(monitorBlock.fields.VARIABLE.name, 'VARIABLE');
- t.equal(monitorBlock.fields.VARIABLE.id, variableId);
- t.equal(monitorBlock.fields.VARIABLE.variableType, Variable.SCALAR_TYPE);
+ assert.strictEqual(monitorBlock.fields.VARIABLE.value, 'hearty');
+ assert.strictEqual(monitorBlock.fields.VARIABLE.name, 'VARIABLE');
+ assert.strictEqual(monitorBlock.fields.VARIABLE.id, variableId);
+ assert.strictEqual(monitorBlock.fields.VARIABLE.variableType, Variable.SCALAR_TYPE);
// Backdrop name monitor is visible, not sprite specific
// should get imported with id that references the name parameter
@@ -131,13 +134,13 @@ test('importing sb3 project with monitors', t => {
let monitorId = 'backdropnumbername_name';
monitorRecord = vm.runtime._monitorState.get(monitorId);
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorRecord.opcode, 'looks_backdropnumbername');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorRecord.opcode, 'looks_backdropnumbername');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
// Test that the monitor block and its fields were constructed correctly
- t.equal(monitorBlock.fields.NUMBER_NAME.value, 'name');
+ assert.strictEqual(monitorBlock.fields.NUMBER_NAME.value, 'name');
// Backdrop name monitor is visible, not sprite specific
// should get imported with id that references the name parameter
@@ -145,52 +148,52 @@ test('importing sb3 project with monitors', t => {
monitorId = 'backdropnumbername_number';
monitorRecord = vm.runtime._monitorState.get(monitorId);
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorRecord.opcode, 'looks_backdropnumbername');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorRecord.opcode, 'looks_backdropnumbername');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
// Test that the monitor block and its fields were constructed correctly
- t.equal(monitorBlock.fields.NUMBER_NAME.value, 'number');
+ assert.strictEqual(monitorBlock.fields.NUMBER_NAME.value, 'number');
// x position monitor is in large mode, specific to shirt sprite
monitorId = `${shirtSprite.id}_xposition`;
monitorRecord = vm.runtime._monitorState.get(monitorId);
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorRecord.opcode, 'motion_xposition');
- t.equal(monitorRecord.mode, 'large');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, 'Shirt-T');
- t.equal(monitorRecord.targetId, shirtSprite.id);
+ assert.strictEqual(monitorRecord.opcode, 'motion_xposition');
+ assert.strictEqual(monitorRecord.mode, 'large');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, 'Shirt-T');
+ assert.strictEqual(monitorRecord.targetId, shirtSprite.id);
// y position monitor is in large mode, specific to shirt sprite
monitorId = `${shirtSprite.id}_yposition`;
monitorRecord = vm.runtime._monitorState.get(monitorId);
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorRecord.opcode, 'motion_yposition');
- t.equal(monitorRecord.mode, 'large');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, 'Shirt-T');
- t.equal(monitorRecord.targetId, shirtSprite.id);
+ assert.strictEqual(monitorRecord.opcode, 'motion_yposition');
+ assert.strictEqual(monitorRecord.mode, 'large');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, 'Shirt-T');
+ assert.strictEqual(monitorRecord.targetId, shirtSprite.id);
// direction monitor is in large mode, specific to shirt sprite
monitorId = `${shirtSprite.id}_direction`;
monitorRecord = vm.runtime._monitorState.get(monitorId);
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorRecord.opcode, 'motion_direction');
- t.equal(monitorRecord.mode, 'large');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, 'Shirt-T');
- t.equal(monitorRecord.targetId, shirtSprite.id);
+ assert.strictEqual(monitorRecord.opcode, 'motion_direction');
+ assert.strictEqual(monitorRecord.mode, 'large');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, 'Shirt-T');
+ assert.strictEqual(monitorRecord.targetId, shirtSprite.id);
monitorId = `${shirtSprite.id}_size`;
monitorRecord = vm.runtime._monitorState.get(monitorId);
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorRecord.opcode, 'looks_size');
- t.equal(monitorRecord.mode, 'large');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, 'Shirt-T');
- t.equal(monitorRecord.targetId, shirtSprite.id);
+ assert.strictEqual(monitorRecord.opcode, 'looks_size');
+ assert.strictEqual(monitorRecord.mode, 'large');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, 'Shirt-T');
+ assert.strictEqual(monitorRecord.targetId, shirtSprite.id);
// The monitor IDs for the sensing_current block should be unique
// to the parameter that is selected on the block being monitored.
@@ -198,61 +201,61 @@ test('importing sb3 project with monitors', t => {
// though the field value on the block is uppercase.
monitorId = 'current_date';
monitorRecord = vm.runtime._monitorState.get(monitorId);
- t.equal(monitorRecord.opcode, 'sensing_current');
+ assert.strictEqual(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorBlock.fields.CURRENTMENU.value, 'DATE');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorBlock.fields.CURRENTMENU.value, 'DATE');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
monitorId = 'current_year';
monitorRecord = vm.runtime._monitorState.get(monitorId);
- t.equal(monitorRecord.opcode, 'sensing_current');
+ assert.strictEqual(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorBlock.fields.CURRENTMENU.value, 'YEAR');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorBlock.fields.CURRENTMENU.value, 'YEAR');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
monitorId = 'current_month';
monitorRecord = vm.runtime._monitorState.get(monitorId);
- t.equal(monitorRecord.opcode, 'sensing_current');
+ assert.strictEqual(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorBlock.fields.CURRENTMENU.value, 'MONTH');
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
+ assert.strictEqual(monitorBlock.fields.CURRENTMENU.value, 'MONTH');
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
// Extension Monitors
monitorId = 'music_getTempo';
monitorRecord = vm.runtime._monitorState.get(monitorId);
- t.equal(monitorRecord.opcode, 'music_getTempo');
+ assert.strictEqual(monitorRecord.opcode, 'music_getTempo');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
- t.equal(vm.extensionManager.isExtensionLoaded('music'), true);
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
+ assert.strictEqual(vm.extensionManager.isExtensionLoaded('music'), true);
monitorId = 'ev3_getDistance';
monitorRecord = vm.runtime._monitorState.get(monitorId);
- t.equal(monitorRecord.opcode, 'ev3_getDistance');
+ assert.strictEqual(monitorRecord.opcode, 'ev3_getDistance');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
- t.equal(monitorRecord.mode, 'default');
- t.equal(monitorRecord.visible, true);
- t.equal(monitorRecord.spriteName, null);
- t.equal(monitorRecord.targetId, null);
- t.equal(vm.extensionManager.isExtensionLoaded('ev3'), true);
+ assert.strictEqual(monitorRecord.mode, 'default');
+ assert.strictEqual(monitorRecord.visible, true);
+ assert.strictEqual(monitorRecord.spriteName, null);
+ assert.strictEqual(monitorRecord.targetId, null);
+ assert.strictEqual(vm.extensionManager.isExtensionLoaded('ev3'), true);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/motion.js b/test/integration/motion.js
index 6d69bb9b..b3820a49 100644
--- a/test/integration/motion.js
+++ b/test/integration/motion.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,20 +8,20 @@ const VirtualMachine = require('../../src/index');
const uri = path.resolve(__dirname, '../fixtures/motion.sb2');
const project = readFileToBuffer(uri);
-test('motion', t => {
+test('motion', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length > 0);
+ assert.ok(threads.length > 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/offline-custom-assets.js b/test/integration/offline-custom-assets.js
index 50bd9c00..4ee5be83 100644
--- a/test/integration/offline-custom-assets.js
+++ b/test/integration/offline-custom-assets.js
@@ -6,7 +6,8 @@
*/
const path = require('path');
const fs = require('fs');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const AdmZip = require('adm-zip');
const ScratchStorage = require('scratch-storage');
const VirtualMachine = require('../../src/index');
@@ -23,7 +24,7 @@ const costumeData = new Uint8Array(costume);
const sound = projectZip.readFile('0.wav');
const soundData = new Uint8Array(sound);
-test('offline-custom-assets', t => {
+test('offline-custom-assets', (t, done) => {
const vm = new VirtualMachine();
// Use a test storage here that does not have any web sources added to it.
const testStorage = new ScratchStorage();
@@ -32,13 +33,13 @@ test('offline-custom-assets', t => {
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length === 0);
+ assert.ok(threads.length === 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
@@ -46,23 +47,23 @@ test('offline-custom-assets', t => {
vm.loadProject(project).then(() => {
// Verify initial state
- t.equals(vm.runtime.targets.length, 2);
+ assert.strictEqual(vm.runtime.targets.length, 2);
const costumes = vm.runtime.targets[1].getCostumes();
- t.equals(costumes.length, 1);
+ assert.strictEqual(costumes.length, 1);
const customCostume = costumes[0];
- t.equals(customCostume.name, 'A_Test_Costume');
+ assert.strictEqual(customCostume.name, 'A_Test_Costume');
const storedCostume = customCostume.asset;
- t.type(storedCostume, 'object');
- t.deepEquals(storedCostume.data, costumeData);
+ assert.strictEqual(typeof storedCostume, 'object');
+ assert.deepEqual(storedCostume.data, costumeData);
const sounds = vm.runtime.targets[1].sprite.sounds;
- t.equals(sounds.length, 1);
+ assert.strictEqual(sounds.length, 1);
const customSound = sounds[0];
- t.equals(customSound.name, 'A_Test_Recording');
+ assert.strictEqual(customSound.name, 'A_Test_Recording');
const storedSound = customSound.asset;
- t.type(storedSound, 'object');
- t.deepEquals(storedSound.data, soundData);
+ assert.strictEqual(typeof storedSound, 'object');
+ assert.deepEqual(storedSound.data, soundData);
vm.greenFlag();
diff --git a/test/integration/pen.js b/test/integration/pen.js
index e2821e24..574da26b 100644
--- a/test/integration/pen.js
+++ b/test/integration/pen.js
@@ -1,6 +1,7 @@
const Worker = require('tiny-worker');
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const Scratch3PenBlocks = require('../../src/extensions/scratch3_pen/index.js');
const VirtualMachine = require('../../src/index');
@@ -15,7 +16,7 @@ const project = readFileToBuffer(uri);
// By default Central Dispatch works with the Worker class built into the browser. Tell it to use TinyWorker instead.
dispatch.workerClass = Worker;
-test('pen', t => {
+test('pen', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -25,7 +26,7 @@ test('pen', t => {
const catSprite = vm.runtime.targets[1].sprite;
const [originalCat, cloneCat] = catSprite.clones;
- t.notStrictEqual(originalCat, cloneCat);
+ assert.notStrictEqual(originalCat, cloneCat);
/** @type {PenState} */
const originalPenState = originalCat.getCustomState(Scratch3PenBlocks.STATE_KEY);
@@ -33,16 +34,16 @@ test('pen', t => {
/** @type {PenState} */
const clonePenState = cloneCat.getCustomState(Scratch3PenBlocks.STATE_KEY);
- t.notStrictEqual(originalPenState, clonePenState);
- t.equal(originalPenState.penAttributes.diameter, 51);
- t.equal(clonePenState.penAttributes.diameter, 42);
+ assert.notStrictEqual(originalPenState, clonePenState);
+ assert.strictEqual(originalPenState.penAttributes.diameter, 51);
+ assert.strictEqual(clonePenState.penAttributes.diameter, 42);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/procedure.js b/test/integration/procedure.js
index a3264fae..fc293a3e 100644
--- a/test/integration/procedure.js
+++ b/test/integration/procedure.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,20 +8,20 @@ const VirtualMachine = require('../../src/index');
const uri = path.resolve(__dirname, '../fixtures/procedure.sb2');
const project = readFileToBuffer(uri);
-test('procedure', t => {
+test('procedure', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length === 0);
+ assert.ok(threads.length === 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/runId.js b/test/integration/runId.js
index cdc006b2..06b1505b 100644
--- a/test/integration/runId.js
+++ b/test/integration/runId.js
@@ -1,6 +1,7 @@
const Worker = require('tiny-worker');
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const VirtualMachine = require('../../src/index');
const dispatch = require('../../src/dispatch/central-dispatch');
@@ -15,7 +16,7 @@ const project = readFileToBuffer(uri);
// By default Central Dispatch works with the Worker class built into the browser. Tell it to use TinyWorker instead.
dispatch.workerClass = Worker;
-test('runId', async t => {
+test('runId', async () => {
const guidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
const isGuid = data => guidRegex.test(data);
@@ -25,7 +26,7 @@ test('runId', async t => {
const runIdLog = [];
const pushRunId = () => {
const runId = storage.scratchFetch.getMetadata(storage.scratchFetch.RequestMetadata.RunId);
- t.ok(isGuid(runId), 'Run IDs should always be a properly-formatted GUID', {runId});
+ assert.ok(isGuid(runId), 'Run IDs should always be a properly-formatted GUID', {runId});
runIdLog.push(runId);
};
@@ -64,10 +65,9 @@ test('runId', async t => {
for (let i = 0; i < runIdLog.length - 1; ++i) {
for (let j = i + 1; j < runIdLog.length; ++j) {
- t.notSame(runIdLog[i], runIdLog[j], 'Run IDs should always be unique', {runIdLog});
+ assert.notDeepEqual(runIdLog[i], runIdLog[j], 'Run IDs should always be unique');
}
}
vm.quit();
- t.end();
});
diff --git a/test/integration/running_project_changed_state.js b/test/integration/running_project_changed_state.js
index ea18f878..2c9eb182 100644
--- a/test/integration/running_project_changed_state.js
+++ b/test/integration/running_project_changed_state.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,7 +8,7 @@ const VirtualMachine = require('../../src/index');
const uri = path.resolve(__dirname, '../fixtures/looks.sb2');
const project = readFileToBuffer(uri);
-test('Running project should not emit project changed event', t => {
+test('Running project should not emit project changed event', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -18,13 +19,13 @@ test('Running project should not emit project changed event', t => {
// Evaluate playground data and exit
vm.on('playgroundData', () => {
- t.equal(projectChanged, false);
+ assert.strictEqual(projectChanged, false);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/saythink-and-wait.js b/test/integration/saythink-and-wait.js
index e902d3a9..65a28083 100644
--- a/test/integration/saythink-and-wait.js
+++ b/test/integration/saythink-and-wait.js
@@ -1,6 +1,7 @@
const Worker = require('tiny-worker');
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -12,12 +13,12 @@ const project = readFileToBuffer(uri);
// By default Central Dispatch works with the Worker class built into the browser. Tell it to use TinyWorker instead.
dispatch.workerClass = Worker;
-test('say/think and wait', t => {
+test('say/think and wait', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
@@ -30,7 +31,7 @@ test('say/think and wait', t => {
setTimeout(() => {
vm.stopAll();
vm.quit();
- t.end();
+ done();
}, 2000);
});
});
diff --git a/test/integration/sb2-import-extension-monitors.js b/test/integration/sb2-import-extension-monitors.js
index 75dad344..9099eae8 100644
--- a/test/integration/sb2-import-extension-monitors.js
+++ b/test/integration/sb2-import-extension-monitors.js
@@ -1,6 +1,6 @@
const path = require('path');
-const tap = require('tap');
-const test = tap.test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const {readFileToBuffer, extractProjectJson} = require('../fixtures/readProjectFile');
const VirtualMachine = require('../../src/index');
@@ -25,7 +25,7 @@ const visibleTempoMonitorProjectUri = path.resolve(
__dirname, '../fixtures/visible-tempo-monitor-no-other-music-blocks.sb2');
const visibleTempoMonitorProject = readFileToBuffer(visibleTempoMonitorProjectUri);
-test('loading sb2 project with invisible video monitor should not load monitor or extension', t => {
+test('loading sb2 project with invisible video monitor should not load monitor or extension', async () => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -34,15 +34,13 @@ test('loading sb2 project with invisible video monitor should not load monitor o
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(invisibleVideoMonitorProject).then(() => {
- t.equal(vm.extensionManager.isExtensionLoaded('videoSensing'), false);
- t.equal(vm.runtime._monitorState.size, 0);
- vm.quit();
- t.end();
- });
+ await vm.loadProject(invisibleVideoMonitorProject);
+ assert.strictEqual(vm.extensionManager.isExtensionLoaded('videoSensing'), false);
+ assert.strictEqual(vm.runtime._monitorState.size, 0);
+ vm.quit();
});
-test('loading sb2 project with visible video monitor should not load extension', t => {
+test('loading sb2 project with visible video monitor should not load extension', async () => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -51,30 +49,26 @@ test('loading sb2 project with visible video monitor should not load extension',
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(visibleVideoMonitorProject).then(() => {
- t.equal(vm.extensionManager.isExtensionLoaded('videoSensing'), false);
- t.equal(vm.runtime._monitorState.size, 0);
- vm.quit();
- t.end();
- });
+ await vm.loadProject(visibleVideoMonitorProject);
+ assert.strictEqual(vm.extensionManager.isExtensionLoaded('videoSensing'), false);
+ assert.strictEqual(vm.runtime._monitorState.size, 0);
+ vm.quit();
});
// This test looks a little different than the rest because loading a project with
// the video sensing block requires a mock renderer and other setup, so instead
// we are just using deserialize to test what we need instead
-test('sb2 project with video sensing blocks and monitor should load extension but not monitor', t => {
+test('sb2 project with video sensing blocks and monitor should load extension but not monitor', async () => {
const vm = new VirtualMachine();
- sb2.deserialize(visibleVideoMonitorAndBlocksProject, vm.runtime).then(project => {
- // Extension loads but monitor does not
- project.extensions.extensionIDs.has('videoSensing');
- // Non-core extension monitors haven't been added to the runtime
- t.equal(vm.runtime._monitorState.size, 0);
- t.end();
- });
+ const project = await sb2.deserialize(visibleVideoMonitorAndBlocksProject, vm.runtime);
+ // Extension loads but monitor does not
+ assert.ok(project.extensions.extensionIDs.has('videoSensing'));
+ // Non-core extension monitors haven't been added to the runtime
+ assert.strictEqual(vm.runtime._monitorState.size, 0);
});
-test('sb2 project with invisible music monitor should not load monitor or extension', t => {
+test('sb2 project with invisible music monitor should not load monitor or extension', async () => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -83,15 +77,13 @@ test('sb2 project with invisible music monitor should not load monitor or extens
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(invisibleTempoMonitorProject).then(() => {
- t.equal(vm.extensionManager.isExtensionLoaded('music'), false);
- t.equal(vm.runtime._monitorState.size, 0);
- vm.quit();
- t.end();
- });
+ await vm.loadProject(invisibleTempoMonitorProject);
+ assert.strictEqual(vm.extensionManager.isExtensionLoaded('music'), false);
+ assert.strictEqual(vm.runtime._monitorState.size, 0);
+ vm.quit();
});
-test('sb2 project with visible music monitor should load monitor and extension', t => {
+test('sb2 project with visible music monitor should load monitor and extension', async () => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
@@ -100,12 +92,10 @@ test('sb2 project with visible music monitor should load monitor and extension',
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
- vm.loadProject(visibleTempoMonitorProject).then(() => {
- t.equal(vm.extensionManager.isExtensionLoaded('music'), true);
- t.equal(vm.runtime._monitorState.size, 1);
- t.equal(vm.runtime._monitorState.has('music_getTempo'), true);
- t.equal(vm.runtime._monitorState.get('music_getTempo').visible, true);
- vm.quit();
- t.end();
- });
+ await vm.loadProject(visibleTempoMonitorProject);
+ assert.strictEqual(vm.extensionManager.isExtensionLoaded('music'), true);
+ assert.strictEqual(vm.runtime._monitorState.size, 1);
+ assert.strictEqual(vm.runtime._monitorState.has('music_getTempo'), true);
+ assert.strictEqual(vm.runtime._monitorState.get('music_getTempo').visible, true);
+ vm.quit();
});
diff --git a/test/integration/sb2_corrupted_png.js b/test/integration/sb2_corrupted_png.js
index 17c1d695..5bfccd66 100644
--- a/test/integration/sb2_corrupted_png.js
+++ b/test/integration/sb2_corrupted_png.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const md5 = require('js-md5');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
@@ -54,9 +55,8 @@ global.document = {
let vm;
let defaultBitmapAssetId;
-tap.setTimeout(30000);
-tap.beforeEach(() => {
+beforeEach(() => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -69,59 +69,52 @@ tap.beforeEach(() => {
return vm.loadProject(project);
});
-const test = tap.test;
-
-test('load sb2 project with corrupted bitmap costume file', t => {
- t.equal(vm.runtime.targets.length, 2);
+test('load sb2 project with corrupted bitmap costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = vm.runtime.targets[1];
- t.equal(greenGuySprite.getName(), 'GreenGuy');
- t.equal(greenGuySprite.getCostumes().length, 1);
+ assert.strictEqual(greenGuySprite.getName(), 'GreenGuy');
+ assert.strictEqual(greenGuySprite.getCostumes().length, 1);
const corruptedCostume = greenGuySprite.getCostumes()[0];
- t.equal(corruptedCostume.name, 'GreenGuy');
- t.equal(corruptedCostume.assetId, defaultBitmapAssetId);
- t.equal(corruptedCostume.dataFormat, 'png');
+ assert.strictEqual(corruptedCostume.name, 'GreenGuy');
+ assert.strictEqual(corruptedCostume.assetId, defaultBitmapAssetId);
+ assert.strictEqual(corruptedCostume.dataFormat, 'png');
// Runtime should have info about broken asset
- t.ok(corruptedCostume.broken);
- t.equal(corruptedCostume.broken.assetId, brokenCostumeMd5);
+ assert.ok(corruptedCostume.broken);
+ assert.strictEqual(corruptedCostume.broken.assetId, brokenCostumeMd5);
// Verify that we saved the original asset data
- t.equal(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
-
- t.end();
+ assert.strictEqual(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
});
-test('load and then save project with corrupted bitmap costume file', t => {
+test('load and then save project with corrupted bitmap costume file', () => {
const resavedProject = JSON.parse(vm.toJSON());
- t.equal(resavedProject.targets.length, 2);
+ assert.strictEqual(resavedProject.targets.length, 2);
const stage = resavedProject.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = resavedProject.targets[1];
- t.equal(greenGuySprite.name, 'GreenGuy');
- t.equal(greenGuySprite.costumes.length, 1);
+ assert.strictEqual(greenGuySprite.name, 'GreenGuy');
+ assert.strictEqual(greenGuySprite.costumes.length, 1);
const corruptedCostume = greenGuySprite.costumes[0];
- t.equal(corruptedCostume.name, 'GreenGuy');
+ assert.strictEqual(corruptedCostume.name, 'GreenGuy');
// Resaved project costume should have the metadata that corresponds to the original broken costume
- t.equal(corruptedCostume.assetId, brokenCostumeMd5);
- t.equal(corruptedCostume.dataFormat, 'png');
+ assert.strictEqual(corruptedCostume.assetId, brokenCostumeMd5);
+ assert.strictEqual(corruptedCostume.dataFormat, 'png');
// Test that we didn't save any data about the costume being broken
- t.notOk(corruptedCostume.broken);
-
- t.end();
+ assert.ok(!corruptedCostume.broken);
});
-test('serializeCostume saves orignal broken costume', t => {
+test('serializeCostume saves orignal broken costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[1].id);
- t.equal(costumeDescs.length, 1);
+ assert.strictEqual(costumeDescs.length, 1);
const costume = costumeDescs[0];
- t.equal(costume.fileName, `${brokenCostumeMd5}.png`);
- t.equal(md5(costume.fileContent), brokenCostumeMd5);
- t.end();
+ assert.strictEqual(costume.fileName, `${brokenCostumeMd5}.png`);
+ assert.strictEqual(md5(costume.fileContent), brokenCostumeMd5);
});
diff --git a/test/integration/sb2_corrupted_svg.js b/test/integration/sb2_corrupted_svg.js
index 5ad71fa1..072d57fb 100644
--- a/test/integration/sb2_corrupted_svg.js
+++ b/test/integration/sb2_corrupted_svg.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const md5 = require('js-md5');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
@@ -47,7 +48,7 @@ global.document = {
let vm;
let defaultVectorAssetId;
-tap.beforeEach(() => {
+beforeEach(() => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -69,59 +70,52 @@ tap.beforeEach(() => {
return vm.loadProject(project);
});
-const test = tap.test;
-
-test('load sb2 project with corrupted vector costume file', t => {
- t.equal(vm.runtime.targets.length, 2);
+test('load sb2 project with corrupted vector costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = vm.runtime.targets[1];
- t.equal(blueGuySprite.getName(), 'Blue Guy');
- t.equal(blueGuySprite.getCostumes().length, 1);
+ assert.strictEqual(blueGuySprite.getName(), 'Blue Guy');
+ assert.strictEqual(blueGuySprite.getCostumes().length, 1);
const corruptedCostume = blueGuySprite.getCostumes()[0];
- t.equal(corruptedCostume.name, 'Blue Guy 2');
- t.equal(corruptedCostume.assetId, defaultVectorAssetId);
- t.equal(corruptedCostume.dataFormat, 'svg');
+ assert.strictEqual(corruptedCostume.name, 'Blue Guy 2');
+ assert.strictEqual(corruptedCostume.assetId, defaultVectorAssetId);
+ assert.strictEqual(corruptedCostume.dataFormat, 'svg');
// Runtime should have info about broken asset
- t.ok(corruptedCostume.broken);
- t.equal(corruptedCostume.broken.assetId, brokenCostumeMd5);
+ assert.ok(corruptedCostume.broken);
+ assert.strictEqual(corruptedCostume.broken.assetId, brokenCostumeMd5);
// Verify that we saved the original asset data
- t.equal(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
-
- t.end();
+ assert.strictEqual(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
});
-test('load and then save project with corrupted vector costume file', t => {
+test('load and then save project with corrupted vector costume file', () => {
const resavedProject = JSON.parse(vm.toJSON());
- t.equal(resavedProject.targets.length, 2);
+ assert.strictEqual(resavedProject.targets.length, 2);
const stage = resavedProject.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = resavedProject.targets[1];
- t.equal(blueGuySprite.name, 'Blue Guy');
- t.equal(blueGuySprite.costumes.length, 1);
+ assert.strictEqual(blueGuySprite.name, 'Blue Guy');
+ assert.strictEqual(blueGuySprite.costumes.length, 1);
const corruptedCostume = blueGuySprite.costumes[0];
- t.equal(corruptedCostume.name, 'Blue Guy 2');
+ assert.strictEqual(corruptedCostume.name, 'Blue Guy 2');
// Resaved project costume should have the metadata that corresponds to the original broken costume
- t.equal(corruptedCostume.assetId, brokenCostumeMd5);
- t.equal(corruptedCostume.dataFormat, 'svg');
+ assert.strictEqual(corruptedCostume.assetId, brokenCostumeMd5);
+ assert.strictEqual(corruptedCostume.dataFormat, 'svg');
// Test that we didn't save any data about the costume being broken
- t.notOk(corruptedCostume.broken);
-
- t.end();
+ assert.ok(!corruptedCostume.broken);
});
-test('serializeCostume saves orignal broken costume', t => {
+test('serializeCostume saves orignal broken costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[1].id);
- t.equal(costumeDescs.length, 1);
+ assert.strictEqual(costumeDescs.length, 1);
const costume = costumeDescs[0];
- t.equal(costume.fileName, `${brokenCostumeMd5}.svg`);
- t.equal(md5(costume.fileContent), brokenCostumeMd5);
- t.end();
+ assert.strictEqual(costume.fileName, `${brokenCostumeMd5}.svg`);
+ assert.strictEqual(md5(costume.fileContent), brokenCostumeMd5);
});
diff --git a/test/integration/sb2_missing_png.js b/test/integration/sb2_missing_png.js
index 8c1870d8..5bbede59 100644
--- a/test/integration/sb2_missing_png.js
+++ b/test/integration/sb2_missing_png.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
const FakeBitmapAdapter = require('../fixtures/fake-bitmap-adapter');
@@ -41,9 +42,7 @@ global.document = {
let vm;
-tap.setTimeout(30000);
-
-tap.beforeEach(() => {
+beforeEach(() => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -54,59 +53,51 @@ tap.beforeEach(() => {
return vm.loadProject(project);
});
-const test = tap.test;
-
-test('loading sb2 project with missing bitmap costume file', t => {
- t.equal(vm.runtime.targets.length, 2);
+test('loading sb2 project with missing bitmap costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = vm.runtime.targets[1];
- t.equal(greenGuySprite.getName(), 'GreenGuy');
- t.equal(greenGuySprite.getCostumes().length, 1);
+ assert.strictEqual(greenGuySprite.getName(), 'GreenGuy');
+ assert.strictEqual(greenGuySprite.getCostumes().length, 1);
const missingCostume = greenGuySprite.getCostumes()[0];
- t.equal(missingCostume.name, 'GreenGuy');
+ assert.strictEqual(missingCostume.name, 'GreenGuy');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
const defaultVectorAssetId = vm.runtime.storage.defaultAssetId.ImageBitmap;
- t.equal(missingCostume.assetId, defaultVectorAssetId);
- t.equal(missingCostume.dataFormat, 'png');
+ assert.strictEqual(missingCostume.assetId, defaultVectorAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'png');
// Runtime should have info about broken asset
- t.ok(missingCostume.broken);
- t.equal(missingCostume.broken.assetId, missingCostumeAssetId);
-
- t.end();
+ assert.ok(missingCostume.broken);
+ assert.strictEqual(missingCostume.broken.assetId, missingCostumeAssetId);
});
-test('load and then save sb2 project with missing costume file', t => {
+test('load and then save sb2 project with missing costume file', () => {
const resavedProject = JSON.parse(vm.toJSON());
- t.equal(resavedProject.targets.length, 2);
+ assert.strictEqual(resavedProject.targets.length, 2);
const stage = resavedProject.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = resavedProject.targets[1];
- t.equal(greenGuySprite.name, 'GreenGuy');
- t.equal(greenGuySprite.costumes.length, 1);
+ assert.strictEqual(greenGuySprite.name, 'GreenGuy');
+ assert.strictEqual(greenGuySprite.costumes.length, 1);
const missingCostume = greenGuySprite.costumes[0];
- t.equal(missingCostume.name, 'GreenGuy');
+ assert.strictEqual(missingCostume.name, 'GreenGuy');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
- t.equal(missingCostume.assetId, missingCostumeAssetId);
- t.equal(missingCostume.dataFormat, 'png');
+ assert.strictEqual(missingCostume.assetId, missingCostumeAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'png');
// Test that we didn't save any data about the costume being broken
- t.notOk(missingCostume.broken);
-
- t.end();
+ assert.ok(!missingCostume.broken);
});
-test('serializeCostume does not save data for missing costume', t => {
+test('serializeCostume does not save data for missing costume', () => {
const costumeDescs = serializeCostumes(vm.runtime);
- t.equal(costumeDescs.length, 1); // Should only have one costume, the backdrop
- t.not(costumeDescs[0].fileName, `${missingCostumeAssetId}.png`);
-
- t.end();
+ assert.strictEqual(costumeDescs.length, 1); // Should only have one costume, the backdrop
+ assert.notStrictEqual(costumeDescs[0].fileName, `${missingCostumeAssetId}.png`);
});
diff --git a/test/integration/sb2_missing_svg.js b/test/integration/sb2_missing_svg.js
index 1c5bb5fb..4a7f88b2 100644
--- a/test/integration/sb2_missing_svg.js
+++ b/test/integration/sb2_missing_svg.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
const FakeBitmapAdapter = require('../fixtures/fake-bitmap-adapter');
@@ -40,7 +41,7 @@ global.document = {
let vm;
-tap.beforeEach(() => {
+beforeEach(() => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -51,59 +52,51 @@ tap.beforeEach(() => {
return vm.loadProject(project);
});
-const test = tap.test;
-
-test('loading sb2 project with missing vector costume file', t => {
- t.equal(vm.runtime.targets.length, 2);
+test('loading sb2 project with missing vector costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = vm.runtime.targets[1];
- t.equal(blueGuySprite.getName(), 'Blue Guy');
- t.equal(blueGuySprite.getCostumes().length, 1);
+ assert.strictEqual(blueGuySprite.getName(), 'Blue Guy');
+ assert.strictEqual(blueGuySprite.getCostumes().length, 1);
const missingCostume = blueGuySprite.getCostumes()[0];
- t.equal(missingCostume.name, 'Blue Guy 2');
+ assert.strictEqual(missingCostume.name, 'Blue Guy 2');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
const defaultVectorAssetId = vm.runtime.storage.defaultAssetId.ImageVector;
- t.equal(missingCostume.assetId, defaultVectorAssetId);
- t.equal(missingCostume.dataFormat, 'svg');
+ assert.strictEqual(missingCostume.assetId, defaultVectorAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'svg');
// Runtime should have info about broken asset
- t.ok(missingCostume.broken);
- t.equal(missingCostume.broken.assetId, missingCostumeAssetId);
-
- t.end();
+ assert.ok(missingCostume.broken);
+ assert.strictEqual(missingCostume.broken.assetId, missingCostumeAssetId);
});
-test('load and then save sb2 project with missing costume file', t => {
+test('load and then save sb2 project with missing costume file', () => {
const resavedProject = JSON.parse(vm.toJSON());
- t.equal(resavedProject.targets.length, 2);
+ assert.strictEqual(resavedProject.targets.length, 2);
const stage = resavedProject.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = resavedProject.targets[1];
- t.equal(blueGuySprite.name, 'Blue Guy');
- t.equal(blueGuySprite.costumes.length, 1);
+ assert.strictEqual(blueGuySprite.name, 'Blue Guy');
+ assert.strictEqual(blueGuySprite.costumes.length, 1);
const missingCostume = blueGuySprite.costumes[0];
- t.equal(missingCostume.name, 'Blue Guy 2');
+ assert.strictEqual(missingCostume.name, 'Blue Guy 2');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
- t.equal(missingCostume.assetId, missingCostumeAssetId);
- t.equal(missingCostume.dataFormat, 'svg');
+ assert.strictEqual(missingCostume.assetId, missingCostumeAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'svg');
// Test that we didn't save any data about the costume being broken
- t.notOk(missingCostume.broken);
-
- t.end();
+ assert.ok(!missingCostume.broken);
});
-test('serializeCostume does not save data for missing costume', t => {
+test('serializeCostume does not save data for missing costume', () => {
const costumeDescs = serializeCostumes(vm.runtime);
- t.equal(costumeDescs.length, 1); // Should only have one costume, the backdrop
- t.not(costumeDescs[0].fileName, `${missingCostumeAssetId}.svg`);
-
- t.end();
+ assert.strictEqual(costumeDescs.length, 1); // Should only have one costume, the backdrop
+ assert.notStrictEqual(costumeDescs[0].fileName, `${missingCostumeAssetId}.svg`);
});
diff --git a/test/integration/sb3-roundtrip.js b/test/integration/sb3-roundtrip.js
index 9dbc339d..5b2c3490 100644
--- a/test/integration/sb3-roundtrip.js
+++ b/test/integration/sb3-roundtrip.js
@@ -1,4 +1,5 @@
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const Blocks = require('../../src/engine/blocks');
const Clone = require('../../src/util/clone');
@@ -18,7 +19,7 @@ const defaultCostumeInfo = {
const defaultSoundInfo = {
};
-test('sb3-roundtrip', t => {
+test('sb3-roundtrip', async () => {
const runtime1 = new Runtime();
runtime1.attachStorage(makeTestStorage());
@@ -26,85 +27,76 @@ test('sb3-roundtrip', t => {
runtime2.attachStorage(makeTestStorage());
const testRuntimeState = (label, runtime) => {
- t.strictEqual(runtime.targets.length, 2, `${label}: target count`);
+ assert.strictEqual(runtime.targets.length, 2, `${label}: target count`);
const [stageClone, spriteClone] = runtime.targets;
- t.strictEqual(stageClone.isOriginal, true);
- t.strictEqual(stageClone.isStage, true);
+ assert.strictEqual(stageClone.isOriginal, true);
+ assert.strictEqual(stageClone.isStage, true);
const stage = stageClone.sprite;
- t.strictEqual(stage.name, 'Stage');
- t.strictEqual(stage.clones.length, 1);
- t.strictEqual(stage.clones[0], stageClone);
+ assert.strictEqual(stage.name, 'Stage');
+ assert.strictEqual(stage.clones.length, 1);
+ assert.strictEqual(stage.clones[0], stageClone);
- t.strictEqual(stage.costumes.length, 1);
+ assert.strictEqual(stage.costumes.length, 1);
const [building] = stage.costumes;
- t.strictEqual(building.assetId, 'fe5e3566965f9de793beeffce377d054');
- t.strictEqual(building.dataFormat, 'jpg');
+ assert.strictEqual(building.assetId, 'fe5e3566965f9de793beeffce377d054');
+ assert.strictEqual(building.dataFormat, 'jpg');
- t.strictEqual(stage.sounds.length, 0);
+ assert.strictEqual(stage.sounds.length, 0);
- t.strictEqual(spriteClone.isOriginal, true);
- t.strictEqual(spriteClone.isStage, false);
+ assert.strictEqual(spriteClone.isOriginal, true);
+ assert.strictEqual(spriteClone.isStage, false);
const sprite = spriteClone.sprite;
- t.strictEqual(sprite.name, 'Sprite');
- t.strictEqual(sprite.clones.length, 1);
- t.strictEqual(sprite.clones[0], spriteClone);
+ assert.strictEqual(sprite.name, 'Sprite');
+ assert.strictEqual(sprite.clones.length, 1);
+ assert.strictEqual(sprite.clones[0], spriteClone);
- t.strictEqual(sprite.costumes.length, 2);
+ assert.strictEqual(sprite.costumes.length, 2);
const [cat, squirrel] = sprite.costumes;
- t.strictEqual(cat.assetId, 'f88bf1935daea28f8ca098462a31dbb0');
- t.strictEqual(cat.dataFormat, 'svg');
- t.strictEqual(squirrel.assetId, '7e24c99c1b853e52f8e7f9004416fa34');
- t.strictEqual(squirrel.dataFormat, 'png');
+ assert.strictEqual(cat.assetId, 'f88bf1935daea28f8ca098462a31dbb0');
+ assert.strictEqual(cat.dataFormat, 'svg');
+ assert.strictEqual(squirrel.assetId, '7e24c99c1b853e52f8e7f9004416fa34');
+ assert.strictEqual(squirrel.dataFormat, 'png');
- t.strictEqual(sprite.sounds.length, 1);
+ assert.strictEqual(sprite.sounds.length, 1);
const [meow] = sprite.sounds;
- t.strictEqual(meow.md5, '83c36d806dc92327b9e7049a565c6bff.wav');
+ assert.strictEqual(meow.md5, '83c36d806dc92327b9e7049a565c6bff.wav');
};
- const loadThings = Promise.all([
+ const [building, cat, squirrel, meow] = await Promise.all([
loadCostume('fe5e3566965f9de793beeffce377d054.jpg', Clone.simple(defaultCostumeInfo), runtime1),
loadCostume('f88bf1935daea28f8ca098462a31dbb0.svg', Clone.simple(defaultCostumeInfo), runtime1),
loadCostume('7e24c99c1b853e52f8e7f9004416fa34.png', Clone.simple(defaultCostumeInfo), runtime1),
loadSound(Object.assign({md5: '83c36d806dc92327b9e7049a565c6bff.wav'}, defaultSoundInfo), runtime1)
]);
- const installThings = loadThings.then(results => {
- const [building, cat, squirrel, meow] = results;
+ const stageBlocks = new Blocks(runtime1);
+ const stage = new Sprite(stageBlocks, runtime1);
+ stage.name = 'Stage';
+ stage.costumes = [building];
+ stage.sounds = [];
+ const stageClone = stage.createClone();
+ stageClone.isStage = true;
- const stageBlocks = new Blocks(runtime1);
- const stage = new Sprite(stageBlocks, runtime1);
- stage.name = 'Stage';
- stage.costumes = [building];
- stage.sounds = [];
- const stageClone = stage.createClone();
- stageClone.isStage = true;
+ const spriteBlocks = new Blocks(runtime1);
+ const sprite = new Sprite(spriteBlocks, runtime1);
+ sprite.name = 'Sprite';
+ sprite.costumes = [cat, squirrel];
+ sprite.sounds = [meow];
+ const spriteClone = sprite.createClone();
- const spriteBlocks = new Blocks(runtime1);
- const sprite = new Sprite(spriteBlocks, runtime1);
- sprite.name = 'Sprite';
- sprite.costumes = [cat, squirrel];
- sprite.sounds = [meow];
- const spriteClone = sprite.createClone();
+ runtime1.targets = [stageClone, spriteClone];
- runtime1.targets = [stageClone, spriteClone];
+ testRuntimeState('original', runtime1);
- testRuntimeState('original', runtime1);
- });
-
- const serializeAndDeserialize = installThings.then(() => {
- // Doing a JSON `stringify` and `parse` here more accurately simulate a save/load cycle. In particular:
- // 1. it ensures that any non-serializable data is thrown away, and
- // 2. `sb3.deserialize` and its helpers do some `hasOwnProperty` checks which fail on the object returned by
- // `sb3.serialize` but succeed if that object is "flattened" in this way.
- const serializedState = JSON.parse(JSON.stringify(sb3.serialize(runtime1)));
- return sb3.deserialize(serializedState, runtime2);
- });
-
- return serializeAndDeserialize.then(({targets}) => {
- runtime2.targets = targets;
- testRuntimeState('copy', runtime2);
- });
+ // Doing a JSON `stringify` and `parse` here more accurately simulate a save/load cycle. In particular:
+ // 1. it ensures that any non-serializable data is thrown away, and
+ // 2. `sb3.deserialize` and its helpers do some `hasOwnProperty` checks which fail on the object returned by
+ // `sb3.serialize` but succeed if that object is "flattened" in this way.
+ const serializedState = JSON.parse(JSON.stringify(sb3.serialize(runtime1)));
+ const {targets} = await sb3.deserialize(serializedState, runtime2);
+ runtime2.targets = targets;
+ testRuntimeState('copy', runtime2);
});
diff --git a/test/integration/sb3_corrupted_png.js b/test/integration/sb3_corrupted_png.js
index 46f75ba1..8ee2c095 100644
--- a/test/integration/sb3_corrupted_png.js
+++ b/test/integration/sb3_corrupted_png.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const md5 = require('js-md5');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
@@ -54,9 +55,8 @@ global.document = {
let vm;
let defaultBitmapAssetId;
-tap.setTimeout(30000);
-tap.beforeEach(() => {
+beforeEach(() => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -69,59 +69,52 @@ tap.beforeEach(() => {
return vm.loadProject(project);
});
-const test = tap.test;
-
-test('load sb3 project with corrupted bitmap costume file', t => {
- t.equal(vm.runtime.targets.length, 2);
+test('load sb3 project with corrupted bitmap costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = vm.runtime.targets[1];
- t.equal(greenGuySprite.getName(), 'Green Guy');
- t.equal(greenGuySprite.getCostumes().length, 1);
+ assert.strictEqual(greenGuySprite.getName(), 'Green Guy');
+ assert.strictEqual(greenGuySprite.getCostumes().length, 1);
const corruptedCostume = greenGuySprite.getCostumes()[0];
- t.equal(corruptedCostume.name, 'Green Guy');
- t.equal(corruptedCostume.assetId, defaultBitmapAssetId);
- t.equal(corruptedCostume.dataFormat, 'png');
+ assert.strictEqual(corruptedCostume.name, 'Green Guy');
+ assert.strictEqual(corruptedCostume.assetId, defaultBitmapAssetId);
+ assert.strictEqual(corruptedCostume.dataFormat, 'png');
// Runtime should have info about broken asset
- t.ok(corruptedCostume.broken);
- t.equal(corruptedCostume.broken.assetId, brokenCostumeMd5);
+ assert.ok(corruptedCostume.broken);
+ assert.strictEqual(corruptedCostume.broken.assetId, brokenCostumeMd5);
// Verify that we saved the original asset data
- t.equal(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
-
- t.end();
+ assert.strictEqual(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
});
-test('load and then save project with corrupted bitmap costume file', t => {
+test('load and then save project with corrupted bitmap costume file', () => {
const resavedProject = JSON.parse(vm.toJSON());
- t.equal(resavedProject.targets.length, 2);
+ assert.strictEqual(resavedProject.targets.length, 2);
const stage = resavedProject.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = resavedProject.targets[1];
- t.equal(greenGuySprite.name, 'Green Guy');
- t.equal(greenGuySprite.costumes.length, 1);
+ assert.strictEqual(greenGuySprite.name, 'Green Guy');
+ assert.strictEqual(greenGuySprite.costumes.length, 1);
const corruptedCostume = greenGuySprite.costumes[0];
- t.equal(corruptedCostume.name, 'Green Guy');
+ assert.strictEqual(corruptedCostume.name, 'Green Guy');
// Resaved project costume should have the metadata that corresponds to the original broken costume
- t.equal(corruptedCostume.assetId, brokenCostumeMd5);
- t.equal(corruptedCostume.dataFormat, 'png');
+ assert.strictEqual(corruptedCostume.assetId, brokenCostumeMd5);
+ assert.strictEqual(corruptedCostume.dataFormat, 'png');
// Test that we didn't save any data about the costume being broken
- t.notOk(corruptedCostume.broken);
-
- t.end();
+ assert.ok(!corruptedCostume.broken);
});
-test('serializeCostume saves orignal broken costume', t => {
+test('serializeCostume saves orignal broken costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[1].id);
- t.equal(costumeDescs.length, 1);
+ assert.strictEqual(costumeDescs.length, 1);
const costume = costumeDescs[0];
- t.equal(costume.fileName, `${brokenCostumeMd5}.png`);
- t.equal(md5(costume.fileContent), brokenCostumeMd5);
- t.end();
+ assert.strictEqual(costume.fileName, `${brokenCostumeMd5}.png`);
+ assert.strictEqual(md5(costume.fileContent), brokenCostumeMd5);
});
diff --git a/test/integration/sb3_corrupted_sound.js b/test/integration/sb3_corrupted_sound.js
index 6afeda71..673159cc 100644
--- a/test/integration/sb3_corrupted_sound.js
+++ b/test/integration/sb3_corrupted_sound.js
@@ -7,7 +7,8 @@
* to load the sound if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const md5 = require('js-md5');
const makeTestStorage = require('../fixtures/make-test-storage');
const {extractAsset, readFileToBuffer} = require('../fixtures/readProjectFile');
@@ -49,7 +50,7 @@ const FakeAudioEngine = function () {
let vm;
let defaultSoundAssetId;
-tap.beforeEach(() => {
+beforeEach(() => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -61,59 +62,52 @@ tap.beforeEach(() => {
return vm.loadProject(project);
});
-const test = tap.test;
-
-test('load sb3 project with corrupted sound file', t => {
- t.equal(vm.runtime.targets.length, 2);
+test('load sb3 project with corrupted sound file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const catSprite = vm.runtime.targets[1];
- t.equal(catSprite.getName(), 'Sprite1');
- t.equal(catSprite.getSounds().length, 1);
+ assert.strictEqual(catSprite.getName(), 'Sprite1');
+ assert.strictEqual(catSprite.getSounds().length, 1);
const corruptedSound = catSprite.getSounds()[0];
- t.equal(corruptedSound.name, 'Boop Sound Recording');
- t.equal(corruptedSound.assetId, defaultSoundAssetId);
- t.equal(corruptedSound.dataFormat, 'wav');
+ assert.strictEqual(corruptedSound.name, 'Boop Sound Recording');
+ assert.strictEqual(corruptedSound.assetId, defaultSoundAssetId);
+ assert.strictEqual(corruptedSound.dataFormat, 'wav');
// Runtime should have info about broken asset
- t.ok(corruptedSound.broken);
- t.equal(corruptedSound.broken.assetId, brokenSoundMd5);
+ assert.ok(corruptedSound.broken);
+ assert.strictEqual(corruptedSound.broken.assetId, brokenSoundMd5);
// Verify that we saved the original asset data
- t.equal(md5(corruptedSound.broken.asset.data), brokenSoundMd5);
-
- t.end();
+ assert.strictEqual(md5(corruptedSound.broken.asset.data), brokenSoundMd5);
});
-test('load and then save project with corrupted sound file', t => {
+test('load and then save project with corrupted sound file', () => {
const resavedProject = JSON.parse(vm.toJSON());
- t.equal(resavedProject.targets.length, 2);
+ assert.strictEqual(resavedProject.targets.length, 2);
const stage = resavedProject.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const catSprite = resavedProject.targets[1];
- t.equal(catSprite.name, 'Sprite1');
- t.equal(catSprite.sounds.length, 1);
+ assert.strictEqual(catSprite.name, 'Sprite1');
+ assert.strictEqual(catSprite.sounds.length, 1);
const corruptedSound = catSprite.sounds[0];
- t.equal(corruptedSound.name, 'Boop Sound Recording');
+ assert.strictEqual(corruptedSound.name, 'Boop Sound Recording');
// Resaved project costume should have the metadata that corresponds to the original broken costume
- t.equal(corruptedSound.assetId, brokenSoundMd5);
- t.equal(corruptedSound.dataFormat, 'wav');
+ assert.strictEqual(corruptedSound.assetId, brokenSoundMd5);
+ assert.strictEqual(corruptedSound.dataFormat, 'wav');
// Test that we didn't save any data about the costume being broken
- t.notOk(corruptedSound.broken);
-
- t.end();
+ assert.ok(!corruptedSound.broken);
});
-test('serializeSounds saves orignal broken sound', t => {
+test('serializeSounds saves orignal broken sound', () => {
const soundDescs = serializeSounds(vm.runtime, vm.runtime.targets[1].id);
- t.equal(soundDescs.length, 1);
+ assert.strictEqual(soundDescs.length, 1);
const sound = soundDescs[0];
- t.equal(sound.fileName, `${brokenSoundMd5}.wav`);
- t.equal(md5(sound.fileContent), brokenSoundMd5);
- t.end();
+ assert.strictEqual(sound.fileName, `${brokenSoundMd5}.wav`);
+ assert.strictEqual(md5(sound.fileContent), brokenSoundMd5);
});
diff --git a/test/integration/sb3_corrupted_svg.js b/test/integration/sb3_corrupted_svg.js
index d4efe365..69d4305b 100644
--- a/test/integration/sb3_corrupted_svg.js
+++ b/test/integration/sb3_corrupted_svg.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const md5 = require('js-md5');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
@@ -27,7 +28,7 @@ const brokenCostumeMd5 = md5(originalCostume);
let vm;
let defaultVectorAssetId;
-tap.beforeEach(() => {
+beforeEach(() => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -48,59 +49,52 @@ tap.beforeEach(() => {
return vm.loadProject(project);
});
-const test = tap.test;
-
-test('load sb3 project with corrupted vector costume file', t => {
- t.equal(vm.runtime.targets.length, 2);
+test('load sb3 project with corrupted vector costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = vm.runtime.targets[1];
- t.equal(blueGuySprite.getName(), 'Blue Square Guy');
- t.equal(blueGuySprite.getCostumes().length, 1);
+ assert.strictEqual(blueGuySprite.getName(), 'Blue Square Guy');
+ assert.strictEqual(blueGuySprite.getCostumes().length, 1);
const corruptedCostume = blueGuySprite.getCostumes()[0];
- t.equal(corruptedCostume.name, 'costume1');
- t.equal(corruptedCostume.assetId, defaultVectorAssetId);
- t.equal(corruptedCostume.dataFormat, 'svg');
+ assert.strictEqual(corruptedCostume.name, 'costume1');
+ assert.strictEqual(corruptedCostume.assetId, defaultVectorAssetId);
+ assert.strictEqual(corruptedCostume.dataFormat, 'svg');
// Runtime should have info about broken asset
- t.ok(corruptedCostume.broken);
- t.equal(corruptedCostume.broken.assetId, brokenCostumeMd5);
+ assert.ok(corruptedCostume.broken);
+ assert.strictEqual(corruptedCostume.broken.assetId, brokenCostumeMd5);
// Verify that we saved the original asset data
- t.equal(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
-
- t.end();
+ assert.strictEqual(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
});
-test('load and then save project with corrupted vector costume file', t => {
+test('load and then save project with corrupted vector costume file', () => {
const resavedProject = JSON.parse(vm.toJSON());
- t.equal(resavedProject.targets.length, 2);
+ assert.strictEqual(resavedProject.targets.length, 2);
const stage = resavedProject.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = resavedProject.targets[1];
- t.equal(blueGuySprite.name, 'Blue Square Guy');
- t.equal(blueGuySprite.costumes.length, 1);
+ assert.strictEqual(blueGuySprite.name, 'Blue Square Guy');
+ assert.strictEqual(blueGuySprite.costumes.length, 1);
const corruptedCostume = blueGuySprite.costumes[0];
- t.equal(corruptedCostume.name, 'costume1');
+ assert.strictEqual(corruptedCostume.name, 'costume1');
// Resaved project costume should have the metadata that corresponds to the original broken costume
- t.equal(corruptedCostume.assetId, brokenCostumeMd5);
- t.equal(corruptedCostume.dataFormat, 'svg');
+ assert.strictEqual(corruptedCostume.assetId, brokenCostumeMd5);
+ assert.strictEqual(corruptedCostume.dataFormat, 'svg');
// Test that we didn't save any data about the costume being broken
- t.notOk(corruptedCostume.broken);
-
- t.end();
+ assert.ok(!corruptedCostume.broken);
});
-test('serializeCostume saves orignal broken costume', t => {
+test('serializeCostume saves orignal broken costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[1].id);
- t.equal(costumeDescs.length, 1);
+ assert.strictEqual(costumeDescs.length, 1);
const costume = costumeDescs[0];
- t.equal(costume.fileName, `${brokenCostumeMd5}.svg`);
- t.equal(md5(costume.fileContent), brokenCostumeMd5);
- t.end();
+ assert.strictEqual(costume.fileName, `${brokenCostumeMd5}.svg`);
+ assert.strictEqual(md5(costume.fileContent), brokenCostumeMd5);
});
diff --git a/test/integration/sb3_missing_png.js b/test/integration/sb3_missing_png.js
index 27924c00..97205602 100644
--- a/test/integration/sb3_missing_png.js
+++ b/test/integration/sb3_missing_png.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
const FakeBitmapAdapter = require('../fixtures/fake-bitmap-adapter');
@@ -41,9 +42,7 @@ global.document = {
let vm;
-tap.setTimeout(30000);
-
-tap.beforeEach(() => {
+beforeEach(() => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -54,59 +53,51 @@ tap.beforeEach(() => {
return vm.loadProject(project);
});
-const test = tap.test;
-
-test('loading sb3 project with missing bitmap costume file', t => {
- t.equal(vm.runtime.targets.length, 2);
+test('loading sb3 project with missing bitmap costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = vm.runtime.targets[1];
- t.equal(greenGuySprite.getName(), 'Green Guy');
- t.equal(greenGuySprite.getCostumes().length, 1);
+ assert.strictEqual(greenGuySprite.getName(), 'Green Guy');
+ assert.strictEqual(greenGuySprite.getCostumes().length, 1);
const missingCostume = greenGuySprite.getCostumes()[0];
- t.equal(missingCostume.name, 'Green Guy');
+ assert.strictEqual(missingCostume.name, 'Green Guy');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
const defaultVectorAssetId = vm.runtime.storage.defaultAssetId.ImageBitmap;
- t.equal(missingCostume.assetId, defaultVectorAssetId);
- t.equal(missingCostume.dataFormat, 'png');
+ assert.strictEqual(missingCostume.assetId, defaultVectorAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'png');
// Runtime should have info about broken asset
- t.ok(missingCostume.broken);
- t.equal(missingCostume.broken.assetId, missingCostumeAssetId);
-
- t.end();
+ assert.ok(missingCostume.broken);
+ assert.strictEqual(missingCostume.broken.assetId, missingCostumeAssetId);
});
-test('load and then save sb3 project with missing costume file', t => {
+test('load and then save sb3 project with missing costume file', () => {
const resavedProject = JSON.parse(vm.toJSON());
- t.equal(resavedProject.targets.length, 2);
+ assert.strictEqual(resavedProject.targets.length, 2);
const stage = resavedProject.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = resavedProject.targets[1];
- t.equal(greenGuySprite.name, 'Green Guy');
- t.equal(greenGuySprite.costumes.length, 1);
+ assert.strictEqual(greenGuySprite.name, 'Green Guy');
+ assert.strictEqual(greenGuySprite.costumes.length, 1);
const missingCostume = greenGuySprite.costumes[0];
- t.equal(missingCostume.name, 'Green Guy');
+ assert.strictEqual(missingCostume.name, 'Green Guy');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
- t.equal(missingCostume.assetId, missingCostumeAssetId);
- t.equal(missingCostume.dataFormat, 'png');
+ assert.strictEqual(missingCostume.assetId, missingCostumeAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'png');
// Test that we didn't save any data about the costume being broken
- t.notOk(missingCostume.broken);
-
- t.end();
+ assert.ok(!missingCostume.broken);
});
-test('serializeCostume does not save data for missing costume', t => {
+test('serializeCostume does not save data for missing costume', () => {
const costumeDescs = serializeCostumes(vm.runtime);
- t.equal(costumeDescs.length, 1); // Should only have one costume, the backdrop
- t.not(costumeDescs[0].fileName, `${missingCostumeAssetId}.png`);
-
- t.end();
+ assert.strictEqual(costumeDescs.length, 1); // Should only have one costume, the backdrop
+ assert.notStrictEqual(costumeDescs[0].fileName, `${missingCostumeAssetId}.png`);
});
diff --git a/test/integration/sb3_missing_sound.js b/test/integration/sb3_missing_sound.js
index b3c6980c..3e0860f1 100644
--- a/test/integration/sb3_missing_sound.js
+++ b/test/integration/sb3_missing_sound.js
@@ -6,7 +6,8 @@
* so that user data does not get overwritten / lost.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -19,7 +20,7 @@ const missingSoundAssetId = '78618aadd225b1db7bf837fa17dc0568';
let vm;
-tap.beforeEach(() => {
+beforeEach(() => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -28,59 +29,51 @@ tap.beforeEach(() => {
return vm.loadProject(project);
});
-const test = tap.test;
-
-test('loading sb3 project with missing sound file', t => {
- t.equal(vm.runtime.targets.length, 2);
+test('loading sb3 project with missing sound file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const catSprite = vm.runtime.targets[1];
- t.equal(catSprite.getSounds().length, 1);
+ assert.strictEqual(catSprite.getSounds().length, 1);
const missingSound = catSprite.getSounds()[0];
- t.equal(missingSound.name, 'Boop Sound Recording');
+ assert.strictEqual(missingSound.name, 'Boop Sound Recording');
// Sound should have original data but no asset
const defaultSoundAssetId = vm.runtime.storage.defaultAssetId.Sound;
- t.equal(missingSound.assetId, defaultSoundAssetId);
- t.equal(missingSound.dataFormat, 'wav');
+ assert.strictEqual(missingSound.assetId, defaultSoundAssetId);
+ assert.strictEqual(missingSound.dataFormat, 'wav');
// Runtime should have info about broken asset
- t.ok(missingSound.broken);
- t.equal(missingSound.broken.assetId, missingSoundAssetId);
-
- t.end();
+ assert.ok(missingSound.broken);
+ assert.strictEqual(missingSound.broken.assetId, missingSoundAssetId);
});
-test('load and then save sb3 project with missing sound file', t => {
+test('load and then save sb3 project with missing sound file', () => {
const resavedProject = JSON.parse(vm.toJSON());
- t.equal(resavedProject.targets.length, 2);
+ assert.strictEqual(resavedProject.targets.length, 2);
const stage = resavedProject.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const catSprite = resavedProject.targets[1];
- t.equal(catSprite.name, 'Sprite1');
- t.equal(catSprite.sounds.length, 1);
+ assert.strictEqual(catSprite.name, 'Sprite1');
+ assert.strictEqual(catSprite.sounds.length, 1);
const missingSound = catSprite.sounds[0];
- t.equal(missingSound.name, 'Boop Sound Recording');
+ assert.strictEqual(missingSound.name, 'Boop Sound Recording');
// Costume should have both default sound data (e.g. "Gray Question Sound" ^_^) and original data
- t.equal(missingSound.assetId, missingSoundAssetId);
- t.equal(missingSound.dataFormat, 'wav');
+ assert.strictEqual(missingSound.assetId, missingSoundAssetId);
+ assert.strictEqual(missingSound.dataFormat, 'wav');
// Test that we didn't save any data about the costume being broken
- t.notOk(missingSound.broken);
-
- t.end();
+ assert.ok(!missingSound.broken);
});
-test('serializeCostume does not save data for missing costume', t => {
+test('serializeCostume does not save data for missing costume', () => {
const soundDescs = serializeSounds(vm.runtime);
- t.equal(soundDescs.length, 1); // Should only have one sound, the pop sound for the stage
- t.not(soundDescs[0].fileName, `${missingSoundAssetId}.wav`);
-
- t.end();
+ assert.strictEqual(soundDescs.length, 1); // Should only have one sound, the pop sound for the stage
+ assert.notStrictEqual(soundDescs[0].fileName, `${missingSoundAssetId}.wav`);
});
diff --git a/test/integration/sb3_missing_svg.js b/test/integration/sb3_missing_svg.js
index f0adf82d..8084f76d 100644
--- a/test/integration/sb3_missing_svg.js
+++ b/test/integration/sb3_missing_svg.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
@@ -21,7 +22,7 @@ const missingCostumeAssetId = 'a267f8b97ee9cf8aa9832aa0b4cfd9eb';
let vm;
-tap.beforeEach(() => {
+beforeEach(() => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -31,59 +32,51 @@ tap.beforeEach(() => {
return vm.loadProject(project);
});
-const test = tap.test;
-
-test('loading sb3 project with missing vector costume file', t => {
- t.equal(vm.runtime.targets.length, 2);
+test('loading sb3 project with missing vector costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = vm.runtime.targets[1];
- t.equal(blueGuySprite.getName(), 'Blue Square Guy');
- t.equal(blueGuySprite.getCostumes().length, 1);
+ assert.strictEqual(blueGuySprite.getName(), 'Blue Square Guy');
+ assert.strictEqual(blueGuySprite.getCostumes().length, 1);
const missingCostume = blueGuySprite.getCostumes()[0];
- t.equal(missingCostume.name, 'costume1');
+ assert.strictEqual(missingCostume.name, 'costume1');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
const defaultVectorAssetId = vm.runtime.storage.defaultAssetId.ImageVector;
- t.equal(missingCostume.assetId, defaultVectorAssetId);
- t.equal(missingCostume.dataFormat, 'svg');
+ assert.strictEqual(missingCostume.assetId, defaultVectorAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'svg');
// Runtime should have info about broken asset
- t.ok(missingCostume.broken);
- t.equal(missingCostume.broken.assetId, missingCostumeAssetId);
-
- t.end();
+ assert.ok(missingCostume.broken);
+ assert.strictEqual(missingCostume.broken.assetId, missingCostumeAssetId);
});
-test('load and then save sb3 project with missing costume file', t => {
+test('load and then save sb3 project with missing costume file', () => {
const resavedProject = JSON.parse(vm.toJSON());
- t.equal(resavedProject.targets.length, 2);
+ assert.strictEqual(resavedProject.targets.length, 2);
const stage = resavedProject.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = resavedProject.targets[1];
- t.equal(blueGuySprite.name, 'Blue Square Guy');
- t.equal(blueGuySprite.costumes.length, 1);
+ assert.strictEqual(blueGuySprite.name, 'Blue Square Guy');
+ assert.strictEqual(blueGuySprite.costumes.length, 1);
const missingCostume = blueGuySprite.costumes[0];
- t.equal(missingCostume.name, 'costume1');
+ assert.strictEqual(missingCostume.name, 'costume1');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
- t.equal(missingCostume.assetId, missingCostumeAssetId);
- t.equal(missingCostume.dataFormat, 'svg');
+ assert.strictEqual(missingCostume.assetId, missingCostumeAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'svg');
// Test that we didn't save any data about the costume being broken
- t.notOk(missingCostume.broken);
-
- t.end();
+ assert.ok(!missingCostume.broken);
});
-test('serializeCostume does not save data for missing costume', t => {
+test('serializeCostume does not save data for missing costume', () => {
const costumeDescs = serializeCostumes(vm.runtime);
- t.equal(costumeDescs.length, 1); // Should only have one costume, the backdrop
- t.not(costumeDescs[0].fileName, `${missingCostumeAssetId}.svg`);
-
- t.end();
+ assert.strictEqual(costumeDescs.length, 1); // Should only have one costume, the backdrop
+ assert.notStrictEqual(costumeDescs[0].fileName, `${missingCostumeAssetId}.svg`);
});
diff --git a/test/integration/sensing.js b/test/integration/sensing.js
index dbe0df94..f4dd4fd3 100644
--- a/test/integration/sensing.js
+++ b/test/integration/sensing.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -7,20 +8,20 @@ const VirtualMachine = require('../../src/index');
const uri = path.resolve(__dirname, '../fixtures/sensing.sb2');
const project = readFileToBuffer(uri);
-test('sensing', t => {
+test('sensing', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length > 0);
+ assert.ok(threads.length > 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/sound.js b/test/integration/sound.js
index 6d27cb51..90efee8e 100644
--- a/test/integration/sound.js
+++ b/test/integration/sound.js
@@ -1,6 +1,7 @@
const Worker = require('tiny-worker');
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -12,20 +13,20 @@ const project = readFileToBuffer(uri);
// By default Central Dispatch works with the Worker class built into the browser. Tell it to use TinyWorker instead.
dispatch.workerClass = Worker;
-test('sound', t => {
+test('sound', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', e => {
const threads = JSON.parse(e.threads);
- t.ok(threads.length > 0);
+ assert.ok(threads.length > 0);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
diff --git a/test/integration/sprite2_corrupted_png.js b/test/integration/sprite2_corrupted_png.js
index 0740eb6b..e5471844 100644
--- a/test/integration/sprite2_corrupted_png.js
+++ b/test/integration/sprite2_corrupted_png.js
@@ -8,7 +8,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const md5 = require('js-md5');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
@@ -59,9 +60,8 @@ global.document = {
let vm;
let defaultBitmapAssetId;
-tap.setTimeout(30000);
-tap.beforeEach(() => {
+beforeEach(async () => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -71,56 +71,50 @@ tap.beforeEach(() => {
vm.attachRenderer(new FakeRenderer());
vm.attachV2BitmapAdapter(new FakeBitmapAdapter());
- return vm.loadProject(project).then(() => vm.addSprite(sprite));
+ await vm.loadProject(project);
+ return vm.addSprite(sprite);
});
-const test = tap.test;
-
-test('load sprite2 with corrupted bitmap costume file', t => {
- t.equal(vm.runtime.targets.length, 3);
+test('load sprite2 with corrupted bitmap costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 3);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = vm.runtime.targets[2];
- t.equal(greenGuySprite.getName(), 'GreenGuy');
- t.equal(greenGuySprite.getCostumes().length, 1);
+ assert.strictEqual(greenGuySprite.getName(), 'GreenGuy');
+ assert.strictEqual(greenGuySprite.getCostumes().length, 1);
const corruptedCostume = greenGuySprite.getCostumes()[0];
- t.equal(corruptedCostume.name, 'GreenGuy');
- t.equal(corruptedCostume.assetId, defaultBitmapAssetId);
- t.equal(corruptedCostume.dataFormat, 'png');
+ assert.strictEqual(corruptedCostume.name, 'GreenGuy');
+ assert.strictEqual(corruptedCostume.assetId, defaultBitmapAssetId);
+ assert.strictEqual(corruptedCostume.dataFormat, 'png');
// Runtime should have info about broken asset
- t.ok(corruptedCostume.broken);
- t.equal(corruptedCostume.broken.assetId, brokenCostumeMd5);
+ assert.ok(corruptedCostume.broken);
+ assert.strictEqual(corruptedCostume.broken.assetId, brokenCostumeMd5);
// Verify that we saved the original asset data
- t.equal(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
-
- t.end();
+ assert.strictEqual(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
});
-test('load and then save sprite with corrupted costume file', t => {
+test('load and then save sprite with corrupted costume file', () => {
const resavedSprite = JSON.parse(vm.toJSON(vm.runtime.targets[2].id));
- t.equal(resavedSprite.name, 'GreenGuy');
- t.equal(resavedSprite.costumes.length, 1);
+ assert.strictEqual(resavedSprite.name, 'GreenGuy');
+ assert.strictEqual(resavedSprite.costumes.length, 1);
const corruptedCostume = resavedSprite.costumes[0];
- t.equal(corruptedCostume.name, 'GreenGuy');
+ assert.strictEqual(corruptedCostume.name, 'GreenGuy');
// Resaved project costume should have the metadata that corresponds to the original broken costume
- t.equal(corruptedCostume.assetId, brokenCostumeMd5);
- t.equal(corruptedCostume.dataFormat, 'png');
+ assert.strictEqual(corruptedCostume.assetId, brokenCostumeMd5);
+ assert.strictEqual(corruptedCostume.dataFormat, 'png');
// Test that we didn't save any data about the costume being broken
- t.notOk(corruptedCostume.broken);
-
- t.end();
+ assert.ok(!corruptedCostume.broken);
});
-test('serializeCostume saves orignal broken costume', t => {
+test('serializeCostume saves orignal broken costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[2].id);
- t.equal(costumeDescs.length, 1);
+ assert.strictEqual(costumeDescs.length, 1);
const costume = costumeDescs[0];
- t.equal(costume.fileName, `${brokenCostumeMd5}.png`);
- t.equal(md5(costume.fileContent), brokenCostumeMd5);
- t.end();
+ assert.strictEqual(costume.fileName, `${brokenCostumeMd5}.png`);
+ assert.strictEqual(md5(costume.fileContent), brokenCostumeMd5);
});
diff --git a/test/integration/sprite2_corrupted_svg.js b/test/integration/sprite2_corrupted_svg.js
index 866448d7..af7c8cbc 100644
--- a/test/integration/sprite2_corrupted_svg.js
+++ b/test/integration/sprite2_corrupted_svg.js
@@ -8,7 +8,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const md5 = require('js-md5');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
@@ -51,7 +52,7 @@ global.document = {
let vm;
let defaultVectorAssetId;
-tap.beforeEach(() => {
+beforeEach(async () => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -70,56 +71,50 @@ tap.beforeEach(() => {
vm.attachRenderer(new FakeRenderer());
vm.attachV2BitmapAdapter(new FakeBitmapAdapter());
- return vm.loadProject(project).then(() => vm.addSprite(sprite));
+ await vm.loadProject(project);
+ return vm.addSprite(sprite);
});
-const test = tap.test;
-
-test('load sprite2 with corrupted vector costume file', t => {
- t.equal(vm.runtime.targets.length, 3);
+test('load sprite2 with corrupted vector costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 3);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = vm.runtime.targets[2];
- t.equal(blueGuySprite.getName(), 'Blue Guy');
- t.equal(blueGuySprite.getCostumes().length, 1);
+ assert.strictEqual(blueGuySprite.getName(), 'Blue Guy');
+ assert.strictEqual(blueGuySprite.getCostumes().length, 1);
const corruptedCostume = blueGuySprite.getCostumes()[0];
- t.equal(corruptedCostume.name, 'Blue Guy 2');
- t.equal(corruptedCostume.assetId, defaultVectorAssetId);
- t.equal(corruptedCostume.dataFormat, 'svg');
+ assert.strictEqual(corruptedCostume.name, 'Blue Guy 2');
+ assert.strictEqual(corruptedCostume.assetId, defaultVectorAssetId);
+ assert.strictEqual(corruptedCostume.dataFormat, 'svg');
// Runtime should have info about broken asset
- t.ok(corruptedCostume.broken);
- t.equal(corruptedCostume.broken.assetId, brokenCostumeMd5);
+ assert.ok(corruptedCostume.broken);
+ assert.strictEqual(corruptedCostume.broken.assetId, brokenCostumeMd5);
// Verify that we saved the original asset data
- t.equal(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
-
- t.end();
+ assert.strictEqual(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
});
-test('load and then save sprite with corrupted costume file', t => {
+test('load and then save sprite with corrupted costume file', () => {
const resavedSprite = JSON.parse(vm.toJSON(vm.runtime.targets[2].id));
- t.equal(resavedSprite.name, 'Blue Guy');
- t.equal(resavedSprite.costumes.length, 1);
+ assert.strictEqual(resavedSprite.name, 'Blue Guy');
+ assert.strictEqual(resavedSprite.costumes.length, 1);
const corruptedCostume = resavedSprite.costumes[0];
- t.equal(corruptedCostume.name, 'Blue Guy 2');
+ assert.strictEqual(corruptedCostume.name, 'Blue Guy 2');
// Resaved project costume should have the metadata that corresponds to the original broken costume
- t.equal(corruptedCostume.assetId, brokenCostumeMd5);
- t.equal(corruptedCostume.dataFormat, 'svg');
+ assert.strictEqual(corruptedCostume.assetId, brokenCostumeMd5);
+ assert.strictEqual(corruptedCostume.dataFormat, 'svg');
// Test that we didn't save any data about the costume being broken
- t.notOk(corruptedCostume.broken);
-
- t.end();
+ assert.ok(!corruptedCostume.broken);
});
-test('serializeCostume saves orignal broken costume', t => {
+test('serializeCostume saves orignal broken costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[2].id);
- t.equal(costumeDescs.length, 1);
+ assert.strictEqual(costumeDescs.length, 1);
const costume = costumeDescs[0];
- t.equal(costume.fileName, `${brokenCostumeMd5}.svg`);
- t.equal(md5(costume.fileContent), brokenCostumeMd5);
- t.end();
+ assert.strictEqual(costume.fileName, `${brokenCostumeMd5}.svg`);
+ assert.strictEqual(md5(costume.fileContent), brokenCostumeMd5);
});
diff --git a/test/integration/sprite2_missing_png.js b/test/integration/sprite2_missing_png.js
index 07453cd1..2c9fa67e 100644
--- a/test/integration/sprite2_missing_png.js
+++ b/test/integration/sprite2_missing_png.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
const FakeBitmapAdapter = require('../fixtures/fake-bitmap-adapter');
@@ -44,9 +45,7 @@ global.document = {
let vm;
-tap.setTimeout(30000);
-
-tap.beforeEach(() => {
+beforeEach(async () => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -54,55 +53,48 @@ tap.beforeEach(() => {
vm.attachRenderer(new FakeRenderer());
vm.attachV2BitmapAdapter(new FakeBitmapAdapter());
- return vm.loadProject(project).then(() => vm.addSprite(sprite));
+ await vm.loadProject(project);
+ return vm.addSprite(sprite);
});
-const test = tap.test;
-
-test('loading sprite2 with missing bitmap costume file', t => {
- t.equal(vm.runtime.targets.length, 3);
+test('loading sprite2 with missing bitmap costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 3);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = vm.runtime.targets[2];
- t.equal(greenGuySprite.getName(), 'GreenGuy');
- t.equal(greenGuySprite.getCostumes().length, 1);
+ assert.strictEqual(greenGuySprite.getName(), 'GreenGuy');
+ assert.strictEqual(greenGuySprite.getCostumes().length, 1);
const missingCostume = greenGuySprite.getCostumes()[0];
- t.equal(missingCostume.name, 'GreenGuy');
+ assert.strictEqual(missingCostume.name, 'GreenGuy');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
const defaultBitmapAssetId = vm.runtime.storage.defaultAssetId.ImageBitmap;
- t.equal(missingCostume.assetId, defaultBitmapAssetId);
- t.equal(missingCostume.dataFormat, 'png');
+ assert.strictEqual(missingCostume.assetId, defaultBitmapAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'png');
// Runtime should have info about broken asset
- t.ok(missingCostume.broken);
- t.equal(missingCostume.broken.assetId, missingCostumeAssetId);
-
- t.end();
+ assert.ok(missingCostume.broken);
+ assert.strictEqual(missingCostume.broken.assetId, missingCostumeAssetId);
});
-test('load and then save sprite2 with missing bitmap costume file', t => {
+test('load and then save sprite2 with missing bitmap costume file', () => {
const resavedSprite = JSON.parse(vm.toJSON(vm.runtime.targets[2].id));
- t.equal(resavedSprite.name, 'GreenGuy');
- t.equal(resavedSprite.costumes.length, 1);
+ assert.strictEqual(resavedSprite.name, 'GreenGuy');
+ assert.strictEqual(resavedSprite.costumes.length, 1);
const missingCostume = resavedSprite.costumes[0];
- t.equal(missingCostume.name, 'GreenGuy');
+ assert.strictEqual(missingCostume.name, 'GreenGuy');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
- t.equal(missingCostume.assetId, missingCostumeAssetId);
- t.equal(missingCostume.dataFormat, 'png');
+ assert.strictEqual(missingCostume.assetId, missingCostumeAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'png');
// Test that we didn't save any data about the costume being broken
- t.notOk(missingCostume.broken);
-
- t.end();
+ assert.ok(!missingCostume.broken);
});
-test('serializeCostume does not save data for missing costume', t => {
+test('serializeCostume does not save data for missing costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[2].id);
- t.equal(costumeDescs.length, 0);
-
- t.end();
+ assert.strictEqual(costumeDescs.length, 0);
});
diff --git a/test/integration/sprite2_missing_svg.js b/test/integration/sprite2_missing_svg.js
index bcd9b12f..ba595f39 100644
--- a/test/integration/sprite2_missing_svg.js
+++ b/test/integration/sprite2_missing_svg.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
const FakeBitmapAdapter = require('../fixtures/fake-bitmap-adapter');
@@ -44,7 +45,7 @@ global.document = {
let vm;
-tap.beforeEach(() => {
+beforeEach(async () => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -52,55 +53,48 @@ tap.beforeEach(() => {
vm.attachRenderer(new FakeRenderer());
vm.attachV2BitmapAdapter(new FakeBitmapAdapter());
- return vm.loadProject(project).then(() => vm.addSprite(sprite));
+ await vm.loadProject(project);
+ return vm.addSprite(sprite);
});
-const test = tap.test;
-
-test('loading sprite2 with missing vector costume file', t => {
- t.equal(vm.runtime.targets.length, 3);
+test('loading sprite2 with missing vector costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 3);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = vm.runtime.targets[2];
- t.equal(blueGuySprite.getName(), 'Blue Guy');
- t.equal(blueGuySprite.getCostumes().length, 1);
+ assert.strictEqual(blueGuySprite.getName(), 'Blue Guy');
+ assert.strictEqual(blueGuySprite.getCostumes().length, 1);
const missingCostume = blueGuySprite.getCostumes()[0];
- t.equal(missingCostume.name, 'Blue Guy 2');
+ assert.strictEqual(missingCostume.name, 'Blue Guy 2');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
const defaultVectorAssetId = vm.runtime.storage.defaultAssetId.ImageVector;
- t.equal(missingCostume.assetId, defaultVectorAssetId);
- t.equal(missingCostume.dataFormat, 'svg');
+ assert.strictEqual(missingCostume.assetId, defaultVectorAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'svg');
// Runtime should have info about broken asset
- t.ok(missingCostume.broken);
- t.equal(missingCostume.broken.assetId, missingCostumeAssetId);
-
- t.end();
+ assert.ok(missingCostume.broken);
+ assert.strictEqual(missingCostume.broken.assetId, missingCostumeAssetId);
});
-test('load and then save sprite2 with missing vector costume file', t => {
+test('load and then save sprite2 with missing vector costume file', () => {
const resavedSprite = JSON.parse(vm.toJSON(vm.runtime.targets[2].id));
- t.equal(resavedSprite.name, 'Blue Guy');
- t.equal(resavedSprite.costumes.length, 1);
+ assert.strictEqual(resavedSprite.name, 'Blue Guy');
+ assert.strictEqual(resavedSprite.costumes.length, 1);
const missingCostume = resavedSprite.costumes[0];
- t.equal(missingCostume.name, 'Blue Guy 2');
+ assert.strictEqual(missingCostume.name, 'Blue Guy 2');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
- t.equal(missingCostume.assetId, missingCostumeAssetId);
- t.equal(missingCostume.dataFormat, 'svg');
+ assert.strictEqual(missingCostume.assetId, missingCostumeAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'svg');
// Test that we didn't save any data about the costume being broken
- t.notOk(missingCostume.broken);
-
- t.end();
+ assert.ok(!missingCostume.broken);
});
-test('serializeCostume does not save data for missing costume', t => {
+test('serializeCostume does not save data for missing costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[2].id);
- t.equal(costumeDescs.length, 0);
-
- t.end();
+ assert.strictEqual(costumeDescs.length, 0);
});
diff --git a/test/integration/sprite3_corrupted_png.js b/test/integration/sprite3_corrupted_png.js
index 98a75687..a581b942 100644
--- a/test/integration/sprite3_corrupted_png.js
+++ b/test/integration/sprite3_corrupted_png.js
@@ -8,7 +8,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const md5 = require('js-md5');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
@@ -59,9 +60,8 @@ global.document = {
let vm;
let defaultBitmapAssetId;
-tap.setTimeout(30000);
-tap.beforeEach(() => {
+beforeEach(async () => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -71,56 +71,50 @@ tap.beforeEach(() => {
vm.attachRenderer(new FakeRenderer());
vm.attachV2BitmapAdapter(new FakeBitmapAdapter());
- return vm.loadProject(project).then(() => vm.addSprite(sprite));
+ await vm.loadProject(project);
+ return vm.addSprite(sprite);
});
-const test = tap.test;
-
-test('load sprite3 with corrupted bitmap costume file', t => {
- t.equal(vm.runtime.targets.length, 3);
+test('load sprite3 with corrupted bitmap costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 3);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = vm.runtime.targets[2];
- t.equal(greenGuySprite.getName(), 'Green Guy');
- t.equal(greenGuySprite.getCostumes().length, 1);
+ assert.strictEqual(greenGuySprite.getName(), 'Green Guy');
+ assert.strictEqual(greenGuySprite.getCostumes().length, 1);
const corruptedCostume = greenGuySprite.getCostumes()[0];
- t.equal(corruptedCostume.name, 'Green Guy');
- t.equal(corruptedCostume.assetId, defaultBitmapAssetId);
- t.equal(corruptedCostume.dataFormat, 'png');
+ assert.strictEqual(corruptedCostume.name, 'Green Guy');
+ assert.strictEqual(corruptedCostume.assetId, defaultBitmapAssetId);
+ assert.strictEqual(corruptedCostume.dataFormat, 'png');
// Runtime should have info about broken asset
- t.ok(corruptedCostume.broken);
- t.equal(corruptedCostume.broken.assetId, brokenCostumeMd5);
+ assert.ok(corruptedCostume.broken);
+ assert.strictEqual(corruptedCostume.broken.assetId, brokenCostumeMd5);
// Verify that we saved the original asset data
- t.equal(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
-
- t.end();
+ assert.strictEqual(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
});
-test('load and then save sprite with corrupted costume file', t => {
+test('load and then save sprite with corrupted costume file', () => {
const resavedSprite = JSON.parse(vm.toJSON(vm.runtime.targets[2].id));
- t.equal(resavedSprite.name, 'Green Guy');
- t.equal(resavedSprite.costumes.length, 1);
+ assert.strictEqual(resavedSprite.name, 'Green Guy');
+ assert.strictEqual(resavedSprite.costumes.length, 1);
const corruptedCostume = resavedSprite.costumes[0];
- t.equal(corruptedCostume.name, 'Green Guy');
+ assert.strictEqual(corruptedCostume.name, 'Green Guy');
// Resaved project costume should have the metadata that corresponds to the original broken costume
- t.equal(corruptedCostume.assetId, brokenCostumeMd5);
- t.equal(corruptedCostume.dataFormat, 'png');
+ assert.strictEqual(corruptedCostume.assetId, brokenCostumeMd5);
+ assert.strictEqual(corruptedCostume.dataFormat, 'png');
// Test that we didn't save any data about the costume being broken
- t.notOk(corruptedCostume.broken);
-
- t.end();
+ assert.ok(!corruptedCostume.broken);
});
-test('serializeCostume saves orignal broken costume', t => {
+test('serializeCostume saves orignal broken costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[2].id);
- t.equal(costumeDescs.length, 1);
+ assert.strictEqual(costumeDescs.length, 1);
const costume = costumeDescs[0];
- t.equal(costume.fileName, `${brokenCostumeMd5}.png`);
- t.equal(md5(costume.fileContent), brokenCostumeMd5);
- t.end();
+ assert.strictEqual(costume.fileName, `${brokenCostumeMd5}.png`);
+ assert.strictEqual(md5(costume.fileContent), brokenCostumeMd5);
});
diff --git a/test/integration/sprite3_corrupted_svg.js b/test/integration/sprite3_corrupted_svg.js
index f78f468a..11debd86 100644
--- a/test/integration/sprite3_corrupted_svg.js
+++ b/test/integration/sprite3_corrupted_svg.js
@@ -8,7 +8,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const md5 = require('js-md5');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
@@ -32,7 +33,7 @@ const brokenCostumeMd5 = md5(originalCostume);
let vm;
let defaultVectorAssetId;
-tap.beforeEach(() => {
+beforeEach(async () => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -50,56 +51,50 @@ tap.beforeEach(() => {
vm.attachRenderer(new FakeRenderer());
- return vm.loadProject(project).then(() => vm.addSprite(sprite));
+ await vm.loadProject(project);
+ return vm.addSprite(sprite);
});
-const test = tap.test;
-
-test('load sprite3 with corrupted vector costume file', t => {
- t.equal(vm.runtime.targets.length, 3);
+test('load sprite3 with corrupted vector costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 3);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = vm.runtime.targets[2];
- t.equal(blueGuySprite.getName(), 'Blue Square Guy');
- t.equal(blueGuySprite.getCostumes().length, 1);
+ assert.strictEqual(blueGuySprite.getName(), 'Blue Square Guy');
+ assert.strictEqual(blueGuySprite.getCostumes().length, 1);
const corruptedCostume = blueGuySprite.getCostumes()[0];
- t.equal(corruptedCostume.name, 'costume1');
- t.equal(corruptedCostume.assetId, defaultVectorAssetId);
- t.equal(corruptedCostume.dataFormat, 'svg');
+ assert.strictEqual(corruptedCostume.name, 'costume1');
+ assert.strictEqual(corruptedCostume.assetId, defaultVectorAssetId);
+ assert.strictEqual(corruptedCostume.dataFormat, 'svg');
// Runtime should have info about broken asset
- t.ok(corruptedCostume.broken);
- t.equal(corruptedCostume.broken.assetId, brokenCostumeMd5);
+ assert.ok(corruptedCostume.broken);
+ assert.strictEqual(corruptedCostume.broken.assetId, brokenCostumeMd5);
// Verify that we saved the original asset data
- t.equal(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
-
- t.end();
+ assert.strictEqual(md5(corruptedCostume.broken.asset.data), brokenCostumeMd5);
});
-test('load and then save sprite with corrupted costume file', t => {
+test('load and then save sprite with corrupted costume file', () => {
const resavedSprite = JSON.parse(vm.toJSON(vm.runtime.targets[2].id));
- t.equal(resavedSprite.name, 'Blue Square Guy');
- t.equal(resavedSprite.costumes.length, 1);
+ assert.strictEqual(resavedSprite.name, 'Blue Square Guy');
+ assert.strictEqual(resavedSprite.costumes.length, 1);
const corruptedCostume = resavedSprite.costumes[0];
- t.equal(corruptedCostume.name, 'costume1');
+ assert.strictEqual(corruptedCostume.name, 'costume1');
// Resaved project costume should have the metadata that corresponds to the original broken costume
- t.equal(corruptedCostume.assetId, brokenCostumeMd5);
- t.equal(corruptedCostume.dataFormat, 'svg');
+ assert.strictEqual(corruptedCostume.assetId, brokenCostumeMd5);
+ assert.strictEqual(corruptedCostume.dataFormat, 'svg');
// Test that we didn't save any data about the costume being broken
- t.notOk(corruptedCostume.broken);
-
- t.end();
+ assert.ok(!corruptedCostume.broken);
});
-test('serializeCostume saves orignal broken costume', t => {
+test('serializeCostume saves orignal broken costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[2].id);
- t.equal(costumeDescs.length, 1);
+ assert.strictEqual(costumeDescs.length, 1);
const costume = costumeDescs[0];
- t.equal(costume.fileName, `${brokenCostumeMd5}.svg`);
- t.equal(md5(costume.fileContent), brokenCostumeMd5);
- t.end();
+ assert.strictEqual(costume.fileName, `${brokenCostumeMd5}.svg`);
+ assert.strictEqual(md5(costume.fileContent), brokenCostumeMd5);
});
diff --git a/test/integration/sprite3_missing_png.js b/test/integration/sprite3_missing_png.js
index b35bdbbb..eeafb372 100644
--- a/test/integration/sprite3_missing_png.js
+++ b/test/integration/sprite3_missing_png.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
const FakeBitmapAdapter = require('../fixtures/fake-bitmap-adapter');
@@ -44,9 +45,7 @@ global.document = {
let vm;
-tap.setTimeout(30000);
-
-tap.beforeEach(() => {
+beforeEach(async () => {
const storage = makeTestStorage();
vm = new VirtualMachine();
@@ -54,55 +53,48 @@ tap.beforeEach(() => {
vm.attachRenderer(new FakeRenderer());
vm.attachV2BitmapAdapter(new FakeBitmapAdapter());
- return vm.loadProject(project).then(() => vm.addSprite(sprite));
+ await vm.loadProject(project);
+ return vm.addSprite(sprite);
});
-const test = tap.test;
-
-test('loading sprite3 with missing bitmap costume file', t => {
- t.equal(vm.runtime.targets.length, 3);
+test('loading sprite3 with missing bitmap costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 3);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const greenGuySprite = vm.runtime.targets[2];
- t.equal(greenGuySprite.getName(), 'Green Guy');
- t.equal(greenGuySprite.getCostumes().length, 1);
+ assert.strictEqual(greenGuySprite.getName(), 'Green Guy');
+ assert.strictEqual(greenGuySprite.getCostumes().length, 1);
const missingCostume = greenGuySprite.getCostumes()[0];
- t.equal(missingCostume.name, 'Green Guy');
+ assert.strictEqual(missingCostume.name, 'Green Guy');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
const defaultBitmapAssetId = vm.runtime.storage.defaultAssetId.ImageBitmap;
- t.equal(missingCostume.assetId, defaultBitmapAssetId);
- t.equal(missingCostume.dataFormat, 'png');
+ assert.strictEqual(missingCostume.assetId, defaultBitmapAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'png');
// Runtime should have info about broken asset
- t.ok(missingCostume.broken);
- t.equal(missingCostume.broken.assetId, missingCostumeAssetId);
-
- t.end();
+ assert.ok(missingCostume.broken);
+ assert.strictEqual(missingCostume.broken.assetId, missingCostumeAssetId);
});
-test('load and then save sprite3 with missing bitmap costume file', t => {
+test('load and then save sprite3 with missing bitmap costume file', () => {
const resavedSprite = JSON.parse(vm.toJSON(vm.runtime.targets[2].id));
- t.equal(resavedSprite.name, 'Green Guy');
- t.equal(resavedSprite.costumes.length, 1);
+ assert.strictEqual(resavedSprite.name, 'Green Guy');
+ assert.strictEqual(resavedSprite.costumes.length, 1);
const missingCostume = resavedSprite.costumes[0];
- t.equal(missingCostume.name, 'Green Guy');
+ assert.strictEqual(missingCostume.name, 'Green Guy');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
- t.equal(missingCostume.assetId, missingCostumeAssetId);
- t.equal(missingCostume.dataFormat, 'png');
+ assert.strictEqual(missingCostume.assetId, missingCostumeAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'png');
// Test that we didn't save any data about the costume being broken
- t.notOk(missingCostume.broken);
-
- t.end();
+ assert.ok(!missingCostume.broken);
});
-test('serializeCostume does not save data for missing costume', t => {
+test('serializeCostume does not save data for missing costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[2].id);
- t.equal(costumeDescs.length, 0);
-
- t.end();
+ assert.strictEqual(costumeDescs.length, 0);
});
diff --git a/test/integration/sprite3_missing_svg.js b/test/integration/sprite3_missing_svg.js
index 1fdbb458..18ba8846 100644
--- a/test/integration/sprite3_missing_svg.js
+++ b/test/integration/sprite3_missing_svg.js
@@ -7,7 +7,8 @@
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
-const tap = require('tap');
+const {test, beforeEach} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
@@ -25,62 +26,55 @@ const missingCostumeAssetId = 'a267f8b97ee9cf8aa9832aa0b4cfd9eb';
let vm;
-tap.beforeEach(() => {
+beforeEach(async () => {
const storage = makeTestStorage();
vm = new VirtualMachine();
vm.attachStorage(storage);
vm.attachRenderer(new FakeRenderer());
- return vm.loadProject(project).then(() => vm.addSprite(sprite));
+ await vm.loadProject(project);
+ return vm.addSprite(sprite);
});
-const test = tap.test;
-
-test('loading sprite3 with missing vector costume file', t => {
- t.equal(vm.runtime.targets.length, 3);
+test('loading sprite3 with missing vector costume file', () => {
+ assert.strictEqual(vm.runtime.targets.length, 3);
const stage = vm.runtime.targets[0];
- t.ok(stage.isStage);
+ assert.ok(stage.isStage);
const blueGuySprite = vm.runtime.targets[2];
- t.equal(blueGuySprite.getName(), 'Blue Square Guy');
- t.equal(blueGuySprite.getCostumes().length, 1);
+ assert.strictEqual(blueGuySprite.getName(), 'Blue Square Guy');
+ assert.strictEqual(blueGuySprite.getCostumes().length, 1);
const missingCostume = blueGuySprite.getCostumes()[0];
- t.equal(missingCostume.name, 'costume1');
+ assert.strictEqual(missingCostume.name, 'costume1');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
const defaultVectorAssetId = vm.runtime.storage.defaultAssetId.ImageVector;
- t.equal(missingCostume.assetId, defaultVectorAssetId);
- t.equal(missingCostume.dataFormat, 'svg');
+ assert.strictEqual(missingCostume.assetId, defaultVectorAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'svg');
// Runtime should have info about broken asset
- t.ok(missingCostume.broken);
- t.equal(missingCostume.broken.assetId, missingCostumeAssetId);
-
- t.end();
+ assert.ok(missingCostume.broken);
+ assert.strictEqual(missingCostume.broken.assetId, missingCostumeAssetId);
});
-test('load and then save sprite3 with missing vector costume file', t => {
+test('load and then save sprite3 with missing vector costume file', () => {
const resavedSprite = JSON.parse(vm.toJSON(vm.runtime.targets[2].id));
- t.equal(resavedSprite.name, 'Blue Square Guy');
- t.equal(resavedSprite.costumes.length, 1);
+ assert.strictEqual(resavedSprite.name, 'Blue Square Guy');
+ assert.strictEqual(resavedSprite.costumes.length, 1);
const missingCostume = resavedSprite.costumes[0];
- t.equal(missingCostume.name, 'costume1');
+ assert.strictEqual(missingCostume.name, 'costume1');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
- t.equal(missingCostume.assetId, missingCostumeAssetId);
- t.equal(missingCostume.dataFormat, 'svg');
+ assert.strictEqual(missingCostume.assetId, missingCostumeAssetId);
+ assert.strictEqual(missingCostume.dataFormat, 'svg');
// Test that we didn't save any data about the costume being broken
- t.notOk(missingCostume.broken);
-
- t.end();
+ assert.ok(!missingCostume.broken);
});
-test('serializeCostume does not save data for missing costume', t => {
+test('serializeCostume does not save data for missing costume', () => {
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[2].id);
- t.equal(costumeDescs.length, 0);
-
- t.end();
+ assert.strictEqual(costumeDescs.length, 0);
});
diff --git a/test/integration/stack-click.js b/test/integration/stack-click.js
index a6911064..928b3431 100644
--- a/test/integration/stack-click.js
+++ b/test/integration/stack-click.js
@@ -1,5 +1,6 @@
const path = require('path');
-const test = require('tap').test;
+const {test} = require('node:test');
+const assert = require('node:assert');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
@@ -14,20 +15,20 @@ const project = readFileToBuffer(projectUri);
* The intention is to make sure that the stack can be activated by a stack click
* even when the hat predicate is false.
*/
-test('stack click activates the stack', t => {
+test('stack click activates the stack', (t, done) => {
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// Evaluate playground data and exit
vm.on('playgroundData', () => {
// The sprite should have moved 100 to the right
- t.equal(vm.editingTarget.x, 100);
+ assert.strictEqual(vm.editingTarget.x, 100);
vm.quit();
- t.end();
+ done();
});
// Start VM, load project, and run
- t.doesNotThrow(() => {
+ assert.doesNotThrow(() => {
vm.start();
vm.clear();
vm.setCompatibilityMode(false);
@@ -37,7 +38,7 @@ test('stack click activates the stack', t => {
const allBlocks = blockContainer._blocks;
// Confirm the editing target is initially at 0
- t.equal(vm.editingTarget.x, 0);
+ assert.strictEqual(vm.editingTarget.x, 0);
// Find hat for greater than and click it
for (const blockId in allBlocks) {
diff --git a/test/integration/tw-block-stop-thread.js b/test/integration/tw-block-stop-thread.js
index b3a7c3cd..f06ad600 100644
--- a/test/integration/tw-block-stop-thread.js
+++ b/test/integration/tw-block-stop-thread.js
@@ -1,4 +1,5 @@
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const fs = require('fs');
const path = require('path');
const VM = require('../../src/virtual-machine');
@@ -16,9 +17,8 @@ const stopBySetStatus = thread => {
thread.status = Thread.STATUS_DONE;
};
-test('constants', t => {
- t.equal(Thread.STATUS_DONE, 4);
- t.end();
+test('constants', () => {
+ assert.strictEqual(Thread.STATUS_DONE, 4);
});
for (const [enableCompiler, stopFunction] of [
@@ -29,10 +29,10 @@ for (const [enableCompiler, stopFunction] of [
]) {
const subtestName = `${enableCompiler ? 'compiler' : 'interpreter'} - ${stopFunction.name}`;
- test(`${subtestName} - stop in command block`, t => {
+ test(`${subtestName} - stop in command block`, async () => {
const vm = new VM();
vm.setCompilerOptions({enabled: enableCompiler});
- t.equal(vm.runtime.compilerOptions.enabled, enableCompiler);
+ assert.strictEqual(vm.runtime.compilerOptions.enabled, enableCompiler);
const callOrder = [];
vm.addAddonBlock({
@@ -58,21 +58,19 @@ for (const [enableCompiler, stopFunction] of [
}
});
- vm.loadProject(fixtureData).then(() => {
- vm.greenFlag();
- vm.runtime._step();
- t.same(callOrder, [
- ['input block', {}],
- ['first block', {'number or text': 1}]
- ]);
- t.end();
- });
+ await vm.loadProject(fixtureData);
+ vm.greenFlag();
+ vm.runtime._step();
+ assert.deepEqual(callOrder, [
+ ['input block', {}],
+ ['first block', {'number or text': 1}]
+ ]);
});
- test(`${subtestName} - stop in command block after yielding once`, t => {
+ test(`${subtestName} - stop in command block after yielding once`, async () => {
const vm = new VM();
vm.setCompilerOptions({enabled: enableCompiler});
- t.equal(vm.runtime.compilerOptions.enabled, enableCompiler);
+ assert.strictEqual(vm.runtime.compilerOptions.enabled, enableCompiler);
const callOrder = [];
vm.addAddonBlock({
@@ -100,21 +98,19 @@ for (const [enableCompiler, stopFunction] of [
}
});
- vm.loadProject(fixtureData).then(() => {
- vm.greenFlag();
- vm.runtime._step();
- t.same(callOrder, [
- ['first block', {'number or text': 5}],
- ['first block', {'number or text': 5}]
- ]);
- t.end();
- });
+ await vm.loadProject(fixtureData);
+ vm.greenFlag();
+ vm.runtime._step();
+ assert.deepEqual(callOrder, [
+ ['first block', {'number or text': 5}],
+ ['first block', {'number or text': 5}]
+ ]);
});
- test(`${subtestName} - stop in reporter block`, t => {
+ test(`${subtestName} - stop in reporter block`, async () => {
const vm = new VM();
vm.setCompilerOptions({enabled: enableCompiler});
- t.equal(vm.runtime.compilerOptions.enabled, enableCompiler);
+ assert.strictEqual(vm.runtime.compilerOptions.enabled, enableCompiler);
const callOrder = [];
vm.addAddonBlock({
@@ -140,20 +136,18 @@ for (const [enableCompiler, stopFunction] of [
}
});
- vm.loadProject(fixtureData).then(() => {
- vm.greenFlag();
- vm.runtime._step();
- t.same(callOrder, [
- ['input block', {}]
- ]);
- t.end();
- });
+ await vm.loadProject(fixtureData);
+ vm.greenFlag();
+ vm.runtime._step();
+ assert.deepEqual(callOrder, [
+ ['input block', {}]
+ ]);
});
- test(`${subtestName} - stop in reporter block after yielding once`, t => {
+ test(`${subtestName} - stop in reporter block after yielding once`, async () => {
const vm = new VM();
vm.setCompilerOptions({enabled: enableCompiler});
- t.equal(vm.runtime.compilerOptions.enabled, enableCompiler);
+ assert.strictEqual(vm.runtime.compilerOptions.enabled, enableCompiler);
const callOrder = [];
vm.addAddonBlock({
@@ -185,14 +179,12 @@ for (const [enableCompiler, stopFunction] of [
}
});
- vm.loadProject(fixtureData).then(() => {
- vm.greenFlag();
- vm.runtime._step();
- t.same(callOrder, [
- ['input block', {}],
- ['input block', {}]
- ]);
- t.end();
- });
+ await vm.loadProject(fixtureData);
+ vm.greenFlag();
+ vm.runtime._step();
+ assert.deepEqual(callOrder, [
+ ['input block', {}],
+ ['input block', {}]
+ ]);
});
}
diff --git a/test/integration/tw-snapshots.js b/test/integration/tw-snapshots.js
index 4f4edc96..5148ef5f 100644
--- a/test/integration/tw-snapshots.js
+++ b/test/integration/tw-snapshots.js
@@ -1,23 +1,21 @@
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const Snapshots = require('../snapshot/lib');
for (const testCase of Snapshots.tests) {
// eslint-disable-next-line no-loop-func
- test(testCase.id, async t => {
+ test(testCase.id, async () => {
const expected = Snapshots.getExpectedSnapshot(testCase);
const actual = await Snapshots.generateActualSnapshot(testCase);
const result = Snapshots.compareSnapshots(expected, actual);
- if (result === 'VALID') {
- t.pass('matches');
- } else if (result === 'INPUT_MODIFIED') {
- t.fail('input project changed; run: node test/snapshot --update');
+ if (result === 'INPUT_MODIFIED') {
+ assert.fail('input project changed; run: node test/snapshot --update');
} else if (result === 'MISSING_SNAPSHOT') {
- t.fail('snapshot is missing; run: node test/snapshot --update');
- } else {
- // This assertion will always fail, but tap will print out the snapshots
+ assert.fail('snapshot is missing; run: node test/snapshot --update');
+ } else if (result !== 'VALID') {
+ // This assertion will always fail, but it will print out the snapshots
// for easier comparison.
- t.equal(expected, actual, 'did not match; you may have to run: node test/snapshot --update');
+ assert.strictEqual(expected, actual, 'did not match; you may have to run: node test/snapshot --update');
}
- t.end();
});
}
diff --git a/test/integration/tw_add_builtin_extension.js b/test/integration/tw_add_builtin_extension.js
index 9992b295..297c1343 100644
--- a/test/integration/tw_add_builtin_extension.js
+++ b/test/integration/tw_add_builtin_extension.js
@@ -1,6 +1,7 @@
const fs = require('fs');
const path = require('path');
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const VM = require('../../src/virtual-machine');
const Scratch = require('../../src/extension-support/tw-extension-api-common');
@@ -23,23 +24,27 @@ class TestBuiltinExtension {
}
}
-test('addBuiltingExtension', t => {
+test('addBuiltingExtension', (t, done) => {
const vm = new VM();
- t.equal(vm.extensionManager.isBuiltinExtension('testbuiltin'), false, 'extension is not known');
- t.equal(vm.extensionManager.isExtensionLoaded('testbuiltin'), false, 'extension is not loaded');
+ assert.strictEqual(vm.extensionManager.isBuiltinExtension('testbuiltin'), false, 'extension is not known');
+ assert.strictEqual(vm.extensionManager.isExtensionLoaded('testbuiltin'), false, 'extension is not loaded');
vm.extensionManager.addBuiltinExtension('testbuiltin', TestBuiltinExtension);
- t.equal(vm.extensionManager.isBuiltinExtension('testbuiltin'), true, 'extension is now known');
- t.equal(vm.extensionManager.isExtensionLoaded('testbuiltin'), false, 'extension is still not loaded');
+ assert.strictEqual(vm.extensionManager.isBuiltinExtension('testbuiltin'), true, 'extension is now known');
+ assert.strictEqual(vm.extensionManager.isExtensionLoaded('testbuiltin'), false, 'extension is still not loaded');
const fixture = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'tw-add-builtin-extension.sb3'));
vm.loadProject(fixture).then(() => {
- t.equal(vm.extensionManager.isExtensionLoaded('testbuiltin'), true, 'extension was loaded automatically');
+ assert.strictEqual(
+ vm.extensionManager.isExtensionLoaded('testbuiltin'),
+ true,
+ 'extension was loaded automatically'
+ );
vm.runtime.on('SAY', (target, type, text) => {
- t.equal(text, 'It works! 123', 'said value from extension');
- t.end();
+ assert.strictEqual(text, 'It works! 123', 'said value from extension');
+ done();
});
vm.greenFlag();
@@ -47,14 +52,12 @@ test('addBuiltingExtension', t => {
});
});
-test('each runtime has own set of extensions', t => {
+test('each runtime has own set of extensions', () => {
const vm1 = new VM();
const vm2 = new VM();
vm1.extensionManager.addBuiltinExtension('testbuiltin', TestBuiltinExtension);
- t.ok(vm1.extensionManager.isBuiltinExtension('testbuiltin'));
- t.notOk(vm2.extensionManager.isBuiltinExtension('testbuiltin'));
-
- t.end();
+ assert.ok(vm1.extensionManager.isBuiltinExtension('testbuiltin'));
+ assert.ok(!vm2.extensionManager.isBuiltinExtension('testbuiltin'));
});
diff --git a/test/integration/tw_addon_blocks.js b/test/integration/tw_addon_blocks.js
index c83f9567..59d86303 100644
--- a/test/integration/tw_addon_blocks.js
+++ b/test/integration/tw_addon_blocks.js
@@ -1,4 +1,5 @@
-const tap = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const fs = require('fs');
const path = require('path');
const VirtualMachine = require('../../src/virtual-machine');
@@ -6,14 +7,14 @@ const Thread = require('../../src/engine/thread');
const fixtureData = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'tw-addon-blocks.sb3'));
-const runExecutionTests = compilerEnabled => test => {
+const runExecutionTests = compilerEnabled => async parent => {
const load = async () => {
const vm = new VirtualMachine();
vm.setCompilerOptions({
enabled: compilerEnabled
});
vm.on('COMPILE_ERROR', (target, error) => {
- test.fail(`Compile error in ${target.getName()}: ${error}`);
+ assert.fail(`Compile error in ${target.getName()}: ${error}`);
});
await vm.loadProject(fixtureData);
return vm;
@@ -24,192 +25,172 @@ const runExecutionTests = compilerEnabled => test => {
return variable.value;
};
- test.test('baseline - no addon blocks', t => {
- load().then(vm => {
- t.equal(getVar(vm, 'block 1'), 'initial');
- t.equal(getVar(vm, 'block 2'), 'initial');
- t.equal(getVar(vm, 'block 3'), 'initial');
- t.equal(getVar(vm, 'block 4'), 'initial');
- t.equal(getVar(vm, 'block 4 output'), 'initial');
+ await parent.test('baseline - no addon blocks', async () => {
+ const vm = await load();
+ assert.strictEqual(getVar(vm, 'block 1'), 'initial');
+ assert.strictEqual(getVar(vm, 'block 2'), 'initial');
+ assert.strictEqual(getVar(vm, 'block 3'), 'initial');
+ assert.strictEqual(getVar(vm, 'block 4'), 'initial');
+ assert.strictEqual(getVar(vm, 'block 4 output'), 'initial');
- vm.greenFlag();
- vm.runtime._step();
+ vm.greenFlag();
+ vm.runtime._step();
- t.equal(getVar(vm, 'block 1'), 'block 1 ran');
- t.equal(getVar(vm, 'block 2'), 'block 2: banana');
- t.equal(getVar(vm, 'block 3'), 'block 3 ran');
- t.equal(getVar(vm, 'block 4'), 'block 4 ran');
- t.equal(getVar(vm, 'block 4 output'), 'block 4: apple');
-
- t.end();
- });
+ assert.strictEqual(getVar(vm, 'block 1'), 'block 1 ran');
+ assert.strictEqual(getVar(vm, 'block 2'), 'block 2: banana');
+ assert.strictEqual(getVar(vm, 'block 3'), 'block 3 ran');
+ assert.strictEqual(getVar(vm, 'block 4'), 'block 4 ran');
+ assert.strictEqual(getVar(vm, 'block 4 output'), 'block 4: apple');
});
- test.test('simple statement blocks', t => {
- load().then(vm => {
- t.plan(9);
+ await parent.test('simple statement blocks', async t => {
+ const vm = await load();
+ t.plan(9);
- let calledBlock1 = false;
- let calledBlock2 = false;
+ let calledBlock1 = false;
+ let calledBlock2 = false;
- vm.addAddonBlock({
- procedureCode: 'block 1',
- callback: (args, util) => {
- calledBlock1 = true;
- t.same(args, {});
- t.ok(util.thread instanceof Thread);
- // may have to update when project changes
- t.equal(util.thread.peekStack(), 'd');
- }
- });
-
- vm.addAddonBlock({
- procedureCode: 'block 2 %s',
- arguments: ['number or text'],
- callback: (args, util) => {
- calledBlock2 = true;
- t.same(args, {
- 'number or text': 'banana'
- });
- // may have to update when project changes
- t.equal(util.thread.peekStack(), 'c');
- }
- });
-
- vm.greenFlag();
- vm.runtime._step();
-
- t.ok(calledBlock1);
- t.ok(calledBlock2);
-
- // Overridden blocks should not run
- t.equal(getVar(vm, 'block 1'), 'false');
- t.equal(getVar(vm, 'block 2'), 'false');
-
- t.end();
- });
- });
-
- test.test('yield with thread.status = STATUS_PROMISE_WAIT', t => {
- load().then(vm => {
- t.plan(7);
-
- let threadToResume;
- let ranBlock3 = false;
- vm.addAddonBlock({
- procedureCode: 'block 3',
- callback: (args, util) => {
- ranBlock3 = true;
- util.thread.status = Thread.STATUS_PROMISE_WAIT;
- threadToResume = util.thread;
- },
- arguments: []
- });
-
- vm.greenFlag();
- vm.runtime._step();
-
- // Make sure we paused it
- t.ok(ranBlock3);
- t.equal(threadToResume.status, Thread.STATUS_PROMISE_WAIT);
-
- // Should've stopped after block 2
- t.equal(getVar(vm, 'block 2'), 'block 2: banana');
- t.equal(getVar(vm, 'block 3'), 'false');
- t.equal(getVar(vm, 'block 4'), 'false');
-
- threadToResume.status = Thread.STATUS_RUNNING;
- vm.runtime._step();
-
- // Should've finished running
- t.equal(getVar(vm, 'block 3'), 'false'); // overridden, should not run
- t.equal(getVar(vm, 'block 4'), 'block 4 ran');
-
- t.end();
- });
- });
-
- test.test('yield with util.yield()', t => {
- load().then(vm => {
- t.plan(10);
-
- let shouldYield = true;
- let calledBlock1 = 0;
-
- vm.addAddonBlock({
- procedureCode: 'block 1',
- callback: (args, util) => {
- calledBlock1++;
-
- if (shouldYield) {
- util.runtime.requestRedraw();
- util.yield();
- }
- },
- arguments: []
- });
-
- vm.greenFlag();
- for (let i = 0; i < 10; i++) {
- vm.runtime._step();
+ vm.addAddonBlock({
+ procedureCode: 'block 1',
+ callback: (args, util) => {
+ calledBlock1 = true;
+ t.assert.deepEqual(args, {});
+ t.assert.ok(util.thread instanceof Thread);
+ // may have to update when project changes
+ t.assert.strictEqual(util.thread.peekStack(), 'd');
}
-
- t.equal(calledBlock1, 10);
- t.equal(getVar(vm, 'block 1'), 'false');
- t.equal(getVar(vm, 'block 2'), 'false');
- t.equal(getVar(vm, 'block 3'), 'false');
- t.equal(getVar(vm, 'block 4'), 'false');
-
- shouldYield = false;
- vm.runtime._step();
-
- t.equal(calledBlock1, 11);
- t.equal(getVar(vm, 'block 1'), 'false'); // overrridden, should not run
- t.equal(getVar(vm, 'block 2'), 'block 2: banana');
- t.equal(getVar(vm, 'block 3'), 'block 3 ran');
- t.equal(getVar(vm, 'block 4'), 'block 4 ran');
-
- t.end();
});
+
+ vm.addAddonBlock({
+ procedureCode: 'block 2 %s',
+ arguments: ['number or text'],
+ callback: (args, util) => {
+ calledBlock2 = true;
+ t.assert.deepEqual(args, {
+ 'number or text': 'banana'
+ });
+ // may have to update when project changes
+ t.assert.strictEqual(util.thread.peekStack(), 'c');
+ }
+ });
+
+ vm.greenFlag();
+ vm.runtime._step();
+
+ t.assert.ok(calledBlock1);
+ t.assert.ok(calledBlock2);
+
+ // Overridden blocks should not run
+ t.assert.strictEqual(getVar(vm, 'block 1'), 'false');
+ t.assert.strictEqual(getVar(vm, 'block 2'), 'false');
});
- test.test('yield with resolved Promise', t => {
- load().then(vm => {
- let resolveCallback;
- vm.addAddonBlock({
- procedureCode: 'block 2 %s',
- arguments: ['number or text'],
- callback: () => new Promise(resolve => {
- resolveCallback = resolve;
- })
- });
-
- vm.greenFlag();
- for (let i = 0; i < 5; i++) {
- vm.runtime._step();
- }
-
- t.type(resolveCallback, 'function');
- t.equal(getVar(vm, 'block 1'), 'block 1 ran');
- t.equal(getVar(vm, 'block 2'), 'false');
- t.equal(getVar(vm, 'block 3'), 'false');
- t.equal(getVar(vm, 'block 4'), 'false');
-
- resolveCallback();
- Promise.resolve().then(() => {
- vm.runtime._step();
- t.equal(getVar(vm, 'block 2'), 'false'); // overridden, should not run
- t.equal(getVar(vm, 'block 3'), 'block 3 ran');
- t.equal(getVar(vm, 'block 4'), 'block 4 ran');
-
- t.end();
- });
+ await parent.test('yield with thread.status = STATUS_PROMISE_WAIT', async () => {
+ const vm = await load();
+ let threadToResume;
+ let ranBlock3 = false;
+ vm.addAddonBlock({
+ procedureCode: 'block 3',
+ callback: (args, util) => {
+ ranBlock3 = true;
+ util.thread.status = Thread.STATUS_PROMISE_WAIT;
+ threadToResume = util.thread;
+ },
+ arguments: []
});
+
+ vm.greenFlag();
+ vm.runtime._step();
+
+ // Make sure we paused it
+ assert.ok(ranBlock3);
+ assert.strictEqual(threadToResume.status, Thread.STATUS_PROMISE_WAIT);
+
+ // Should've stopped after block 2
+ assert.strictEqual(getVar(vm, 'block 2'), 'block 2: banana');
+ assert.strictEqual(getVar(vm, 'block 3'), 'false');
+ assert.strictEqual(getVar(vm, 'block 4'), 'false');
+
+ threadToResume.status = Thread.STATUS_RUNNING;
+ vm.runtime._step();
+
+ // Should've finished running
+ assert.strictEqual(getVar(vm, 'block 3'), 'false'); // overridden, should not run
+ assert.strictEqual(getVar(vm, 'block 4'), 'block 4 ran');
+ });
+
+ await parent.test('yield with util.yield()', async () => {
+ const vm = await load();
+ let shouldYield = true;
+ let calledBlock1 = 0;
+
+ vm.addAddonBlock({
+ procedureCode: 'block 1',
+ callback: (args, util) => {
+ calledBlock1++;
+
+ if (shouldYield) {
+ util.runtime.requestRedraw();
+ util.yield();
+ }
+ },
+ arguments: []
+ });
+
+ vm.greenFlag();
+ for (let i = 0; i < 10; i++) {
+ vm.runtime._step();
+ }
+
+ assert.strictEqual(calledBlock1, 10);
+ assert.strictEqual(getVar(vm, 'block 1'), 'false');
+ assert.strictEqual(getVar(vm, 'block 2'), 'false');
+ assert.strictEqual(getVar(vm, 'block 3'), 'false');
+ assert.strictEqual(getVar(vm, 'block 4'), 'false');
+
+ shouldYield = false;
+ vm.runtime._step();
+
+ assert.strictEqual(calledBlock1, 11);
+ assert.strictEqual(getVar(vm, 'block 1'), 'false'); // overrridden, should not run
+ assert.strictEqual(getVar(vm, 'block 2'), 'block 2: banana');
+ assert.strictEqual(getVar(vm, 'block 3'), 'block 3 ran');
+ assert.strictEqual(getVar(vm, 'block 4'), 'block 4 ran');
+ });
+
+ await parent.test('yield with resolved Promise', async () => {
+ const vm = await load();
+ let resolveCallback;
+ vm.addAddonBlock({
+ procedureCode: 'block 2 %s',
+ arguments: ['number or text'],
+ callback: () => new Promise(resolve => {
+ resolveCallback = resolve;
+ })
+ });
+
+ vm.greenFlag();
+ for (let i = 0; i < 5; i++) {
+ vm.runtime._step();
+ }
+
+ assert.strictEqual(typeof resolveCallback, 'function');
+ assert.strictEqual(getVar(vm, 'block 1'), 'block 1 ran');
+ assert.strictEqual(getVar(vm, 'block 2'), 'false');
+ assert.strictEqual(getVar(vm, 'block 3'), 'false');
+ assert.strictEqual(getVar(vm, 'block 4'), 'false');
+
+ resolveCallback();
+ await Promise.resolve();
+ vm.runtime._step();
+ assert.strictEqual(getVar(vm, 'block 2'), 'false'); // overridden, should not run
+ assert.strictEqual(getVar(vm, 'block 3'), 'block 3 ran');
+ assert.strictEqual(getVar(vm, 'block 4'), 'block 4 ran');
});
/*
// Doesn't work right now -- not clear whether it should or not
- test.skip('yield with rejected Promise', t => {
+ parent.test.skip('yield with rejected Promise', t => {
load().then(vm => {
let rejectCallback;
vm.addAddonBlock({
@@ -244,39 +225,34 @@ const runExecutionTests = compilerEnabled => test => {
});
*/
- test.test('returning values', t => {
- load().then(vm => {
- vm.addAddonBlock({
- procedureCode: 'block 4 %s',
- callback: args => {
- t.same(args, {
- 'number or text': 'apple'
- });
- return `value from addon block: ${args['number or text']}`;
- },
- arguments: ['number or text']
- });
-
- vm.greenFlag();
- vm.runtime._step();
-
- t.equal(getVar(vm, 'block 1'), 'block 1 ran');
- t.equal(getVar(vm, 'block 2'), 'block 2: banana');
- t.equal(getVar(vm, 'block 3'), 'block 3 ran');
- t.equal(getVar(vm, 'block 4'), 'false'); // block 4 itself should not have run, we overrode it
- t.equal(getVar(vm, 'block 4 output'), 'value from addon block: apple');
-
- t.end();
+ await parent.test('returning values', async () => {
+ const vm = await load();
+ vm.addAddonBlock({
+ procedureCode: 'block 4 %s',
+ callback: args => {
+ assert.deepEqual(args, {
+ 'number or text': 'apple'
+ });
+ return `value from addon block: ${args['number or text']}`;
+ },
+ arguments: ['number or text']
});
- });
- test.end();
+ vm.greenFlag();
+ vm.runtime._step();
+
+ assert.strictEqual(getVar(vm, 'block 1'), 'block 1 ran');
+ assert.strictEqual(getVar(vm, 'block 2'), 'block 2: banana');
+ assert.strictEqual(getVar(vm, 'block 3'), 'block 3 ran');
+ assert.strictEqual(getVar(vm, 'block 4'), 'false'); // block 4 itself should not have run, we overrode it
+ assert.strictEqual(getVar(vm, 'block 4 output'), 'value from addon block: apple');
+ });
};
-tap.test('with compiler disabled', runExecutionTests(false));
-tap.test('with compiler enabled', runExecutionTests(true));
+test('with compiler disabled', runExecutionTests(false));
+test('with compiler enabled', runExecutionTests(true));
-tap.test('block info', t => {
+test('block info', () => {
const vm = new VirtualMachine();
const BLOCK_INFO_ID = 'a-b';
@@ -289,7 +265,7 @@ tap.test('block info', t => {
});
let blockInfo = vm.runtime._blockInfo.find(i => i.id === BLOCK_INFO_ID);
- t.equal(blockInfo, undefined);
+ assert.strictEqual(blockInfo, undefined);
vm.addAddonBlock({
procedureCode: 'statement %s',
@@ -304,12 +280,12 @@ tap.test('block info', t => {
});
blockInfo = vm.runtime._blockInfo.find(i => i.id === BLOCK_INFO_ID);
- t.type(blockInfo.id, 'string');
- t.type(blockInfo.name, 'string');
- t.type(blockInfo.color1, 'string');
- t.type(blockInfo.color2, 'string');
- t.type(blockInfo.color3, 'string');
- t.same(blockInfo.blocks, [
+ assert.strictEqual(typeof blockInfo.id, 'string');
+ assert.strictEqual(typeof blockInfo.name, 'string');
+ assert.strictEqual(typeof blockInfo.color1, 'string');
+ assert.strictEqual(typeof blockInfo.color2, 'string');
+ assert.strictEqual(typeof blockInfo.color3, 'string');
+ assert.deepEqual(blockInfo.blocks, [
{
info: {},
// eslint-disable-next-line max-len
@@ -321,6 +297,4 @@ tap.test('block info', t => {
xml: ''
}
]);
-
- t.end();
});
diff --git a/test/integration/tw_allow_drop_anywhere.js b/test/integration/tw_allow_drop_anywhere.js
index 0bc19fbc..8053e6cb 100644
--- a/test/integration/tw_allow_drop_anywhere.js
+++ b/test/integration/tw_allow_drop_anywhere.js
@@ -1,16 +1,16 @@
-const {test} = require('tap');
+const {test} = require('node:test');
const Runtime = require('../../src/engine/runtime');
const BlockType = require('../../src/extension-support/block-type');
-test('allowDropAnywhere', t => {
+test('allowDropAnywhere', (t, done) => {
t.plan(2);
const rt = new Runtime();
rt.on('EXTENSION_ADDED', json => {
- t.equal(json.blocks[0].json.output, 'String');
- t.equal(json.blocks[1].json.output, null);
- t.end();
+ t.assert.strictEqual(json.blocks[0].json.output, 'String');
+ t.assert.strictEqual(json.blocks[1].json.output, null);
+ done();
});
rt._registerExtensionPrimitives({
diff --git a/test/integration/tw_asset_progress.js b/test/integration/tw_asset_progress.js
index 4eccf9d3..782431c1 100644
--- a/test/integration/tw_asset_progress.js
+++ b/test/integration/tw_asset_progress.js
@@ -1,4 +1,5 @@
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const fs = require('fs');
const path = require('path');
const Runtime = require('../../src/engine/runtime');
@@ -6,19 +7,19 @@ const VirtualMachine = require('../../src/virtual-machine');
const makeTestStorage = require('../fixtures/make-test-storage');
const AssetUtil = require('../../src/util/tw-asset-util');
-test('emitAssetProgress', t => {
+test('emitAssetProgress', () => {
const vm = new VirtualMachine();
let runtimeOK = false;
let vmOK = false;
vm.runtime.on('ASSET_PROGRESS', (finished, total) => {
- t.equal(finished, 1, 'runtime finished');
- t.equal(total, 2, 'runtime total');
+ assert.strictEqual(finished, 1, 'runtime finished');
+ assert.strictEqual(total, 2, 'runtime total');
runtimeOK = true;
});
vm.on('ASSET_PROGRESS', (finished, total) => {
- t.equal(finished, 1, 'vm finished');
- t.equal(total, 2, 'vm total');
+ assert.strictEqual(finished, 1, 'vm finished');
+ assert.strictEqual(total, 2, 'vm total');
vmOK = true;
});
@@ -26,9 +27,8 @@ test('emitAssetProgress', t => {
vm.runtime.finishedAssetRequests = 1;
vm.runtime.emitAssetProgress();
- t.ok(runtimeOK, 'runtime');
- t.ok(vmOK, 'vm');
- t.end();
+ assert.ok(runtimeOK, 'runtime');
+ assert.ok(vmOK, 'vm');
});
test('resetProgress', t => {
@@ -39,28 +39,26 @@ test('resetProgress', t => {
runtime.totalAssetRequests = 10;
runtime.on('ASSET_PROGRESS', (finished, total) => {
- t.equal(finished, 0, 'event finished');
- t.equal(total, 0, 'event total');
+ t.assert.strictEqual(finished, 0, 'event finished');
+ t.assert.strictEqual(total, 0, 'event total');
});
runtime.resetProgress();
- t.equal(runtime.finishedAssetRequests, 0, 'property finishedAssetRequests');
- t.equal(runtime.totalAssetRequests, 0, 'property totalAssetRequests');
- t.end();
+ t.assert.strictEqual(runtime.finishedAssetRequests, 0, 'property finishedAssetRequests');
+ t.assert.strictEqual(runtime.totalAssetRequests, 0, 'property totalAssetRequests');
});
test('dispose', t => {
t.plan(1);
const runtime = new Runtime();
runtime.resetProgress = () => {
- t.pass();
+ t.assert.ok(true);
};
runtime.dispose();
- t.end();
});
-test('wrapAssetRequest', t => {
+test('wrapAssetRequest', (t, done) => {
const runtime = new Runtime();
const log = [];
@@ -72,12 +70,12 @@ test('wrapAssetRequest', t => {
runtime.wrapAssetRequest(() => Promise.resolve(1)),
runtime.wrapAssetRequest(() => Promise.resolve(2))
]).then(results => {
- t.same(results, [1, 2]);
+ assert.deepEqual(results, [1, 2]);
// eslint-disable-next-line prefer-promise-reject-errors
runtime.wrapAssetRequest(() => Promise.reject(3)).catch(error => {
- t.equal(error, 3);
- t.same(log, [
+ assert.strictEqual(error, 3);
+ assert.deepEqual(log, [
[0, 1],
[0, 2],
[1, 2],
@@ -85,12 +83,12 @@ test('wrapAssetRequest', t => {
[2, 3],
[3, 3]
]);
- t.end();
+ done();
});
});
});
-test('asset util emits progress', t => {
+test('asset util emits progress', async () => {
const runtime = new Runtime();
const storage = makeTestStorage();
@@ -104,19 +102,17 @@ test('asset util emits progress', t => {
log.push([finished, total]);
});
- AssetUtil.getByMd5ext(runtime, null, runtime.storage.AssetType.SVG, 'abcdef.svg').then(() => {
- t.same(log, [
- [0, 1],
- [1, 1]
- ]);
- t.end();
- });
+ await AssetUtil.getByMd5ext(runtime, null, runtime.storage.AssetType.SVG, 'abcdef.svg');
+ assert.deepEqual(log, [
+ [0, 1],
+ [1, 1]
+ ]);
});
// For the next tests, we have some fixtures that contain 2 assets: 1 sound + 1 costume
// We'll just load them and make sure that each deserializer emits reasonable progress events
for (const format of ['sb', 'sb2', 'sb3']) {
- test(format, t => {
+ test(format, async () => {
const fixture = fs.readFileSync(path.join(__dirname, `../fixtures/tw-asset-progress.${format}`));
const vm = new VirtualMachine();
@@ -125,16 +121,13 @@ for (const format of ['sb', 'sb2', 'sb3']) {
log.push([finished, total]);
});
- vm.loadProject(fixture)
- .then(() => {
- t.same(log, [
- [0, 0], // loadProject() implies dispose()
- [0, 1],
- [0, 2],
- [1, 2],
- [2, 2]
- ]);
- t.end();
- });
+ await vm.loadProject(fixture);
+ assert.deepEqual(log, [
+ [0, 0], // loadProject() implies dispose()
+ [0, 1],
+ [0, 2],
+ [1, 2],
+ [2, 2]
+ ]);
});
}
diff --git a/test/integration/tw_automatic_variable_creation.js b/test/integration/tw_automatic_variable_creation.js
index e77d575a..c83e1e13 100644
--- a/test/integration/tw_automatic_variable_creation.js
+++ b/test/integration/tw_automatic_variable_creation.js
@@ -1,16 +1,17 @@
const fs = require('fs');
const path = require('path');
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const VM = require('../../src/virtual-machine');
for (const compilerEnabled of [false, true]) {
const prefix = compilerEnabled ? 'compiler' : 'interpreter';
- test(`${prefix} - quirks when block field has literal null for variable ID`, t => {
+ test(`${prefix} - quirks when block field has literal null for variable ID`, async () => {
const vm = new VM();
vm.setCompilerOptions({
enabled: compilerEnabled
});
- t.equal(vm.runtime.compilerOptions.enabled, compilerEnabled, 'compiler options sanity check');
+ assert.strictEqual(vm.runtime.compilerOptions.enabled, compilerEnabled, 'compiler options sanity check');
// The execute tests ensure that this fixture compiles and runs fine and the snapshot test ensures
// it compiles correctly. This additional test will ensure that the internal variable objects are
@@ -20,24 +21,21 @@ for (const compilerEnabled of [false, true]) {
'../fixtures/execute/tw-automatic-variable-creation-literal-null-id.sb3'
);
- vm.loadProject(fs.readFileSync(fixturePath)).then(() => {
- vm.greenFlag();
- vm.runtime._step();
+ await vm.loadProject(fs.readFileSync(fixturePath));
+ vm.greenFlag();
+ vm.runtime._step();
- // Variable does not exist, should get made as local variable in sprite
- const variables = vm.runtime.targets[1].variables;
- t.equal(Object.keys(variables).length, 1, 'created 1 new variable');
+ // Variable does not exist, should get made as local variable in sprite
+ const variables = vm.runtime.targets[1].variables;
+ assert.strictEqual(Object.keys(variables).length, 1, 'created 1 new variable');
- // Scratch quirk - the entry in .variables should have key "null"
- const newVariableKey = Object.keys(variables)[0];
- t.equal(newVariableKey, 'null', 'key is "null"');
+ // Scratch quirk - the entry in .variables should have key "null"
+ const newVariableKey = Object.keys(variables)[0];
+ assert.strictEqual(newVariableKey, 'null', 'key is "null"');
- // Scratch quirk - the actual variable.id should be the random string
- const newVariable = Object.values(variables)[0];
- t.notEqual(newVariable.id, 'null', 'variable.id is not "null"');
- t.type(newVariable.id, 'string', 'variable.id is a string');
-
- t.end();
- });
+ // Scratch quirk - the actual variable.id should be the random string
+ const newVariable = Object.values(variables)[0];
+ assert.notStrictEqual(newVariable.id, 'null', 'variable.id is not "null"');
+ assert.strictEqual(typeof newVariable.id, 'string', 'variable.id is a string');
});
}
diff --git a/test/integration/tw_block_returning_promise_like.js b/test/integration/tw_block_returning_promise_like.js
index e212ef42..a0a94d1a 100644
--- a/test/integration/tw_block_returning_promise_like.js
+++ b/test/integration/tw_block_returning_promise_like.js
@@ -1,4 +1,5 @@
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const fs = require('fs');
const path = require('path');
const VirtualMachine = require('../../src/virtual-machine');
@@ -36,34 +37,33 @@ class TestExtension {
const fixture = fs.readFileSync(path.join(__dirname, '../fixtures/tw-block-returning-promise-like.sb3'));
for (const compilerEnabled of [false, true]) {
- test(`handles blocks that return a promise-like object - ${compilerEnabled ? 'compiled' : 'interpreted'}`, t => {
+ // eslint-disable-next-line max-len
+ test(`handles blocks that return a promise-like object - ${compilerEnabled ? 'compiled' : 'interpreted'}`, async () => {
const vm = new VirtualMachine();
vm.extensionManager.addBuiltinExtension('testextension', TestExtension);
vm.setCompilerOptions({
enabled: compilerEnabled
});
- t.equal(vm.runtime.compilerOptions.enabled, compilerEnabled, 'sanity check');
+ assert.strictEqual(vm.runtime.compilerOptions.enabled, compilerEnabled, 'sanity check');
vm.runtime.on('COMPILE_ERROR', () => {
- t.fail('Compile error');
+ assert.fail('Compile error');
});
- vm.loadProject(fixture).then(() => {
- let ended = 0;
- vm.runtime.on('SAY', (target, type, text) => {
- if (text === 'end') {
- ended++;
- } else {
- t.fail('said something unknown');
- }
- });
-
- vm.greenFlag();
- vm.runtime._step();
-
- t.equal(ended, 1, 'script ran once immediately');
- t.end();
+ await vm.loadProject(fixture);
+ let ended = 0;
+ vm.runtime.on('SAY', (target, type, text) => {
+ if (text === 'end') {
+ ended++;
+ } else {
+ assert.fail('said something unknown');
+ }
});
+
+ vm.greenFlag();
+ vm.runtime._step();
+
+ assert.strictEqual(ended, 1, 'script ran once immediately');
});
}
diff --git a/test/integration/tw_compat_block_utility_stackframe_exposed.js b/test/integration/tw_compat_block_utility_stackframe_exposed.js
index a49aac67..efa5404b 100644
--- a/test/integration/tw_compat_block_utility_stackframe_exposed.js
+++ b/test/integration/tw_compat_block_utility_stackframe_exposed.js
@@ -1,15 +1,14 @@
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const fs = require('fs');
const path = require('path');
const VM = require('../../src/virtual-machine');
const Timer = require('../../src/util/timer');
-test('compatibility stack frame is exposed on thread', t => {
+test('compatibility stack frame is exposed on thread', async () => {
const vm = new VM();
- vm.loadProject(fs.readFileSync(path.join(__dirname, '../fixtures/tw-glide.sb3'))).then(() => {
- vm.greenFlag();
- vm.runtime._step();
- t.ok(vm.runtime.threads[0].compatibilityStackFrame.timer instanceof Timer);
- t.end();
- });
+ await vm.loadProject(fs.readFileSync(path.join(__dirname, '../fixtures/tw-glide.sb3')));
+ vm.greenFlag();
+ vm.runtime._step();
+ assert.ok(vm.runtime.threads[0].compatibilityStackFrame.timer instanceof Timer);
});
diff --git a/test/integration/tw_compression_per_file_type.js b/test/integration/tw_compression_per_file_type.js
index 35f02a68..28b6efdf 100644
--- a/test/integration/tw_compression_per_file_type.js
+++ b/test/integration/tw_compression_per_file_type.js
@@ -1,31 +1,28 @@
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const fs = require('fs');
const path = require('path');
const VM = require('../../src/virtual-machine');
const makeTestStorage = require('../fixtures/make-test-storage');
const JSZip = require('@turbowarp/jszip');
-test('saveProjectSb3() per-file compression', t => {
+test('saveProjectSb3() per-file compression', async () => {
const vm = new VM();
vm.attachStorage(makeTestStorage());
const fixture = fs.readFileSync(path.join(__dirname, '../fixtures/tw-mixed-file-formats.sb3'));
- vm.loadProject(fixture)
- .then(() => vm.saveProjectSb3('arraybuffer'))
- .then(buffer => JSZip.loadAsync(buffer))
- .then(zip => {
- const isCompressed = pathInZip => {
- // note: uses JSZip private APIs, not very stable, but it should be okay...
- const file = zip.files[pathInZip];
- return file._data.compression.magic === '\x08\x00';
- };
+ await vm.loadProject(fixture);
+ const buffer = await vm.saveProjectSb3('arraybuffer');
+ const zip = await JSZip.loadAsync(buffer);
+ const isCompressed = pathInZip => {
+ // note: uses JSZip private APIs, not very stable, but it should be okay...
+ const file = zip.files[pathInZip];
+ return file._data.compression.magic === '\x08\x00';
+ };
- t.ok(isCompressed('project.json'));
- t.ok(isCompressed('5cb46ddd903fc2c9976ff881df9273c9.wav'));
- t.ok(isCompressed('cd21514d0531fdffb22204e0ec5ed84a.svg'));
+ assert.ok(isCompressed('project.json'));
+ assert.ok(isCompressed('5cb46ddd903fc2c9976ff881df9273c9.wav'));
+ assert.ok(isCompressed('cd21514d0531fdffb22204e0ec5ed84a.svg'));
- t.notOk(isCompressed('0b2e50ca4107ce57416e2ceb840a6347.jpg'));
- t.notOk(isCompressed('5c8826d846c06dddeb77590e8792fb7d.png'));
-
- t.end();
- });
+ assert.ok(!isCompressed('0b2e50ca4107ce57416e2ceb840a6347.jpg'));
+ assert.ok(!isCompressed('5c8826d846c06dddeb77590e8792fb7d.png'));
});
diff --git a/test/integration/tw_conditional_and_loop.js b/test/integration/tw_conditional_and_loop.js
index 05efbde4..69bb7432 100644
--- a/test/integration/tw_conditional_and_loop.js
+++ b/test/integration/tw_conditional_and_loop.js
@@ -1,6 +1,6 @@
const fs = require('fs');
const path = require('path');
-const {test} = require('tap');
+const {test} = require('node:test');
const VirtualMachine = require('../../src/virtual-machine');
const Scratch = require('../../src/extension-support/tw-extension-api-common');
@@ -139,7 +139,7 @@ class TestExtensionUsingStartBranch {
for (const Extension of [TestExtensionUsingReturn, TestExtensionUsingStartBranch]) {
for (const compilerEnabled of [false, true]) {
- test(`CONDITIONAL - ${Extension.name} - ${compilerEnabled ? 'compiled' : 'interpreted'}`, t => {
+ test(`CONDITIONAL - ${Extension.name} - ${compilerEnabled ? 'compiled' : 'interpreted'}`, (t, done) => {
t.plan(1);
const vm = new VirtualMachine();
@@ -148,7 +148,7 @@ for (const Extension of [TestExtensionUsingReturn, TestExtensionUsingStartBranch
});
vm.extensionManager.addBuiltinExtension('loopsAndThings', Extension);
vm.runtime.on('COMPILE_ERROR', () => {
- t.fail('Compile error');
+ t.assert.fail('Compile error');
});
vm.loadProject(fs.readFileSync(path.join(__dirname, '../fixtures/tw-conditional.sb3'))).then(() => {
@@ -158,10 +158,10 @@ for (const Extension of [TestExtensionUsingReturn, TestExtensionUsingStartBranch
okayCount++;
} else if (text === 'end') {
vm.quit();
- t.equal(okayCount, 5);
- t.end();
+ t.assert.strictEqual(okayCount, 5);
+ done();
} else {
- t.fail(`Unexpected text: ${text}`);
+ t.assert.fail(`Unexpected text: ${text}`);
}
});
@@ -170,7 +170,7 @@ for (const Extension of [TestExtensionUsingReturn, TestExtensionUsingStartBranch
});
});
- test(`LOOP - ${Extension.name} - ${compilerEnabled ? 'compiled' : 'interpreted'}`, t => {
+ test(`LOOP - ${Extension.name} - ${compilerEnabled ? 'compiled' : 'interpreted'}`, (t, done) => {
t.plan(1);
const vm = new VirtualMachine();
@@ -179,14 +179,14 @@ for (const Extension of [TestExtensionUsingReturn, TestExtensionUsingStartBranch
});
vm.extensionManager.addBuiltinExtension('loopsAndThings', Extension);
vm.runtime.on('COMPILE_ERROR', () => {
- t.fail('Compile error');
+ t.assert.fail('Compile error');
});
vm.loadProject(fs.readFileSync(path.join(__dirname, '../fixtures/tw-loop.sb3'))).then(() => {
vm.runtime.on('SAY', (target, type, text) => {
vm.quit();
- t.equal(text, 'a 3 b 12 c 48 frames 64');
- t.end();
+ t.assert.strictEqual(text, 'a 3 b 12 c 48 frames 64');
+ done();
});
vm.greenFlag();
@@ -194,7 +194,7 @@ for (const Extension of [TestExtensionUsingReturn, TestExtensionUsingStartBranch
});
});
- test(`beyond branchCount - ${Extension.name} - ${compilerEnabled ? 'compiled' : 'interpreted'}`, t => {
+ test(`beyond branchCount - ${Extension.name} - ${compilerEnabled ? 'compiled' : 'interpreted'}`, (t, done) => {
t.plan(1);
const vm = new VirtualMachine();
@@ -203,16 +203,16 @@ for (const Extension of [TestExtensionUsingReturn, TestExtensionUsingStartBranch
});
vm.extensionManager.addBuiltinExtension('loopsAndThings', Extension);
vm.runtime.on('COMPILE_ERROR', () => {
- t.fail('Compile error');
+ t.assert.fail('Compile error');
});
vm.loadProject(fs.readFileSync(path.join(__dirname, '../fixtures/tw-beyond-branchCount.sb3'))).then(() => {
vm.runtime.on('SAY', (target, type, text) => {
if (text === 'BeyondBranchCount') {
- t.pass('BeyondBranchCount');
+ t.assert.ok(true, 'BeyondBranchCount');
} else if (text === 'end') {
vm.quit();
- t.end();
+ done();
}
});
diff --git a/test/integration/tw_default_extension_url.js b/test/integration/tw_default_extension_url.js
index 2dd6573b..ca7b034d 100644
--- a/test/integration/tw_default_extension_url.js
+++ b/test/integration/tw_default_extension_url.js
@@ -1,9 +1,8 @@
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const VirtualMachine = require('../../src/virtual-machine');
-test('Loading project uses default extension URLs', t => {
- t.plan(1);
-
+test('Loading project uses default extension URLs', async () => {
const vm = new VirtualMachine();
const events = [];
vm.securityManager.canLoadExtensionFromProject = url => {
@@ -15,7 +14,7 @@ test('Loading project uses default extension URLs', t => {
return Promise.resolve();
};
- vm.loadProject({
+ await vm.loadProject({
targets: [
{
isStage: true,
@@ -91,14 +90,11 @@ test('Loading project uses default extension URLs', t => {
vm: '0.2.0',
agent: ''
}
- }).then(() => {
- t.same(events, [
- 'canLoadExtensionFromProject https://extensions.turbowarp.org/lab/text.js',
- 'loadExtensionURL https://extensions.turbowarp.org/lab/text.js',
- 'canLoadExtensionFromProject https://example.com/box2d.js',
- 'loadExtensionURL https://example.com/box2d.js'
- ]);
-
- t.end();
});
+ assert.deepEqual(events, [
+ 'canLoadExtensionFromProject https://extensions.turbowarp.org/lab/text.js',
+ 'loadExtensionURL https://extensions.turbowarp.org/lab/text.js',
+ 'canLoadExtensionFromProject https://example.com/box2d.js',
+ 'loadExtensionURL https://example.com/box2d.js'
+ ]);
});
diff --git a/test/integration/tw_deterministic_sb3.js b/test/integration/tw_deterministic_sb3.js
index 1e903eb0..c65076eb 100644
--- a/test/integration/tw_deterministic_sb3.js
+++ b/test/integration/tw_deterministic_sb3.js
@@ -1,14 +1,13 @@
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const VM = require('../../src/virtual-machine');
-test('saveProjectSb3 is deterministic over time', t => {
+test('saveProjectSb3 is deterministic over time', async () => {
const vm = new VM();
- Promise.all([
+ const [a, b] = await Promise.all([
vm.saveProjectSb3('nodebuffer'),
// Zip modification time is only accurate to the second
new Promise(resolve => setTimeout(resolve, 1000)).then(() => vm.saveProjectSb3('nodebuffer'))
- ]).then(([a, b]) => {
- t.same(a, b);
- t.end();
- });
+ ]);
+ assert.deepEqual(a, b);
});
diff --git a/test/integration/tw_edge_activated_hat_returns_promise.js b/test/integration/tw_edge_activated_hat_returns_promise.js
index c24386e8..b8e0e553 100644
--- a/test/integration/tw_edge_activated_hat_returns_promise.js
+++ b/test/integration/tw_edge_activated_hat_returns_promise.js
@@ -1,22 +1,19 @@
const VM = require('../../src/virtual-machine');
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const fs = require('fs');
const path = require('path');
const compilerAndInterpreter = (name, callback) => {
- test(`${name} - interpreted`, t => {
- callback(t, {
- enabled: false
- });
- });
- test(`${name} - compiled`, t => {
- callback(t, {
- enabled: true
- });
- });
+ test(`${name} - interpreted`, () => callback({
+ enabled: false
+ }));
+ test(`${name} - compiled`, () => callback({
+ enabled: true
+ }));
};
-compilerAndInterpreter('edge activated hats returning promises work properly', async (t, co) => {
+compilerAndInterpreter('edge activated hats returning promises work properly', async co => {
const vm = new VM();
vm.setCompilerOptions(co);
@@ -44,28 +41,26 @@ compilerAndInterpreter('edge activated hats returning promises work properly', a
hatValue = false;
await step(10);
- t.equal(sayCounter, 0);
+ assert.strictEqual(sayCounter, 0);
hatValue = true;
await step();
// promise can't resolve in this tick, so block shouldn't run yet
- t.equal(sayCounter, 0);
+ assert.strictEqual(sayCounter, 0);
await step();
- t.equal(sayCounter, 1);
+ assert.strictEqual(sayCounter, 1);
await step(10);
- t.equal(sayCounter, 1);
+ assert.strictEqual(sayCounter, 1);
hatValue = false;
await step(10);
- t.equal(sayCounter, 1);
+ assert.strictEqual(sayCounter, 1);
hatValue = true;
await step();
- t.equal(sayCounter, 1);
+ assert.strictEqual(sayCounter, 1);
await step();
- t.equal(sayCounter, 2);
+ assert.strictEqual(sayCounter, 2);
await step(10);
- t.equal(sayCounter, 2);
-
- t.end();
+ assert.strictEqual(sayCounter, 2);
});
diff --git a/test/integration/tw_extension_and_block_xml.js b/test/integration/tw_extension_and_block_xml.js
index 673fe339..8df1c49f 100644
--- a/test/integration/tw_extension_and_block_xml.js
+++ b/test/integration/tw_extension_and_block_xml.js
@@ -1,7 +1,8 @@
const fs = require('fs');
const pathUtil = require('path');
const htmlparser = require('htmlparser2');
-const {test} = require('tap');
+const {test} = require('node:test');
+const assert = require('node:assert');
const VirtualMachine = require('../../src/virtual-machine');
const Runtime = require('../../src/engine/runtime');
const ArgumentType = require('../../src/extension-support/argument-type');
@@ -66,7 +67,7 @@ const baseExtensionInfo = {
}
};
-test('XML escaped in Runtime.getBlocksXML()', t => {
+test('XML escaped in Runtime.getBlocksXML()', () => {
// While these changes will make the extension unusable in a real editor environment, we still
// want to make sure that these fields are actually being escaped.
const mangledExtension = JSON.parse(JSON.stringify(baseExtensionInfo));
@@ -80,14 +81,14 @@ test('XML escaped in Runtime.getBlocksXML()', t => {
});
const xmlList = vm.runtime.getBlocksXML();
- t.type(xmlList, Array, 'getBlocksXML returns array');
- t.equal(xmlList.length, 1, 'array has 1 item');
+ assert.ok(xmlList instanceof Array, 'getBlocksXML returns array');
+ assert.strictEqual(xmlList.length, 1, 'array has 1 item');
const xmlEntry = xmlList[0];
- t.equal(xmlEntry.id, `xmltest`, 'id worked');
+ assert.strictEqual(xmlEntry.id, `xmltest`, 'id worked');
const parsedXml = htmlparser.parseDOM(xmlEntry.xml);
- t.equal(parsedXml.length, 1, 'xml has 1 root node');
+ assert.strictEqual(parsedXml.length, 1, 'xml has 1 root node');
/*
Expected XML structure:
@@ -112,52 +113,64 @@ test('XML escaped in Runtime.getBlocksXML()', t => {
*/
const category = parsedXml[0];
- t.equal(category.name, 'category', 'has ');
- t.equal(category.attribs.name, '<>"'&& Name', 'escaped category name');
- t.equal(category.attribs.id, 'xmltest', 'category id');
- t.equal(category.attribs.colour, '<"'&amp;color1>', 'escaped category color');
- t.equal(category.attribs.secondarycolour, '<"'&amp;color2>', 'escaped category color 2');
- t.equal(category.attribs.iconuri, 'data:<>&"' category icon', 'escaped category icon');
- t.equal(category.children.length, 3, 'category has 3 children');
+ assert.strictEqual(category.name, 'category', 'has ');
+ assert.strictEqual(category.attribs.name, '<>"'&& Name', 'escaped category name');
+ assert.strictEqual(category.attribs.id, 'xmltest', 'category id');
+ assert.strictEqual(category.attribs.colour, '<"'&amp;color1>', 'escaped category color');
+ assert.strictEqual(
+ category.attribs.secondarycolour,
+ '<"'&amp;color2>',
+ 'escaped category color 2'
+ );
+ assert.strictEqual(
+ category.attribs.iconuri,
+ 'data:<>&"' category icon',
+ 'escaped category icon'
+ );
+ assert.strictEqual(category.children.length, 3, 'category has 3 children');
// Check docsURI
const docsButton = category.children[0];
- t.equal(docsButton.name, 'button', 'has docs