Skip to content

Commit

Permalink
core: Don't use global buffer (#1422)
Browse files Browse the repository at this point in the history
* remove unused file

* two test is coveraged by the Uint8Array test

* use arrayBuffer to test base64 instead

* avoid testing buffer

* avoid using Buffer

* import buffer module

* use one same textEncoder

* import stream consumer that can test iterable objects

* fix a test

* fix test where type should be empty
  • Loading branch information
jimmywarting committed Dec 21, 2021
1 parent eb33090 commit 1493d04
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 108 deletions.
5 changes: 3 additions & 2 deletions package.json
Expand Up @@ -58,13 +58,14 @@
"formdata-node": "^4.2.4",
"mocha": "^9.1.3",
"p-timeout": "^5.0.0",
"stream-consumers": "^1.0.1",
"tsd": "^0.14.0",
"xo": "^0.39.1"
},
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"formdata-polyfill": "^4.0.10",
"fetch-blob": "^3.1.3"
"fetch-blob": "^3.1.3",
"formdata-polyfill": "^4.0.10"
},
"tsd": {
"cwd": "@types",
Expand Down
1 change: 1 addition & 0 deletions src/body.js
Expand Up @@ -7,6 +7,7 @@

import Stream, {PassThrough} from 'node:stream';
import {types, deprecate, promisify} from 'node:util';
import {Buffer} from 'node:buffer';

import Blob from 'fetch-blob';
import {FormData, formDataToBlob} from 'formdata-polyfill/esm.min.js';
Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Expand Up @@ -10,6 +10,8 @@ import http from 'node:http';
import https from 'node:https';
import zlib from 'node:zlib';
import Stream, {PassThrough, pipeline as pump} from 'node:stream';
import {Buffer} from 'node:buffer';

import dataUriToBuffer from 'data-uri-to-buffer';

import {writeToStream, clone} from './body.js';
Expand Down
17 changes: 8 additions & 9 deletions test/external-encoding.js
Expand Up @@ -5,15 +5,14 @@ const {expect} = chai;

describe('external encoding', () => {
describe('data uri', () => {
it('should accept base64-encoded gif data uri', () => {
return fetch('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=').then(r => {
expect(r.status).to.equal(200);
expect(r.headers.get('Content-Type')).to.equal('image/gif');

return r.buffer().then(b => {
expect(b).to.be.an.instanceOf(Buffer);
});
});
it('should accept base64-encoded gif data uri', async () => {
const b64 = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';
const res = await fetch(b64);
expect(res.status).to.equal(200);
expect(res.headers.get('Content-Type')).to.equal('image/gif');
const buf = await res.arrayBuffer();
expect(buf.byteLength).to.equal(35);
expect(buf).to.be.an.instanceOf(ArrayBuffer);
});

it('should accept data uri with specified charset', async () => {
Expand Down
2 changes: 0 additions & 2 deletions test/headers.js
Expand Up @@ -178,7 +178,6 @@ describe('Headers', () => {
res.j = Number.NaN;
res.k = true;
res.l = false;
res.m = Buffer.from('test');

const h1 = new Headers(res);
h1.set('n', [1, 2]);
Expand All @@ -198,7 +197,6 @@ describe('Headers', () => {
expect(h1Raw.j).to.include('NaN');
expect(h1Raw.k).to.include('true');
expect(h1Raw.l).to.include('false');
expect(h1Raw.m).to.include('test');
expect(h1Raw.n).to.include('1,2');
expect(h1Raw.n).to.include('3,4');

Expand Down
97 changes: 26 additions & 71 deletions test/main.js
Expand Up @@ -16,6 +16,7 @@ import {FormData as FormDataNode} from 'formdata-polyfill/esm.min.js';
import delay from 'delay';
import AbortControllerMysticatea from 'abort-controller';
import abortControllerPolyfill from 'abortcontroller-polyfill/dist/abortcontroller.js';
import {text} from 'stream-consumers';

// Test subjects
import Blob from 'fetch-blob';
Expand All @@ -36,6 +37,7 @@ import TestServer from './utils/server.js';
import chaiTimeout from './utils/chai-timeout.js';

const AbortControllerPolyfill = abortControllerPolyfill.AbortController;
const encoder = new TextEncoder();

function isNodeLowerThan(version) {
return !~process.version.localeCompare(version, undefined, {numeric: true});
Expand All @@ -51,18 +53,6 @@ chai.use(chaiString);
chai.use(chaiTimeout);
const {expect} = chai;

function streamToPromise(stream, dataHandler) {
return new Promise((resolve, reject) => {
stream.on('data', (...args) => {
Promise.resolve()
.then(() => dataHandler(...args))
.catch(reject);
});
stream.on('end', resolve);
stream.on('error', reject);
});
}

describe('node-fetch', () => {
const local = new TestServer();
let base;
Expand Down Expand Up @@ -1314,25 +1304,7 @@ describe('node-fetch', () => {
});
});

it('should allow POST request with buffer body', () => {
const url = `${base}inspect`;
const options = {
method: 'POST',
body: Buffer.from('a=1', 'utf-8')
};
return fetch(url, options).then(res => {
return res.json();
}).then(res => {
expect(res.method).to.equal('POST');
expect(res.body).to.equal('a=1');
expect(res.headers['transfer-encoding']).to.be.undefined;
expect(res.headers['content-type']).to.be.undefined;
expect(res.headers['content-length']).to.equal('3');
});
});

it('should allow POST request with ArrayBuffer body', () => {
const encoder = new TextEncoder();
const url = `${base}inspect`;
const options = {
method: 'POST',
Expand All @@ -1351,7 +1323,7 @@ describe('node-fetch', () => {
const url = `${base}inspect`;
const options = {
method: 'POST',
body: new VMUint8Array(Buffer.from('Hello, world!\n')).buffer
body: new VMUint8Array(encoder.encode('Hello, world!\n')).buffer
};
return fetch(url, options).then(res => res.json()).then(res => {
expect(res.method).to.equal('POST');
Expand All @@ -1363,7 +1335,6 @@ describe('node-fetch', () => {
});

it('should allow POST request with ArrayBufferView (Uint8Array) body', () => {
const encoder = new TextEncoder();
const url = `${base}inspect`;
const options = {
method: 'POST',
Expand All @@ -1379,7 +1350,6 @@ describe('node-fetch', () => {
});

it('should allow POST request with ArrayBufferView (DataView) body', () => {
const encoder = new TextEncoder();
const url = `${base}inspect`;
const options = {
method: 'POST',
Expand All @@ -1398,7 +1368,7 @@ describe('node-fetch', () => {
const url = `${base}inspect`;
const options = {
method: 'POST',
body: new VMUint8Array(Buffer.from('Hello, world!\n'))
body: new VMUint8Array(encoder.encode('Hello, world!\n'))
};
return fetch(url, options).then(res => res.json()).then(res => {
expect(res.method).to.equal('POST');
Expand All @@ -1410,7 +1380,6 @@ describe('node-fetch', () => {
});

it('should allow POST request with ArrayBufferView (Uint8Array, offset, length) body', () => {
const encoder = new TextEncoder();
const url = `${base}inspect`;
const options = {
method: 'POST',
Expand Down Expand Up @@ -1846,39 +1815,28 @@ describe('node-fetch', () => {
});
});

it('should allow piping response body as stream', () => {
it('should allow piping response body as stream', async () => {
const url = `${base}hello`;
return fetch(url).then(res => {
expect(res.body).to.be.an.instanceof(stream.Transform);
return streamToPromise(res.body, chunk => {
if (chunk === null) {
return;
}

expect(chunk.toString()).to.equal('world');
});
});
const res = await fetch(url);
expect(res.body).to.be.an.instanceof(stream.Transform);
const body = await text(res.body);
expect(body).to.equal('world');
});

it('should allow cloning a response, and use both as stream', () => {
it('should allow cloning a response, and use both as stream', async () => {
const url = `${base}hello`;
return fetch(url).then(res => {
const r1 = res.clone();
expect(res.body).to.be.an.instanceof(stream.Transform);
expect(r1.body).to.be.an.instanceof(stream.Transform);
const dataHandler = chunk => {
if (chunk === null) {
return;
}
const res = await fetch(url);
const r1 = res.clone();
expect(res.body).to.be.an.instanceof(stream.Transform);
expect(r1.body).to.be.an.instanceof(stream.Transform);

expect(chunk.toString()).to.equal('world');
};
const [t1, t2] = await Promise.all([
text(res.body),
text(r1.body)
]);

return Promise.all([
streamToPromise(res.body, dataHandler),
streamToPromise(r1.body, dataHandler)
]);
});
expect(t1).to.equal('world');
expect(t2).to.equal('world');
});

it('should allow cloning a json response and log it as text response', () => {
Expand Down Expand Up @@ -2141,13 +2099,10 @@ describe('node-fetch', () => {
});
});

it('should support reading blob as stream', () => {
return new Response('hello')
.blob()
.then(blob => streamToPromise(stream.Readable.from(blob.stream()), data => {
const string = Buffer.from(data).toString();
expect(string).to.equal('hello');
}));
it('should support reading blob as stream', async () => {
const blob = await new Response('hello').blob();
const str = await text(blob.stream());
expect(str).to.equal('hello');
});

it('should support blob round-trip', () => {
Expand Down Expand Up @@ -2233,7 +2188,7 @@ describe('node-fetch', () => {
// Issue #414
it('should reject if attempt to accumulate body stream throws', () => {
const res = new Response(stream.Readable.from((async function * () {
yield Buffer.from('tada');
yield encoder.encode('tada');
await new Promise(resolve => {
setTimeout(resolve, 200);
});
Expand Down Expand Up @@ -2329,7 +2284,7 @@ describe('node-fetch', () => {
size: 1024
});

const bufferBody = Buffer.from(bodyContent);
const bufferBody = encoder.encode(bodyContent);
const bufferRequest = new Request(url, {
method: 'POST',
body: bufferBody,
Expand Down
2 changes: 1 addition & 1 deletion test/referrer.js
Expand Up @@ -127,7 +127,7 @@ describe('Request constructor', () => {
expect(() => {
const req = new Request('http://example.com', {referrer: 'foobar'});
expect.fail(req);
}).to.throw(TypeError, 'Invalid URL: foobar');
}).to.throw(TypeError, /Invalid URL/);
});
});

Expand Down
13 changes: 6 additions & 7 deletions test/request.js
Expand Up @@ -201,18 +201,17 @@ describe('Request', () => {
});
});

it('should support blob() method', () => {
it('should support blob() method', async () => {
const url = base;
const request = new Request(url, {
method: 'POST',
body: Buffer.from('a=1')
body: new TextEncoder().encode('a=1')
});
expect(request.url).to.equal(url);
return request.blob().then(result => {
expect(result).to.be.an.instanceOf(Blob);
expect(result.size).to.equal(3);
expect(result.type).to.equal('');
});
const blob = await request.blob();
expect(blob).to.be.an.instanceOf(Blob);
expect(blob.size).to.equal(3);
expect(blob.type).to.equal('');
});

it('should support clone() method', () => {
Expand Down
7 changes: 0 additions & 7 deletions test/response.js
Expand Up @@ -154,13 +154,6 @@ describe('Response', () => {
});
});

it('should support buffer as body', () => {
const res = new Response(Buffer.from('a=1'));
return res.text().then(result => {
expect(result).to.equal('a=1');
});
});

it('should support ArrayBuffer as body', () => {
const encoder = new TextEncoder();
const res = new Response(encoder.encode('a=1'));
Expand Down
9 changes: 0 additions & 9 deletions test/utils/read-stream.js

This file was deleted.

0 comments on commit 1493d04

Please sign in to comment.