Skip to content

Commit

Permalink
Add tests for Bun
Browse files Browse the repository at this point in the history
  • Loading branch information
ardatan committed Nov 18, 2024
1 parent c80216d commit d4e9457
Show file tree
Hide file tree
Showing 36 changed files with 564 additions and 378 deletions.
7 changes: 7 additions & 0 deletions .changeset/cuddly-peas-complain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@whatwg-node/node-fetch': patch
'@whatwg-node/server': patch
'@whatwg-node/fetch': patch
---

Small improvements for Bun support
29 changes: 29 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,35 @@ jobs:
max_attempts: 5
command: yarn test --ci

unit-bun:
name: unit / bun ${{matrix.node-version}}
runs-on: ubuntu-latest
services:
httpbin:
image: kennethreitz/httpbin
ports:
- 8888:80
strategy:
fail-fast: false
steps:
- name: Checkout Master
uses: actions/checkout@v4
- name: Install Required Libraries
run: sudo apt update && sudo apt install -y libcurl4-openssl-dev libssl-dev
- name: Setup env
uses: the-guild-org/shared-config/setup@main
with:
nodeVersion: 22
- name: Cache Jest
uses: actions/cache@v4
with:
path: .cache/jest
key: ${{ runner.os }}-${{matrix.node-version}}-jest-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{matrix.node-version}}-jest-
- name: Test
run: yarn test:bun --ci

unit-leaks:
name: unit / leaks / node ${{matrix.node-version}}
runs-on: ubuntu-latest
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"prettier:check": "prettier --ignore-path .gitignore --ignore-path .prettierignore --check .",
"release": "changeset publish",
"test": "jest --runInBand --forceExit",
"test:bun": "bun test --bail",
"test:leaks": "LEAK_TEST=1 jest --runInBand --detectOpenHandles --detectLeaks --logHeapUsage --forceExit",
"ts:check": "tsc --noEmit"
},
Expand All @@ -37,13 +38,15 @@
"@changesets/changelog-github": "0.5.0",
"@changesets/cli": "2.27.9",
"@theguild/prettier-config": "2.0.7",
"@types/bun": "1.1.13",
"@types/jest": "29.5.14",
"@types/node": "22.9.0",
"@types/react-dom": "18.2.18",
"@typescript-eslint/eslint-plugin": "7.18.0",
"@typescript-eslint/parser": "7.18.0",
"babel-jest": "29.7.0",
"bob-the-bundler": "7.0.1",
"bun": "1.1.34",
"cross-env": "7.0.3",
"eslint": "9.15.0",
"eslint-config-prettier": "9.1.0",
Expand Down
8 changes: 6 additions & 2 deletions packages/fetch/dist/create-node-ponyfill.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const shouldSkipPonyfill = require('./shouldSkipPonyfill');
let newNodeFetch;

module.exports = function createNodePonyfill(opts = {}) {
const ponyfills = {};
Expand All @@ -11,7 +12,10 @@ module.exports = function createNodePonyfill(opts = {}) {
ponyfills.URLPattern = urlPatternModule.URLPattern;
}

if (opts.skipPonyfill || shouldSkipPonyfill()) {
if (
(opts.skipPonyfill || shouldSkipPonyfill())
&& opts.skipPonyfill !== false
) {
return {
fetch: globalThis.fetch,
Headers: globalThis.Headers,
Expand All @@ -37,7 +41,7 @@ module.exports = function createNodePonyfill(opts = {}) {
};
}

const newNodeFetch = require('@whatwg-node/node-fetch');
newNodeFetch ||= require('@whatwg-node/node-fetch');

ponyfills.fetch = newNodeFetch.fetch;
ponyfills.Request = newNodeFetch.Request;
Expand Down
27 changes: 25 additions & 2 deletions packages/node-fetch/src/URL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { PonyfillURLSearchParams } from './URLSearchParams.js';

FastUrl.queryString = FastQuerystring;

export class PonyfillURL extends FastUrl implements URL {
constructor(url: string, base?: string | URL) {
class PonyfillURL extends FastUrl {
constructor(url: string | URL, base?: string | URL | undefined) {
url = url.toString();
super();
if (url.startsWith('data:')) {
this.protocol = 'data:';
Expand All @@ -24,6 +25,16 @@ export class PonyfillURL extends FastUrl implements URL {
}
}

canParse(url: string, base?: string): boolean {
try {
// eslint-disable-next-line no-new
new PonyfillURL(url, base);
return true;
} catch {
return false;
}
}

get origin(): string {
return `${this.protocol}//${this.host}`;
}
Expand Down Expand Up @@ -63,6 +74,14 @@ export class PonyfillURL extends FastUrl implements URL {

private static blobRegistry = new Map<string, Blob>();

createObjectURL(obj: Blob): string {
return PonyfillURL.createObjectURL(obj);
}

revokeObjectURL(url: string): void {
PonyfillURL.resolveObjectURL(url);
}

static createObjectURL(blob: Blob): string {
const blobUrl = `blob:whatwgnode:${randomUUID()}`;
this.blobRegistry.set(blobUrl, blob);
Expand All @@ -81,3 +100,7 @@ export class PonyfillURL extends FastUrl implements URL {
return (this.blobRegistry.get(url) || resolveObjectURL(url)) as Blob | PonyfillBlob | undefined;
}
}

const URLCtor = PonyfillURL as unknown as typeof URL;

export { URLCtor as PonyfillURL };
7 changes: 5 additions & 2 deletions packages/node-fetch/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
export { fetchPonyfill as fetch } from './fetch.js';
export { PonyfillHeaders as Headers } from './Headers.js';
export { PonyfillBody as Body } from './Body.js';
export { PonyfillRequest as Request, RequestPonyfillInit as RequestInit } from './Request.js';
export { PonyfillResponse as Response, ResponsePonyfilInit as ResponseInit } from './Response.js';
export { PonyfillRequest as Request, type RequestPonyfillInit as RequestInit } from './Request.js';
export {
PonyfillResponse as Response,
type ResponsePonyfilInit as ResponseInit,
} from './Response.js';
export { PonyfillReadableStream as ReadableStream } from './ReadableStream.js';
export { PonyfillFile as File } from './File.js';
export { PonyfillFormData as FormData } from './FormData.js';
Expand Down
7 changes: 6 additions & 1 deletion packages/node-fetch/tests/Body.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ describe('Body', () => {
type: 'multipart/form-data; boundary=Boundary_with_capital_letters',
}),
);
await expect(() => body.formData()).rejects.toThrow(TypeError);
try {
await body.formData();
expect(true).toBe(false);
} catch (e) {
expect(e).toBeInstanceOf(TypeError);
}
});
});
9 changes: 6 additions & 3 deletions packages/node-fetch/tests/FormData.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,12 @@ describe('Form Data', () => {
fileSize: 1,
},
});
await expect(() => requestWillParse.formData()).rejects.toThrowError(
'File size limit exceeded: 1 bytes',
);
try {
await requestWillParse.formData();
expect(true).toBe(false);
} catch (error: any) {
expect(error.message).toBe('File size limit exceeded: 1 bytes');
}
});
it('support native Blob', async () => {
const formData = new PonyfillFormData();
Expand Down
62 changes: 29 additions & 33 deletions packages/node-fetch/tests/ReadableStream.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('ReadableStream', () => {
}
chunksStr += (value as Buffer).toString('utf-8');
}
expect(chunksStr).toMatchInlineSnapshot(`"{"cnt":0}{"cnt":1}{"cnt":2}{"cnt":3}"`);
expect(chunksStr).toBe(`{"cnt":0}{"cnt":1}{"cnt":2}{"cnt":3}`);
});
it('should send data from start and push lazily', async () => {
let interval: any;
Expand Down Expand Up @@ -73,28 +73,26 @@ describe('ReadableStream', () => {
break;
}
}
expect(chunksStr).toMatchInlineSnapshot(`
"startCount: 0
startCount: 1
startCount: 2
pullCount: 0
startCount: 3
startCount: 4
startCount: 5
startCount: 6
pullCount: 1
startCount: 7
startCount: 8
startCount: 9
startCount: 10
pullCount: 2
startCount: 11
startCount: 12
startCount: 13
startCount: 14
pullCount: 3
"
`);
expect(chunksStr).toBe(`startCount: 0
startCount: 1
startCount: 2
pullCount: 0
startCount: 3
startCount: 4
startCount: 5
startCount: 6
pullCount: 1
startCount: 7
startCount: 8
startCount: 9
startCount: 10
pullCount: 2
startCount: 11
startCount: 12
startCount: 13
startCount: 14
pullCount: 3
`);
});
it('should send data from start without pull lazily', async () => {
let interval: any;
Expand Down Expand Up @@ -122,15 +120,13 @@ describe('ReadableStream', () => {
break;
}
}
expect(chunks).toMatchInlineSnapshot(`
[
"startCount: 0",
"startCount: 1",
"startCount: 2",
"startCount: 3",
"startCount: 4",
"startCount: 5",
]
`);
expect(chunks).toEqual([
'startCount: 0',
'startCount: 1',
'startCount: 2',
'startCount: 3',
'startCount: 4',
'startCount: 5',
]);
});
});
2 changes: 1 addition & 1 deletion packages/node-fetch/tests/TextEncoderDecoderStream.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { runTestsForEachFetchImpl } from '../../server/test/test-fetch';
import { runTestsForEachFetchImpl } from '../../server/tests/test-fetch';

describe('TextEncoderDecoderStream', () => {
runTestsForEachFetchImpl((_, { fetchAPI }) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/node-fetch/tests/cleanup-resources.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { runTestsForEachFetchImpl } from '../../server/test/test-fetch';
import { runTestsForEachServerImpl } from '../../server/test/test-server';
import { runTestsForEachFetchImpl } from '../../server/tests/test-fetch';
import { runTestsForEachServerImpl } from '../../server/tests/test-server';

describe('Cleanup Resources', () => {
runTestsForEachFetchImpl((_, { createServerAdapter, fetchAPI: { Response, fetch } }) => {
Expand Down
Loading

0 comments on commit d4e9457

Please sign in to comment.