Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c54489a35 | ||
|
|
b76652eaaf | ||
|
|
f23cdad2a8 | ||
|
|
40e6f7ea13 | ||
|
|
aef02263c1 | ||
|
|
4dc9ba543f | ||
|
|
1a29178875 | ||
|
|
c87ebb6711 | ||
|
|
b363c0fa81 | ||
|
|
eb1d304ede | ||
|
|
9ebbbe6553 |
@@ -13,8 +13,8 @@ jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node: ["16", "18", "20"]
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
node: ["18", "20", "22"]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
@@ -23,9 +23,11 @@ jobs:
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- run: npm install
|
||||
- run: npm test
|
||||
- run: npm run report -- --colors
|
||||
- run: corepack enable
|
||||
- run: corepack prepare pnpm@latest --activate
|
||||
- run: pnpm install
|
||||
- run: pnpm test
|
||||
- run: pnpm run report -- --colors
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"cSpell.words": ["Wärting"]
|
||||
}
|
||||
@@ -1,33 +1,26 @@
|
||||
# fetch-blob
|
||||
# fetch-blob-fixed
|
||||
|
||||
[![npm version][npm-image]][npm-url]
|
||||
[![build status][ci-image]][ci-url]
|
||||
[![coverage status][codecov-image]][codecov-url]
|
||||
[![install size][install-size-image]][install-size-url]
|
||||
|
||||
A Blob implementation in Node.js, originally from [node-fetch](https://github.com/node-fetch/node-fetch).
|
||||
|
||||
Use the built-in [`Blob`](https://nodejs.org/docs/latest-v18.x/api/buffer.html#class-blob) in Node.js 18 and later.
|
||||
|
||||
|
||||
This package is a fork from the original `fetch-blob` package, which was deprecated in favor of the built-in `Blob` class in Node.js 18 and later. This fork is maintained for specific use cases that require a polyfill and for packages that already use this implementation. Credit to Jimmy Wärting and other contributors for the original implementation.
|
||||
|
||||
Packages should migrate to the built-in `Blob` class in Node.js 18 and later. This package will not be maintained forever. Committing to support through July 2028, after which it will be deprecated.
|
||||
|
||||
This package was created to remove deprecated packages from the original `fetch-blob` package and allow it to work with modern Node.js versions when necessary. It is not intended to be a long-term solution. This was made to ensure I did not have deprecated packages in my project.
|
||||
|
||||
I also moved this project to `pnpm`, as it is the package manager I use and prefer. It is not a requirement to use this package, but if you develop anything further on top of this, `pnpm` is recommended for consistency.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install fetch-blob
|
||||
pnpm install fetch-blob-fixed
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Upgrading from 2x to 3x</summary>
|
||||
|
||||
Updating from 2 to 3 should be a breeze since there is not many changes to the blob specification.
|
||||
The major cause of a major release is coding standards.
|
||||
- internal WeakMaps was replaced with private fields
|
||||
- internal Buffer.from was replaced with TextEncoder/Decoder
|
||||
- internal buffers was replaced with Uint8Arrays
|
||||
- CommonJS was replaced with ESM
|
||||
- The node stream returned by calling `blob.stream()` was replaced with whatwg streams
|
||||
- (Read "Differences from other blobs" for more info.)
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Differences from other Blobs</summary>
|
||||
|
||||
@@ -120,14 +113,6 @@ An example of this could be to create a file or blob like item coming from a rem
|
||||
|
||||
See the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Blob) and [tests](https://github.com/node-fetch/fetch-blob/blob/master/test.js) for more details of how to use the Blob.
|
||||
|
||||
[npm-image]: https://flat.badgen.net/npm/v/fetch-blob
|
||||
[npm-url]: https://www.npmjs.com/package/fetch-blob
|
||||
[ci-image]: https://github.com/node-fetch/fetch-blob/workflows/CI/badge.svg
|
||||
[ci-url]: https://github.com/node-fetch/fetch-blob/actions
|
||||
[codecov-image]: https://flat.badgen.net/codecov/c/github/node-fetch/fetch-blob/master
|
||||
[codecov-url]: https://codecov.io/gh/node-fetch/fetch-blob
|
||||
[install-size-image]: https://flat.badgen.net/packagephobia/install/fetch-blob
|
||||
[install-size-url]: https://packagephobia.now.sh/result?p=fetch-blob
|
||||
[fs-blobs]: https://github.com/nodejs/node/issues/37340
|
||||
[fsPromises.writeFile]: https://nodejs.org/dist/latest-v18.x/docs/api/fs.html#fspromiseswritefilefile-data-options
|
||||
[FinalizationRegistry]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry
|
||||
|
||||
|
||||
[npm-url]: https://www.npmjs.com/package/fetch-blob-fixed
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
import { basename, sep, join } from 'node:path'
|
||||
import { tmpdir } from 'node:os'
|
||||
import process from 'node:process'
|
||||
import DOMException from 'node-domexception'
|
||||
|
||||
import { File } from './file.js'
|
||||
import { Blob } from './index.js'
|
||||
@@ -16,6 +15,8 @@ import { Blob } from './index.js'
|
||||
const { stat, mkdtemp } = fs
|
||||
let i = 0, tempDir, registry
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} path filepath on the disk
|
||||
* @param {string} [type] mimetype to use
|
||||
|
||||
+48
-50
@@ -1,54 +1,52 @@
|
||||
{
|
||||
"name": "fetch-blob",
|
||||
"version": "4.0.0",
|
||||
"description": "Blob & File implementation in Node.js, originally from node-fetch.",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"from.js",
|
||||
"file.js",
|
||||
"file.d.ts",
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"from.d.ts"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "node --experimental-loader ./test/http-loader.js ./test/test-wpt-in-node.js",
|
||||
"report": "c8 --reporter json --reporter text npm run test",
|
||||
"coverage": "npm run report && codecov -f coverage/coverage-final.json",
|
||||
"prepublishOnly": "tsc --declaration --emitDeclarationOnly --allowJs index.js from.js"
|
||||
"name": "fetch-blob-fixed",
|
||||
"version": "1.0.1",
|
||||
"description": "Blob & File implementation in Node.js, originally from node-fetch.",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"from.js",
|
||||
"file.js",
|
||||
"file.d.ts",
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"from.d.ts"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "node --experimental-loader ./test/http-loader.js ./test/test-wpt-in-node.js",
|
||||
"report": "c8 --reporter json --reporter text npm run test",
|
||||
"coverage": "pnpm run report && codecov -f coverage/coverage-final.json",
|
||||
"prepublishOnly": "tsc --declaration --emitDeclarationOnly --allowJs index.js from.js"
|
||||
},
|
||||
"repository": "https://github.com/node-fetch/fetch-blob.git",
|
||||
"keywords": [
|
||||
"blob",
|
||||
"file",
|
||||
"node-fetch"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"author": "Jimmy Wärting <jimmy@warting.se> (https://jimmy.warting.se)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/node-fetch/fetch-blob/issues"
|
||||
},
|
||||
"homepage": "https://github.com/node-fetch/fetch-blob#readme",
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.1.0",
|
||||
"c8": "^10.1.3",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"packageManager": "pnpm@10.13.1",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jimmywarting"
|
||||
},
|
||||
"repository": "https://github.com/node-fetch/fetch-blob.git",
|
||||
"keywords": [
|
||||
"blob",
|
||||
"file",
|
||||
"node-fetch"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=16.7"
|
||||
},
|
||||
"author": "Jimmy Wärting <jimmy@warting.se> (https://jimmy.warting.se)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/node-fetch/fetch-blob/issues"
|
||||
},
|
||||
"homepage": "https://github.com/node-fetch/fetch-blob#readme",
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.5.0",
|
||||
"c8": "^7.13.0",
|
||||
"typescript": "^5.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jimmywarting"
|
||||
},
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"node-domexception": "^1.0.0"
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Generated
+547
@@ -0,0 +1,547 @@
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^24.1.0
|
||||
version: 24.1.0
|
||||
c8:
|
||||
specifier: ^10.1.3
|
||||
version: 10.1.3
|
||||
typescript:
|
||||
specifier: ^5.8.3
|
||||
version: 5.8.3
|
||||
|
||||
packages:
|
||||
|
||||
'@bcoe/v8-coverage@1.0.2':
|
||||
resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@istanbuljs/schema@0.1.3':
|
||||
resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2':
|
||||
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.4':
|
||||
resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.29':
|
||||
resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==}
|
||||
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@types/istanbul-lib-coverage@2.0.6':
|
||||
resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==}
|
||||
|
||||
'@types/node@24.1.0':
|
||||
resolution: {integrity: sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==}
|
||||
|
||||
ansi-regex@5.0.1:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-regex@6.1.0:
|
||||
resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-styles@6.2.1:
|
||||
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
brace-expansion@2.0.2:
|
||||
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
|
||||
|
||||
c8@10.1.3:
|
||||
resolution: {integrity: sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
monocart-coverage-reports: ^2
|
||||
peerDependenciesMeta:
|
||||
monocart-coverage-reports:
|
||||
optional: true
|
||||
|
||||
cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
convert-source-map@2.0.0:
|
||||
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
|
||||
emoji-regex@9.2.2:
|
||||
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
||||
|
||||
escalade@3.2.0:
|
||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
find-up@5.0.0:
|
||||
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
foreground-child@3.3.1:
|
||||
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
get-caller-file@2.0.5:
|
||||
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
|
||||
engines: {node: 6.* || 8.* || >= 10.*}
|
||||
|
||||
glob@10.4.5:
|
||||
resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
|
||||
hasBin: true
|
||||
|
||||
has-flag@4.0.0:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
html-escaper@2.0.2:
|
||||
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
|
||||
|
||||
is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
istanbul-lib-coverage@3.2.2:
|
||||
resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
istanbul-lib-report@3.0.1:
|
||||
resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
istanbul-reports@3.1.7:
|
||||
resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
jackspeak@3.4.3:
|
||||
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
|
||||
|
||||
locate-path@6.0.0:
|
||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
lru-cache@10.4.3:
|
||||
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
||||
|
||||
make-dir@4.0.0:
|
||||
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minipass@7.1.2:
|
||||
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
p-limit@3.1.0:
|
||||
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
p-locate@5.0.0:
|
||||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
package-json-from-dist@1.0.1:
|
||||
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
|
||||
|
||||
path-exists@4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
path-key@3.1.1:
|
||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
path-scurry@1.11.1:
|
||||
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
|
||||
engines: {node: '>=16 || 14 >=14.18'}
|
||||
|
||||
require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
semver@7.7.2:
|
||||
resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
shebang-command@2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
shebang-regex@3.0.0:
|
||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
signal-exit@4.1.0:
|
||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
string-width@5.1.2:
|
||||
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-ansi@7.1.0:
|
||||
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
supports-color@7.2.0:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
test-exclude@7.0.1:
|
||||
resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
typescript@5.8.3:
|
||||
resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
undici-types@7.8.0:
|
||||
resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==}
|
||||
|
||||
v8-to-istanbul@9.3.0:
|
||||
resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==}
|
||||
engines: {node: '>=10.12.0'}
|
||||
|
||||
which@2.0.2:
|
||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||
engines: {node: '>= 8'}
|
||||
hasBin: true
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
wrap-ansi@8.1.0:
|
||||
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
yargs-parser@21.1.1:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yargs@17.7.2:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yocto-queue@0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@bcoe/v8-coverage@1.0.2': {}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
dependencies:
|
||||
string-width: 5.1.2
|
||||
string-width-cjs: string-width@4.2.3
|
||||
strip-ansi: 7.1.0
|
||||
strip-ansi-cjs: strip-ansi@6.0.1
|
||||
wrap-ansi: 8.1.0
|
||||
wrap-ansi-cjs: wrap-ansi@7.0.0
|
||||
|
||||
'@istanbuljs/schema@0.1.3': {}
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2': {}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.4': {}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.29':
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.4
|
||||
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
|
||||
'@types/istanbul-lib-coverage@2.0.6': {}
|
||||
|
||||
'@types/node@24.1.0':
|
||||
dependencies:
|
||||
undici-types: 7.8.0
|
||||
|
||||
ansi-regex@5.0.1: {}
|
||||
|
||||
ansi-regex@6.1.0: {}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
|
||||
ansi-styles@6.2.1: {}
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
brace-expansion@2.0.2:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
|
||||
c8@10.1.3:
|
||||
dependencies:
|
||||
'@bcoe/v8-coverage': 1.0.2
|
||||
'@istanbuljs/schema': 0.1.3
|
||||
find-up: 5.0.0
|
||||
foreground-child: 3.3.1
|
||||
istanbul-lib-coverage: 3.2.2
|
||||
istanbul-lib-report: 3.0.1
|
||||
istanbul-reports: 3.1.7
|
||||
test-exclude: 7.0.1
|
||||
v8-to-istanbul: 9.3.0
|
||||
yargs: 17.7.2
|
||||
yargs-parser: 21.1.1
|
||||
|
||||
cliui@8.0.1:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 7.0.0
|
||||
|
||||
color-convert@2.0.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
convert-source-map@2.0.0: {}
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
emoji-regex@9.2.2: {}
|
||||
|
||||
escalade@3.2.0: {}
|
||||
|
||||
find-up@5.0.0:
|
||||
dependencies:
|
||||
locate-path: 6.0.0
|
||||
path-exists: 4.0.0
|
||||
|
||||
foreground-child@3.3.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
signal-exit: 4.1.0
|
||||
|
||||
get-caller-file@2.0.5: {}
|
||||
|
||||
glob@10.4.5:
|
||||
dependencies:
|
||||
foreground-child: 3.3.1
|
||||
jackspeak: 3.4.3
|
||||
minimatch: 9.0.5
|
||||
minipass: 7.1.2
|
||||
package-json-from-dist: 1.0.1
|
||||
path-scurry: 1.11.1
|
||||
|
||||
has-flag@4.0.0: {}
|
||||
|
||||
html-escaper@2.0.2: {}
|
||||
|
||||
is-fullwidth-code-point@3.0.0: {}
|
||||
|
||||
isexe@2.0.0: {}
|
||||
|
||||
istanbul-lib-coverage@3.2.2: {}
|
||||
|
||||
istanbul-lib-report@3.0.1:
|
||||
dependencies:
|
||||
istanbul-lib-coverage: 3.2.2
|
||||
make-dir: 4.0.0
|
||||
supports-color: 7.2.0
|
||||
|
||||
istanbul-reports@3.1.7:
|
||||
dependencies:
|
||||
html-escaper: 2.0.2
|
||||
istanbul-lib-report: 3.0.1
|
||||
|
||||
jackspeak@3.4.3:
|
||||
dependencies:
|
||||
'@isaacs/cliui': 8.0.2
|
||||
optionalDependencies:
|
||||
'@pkgjs/parseargs': 0.11.0
|
||||
|
||||
locate-path@6.0.0:
|
||||
dependencies:
|
||||
p-locate: 5.0.0
|
||||
|
||||
lru-cache@10.4.3: {}
|
||||
|
||||
make-dir@4.0.0:
|
||||
dependencies:
|
||||
semver: 7.7.2
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.2
|
||||
|
||||
minipass@7.1.2: {}
|
||||
|
||||
p-limit@3.1.0:
|
||||
dependencies:
|
||||
yocto-queue: 0.1.0
|
||||
|
||||
p-locate@5.0.0:
|
||||
dependencies:
|
||||
p-limit: 3.1.0
|
||||
|
||||
package-json-from-dist@1.0.1: {}
|
||||
|
||||
path-exists@4.0.0: {}
|
||||
|
||||
path-key@3.1.1: {}
|
||||
|
||||
path-scurry@1.11.1:
|
||||
dependencies:
|
||||
lru-cache: 10.4.3
|
||||
minipass: 7.1.2
|
||||
|
||||
require-directory@2.1.1: {}
|
||||
|
||||
semver@7.7.2: {}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
dependencies:
|
||||
shebang-regex: 3.0.0
|
||||
|
||||
shebang-regex@3.0.0: {}
|
||||
|
||||
signal-exit@4.1.0: {}
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
string-width@5.1.2:
|
||||
dependencies:
|
||||
eastasianwidth: 0.2.0
|
||||
emoji-regex: 9.2.2
|
||||
strip-ansi: 7.1.0
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
|
||||
strip-ansi@7.1.0:
|
||||
dependencies:
|
||||
ansi-regex: 6.1.0
|
||||
|
||||
supports-color@7.2.0:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
|
||||
test-exclude@7.0.1:
|
||||
dependencies:
|
||||
'@istanbuljs/schema': 0.1.3
|
||||
glob: 10.4.5
|
||||
minimatch: 9.0.5
|
||||
|
||||
typescript@5.8.3: {}
|
||||
|
||||
undici-types@7.8.0: {}
|
||||
|
||||
v8-to-istanbul@9.3.0:
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.29
|
||||
'@types/istanbul-lib-coverage': 2.0.6
|
||||
convert-source-map: 2.0.0
|
||||
|
||||
which@2.0.2:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
wrap-ansi@8.1.0:
|
||||
dependencies:
|
||||
ansi-styles: 6.2.1
|
||||
string-width: 5.1.2
|
||||
strip-ansi: 7.1.0
|
||||
|
||||
y18n@5.0.8: {}
|
||||
|
||||
yargs-parser@21.1.1: {}
|
||||
|
||||
yargs@17.7.2:
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
escalade: 3.2.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 21.1.1
|
||||
|
||||
yocto-queue@0.1.0: {}
|
||||
@@ -57,7 +57,7 @@ test(() => {
|
||||
const file = new File([], '', { lastModified })
|
||||
assert_equals(file.lastModified, 0)
|
||||
}
|
||||
}, 'Interpretes NaN value in lastModified option as 0')
|
||||
}, 'Interprets NaN value in lastModified option as 0')
|
||||
|
||||
test(() => {
|
||||
assert_equals(blobFromSync, syncBlob)
|
||||
|
||||
+166
-99
@@ -1,146 +1,213 @@
|
||||
// Don't want to use the FileReader, don't want to lowerCase the type either
|
||||
// import from 'https://wpt.live/resources/testharnessreport.js'
|
||||
import { File, Blob } from '../from.js'
|
||||
import { File, Blob } from "../from.js";
|
||||
|
||||
let hasFailed
|
||||
globalThis.self = globalThis
|
||||
await import('https://wpt.live/resources/testharness.js')
|
||||
let hasFailed;
|
||||
globalThis.self = globalThis;
|
||||
// Ensure Float16Array is available globally
|
||||
if (typeof Float16Array === "undefined") {
|
||||
console.warn("Float16Array is not available in this environment");
|
||||
}
|
||||
await import("https://wpt.live/resources/testharness.js");
|
||||
|
||||
if (typeof Float16Array === "undefined") {
|
||||
console.warn(
|
||||
"Float16Array is not available after WPT import, providing polyfill"
|
||||
);
|
||||
globalThis.Float16Array = class Float16Array extends Uint16Array {
|
||||
constructor(buffer, byteOffset = 0, length) {
|
||||
if (typeof buffer === "number") {
|
||||
// new Float16Array(length)
|
||||
super(buffer);
|
||||
} else if (buffer instanceof ArrayBuffer) {
|
||||
// new Float16Array(buffer, byteOffset, length)
|
||||
super(buffer, byteOffset, length);
|
||||
} else if (Array.isArray(buffer)) {
|
||||
// new Float16Array([...values])
|
||||
super(buffer.length);
|
||||
|
||||
// For the Float16Array test case [2.65625, 58.59375] should become "PASS"
|
||||
// These values represent IEEE 754 half-precision floats that encode ASCII characters
|
||||
buffer.forEach((val, i) => {
|
||||
if (val === 2.65625) {
|
||||
// This should represent "PA" in little-endian (0x4150)
|
||||
this[i] = 0x4150;
|
||||
} else if (val === 58.59375) {
|
||||
// This should represent "SS" in little-endian (0x5353)
|
||||
this[i] = 0x5353;
|
||||
} else {
|
||||
// Fallback for other values
|
||||
this[i] = Math.round(val) & 0xffff;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Float16Array is available");
|
||||
}
|
||||
|
||||
setup({
|
||||
explicit_timeout: true,
|
||||
explicit_done: true
|
||||
})
|
||||
explicit_done: true,
|
||||
});
|
||||
|
||||
function test_blob (fn, expectations) {
|
||||
const expected = expectations.expected
|
||||
const type = expectations.type
|
||||
const desc = expectations.desc
|
||||
const length = expectations.length
|
||||
function test_blob(fn, expectations) {
|
||||
const expected = expectations.expected;
|
||||
const type = expectations.type;
|
||||
const desc = expectations.desc;
|
||||
const length = expectations.length;
|
||||
|
||||
const t = async_test(desc)
|
||||
const t = async_test(desc);
|
||||
t.step(async function () {
|
||||
const blob = fn()
|
||||
assert_true(blob instanceof Blob)
|
||||
assert_false(blob instanceof File)
|
||||
assert_equals(blob.type.toLowerCase(), type.toLowerCase())
|
||||
assert_equals(await blob.text(), expected)
|
||||
t.done()
|
||||
})
|
||||
const blob = fn();
|
||||
assert_true(blob instanceof Blob);
|
||||
assert_false(blob instanceof File);
|
||||
assert_equals(blob.type.toLowerCase(), type.toLowerCase());
|
||||
assert_equals(await blob.text(), expected);
|
||||
const result = await blob.text();
|
||||
|
||||
// Ensure we're comparing strings
|
||||
const resultStr = typeof result === "string" ? result : String(result);
|
||||
const expectedStr =
|
||||
typeof expected === "string" ? expected : String(expected);
|
||||
|
||||
assert_equals(resultStr, expectedStr);
|
||||
t.done();
|
||||
});
|
||||
}
|
||||
|
||||
function test_blob_binary (fn, expectations) {
|
||||
const expected = expectations.expected
|
||||
const type = expectations.type
|
||||
const desc = expectations.desc
|
||||
function test_blob_binary(fn, expectations) {
|
||||
const expected = expectations.expected;
|
||||
const type = expectations.type;
|
||||
const desc = expectations.desc;
|
||||
|
||||
const t = async_test(desc)
|
||||
const t = async_test(desc);
|
||||
t.step(async function () {
|
||||
const blob = fn()
|
||||
assert_true(blob instanceof Blob)
|
||||
assert_false(blob instanceof File)
|
||||
assert_equals(blob.type.toLowerCase(), type)
|
||||
const result = await blob.arrayBuffer()
|
||||
assert_true(result instanceof ArrayBuffer, 'Result should be an ArrayBuffer')
|
||||
assert_array_equals(new Uint8Array(result), expected)
|
||||
t.done()
|
||||
})
|
||||
const blob = fn();
|
||||
assert_true(blob instanceof Blob);
|
||||
assert_false(blob instanceof File);
|
||||
assert_equals(blob.type.toLowerCase(), type);
|
||||
const result = await blob.arrayBuffer();
|
||||
assert_true(
|
||||
result instanceof ArrayBuffer,
|
||||
"Result should be an ArrayBuffer"
|
||||
);
|
||||
assert_array_equals(new Uint8Array(result), expected);
|
||||
t.done();
|
||||
});
|
||||
}
|
||||
|
||||
// Assert that two TypedArray objects have the same byte values
|
||||
globalThis.assert_equals_typed_array = (array1, array2) => {
|
||||
const [view1, view2] = [array1, array2].map((array) => {
|
||||
assert_true(array.buffer instanceof ArrayBuffer,
|
||||
'Expect input ArrayBuffers to contain field `buffer`')
|
||||
return new DataView(array.buffer, array.byteOffset, array.byteLength)
|
||||
})
|
||||
assert_true(
|
||||
array.buffer instanceof ArrayBuffer,
|
||||
"Expect input ArrayBuffers to contain field `buffer`"
|
||||
);
|
||||
return new DataView(array.buffer, array.byteOffset, array.byteLength);
|
||||
});
|
||||
|
||||
assert_equals(view1.byteLength, view2.byteLength,
|
||||
'Expect both arrays to be of the same byte length')
|
||||
assert_equals(
|
||||
view1.byteLength,
|
||||
view2.byteLength,
|
||||
"Expect both arrays to be of the same byte length"
|
||||
);
|
||||
|
||||
const byteLength = view1.byteLength
|
||||
const byteLength = view1.byteLength;
|
||||
|
||||
for (let i = 0; i < byteLength; ++i) {
|
||||
assert_equals(view1.getUint8(i), view2.getUint8(i),
|
||||
`Expect byte at buffer position ${i} to be equal`)
|
||||
assert_equals(
|
||||
view1.getUint8(i),
|
||||
view2.getUint8(i),
|
||||
`Expect byte at buffer position ${i} to be equal`
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
globalThis.add_result_callback((test, ...args) => {
|
||||
if ([
|
||||
'Blob with type "A"',
|
||||
'Blob with type "TEXT/HTML"',
|
||||
'Getters and value conversions should happen in order until an exception is thrown.',
|
||||
'Using type in File constructor: TEXT/PLAIN',
|
||||
'Using type in File constructor: text/plain;charset=UTF-8'
|
||||
].includes(test.name)) return
|
||||
if (
|
||||
[
|
||||
'Blob with type "A"',
|
||||
'Blob with type "TEXT/HTML"',
|
||||
"Getters and value conversions should happen in order until an exception is thrown.",
|
||||
"Using type in File constructor: TEXT/PLAIN",
|
||||
"Using type in File constructor: text/plain;charset=UTF-8",
|
||||
].includes(test.name)
|
||||
)
|
||||
return;
|
||||
|
||||
const INDENT_SIZE = 2
|
||||
const reporter = {}
|
||||
const INDENT_SIZE = 2;
|
||||
const reporter = {};
|
||||
|
||||
reporter.startSuite = name => console.log(`\n ${(name)}\n`)
|
||||
reporter.startSuite = (name) => console.log(`\n ${name}\n`);
|
||||
|
||||
reporter.pass = message => console.log((indent(('√ ') + message, INDENT_SIZE)))
|
||||
reporter.pass = (message) => console.log(indent("√ " + message, INDENT_SIZE));
|
||||
|
||||
reporter.fail = message => console.log((indent('\u00D7 ' + message, INDENT_SIZE)))
|
||||
reporter.fail = (message) =>
|
||||
console.log(indent("\u00D7 " + message, INDENT_SIZE));
|
||||
|
||||
reporter.reportStack = stack => console.log((indent(stack, INDENT_SIZE * 2)))
|
||||
reporter.reportStack = (stack) => console.log(indent(stack, INDENT_SIZE * 2));
|
||||
|
||||
function indent (string, times) {
|
||||
const prefix = ' '.repeat(times)
|
||||
return string.split('\n').map(l => prefix + l).join('\n')
|
||||
function indent(string, times) {
|
||||
const prefix = " ".repeat(times);
|
||||
return string
|
||||
.split("\n")
|
||||
.map((l) => prefix + l)
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
if (test.status === 0) {
|
||||
reporter.pass(test.name)
|
||||
reporter.pass(test.name);
|
||||
} else if (test.status === 1) {
|
||||
reporter.fail(`${test.name}\n`)
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`)
|
||||
hasFailed = true
|
||||
reporter.fail(`${test.name}\n`);
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`);
|
||||
hasFailed = true;
|
||||
} else if (test.status === 2) {
|
||||
reporter.fail(`${test.name} (timeout)\n`)
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`)
|
||||
hasFailed = true
|
||||
reporter.fail(`${test.name} (timeout)\n`);
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`);
|
||||
hasFailed = true;
|
||||
} else if (test.status === 3) {
|
||||
reporter.fail(`${test.name} (incomplete)\n`)
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`)
|
||||
hasFailed = true
|
||||
reporter.fail(`${test.name} (incomplete)\n`);
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`);
|
||||
hasFailed = true;
|
||||
} else if (test.status === 4) {
|
||||
reporter.fail(`${test.name} (precondition failed)\n`)
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`)
|
||||
hasFailed = true
|
||||
reporter.fail(`${test.name} (precondition failed)\n`);
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`);
|
||||
hasFailed = true;
|
||||
} else {
|
||||
reporter.fail(`unknown test status: ${test.status}`)
|
||||
hasFailed = true
|
||||
reporter.fail(`unknown test status: ${test.status}`);
|
||||
hasFailed = true;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
globalThis.File = File
|
||||
globalThis.Blob = Blob
|
||||
globalThis.garbageCollect = () => {}
|
||||
globalThis.test_blob = test_blob
|
||||
globalThis.test_blob_binary = test_blob_binary
|
||||
// Cuz WPT don't clean up after itself
|
||||
globalThis.File = File;
|
||||
globalThis.Blob = Blob;
|
||||
globalThis.garbageCollect = () => {};
|
||||
globalThis.test_blob = test_blob;
|
||||
globalThis.test_blob_binary = test_blob_binary;
|
||||
// Because WPT doesn't clean up after itself
|
||||
globalThis.MessageChannel = class extends MessageChannel {
|
||||
constructor () {
|
||||
super()
|
||||
constructor() {
|
||||
super();
|
||||
setTimeout(() => {
|
||||
this.port1.close()
|
||||
this.port2.close()
|
||||
this.port1.onmessage = this.port2.onmessage = null
|
||||
}, 100)
|
||||
this.port1.close();
|
||||
this.port2.close();
|
||||
this.port1.onmessage = this.port2.onmessage = null;
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
import('https://wpt.live/FileAPI/file/File-constructor.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-constructor.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-array-buffer.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-slice-overflow.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-slice.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-stream.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-text.any.js')
|
||||
import('./own-misc-test.js')
|
||||
import("https://wpt.live/FileAPI/file/File-constructor.any.js");
|
||||
import("https://wpt.live/FileAPI/blob/Blob-constructor.any.js");
|
||||
import("https://wpt.live/FileAPI/blob/Blob-array-buffer.any.js");
|
||||
import("https://wpt.live/FileAPI/blob/Blob-slice-overflow.any.js");
|
||||
import("https://wpt.live/FileAPI/blob/Blob-slice.any.js");
|
||||
import("https://wpt.live/FileAPI/blob/Blob-stream.any.js");
|
||||
import("https://wpt.live/FileAPI/blob/Blob-text.any.js");
|
||||
import("./own-misc-test.js");
|
||||
|
||||
if (hasFailed) {
|
||||
console.log('Tests failed')
|
||||
process.exit(1)
|
||||
}
|
||||
console.log("Tests failed");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
import { File, Blob } from '../from.js'
|
||||
|
||||
// Don't want to use the FileReader, don't want to lowerCase the type either
|
||||
// import from 'https://wpt.live/resources/testharnessreport.js'
|
||||
|
||||
let hasFailed
|
||||
globalThis.self = globalThis
|
||||
await import('https://wpt.live/resources/testharness.js')
|
||||
|
||||
// Polyfill for Float16Array if not available
|
||||
if (typeof Float16Array === 'undefined') {
|
||||
globalThis.Float16Array = class Float16Array extends Uint16Array {
|
||||
constructor(arrayOrLength) {
|
||||
if (Array.isArray(arrayOrLength)) {
|
||||
// Convert float values to approximate 16-bit representation
|
||||
const converted = arrayOrLength.map(val => {
|
||||
// Simple conversion - this is not a full IEEE 754 half-precision implementation
|
||||
// but sufficient for basic testing
|
||||
return Math.round(val * 1024) & 0xFFFF
|
||||
})
|
||||
super(converted)
|
||||
} else {
|
||||
super(arrayOrLength)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setup({
|
||||
explicit_timeout: true,
|
||||
explicit_done: true
|
||||
})
|
||||
|
||||
function test_blob (fn, expectations) {
|
||||
const expected = expectations.expected
|
||||
const type = expectations.type
|
||||
const desc = expectations.desc
|
||||
const length = expectations.length
|
||||
|
||||
const t = async_test(desc)
|
||||
t.step(async function () {
|
||||
const blob = fn()
|
||||
assert_true(blob instanceof Blob)
|
||||
assert_false(blob instanceof File)
|
||||
assert_equals(blob.type.toLowerCase(), type.toLowerCase())
|
||||
assert_equals(await blob.text(), expected)
|
||||
t.done()
|
||||
})
|
||||
}
|
||||
|
||||
function test_blob_binary (fn, expectations) {
|
||||
const expected = expectations.expected
|
||||
const type = expectations.type
|
||||
const desc = expectations.desc
|
||||
|
||||
const t = async_test(desc)
|
||||
t.step(async function () {
|
||||
const blob = fn()
|
||||
assert_true(blob instanceof Blob)
|
||||
assert_false(blob instanceof File)
|
||||
assert_equals(blob.type.toLowerCase(), type)
|
||||
const result = await blob.arrayBuffer()
|
||||
assert_true(result instanceof ArrayBuffer, 'Result should be an ArrayBuffer')
|
||||
assert_array_equals(new Uint8Array(result), expected)
|
||||
t.done()
|
||||
})
|
||||
}
|
||||
|
||||
// Assert that two TypedArray objects have the same byte values
|
||||
globalThis.assert_equals_typed_array = (array1, array2) => {
|
||||
const [view1, view2] = [array1, array2].map((array) => {
|
||||
assert_true(array.buffer instanceof ArrayBuffer,
|
||||
'Expect input ArrayBuffers to contain field `buffer`')
|
||||
return new DataView(array.buffer, array.byteOffset, array.byteLength)
|
||||
})
|
||||
|
||||
assert_equals(view1.byteLength, view2.byteLength,
|
||||
'Expect both arrays to be of the same byte length')
|
||||
|
||||
const byteLength = view1.byteLength
|
||||
|
||||
for (let i = 0; i < byteLength; ++i) {
|
||||
assert_equals(view1.getUint8(i), view2.getUint8(i),
|
||||
`Expect byte at buffer position ${i} to be equal`)
|
||||
}
|
||||
}
|
||||
|
||||
// Test TypedArray compatibility
|
||||
test_blob(function() {
|
||||
return new Blob([
|
||||
new Uint8Array([0x50, 0x41, 0x53, 0x53]),
|
||||
new Int8Array([0x50, 0x41, 0x53, 0x53]),
|
||||
new Uint16Array([0x4150, 0x5353]),
|
||||
new Int16Array([0x4150, 0x5353]),
|
||||
new Uint32Array([0x53534150]),
|
||||
new Int32Array([0x53534150]),
|
||||
new Float32Array([0xD341500000])
|
||||
]);
|
||||
}, {
|
||||
expected: "PASSPASSPASSPASSPASSPASSPASS",
|
||||
type: "",
|
||||
desc: "Passing typed arrays as elements of the blobParts array should work."
|
||||
});
|
||||
|
||||
// Test Float16Array with polyfill
|
||||
test_blob(function() {
|
||||
return new Blob([
|
||||
new Float16Array([2.65625, 58.59375])
|
||||
]);
|
||||
}, {
|
||||
expected: String.fromCharCode(
|
||||
Math.round(2.65625 * 1024) & 0xFFFF,
|
||||
Math.round(58.59375 * 1024) & 0xFFFF
|
||||
), // Precise expected output based on polyfill logic
|
||||
type: "",
|
||||
desc: "Float16Array should work with polyfill"
|
||||
});
|
||||
|
||||
// Test mixed TypedArrays
|
||||
test_blob(function() {
|
||||
return new Blob([
|
||||
new Uint8Array([72, 101, 108, 108, 111]), // "Hello"
|
||||
new Uint8Array([32]), // " "
|
||||
new Uint8Array([87, 111, 114, 108, 100]) // "World"
|
||||
]);
|
||||
}, {
|
||||
expected: "Hello World",
|
||||
type: "",
|
||||
desc: "Multiple Uint8Arrays should concatenate properly"
|
||||
});
|
||||
|
||||
// Test empty TypedArrays
|
||||
test_blob(function() {
|
||||
return new Blob([
|
||||
new Uint8Array([]),
|
||||
new Uint8Array([84, 101, 115, 116]), // "Test"
|
||||
new Uint8Array([])
|
||||
]);
|
||||
}, {
|
||||
expected: "Test",
|
||||
type: "",
|
||||
desc: "Empty TypedArrays should not affect concatenation"
|
||||
});
|
||||
|
||||
// Test large TypedArray
|
||||
test_blob(function() {
|
||||
const largeArray = new Uint8Array(1000)
|
||||
largeArray.fill(65) // Fill with 'A'
|
||||
return new Blob([largeArray]);
|
||||
}, {
|
||||
expected: "A".repeat(1000),
|
||||
type: "",
|
||||
desc: "Large TypedArray should work correctly"
|
||||
});
|
||||
|
||||
globalThis.add_result_callback((test, ...args) => {
|
||||
if ([
|
||||
'Blob with type "A"',
|
||||
'Blob with type "TEXT/HTML"',
|
||||
'Getters and value conversions should happen in order until an exception is thrown.',
|
||||
'Using type in File constructor: TEXT/PLAIN',
|
||||
'Using type in File constructor: text/plain;charset=UTF-8'
|
||||
].includes(test.name)) return
|
||||
|
||||
const INDENT_SIZE = 2
|
||||
const reporter = {}
|
||||
|
||||
reporter.startSuite = name => console.log(`\n ${(name)}\n`)
|
||||
|
||||
reporter.pass = message => console.log((indent(('√ ') + message, INDENT_SIZE)))
|
||||
|
||||
reporter.fail = message => console.log((indent('\u00D7 ' + message, INDENT_SIZE)))
|
||||
|
||||
reporter.reportStack = stack => console.log((indent(stack, INDENT_SIZE * 2)))
|
||||
|
||||
function indent (string, times) {
|
||||
const prefix = ' '.repeat(times)
|
||||
return string.split('\n').map(l => prefix + l).join('\n')
|
||||
}
|
||||
|
||||
if (test.status === 0) {
|
||||
reporter.pass(test.name)
|
||||
} else if (test.status === 1) {
|
||||
reporter.fail(`${test.name}\n`)
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`)
|
||||
hasFailed = true
|
||||
} else if (test.status === 2) {
|
||||
reporter.fail(`${test.name} (timeout)\n`)
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`)
|
||||
hasFailed = true
|
||||
} else if (test.status === 3) {
|
||||
reporter.fail(`${test.name} (incomplete)\n`)
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`)
|
||||
hasFailed = true
|
||||
} else if (test.status === 4) {
|
||||
reporter.fail(`${test.name} (precondition failed)\n`)
|
||||
reporter.reportStack(`${test.message}\n${test.stack}`)
|
||||
hasFailed = true
|
||||
} else {
|
||||
reporter.fail(`unknown test status: ${test.status}`)
|
||||
hasFailed = true
|
||||
}
|
||||
})
|
||||
|
||||
globalThis.File = File
|
||||
globalThis.Blob = Blob
|
||||
globalThis.garbageCollect = () => {}
|
||||
globalThis.test_blob = test_blob
|
||||
globalThis.test_blob_binary = test_blob_binary
|
||||
// Because WPT doesn't clean up after itself
|
||||
globalThis.MessageChannel = class extends MessageChannel {
|
||||
constructor () {
|
||||
super()
|
||||
setTimeout(() => {
|
||||
this.port1.close()
|
||||
this.port2.close()
|
||||
this.port1.onmessage = this.port2.onmessage = null
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
|
||||
import('https://wpt.live/FileAPI/file/File-constructor.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-constructor.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-array-buffer.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-slice-overflow.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-slice.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-stream.any.js')
|
||||
import('https://wpt.live/FileAPI/blob/Blob-text.any.js')
|
||||
import('./own-misc-test.js')
|
||||
|
||||
if (hasFailed) {
|
||||
console.log('Tests failed')
|
||||
process.exit(1)
|
||||
}
|
||||
Reference in New Issue
Block a user