mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
Copy some node tests (#13458)
This commit is contained in:
@@ -441,6 +441,8 @@ async function spawnBun(execPath, { args, cwd, timeout, env, stdout, stderr }) {
|
||||
BUN_RUNTIME_TRANSPILER_CACHE_PATH: "0",
|
||||
BUN_INSTALL_CACHE_DIR: tmpdirPath,
|
||||
SHELLOPTS: isWindows ? "igncr" : undefined, // ignore "\r" on Windows
|
||||
// Used in Node.js tests.
|
||||
TEST_TMPDIR: tmpdirPath,
|
||||
};
|
||||
if (env) {
|
||||
Object.assign(bunEnv, env);
|
||||
|
||||
2
test/bunfig.toml
Normal file
2
test/bunfig.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[test]
|
||||
preload = "./preload.ts"
|
||||
@@ -1264,3 +1264,11 @@ https://buildkite.com/docs/pipelines/security/secrets/buildkite-secrets`;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// Make it easier to run some node tests.
|
||||
Object.defineProperty(globalThis, "gc", {
|
||||
value: Bun.gc,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
BIN
test/js/node/test/fixtures/pseudo-multimember-gzip.gz
vendored
Normal file
BIN
test/js/node/test/fixtures/pseudo-multimember-gzip.gz
vendored
Normal file
Binary file not shown.
BIN
test/js/node/test/fixtures/pseudo-multimember-gzip.z
vendored
Normal file
BIN
test/js/node/test/fixtures/pseudo-multimember-gzip.z
vendored
Normal file
Binary file not shown.
42
test/js/node/test/parallel/fs-readdir-recursive.test.js
Normal file
42
test/js/node/test/parallel/fs-readdir-recursive.test.js
Normal file
@@ -0,0 +1,42 @@
|
||||
//#FILE: test-fs-readdir-recursive.js
|
||||
//#SHA1: daa6ac8e46cd3d530e4546354a11f87f1b1c092d
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const net = require('net');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const tmpdir = path.join(os.tmpdir(), 'node-test-fs-readdir-recursive');
|
||||
|
||||
beforeAll(() => {
|
||||
// Refresh tmpdir
|
||||
if (fs.existsSync(tmpdir)) {
|
||||
fs.rmSync(tmpdir, { recursive: true, force: true });
|
||||
}
|
||||
fs.mkdirSync(tmpdir, { recursive: true });
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
// Clean up tmpdir
|
||||
fs.rmSync(tmpdir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test('fs.readdirSync with recursive option should not crash', (done) => {
|
||||
const server = net.createServer().listen(
|
||||
path.join(tmpdir, 'test.sock'),
|
||||
() => {
|
||||
// The process should not crash
|
||||
// See https://github.com/nodejs/node/issues/52159
|
||||
expect(() => {
|
||||
fs.readdirSync(tmpdir, { recursive: true });
|
||||
}).not.toThrow();
|
||||
|
||||
server.close();
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-readdir-recursive.js
|
||||
82
test/js/node/test/parallel/fs-readdir.test.js
Normal file
82
test/js/node/test/parallel/fs-readdir.test.js
Normal file
@@ -0,0 +1,82 @@
|
||||
//#FILE: test-fs-readdir.js
|
||||
//#SHA1: ce2c5a12cb271c5023f965afe712e78b1a484ad5
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const readdirDir = path.join(os.tmpdir(), 'test-fs-readdir');
|
||||
const files = ['empty', 'files', 'for', 'just', 'testing'];
|
||||
|
||||
beforeAll(() => {
|
||||
// Make sure tmp directory is clean
|
||||
if (fs.existsSync(readdirDir)) {
|
||||
fs.rmSync(readdirDir, { recursive: true, force: true });
|
||||
}
|
||||
fs.mkdirSync(readdirDir, { recursive: true });
|
||||
|
||||
// Create the necessary files
|
||||
files.forEach((currentFile) => {
|
||||
fs.closeSync(fs.openSync(path.join(readdirDir, currentFile), 'w'));
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
// Clean up
|
||||
fs.rmSync(readdirDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test('fs.readdirSync returns correct files', () => {
|
||||
expect(fs.readdirSync(readdirDir).sort()).toEqual(files);
|
||||
});
|
||||
|
||||
test('fs.readdir returns correct files', async () => {
|
||||
await new Promise((resolve) => {
|
||||
fs.readdir(readdirDir, (err, f) => {
|
||||
expect(err).toBeNull();
|
||||
expect(f.sort()).toEqual(files);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('fs.readdirSync throws ENOTDIR on file', () => {
|
||||
expect(() => {
|
||||
fs.readdirSync(__filename);
|
||||
}).toThrow(expect.objectContaining({
|
||||
code: 'ENOTDIR',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
|
||||
test('fs.readdir throws ENOTDIR on file', async () => {
|
||||
await new Promise((resolve) => {
|
||||
fs.readdir(__filename, (e) => {
|
||||
expect(e).toEqual(expect.objectContaining({
|
||||
code: 'ENOTDIR',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('fs.readdir and fs.readdirSync throw on invalid input', () => {
|
||||
[false, 1, [], {}, null, undefined].forEach((i) => {
|
||||
expect(() => fs.readdir(i, () => {})).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
|
||||
expect(() => fs.readdirSync(i)).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-readdir.js
|
||||
52
test/js/node/test/parallel/fs-readfile-unlink.test.js
Normal file
52
test/js/node/test/parallel/fs-readfile-unlink.test.js
Normal file
@@ -0,0 +1,52 @@
|
||||
//#FILE: test-fs-readfile-unlink.js
|
||||
//#SHA1: a7107747d7901dfcc1ffd0e7adbf548412a1016a
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
// Test that unlink succeeds immediately after readFile completes.
|
||||
|
||||
test('unlink succeeds immediately after readFile completes', async () => {
|
||||
const tmpdir = path.join(os.tmpdir(), 'node-test-fs-readfile-unlink');
|
||||
await fs.promises.mkdir(tmpdir, { recursive: true });
|
||||
|
||||
const fileName = path.join(tmpdir, 'test.bin');
|
||||
const buf = Buffer.alloc(512 * 1024, 42);
|
||||
|
||||
await fs.promises.writeFile(fileName, buf);
|
||||
|
||||
const data = await fs.promises.readFile(fileName);
|
||||
|
||||
expect(data.length).toBe(buf.length);
|
||||
expect(data[0]).toBe(42);
|
||||
|
||||
// Unlink should not throw. This is part of the test. It used to throw on
|
||||
// Windows due to a bug.
|
||||
await expect(fs.promises.unlink(fileName)).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-readfile-unlink.js
|
||||
@@ -0,0 +1,61 @@
|
||||
//#FILE: test-fs-readfile-zero-byte-liar.js
|
||||
//#SHA1: ddca2f114cf32b03f36405a21c81058e7a1f0c18
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
// Test that readFile works even when stat returns size 0.
|
||||
|
||||
const dataExpected = fs.readFileSync(__filename, 'utf8');
|
||||
|
||||
// Sometimes stat returns size=0, but it's a lie.
|
||||
fs._fstat = fs.fstat;
|
||||
fs._fstatSync = fs.fstatSync;
|
||||
|
||||
fs.fstat = (fd, cb) => {
|
||||
fs._fstat(fd, (er, st) => {
|
||||
if (er) return cb(er);
|
||||
st.size = 0;
|
||||
return cb(er, st);
|
||||
});
|
||||
};
|
||||
|
||||
fs.fstatSync = (fd) => {
|
||||
const st = fs._fstatSync(fd);
|
||||
st.size = 0;
|
||||
return st;
|
||||
};
|
||||
|
||||
test('readFileSync works with zero byte liar', () => {
|
||||
const d = fs.readFileSync(__filename, 'utf8');
|
||||
expect(d).toBe(dataExpected);
|
||||
});
|
||||
|
||||
test('readFile works with zero byte liar', async () => {
|
||||
const d = await fs.promises.readFile(__filename, 'utf8');
|
||||
expect(d).toBe(dataExpected);
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-readfile-zero-byte-liar.js
|
||||
26
test/js/node/test/parallel/fs-readlink-type-check.test.js
Normal file
26
test/js/node/test/parallel/fs-readlink-type-check.test.js
Normal file
@@ -0,0 +1,26 @@
|
||||
//#FILE: test-fs-readlink-type-check.js
|
||||
//#SHA1: dd36bda8e12e6c22c342325345dd8d1de2097d9c
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
[false, 1, {}, [], null, undefined].forEach((i) => {
|
||||
test(`fs.readlink throws for invalid input: ${JSON.stringify(i)}`, () => {
|
||||
expect(() => fs.readlink(i, jest.fn())).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
|
||||
test(`fs.readlinkSync throws for invalid input: ${JSON.stringify(i)}`, () => {
|
||||
expect(() => fs.readlinkSync(i)).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-readlink-type-check.js
|
||||
69
test/js/node/test/parallel/fs-readv-promises.test.js
Normal file
69
test/js/node/test/parallel/fs-readv-promises.test.js
Normal file
@@ -0,0 +1,69 @@
|
||||
//#FILE: test-fs-readv-promises.js
|
||||
//#SHA1: 43d801fa8a2eabf438e98f5aa713eb9680fe798b
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs').promises;
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const expected = 'ümlaut. Лорем 運務ホソモ指及 आपको करने विकास 紙読決多密所 أضف';
|
||||
const expectedBuff = Buffer.from(expected);
|
||||
|
||||
let cnt = 0;
|
||||
function getFileName() {
|
||||
return path.join(os.tmpdir(), `readv_promises_${++cnt}.txt`);
|
||||
}
|
||||
|
||||
const allocateEmptyBuffers = (combinedLength) => {
|
||||
const bufferArr = [];
|
||||
// Allocate two buffers, each half the size of expectedBuff
|
||||
bufferArr[0] = Buffer.alloc(Math.floor(combinedLength / 2));
|
||||
bufferArr[1] = Buffer.alloc(combinedLength - bufferArr[0].length);
|
||||
|
||||
return bufferArr;
|
||||
};
|
||||
|
||||
describe('fs.promises.readv', () => {
|
||||
beforeEach(() => {
|
||||
cnt = 0;
|
||||
});
|
||||
|
||||
test('readv with position', async () => {
|
||||
const filename = getFileName();
|
||||
await fs.writeFile(filename, expectedBuff);
|
||||
const handle = await fs.open(filename, 'r');
|
||||
const bufferArr = allocateEmptyBuffers(expectedBuff.length);
|
||||
const expectedLength = expectedBuff.length;
|
||||
|
||||
let { bytesRead, buffers } = await handle.readv([Buffer.from('')], null);
|
||||
expect(bytesRead).toBe(0);
|
||||
expect(buffers).toEqual([Buffer.from('')]);
|
||||
|
||||
({ bytesRead, buffers } = await handle.readv(bufferArr, null));
|
||||
expect(bytesRead).toBe(expectedLength);
|
||||
expect(buffers).toEqual(bufferArr);
|
||||
expect(Buffer.concat(bufferArr)).toEqual(await fs.readFile(filename));
|
||||
await handle.close();
|
||||
});
|
||||
|
||||
test('readv without position', async () => {
|
||||
const filename = getFileName();
|
||||
await fs.writeFile(filename, expectedBuff);
|
||||
const handle = await fs.open(filename, 'r');
|
||||
const bufferArr = allocateEmptyBuffers(expectedBuff.length);
|
||||
const expectedLength = expectedBuff.length;
|
||||
|
||||
let { bytesRead, buffers } = await handle.readv([Buffer.from('')]);
|
||||
expect(bytesRead).toBe(0);
|
||||
expect(buffers).toEqual([Buffer.from('')]);
|
||||
|
||||
({ bytesRead, buffers } = await handle.readv(bufferArr));
|
||||
expect(bytesRead).toBe(expectedLength);
|
||||
expect(buffers).toEqual(bufferArr);
|
||||
expect(Buffer.concat(bufferArr)).toEqual(await fs.readFile(filename));
|
||||
await handle.close();
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-readv-promises.js
|
||||
100
test/js/node/test/parallel/fs-readv-sync.test.js
Normal file
100
test/js/node/test/parallel/fs-readv-sync.test.js
Normal file
@@ -0,0 +1,100 @@
|
||||
//#FILE: test-fs-readv-sync.js
|
||||
//#SHA1: e9a4527b118e4a814a04c976eaafb5127f7c7c9d
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const expected = 'ümlaut. Лорем 運務ホソモ指及 आपको करने विकास 紙読決多密所 أضف';
|
||||
|
||||
const exptectedBuff = Buffer.from(expected);
|
||||
const expectedLength = exptectedBuff.length;
|
||||
|
||||
let filename;
|
||||
let tmpdir;
|
||||
|
||||
beforeAll(() => {
|
||||
tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-fs-readv-sync-'));
|
||||
filename = path.join(tmpdir, 'readv_sync.txt');
|
||||
fs.writeFileSync(filename, exptectedBuff);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
fs.rmSync(tmpdir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
const allocateEmptyBuffers = (combinedLength) => {
|
||||
const bufferArr = [];
|
||||
// Allocate two buffers, each half the size of exptectedBuff
|
||||
bufferArr[0] = Buffer.alloc(Math.floor(combinedLength / 2));
|
||||
bufferArr[1] = Buffer.alloc(combinedLength - bufferArr[0].length);
|
||||
|
||||
return bufferArr;
|
||||
};
|
||||
|
||||
// fs.readvSync with array of buffers with all parameters
|
||||
test('fs.readvSync with array of buffers with all parameters', () => {
|
||||
const fd = fs.openSync(filename, 'r');
|
||||
|
||||
const bufferArr = allocateEmptyBuffers(exptectedBuff.length);
|
||||
|
||||
let read = fs.readvSync(fd, [Buffer.from('')], 0);
|
||||
expect(read).toBe(0);
|
||||
|
||||
read = fs.readvSync(fd, bufferArr, 0);
|
||||
expect(read).toBe(expectedLength);
|
||||
|
||||
fs.closeSync(fd);
|
||||
|
||||
expect(Buffer.concat(bufferArr)).toEqual(fs.readFileSync(filename));
|
||||
});
|
||||
|
||||
// fs.readvSync with array of buffers without position
|
||||
test('fs.readvSync with array of buffers without position', () => {
|
||||
const fd = fs.openSync(filename, 'r');
|
||||
|
||||
const bufferArr = allocateEmptyBuffers(exptectedBuff.length);
|
||||
|
||||
let read = fs.readvSync(fd, [Buffer.from('')]);
|
||||
expect(read).toBe(0);
|
||||
|
||||
read = fs.readvSync(fd, bufferArr);
|
||||
expect(read).toBe(expectedLength);
|
||||
|
||||
fs.closeSync(fd);
|
||||
|
||||
expect(Buffer.concat(bufferArr)).toEqual(fs.readFileSync(filename));
|
||||
});
|
||||
|
||||
/**
|
||||
* Testing with incorrect arguments
|
||||
*/
|
||||
const wrongInputs = [false, 'test', {}, [{}], ['sdf'], null, undefined];
|
||||
|
||||
test('fs.readvSync with incorrect arguments', () => {
|
||||
const fd = fs.openSync(filename, 'r');
|
||||
|
||||
for (const wrongInput of wrongInputs) {
|
||||
expect(() => fs.readvSync(fd, wrongInput, null)).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
}
|
||||
|
||||
fs.closeSync(fd);
|
||||
});
|
||||
|
||||
test('fs.readvSync with wrong fd argument', () => {
|
||||
for (const wrongInput of wrongInputs) {
|
||||
expect(() => fs.readvSync(wrongInput)).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-readv-sync.js
|
||||
106
test/js/node/test/parallel/fs-readv.test.js
Normal file
106
test/js/node/test/parallel/fs-readv.test.js
Normal file
@@ -0,0 +1,106 @@
|
||||
//#FILE: test-fs-readv.js
|
||||
//#SHA1: 07d6fe434017163aea491c98db8127bc2c942b96
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const expected = 'ümlaut. Лорем 運務ホソモ指及 आपको करने विकास 紙読決多密所 أضف';
|
||||
|
||||
let cnt = 0;
|
||||
const getFileName = () => path.join(os.tmpdir(), `readv_${++cnt}.txt`);
|
||||
const expectedBuff = Buffer.from(expected);
|
||||
|
||||
const allocateEmptyBuffers = (combinedLength) => {
|
||||
const bufferArr = [];
|
||||
// Allocate two buffers, each half the size of expectedBuff
|
||||
bufferArr[0] = Buffer.alloc(Math.floor(combinedLength / 2));
|
||||
bufferArr[1] = Buffer.alloc(combinedLength - bufferArr[0].length);
|
||||
|
||||
return bufferArr;
|
||||
};
|
||||
|
||||
const getCallback = (fd, bufferArr) => {
|
||||
return (err, bytesRead, buffers) => {
|
||||
expect(err).toBeNull();
|
||||
expect(bufferArr).toEqual(buffers);
|
||||
const expectedLength = expectedBuff.length;
|
||||
expect(bytesRead).toBe(expectedLength);
|
||||
fs.closeSync(fd);
|
||||
|
||||
expect(Buffer.concat(bufferArr).equals(expectedBuff)).toBe(true);
|
||||
};
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(fs, 'writeSync');
|
||||
jest.spyOn(fs, 'writeFileSync');
|
||||
jest.spyOn(fs, 'openSync');
|
||||
jest.spyOn(fs, 'closeSync');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
test('fs.readv with array of buffers with all parameters', (done) => {
|
||||
const filename = getFileName();
|
||||
const fd = fs.openSync(filename, 'w+');
|
||||
fs.writeSync(fd, expectedBuff);
|
||||
|
||||
const bufferArr = allocateEmptyBuffers(expectedBuff.length);
|
||||
const callback = getCallback(fd, bufferArr);
|
||||
|
||||
fs.readv(fd, bufferArr, 0, (err, bytesRead, buffers) => {
|
||||
callback(err, bytesRead, buffers);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('fs.readv with array of buffers without position', (done) => {
|
||||
const filename = getFileName();
|
||||
fs.writeFileSync(filename, expectedBuff);
|
||||
const fd = fs.openSync(filename, 'r');
|
||||
|
||||
const bufferArr = allocateEmptyBuffers(expectedBuff.length);
|
||||
const callback = getCallback(fd, bufferArr);
|
||||
|
||||
fs.readv(fd, bufferArr, (err, bytesRead, buffers) => {
|
||||
callback(err, bytesRead, buffers);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Testing with incorrect arguments', () => {
|
||||
const wrongInputs = [false, 'test', {}, [{}], ['sdf'], null, undefined];
|
||||
|
||||
test('fs.readv with wrong buffers argument', () => {
|
||||
const filename = getFileName();
|
||||
fs.writeFileSync(filename, expectedBuff);
|
||||
const fd = fs.openSync(filename, 'r');
|
||||
|
||||
for (const wrongInput of wrongInputs) {
|
||||
expect(() => fs.readv(fd, wrongInput, null, jest.fn())).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
}
|
||||
|
||||
fs.closeSync(fd);
|
||||
});
|
||||
|
||||
test('fs.readv with wrong fd argument', () => {
|
||||
for (const wrongInput of wrongInputs) {
|
||||
expect(() => fs.readv(wrongInput, jest.fn())).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-readv.js
|
||||
47
test/js/node/test/parallel/fs-realpath-pipe.test.js
Normal file
47
test/js/node/test/parallel/fs-realpath-pipe.test.js
Normal file
@@ -0,0 +1,47 @@
|
||||
//#FILE: test-fs-realpath-pipe.js
|
||||
//#SHA1: 2a876967f5134cd77e2214f2abcbf753d46983cf
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
// Skip test for Windows, AIX, and IBMi
|
||||
const isSkippedPlatform = ['win32', 'aix', 'os400'].includes(process.platform);
|
||||
const testName = `No /dev/stdin on ${process.platform}.`;
|
||||
|
||||
(isSkippedPlatform ? test.skip : test)(testName, () => {
|
||||
const testCases = [
|
||||
`require('fs').realpath('/dev/stdin', (err, resolvedPath) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
if (resolvedPath) {
|
||||
process.exit(2);
|
||||
}
|
||||
});`,
|
||||
`try {
|
||||
if (require('fs').realpathSync('/dev/stdin')) {
|
||||
process.exit(2);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}`
|
||||
];
|
||||
|
||||
for (const code of testCases) {
|
||||
const child = spawnSync(process.execPath, ['-e', code], {
|
||||
stdio: 'pipe'
|
||||
});
|
||||
|
||||
if (child.status !== 2) {
|
||||
console.log(code);
|
||||
console.log(child.stderr.toString());
|
||||
}
|
||||
|
||||
expect(child.status).toBe(2);
|
||||
}
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-realpath-pipe.js
|
||||
24
test/js/node/test/parallel/fs-rmdir-type-check.test.js
Normal file
24
test/js/node/test/parallel/fs-rmdir-type-check.test.js
Normal file
@@ -0,0 +1,24 @@
|
||||
//#FILE: test-fs-rmdir-type-check.js
|
||||
//#SHA1: 2a00191160af6f0f76a82dcaef31d13c9b223d3b
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
test('fs.rmdir and fs.rmdirSync with invalid arguments', () => {
|
||||
[false, 1, [], {}, null, undefined].forEach((i) => {
|
||||
expect(() => fs.rmdir(i, jest.fn())).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
|
||||
expect(() => fs.rmdirSync(i)).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-rmdir-type-check.js
|
||||
84
test/js/node/test/parallel/fs-stream-double-close.test.js
Normal file
84
test/js/node/test/parallel/fs-stream-double-close.test.js
Normal file
@@ -0,0 +1,84 @@
|
||||
//#FILE: test-fs-stream-double-close.js
|
||||
//#SHA1: 25fa219f7ee462e67611751f996393afc1869490
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const tmpdir = path.join(os.tmpdir(), 'node-test-fs-stream-double-close');
|
||||
beforeAll(() => {
|
||||
if (!fs.existsSync(tmpdir)) {
|
||||
fs.mkdirSync(tmpdir, { recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
fs.rmSync(tmpdir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test('test1 with ReadStream', () => {
|
||||
test1(fs.createReadStream(__filename));
|
||||
});
|
||||
|
||||
test('test2 with ReadStream', () => {
|
||||
test2(fs.createReadStream(__filename));
|
||||
});
|
||||
|
||||
test('test3 with ReadStream', () => {
|
||||
test3(fs.createReadStream(__filename));
|
||||
});
|
||||
|
||||
test('test1 with WriteStream', () => {
|
||||
test1(fs.createWriteStream(path.join(tmpdir, 'dummy1')));
|
||||
});
|
||||
|
||||
test('test2 with WriteStream', () => {
|
||||
test2(fs.createWriteStream(path.join(tmpdir, 'dummy2')));
|
||||
});
|
||||
|
||||
test('test3 with WriteStream', () => {
|
||||
test3(fs.createWriteStream(path.join(tmpdir, 'dummy3')));
|
||||
});
|
||||
|
||||
function test1(stream) {
|
||||
stream.destroy();
|
||||
stream.destroy();
|
||||
}
|
||||
|
||||
function test2(stream) {
|
||||
stream.destroy();
|
||||
stream.on('open', jest.fn());
|
||||
}
|
||||
|
||||
function test3(stream) {
|
||||
const openHandler = jest.fn();
|
||||
stream.on('open', openHandler);
|
||||
stream.emit('open');
|
||||
expect(openHandler).toHaveBeenCalledTimes(1);
|
||||
stream.destroy();
|
||||
stream.destroy();
|
||||
}
|
||||
|
||||
//<#END_FILE: test-fs-stream-double-close.js
|
||||
148
test/js/node/test/parallel/fs-symlink.test.js
Normal file
148
test/js/node/test/parallel/fs-symlink.test.js
Normal file
@@ -0,0 +1,148 @@
|
||||
//#FILE: test-fs-symlink.js
|
||||
//#SHA1: 4861a453e314d789a1b933d7179da96b7a35378c
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const canCreateSymLink = () => {
|
||||
try {
|
||||
fs.symlinkSync('', '');
|
||||
fs.unlinkSync('');
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
if (!canCreateSymLink()) {
|
||||
it.skip('insufficient privileges', () => {});
|
||||
} else {
|
||||
let linkTime;
|
||||
let fileTime;
|
||||
const tmpdir = os.tmpdir();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(fs, 'symlink');
|
||||
jest.spyOn(fs, 'lstat');
|
||||
jest.spyOn(fs, 'stat');
|
||||
jest.spyOn(fs, 'readlink');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
test('Test creating and reading symbolic link', async () => {
|
||||
const linkData = path.resolve(__dirname, '../fixtures/cycles/root.js');
|
||||
const linkPath = path.resolve(tmpdir, 'symlink1.js');
|
||||
|
||||
await new Promise((resolve) => {
|
||||
fs.symlink(linkData, linkPath, resolve);
|
||||
});
|
||||
|
||||
expect(fs.symlink).toHaveBeenCalled();
|
||||
|
||||
await new Promise((resolve) => {
|
||||
fs.lstat(linkPath, (err, stats) => {
|
||||
expect(err).toBeNull();
|
||||
linkTime = stats.mtime.getTime();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
await new Promise((resolve) => {
|
||||
fs.stat(linkPath, (err, stats) => {
|
||||
expect(err).toBeNull();
|
||||
fileTime = stats.mtime.getTime();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
await new Promise((resolve) => {
|
||||
fs.readlink(linkPath, (err, destination) => {
|
||||
expect(err).toBeNull();
|
||||
expect(destination).toBe(linkData);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('Test invalid symlink', async () => {
|
||||
const linkData = path.resolve(__dirname, '../fixtures/not/exists/file');
|
||||
const linkPath = path.resolve(tmpdir, 'symlink2.js');
|
||||
|
||||
await new Promise((resolve) => {
|
||||
fs.symlink(linkData, linkPath, resolve);
|
||||
});
|
||||
|
||||
expect(fs.existsSync(linkPath)).toBe(false);
|
||||
});
|
||||
|
||||
test('Test invalid inputs', () => {
|
||||
const invalidInputs = [false, 1, {}, [], null, undefined];
|
||||
const errObj = expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.stringMatching(/target|path/)
|
||||
});
|
||||
|
||||
invalidInputs.forEach((input) => {
|
||||
expect(() => fs.symlink(input, '', () => {})).toThrow(errObj);
|
||||
expect(() => fs.symlinkSync(input, '')).toThrow(errObj);
|
||||
|
||||
expect(() => fs.symlink('', input, () => {})).toThrow(errObj);
|
||||
expect(() => fs.symlinkSync('', input)).toThrow(errObj);
|
||||
});
|
||||
});
|
||||
|
||||
test('Test invalid type inputs', () => {
|
||||
const errObj = expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_VALUE',
|
||||
name: 'TypeError',
|
||||
});
|
||||
|
||||
expect(() => fs.symlink('', '', '🍏', () => {})).toThrow(errObj);
|
||||
expect(() => fs.symlinkSync('', '', '🍏')).toThrow(errObj);
|
||||
|
||||
expect(() => fs.symlink('', '', 'nonExistentType', () => {})).toThrow(errObj);
|
||||
expect(() => fs.symlinkSync('', '', 'nonExistentType')).toThrow(errObj);
|
||||
expect(fs.promises.symlink('', '', 'nonExistentType')).rejects.toMatchObject(errObj);
|
||||
|
||||
expect(() => fs.symlink('', '', false, () => {})).toThrow(errObj);
|
||||
expect(() => fs.symlinkSync('', '', false)).toThrow(errObj);
|
||||
expect(fs.promises.symlink('', '', false)).rejects.toMatchObject(errObj);
|
||||
|
||||
expect(() => fs.symlink('', '', {}, () => {})).toThrow(errObj);
|
||||
expect(() => fs.symlinkSync('', '', {})).toThrow(errObj);
|
||||
expect(fs.promises.symlink('', '', {})).rejects.toMatchObject(errObj);
|
||||
});
|
||||
|
||||
test('Link time should not be equal to file time', () => {
|
||||
expect(linkTime).not.toBe(fileTime);
|
||||
});
|
||||
}
|
||||
|
||||
//<#END_FILE: test-fs-symlink.js
|
||||
@@ -0,0 +1,67 @@
|
||||
//#FILE: test-fs-truncate-clear-file-zero.js
|
||||
//#SHA1: 28aa057c9903ea2436c340ccecfec093c647714c
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
// This test ensures that `fs.truncate` opens the file with `r+` and not `w`,
|
||||
// which had earlier resulted in the target file's content getting zeroed out.
|
||||
// https://github.com/nodejs/node-v0.x-archive/issues/6233
|
||||
|
||||
const filename = path.join(os.tmpdir(), 'truncate-file.txt');
|
||||
|
||||
beforeEach(() => {
|
||||
// Clean up any existing test file
|
||||
try {
|
||||
fs.unlinkSync(filename);
|
||||
} catch (err) {
|
||||
if (err.code !== 'ENOENT') throw err;
|
||||
}
|
||||
});
|
||||
|
||||
test('fs.truncateSync', () => {
|
||||
fs.writeFileSync(filename, '0123456789');
|
||||
expect(fs.readFileSync(filename, 'utf8')).toBe('0123456789');
|
||||
fs.truncateSync(filename, 5);
|
||||
expect(fs.readFileSync(filename, 'utf8')).toBe('01234');
|
||||
});
|
||||
|
||||
test('fs.truncate', async () => {
|
||||
fs.writeFileSync(filename, '0123456789');
|
||||
expect(fs.readFileSync(filename, 'utf8')).toBe('0123456789');
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
fs.truncate(filename, 5, (err) => {
|
||||
if (err) reject(err);
|
||||
else resolve();
|
||||
});
|
||||
});
|
||||
|
||||
expect(fs.readFileSync(filename, 'utf8')).toBe('01234');
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-truncate-clear-file-zero.js
|
||||
26
test/js/node/test/parallel/fs-unlink-type-check.test.js
Normal file
26
test/js/node/test/parallel/fs-unlink-type-check.test.js
Normal file
@@ -0,0 +1,26 @@
|
||||
//#FILE: test-fs-unlink-type-check.js
|
||||
//#SHA1: 337e42f3b15589a7652c32c0a1c92292abf098d0
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
test('fs.unlink and fs.unlinkSync with invalid types', () => {
|
||||
const invalidTypes = [false, 1, {}, [], null, undefined];
|
||||
|
||||
invalidTypes.forEach((invalidType) => {
|
||||
expect(() => fs.unlink(invalidType, jest.fn())).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
|
||||
expect(() => fs.unlinkSync(invalidType)).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-unlink-type-check.js
|
||||
@@ -0,0 +1,62 @@
|
||||
//#FILE: test-fs-watch-close-when-destroyed.js
|
||||
//#SHA1: f062b7243d0c42722a289a6228d4c2c1a503be1b
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
// This tests that closing a watcher when the underlying handle is
|
||||
// already destroyed will result in a noop instead of a crash.
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
// fs-watch on folders have limited capability in AIX.
|
||||
// The testcase makes use of folder watching, and causes
|
||||
// hang. This behavior is documented. Skip this for AIX.
|
||||
|
||||
if (process.platform === 'aix') {
|
||||
it.skip('folder watch capability is limited in AIX.');
|
||||
} else if (process.platform === 'os400') {
|
||||
it.skip('IBMi does not support `fs.watch()`');
|
||||
} else {
|
||||
let root;
|
||||
|
||||
beforeEach(() => {
|
||||
root = path.join(os.tmpdir(), 'watched-directory-' + Math.random().toString(36).slice(2));
|
||||
fs.mkdirSync(root);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
try {
|
||||
fs.rmdirSync(root);
|
||||
} catch (error) {
|
||||
// Ignore errors, directory might already be removed
|
||||
}
|
||||
});
|
||||
|
||||
it('should not crash when closing watcher after handle is destroyed', (done) => {
|
||||
const watcher = fs.watch(root, { persistent: false, recursive: false });
|
||||
|
||||
// The following listeners may or may not be invoked.
|
||||
|
||||
watcher.addListener('error', () => {
|
||||
setTimeout(
|
||||
() => { watcher.close(); }, // Should not crash if it's invoked
|
||||
10
|
||||
);
|
||||
});
|
||||
|
||||
watcher.addListener('change', () => {
|
||||
setTimeout(
|
||||
() => { watcher.close(); },
|
||||
10
|
||||
);
|
||||
});
|
||||
|
||||
fs.rmdirSync(root);
|
||||
// Wait for the listener to hit
|
||||
setTimeout(done, 100);
|
||||
});
|
||||
}
|
||||
|
||||
//<#END_FILE: test-fs-watch-close-when-destroyed.js
|
||||
@@ -0,0 +1,65 @@
|
||||
//#FILE: test-fs-watch-file-enoent-after-deletion.js
|
||||
//#SHA1: d6c93db608d119bd35fcab0e1e9307bfd6558b68
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
// Make sure the deletion event gets reported in the following scenario:
|
||||
// 1. Watch a file.
|
||||
// 2. The initial stat() goes okay.
|
||||
// 3. Something deletes the watched file.
|
||||
// 4. The second stat() fails with ENOENT.
|
||||
|
||||
// The second stat() translates into the first 'change' event but a logic error
|
||||
// stopped it from getting emitted.
|
||||
// https://github.com/nodejs/node-v0.x-archive/issues/4027
|
||||
|
||||
test('fs.watchFile reports deletion', (done) => {
|
||||
const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-'));
|
||||
const filename = path.join(tmpdir, 'watched');
|
||||
fs.writeFileSync(filename, 'quis custodiet ipsos custodes');
|
||||
|
||||
const watcher = jest.fn();
|
||||
fs.watchFile(filename, { interval: 50 }, watcher);
|
||||
|
||||
setTimeout(() => {
|
||||
fs.unlinkSync(filename);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(watcher).toHaveBeenCalledTimes(1);
|
||||
const [curr, prev] = watcher.mock.calls[0];
|
||||
expect(curr.nlink).toBe(0);
|
||||
expect(prev.nlink).toBe(1);
|
||||
|
||||
fs.unwatchFile(filename);
|
||||
fs.rmdirSync(tmpdir);
|
||||
done();
|
||||
}, 100);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-watch-file-enoent-after-deletion.js
|
||||
@@ -0,0 +1,55 @@
|
||||
//#FILE: test-fs-watch-recursive-add-file-with-url.js
|
||||
//#SHA1: e6498ea80abdf69cb66d888bbd7d631931970c0a
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const { setTimeout } = require('timers/promises');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { pathToFileURL } = require('url');
|
||||
const os = require('os');
|
||||
|
||||
const isIBMi = process.platform === 'os400';
|
||||
const isAIX = process.platform === 'aix';
|
||||
|
||||
if (isIBMi) {
|
||||
it.skip('IBMi does not support `fs.watch()`', () => {});
|
||||
} else if (isAIX) {
|
||||
it.skip('folder watch capability is limited in AIX.', () => {});
|
||||
} else {
|
||||
it('should watch for file changes using URL as path', async () => {
|
||||
const testDir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-'));
|
||||
|
||||
// Add a file to already watching folder, and use URL as the path
|
||||
const rootDirectory = fs.mkdtempSync(path.join(testDir, path.sep));
|
||||
const testDirectory = path.join(rootDirectory, 'test-5');
|
||||
fs.mkdirSync(testDirectory);
|
||||
|
||||
const filePath = path.join(testDirectory, 'file-8.txt');
|
||||
const url = pathToFileURL(testDirectory);
|
||||
|
||||
const watcher = fs.watch(url, { recursive: true });
|
||||
let watcherClosed = false;
|
||||
|
||||
const watchPromise = new Promise((resolve) => {
|
||||
watcher.on('change', function(event, filename) {
|
||||
expect(event).toBe('rename');
|
||||
|
||||
if (filename === path.basename(filePath)) {
|
||||
watcher.close();
|
||||
watcherClosed = true;
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await setTimeout(100);
|
||||
fs.writeFileSync(filePath, 'world');
|
||||
|
||||
await watchPromise;
|
||||
|
||||
expect(watcherClosed).toBe(true);
|
||||
}, 10000); // Increase timeout to 10 seconds
|
||||
}
|
||||
|
||||
//<#END_FILE: test-fs-watch-recursive-add-file-with-url.js
|
||||
@@ -0,0 +1,60 @@
|
||||
//#FILE: test-fs-watch-recursive-add-file.js
|
||||
//#SHA1: e87d2c9f4789a6e6a83fbdca56e39683625bd0af
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
|
||||
const isIBMi = os.platform() === 'os400';
|
||||
const isAIX = os.platform() === 'aix';
|
||||
|
||||
if (isIBMi) {
|
||||
it.skip('IBMi does not support `fs.watch()`', () => {});
|
||||
} else if (isAIX) {
|
||||
it.skip('folder watch capability is limited in AIX.', () => {});
|
||||
} else {
|
||||
const tmpdir = {
|
||||
path: path.join(os.tmpdir(), 'jest-test-fs-watch-recursive-add-file'),
|
||||
refresh: () => {
|
||||
if (fs.existsSync(tmpdir.path)) {
|
||||
fs.rmSync(tmpdir.path, { recursive: true, force: true });
|
||||
}
|
||||
fs.mkdirSync(tmpdir.path, { recursive: true });
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
tmpdir.refresh();
|
||||
});
|
||||
|
||||
it('should detect file added to already watching folder', (done) => {
|
||||
const rootDirectory = fs.mkdtempSync(tmpdir.path + path.sep);
|
||||
const testDirectory = path.join(rootDirectory, 'test-1');
|
||||
fs.mkdirSync(testDirectory);
|
||||
|
||||
const testFile = path.join(testDirectory, 'file-1.txt');
|
||||
|
||||
const watcher = fs.watch(testDirectory, { recursive: true });
|
||||
let watcherClosed = false;
|
||||
|
||||
watcher.on('change', function(event, filename) {
|
||||
expect(event).toBe('rename');
|
||||
|
||||
if (filename === path.basename(testFile)) {
|
||||
watcher.close();
|
||||
watcherClosed = true;
|
||||
expect(watcherClosed).toBe(true);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
// Do the write with a delay to ensure that the OS is ready to notify us.
|
||||
setTimeout(() => {
|
||||
fs.writeFileSync(testFile, 'world');
|
||||
}, process.platform === 'win32' ? 200 : 100);
|
||||
});
|
||||
}
|
||||
|
||||
//<#END_FILE: test-fs-watch-recursive-add-file.js
|
||||
@@ -0,0 +1,59 @@
|
||||
//#FILE: test-fs-watch-recursive-add-folder.js
|
||||
//#SHA1: 4c2908ccc8502f5f760963a9b9a6db6ddadd4c1c
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const { setTimeout } = require('timers/promises');
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
|
||||
const isIBMi = os.platform() === 'os400';
|
||||
const isAIX = os.platform() === 'aix';
|
||||
|
||||
if (isIBMi) {
|
||||
it.skip('IBMi does not support `fs.watch()`', () => {});
|
||||
} else if (isAIX) {
|
||||
it.skip('folder watch capability is limited in AIX.', () => {});
|
||||
} else {
|
||||
const testDir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-'));
|
||||
|
||||
afterAll(() => {
|
||||
fs.rmSync(testDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test('Add a folder to already watching folder', async () => {
|
||||
// Add a folder to already watching folder
|
||||
|
||||
const rootDirectory = fs.mkdtempSync(path.join(testDir, 'root-'));
|
||||
const testDirectory = path.join(rootDirectory, 'test-2');
|
||||
fs.mkdirSync(testDirectory);
|
||||
|
||||
const testFile = path.join(testDirectory, 'folder-2');
|
||||
|
||||
const watcher = fs.watch(testDirectory, { recursive: true });
|
||||
let watcherClosed = false;
|
||||
|
||||
const watchPromise = new Promise((resolve) => {
|
||||
watcher.on('change', function(event, filename) {
|
||||
expect(event).toBe('rename');
|
||||
|
||||
if (filename === path.basename(testFile)) {
|
||||
watcher.close();
|
||||
watcherClosed = true;
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await setTimeout(100);
|
||||
fs.mkdirSync(testFile);
|
||||
|
||||
await watchPromise;
|
||||
|
||||
expect(watcherClosed).toBe(true);
|
||||
});
|
||||
}
|
||||
|
||||
//<#END_FILE: test-fs-watch-recursive-add-folder.js
|
||||
@@ -0,0 +1,52 @@
|
||||
//#FILE: test-fs-watch-recursive-linux-parallel-remove.js
|
||||
//#SHA1: ed10536d8d54febe24a3dcf494a26eab06bc4f66
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const path = require('node:path');
|
||||
const fs = require('node:fs');
|
||||
const { spawn } = require('node:child_process');
|
||||
const os = require('node:os');
|
||||
|
||||
// Skip test if not running on Linux
|
||||
if (os.platform() !== 'linux') {
|
||||
test.skip('This test can run only on Linux', () => {});
|
||||
} else {
|
||||
// Test that the watcher do not crash if the file "disappears" while
|
||||
// watch is being set up.
|
||||
|
||||
let testDir;
|
||||
let watcher;
|
||||
|
||||
beforeEach(() => {
|
||||
testDir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-'));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
if (watcher) {
|
||||
watcher.close();
|
||||
}
|
||||
fs.rmSync(testDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test('fs.watch does not crash on parallel file removal', (done) => {
|
||||
watcher = fs.watch(testDir, { recursive: true });
|
||||
watcher.on('change', function(event, filename) {
|
||||
// This console.log makes the error happen
|
||||
// do not remove
|
||||
console.log(filename, event);
|
||||
});
|
||||
|
||||
const testFile = path.join(testDir, 'a');
|
||||
const child = spawn(process.argv[0], ['-e', `const fs = require('node:fs'); for (let i = 0; i < 10000; i++) { const fd = fs.openSync('${testFile}', 'w'); fs.writeSync(fd, Buffer.from('hello')); fs.rmSync('${testFile}') }`], {
|
||||
stdio: 'inherit'
|
||||
});
|
||||
|
||||
child.on('exit', function() {
|
||||
watcher.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//<#END_FILE: test-fs-watch-recursive-linux-parallel-remove.js
|
||||
@@ -0,0 +1,47 @@
|
||||
//#FILE: test-fs-watch-recursive-validate.js
|
||||
//#SHA1: eb5d9ff1caac7f9d4acf694c43e4f634f538befb
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
|
||||
const isIBMi = process.platform === 'os400';
|
||||
const isAIX = process.platform === 'aix';
|
||||
const isWindows = process.platform === 'win32';
|
||||
const isOSX = process.platform === 'darwin';
|
||||
|
||||
if (isIBMi) {
|
||||
test.skip('IBMi does not support `fs.watch()`', () => {});
|
||||
} else if (isAIX) {
|
||||
test.skip('folder watch capability is limited in AIX.', () => {});
|
||||
} else {
|
||||
const tmpdir = {
|
||||
path: path.join(os.tmpdir(), 'jest-fs-watch-recursive-validate'),
|
||||
refresh: () => {
|
||||
if (fs.existsSync(tmpdir.path)) {
|
||||
fs.rmSync(tmpdir.path, { recursive: true, force: true });
|
||||
}
|
||||
fs.mkdirSync(tmpdir.path, { recursive: true });
|
||||
},
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
tmpdir.refresh();
|
||||
});
|
||||
|
||||
test('Handle non-boolean values for options.recursive', async () => {
|
||||
if (!isWindows && !isOSX) {
|
||||
expect(() => {
|
||||
const testsubdir = fs.mkdtempSync(tmpdir.path + path.sep);
|
||||
fs.watch(testsubdir, { recursive: '1' });
|
||||
}).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//<#END_FILE: test-fs-watch-recursive-validate.js
|
||||
@@ -0,0 +1,66 @@
|
||||
//#FILE: test-fs-watch-recursive-watch-file.js
|
||||
//#SHA1: 1f06958f6f645cb5c80b424a24b046f107ab83ae
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
|
||||
const isIBMi = os.platform() === 'os400';
|
||||
const isAIX = os.platform() === 'aix';
|
||||
|
||||
if (isIBMi) {
|
||||
test.skip('IBMi does not support `fs.watch()`');
|
||||
}
|
||||
|
||||
// fs-watch on folders have limited capability in AIX.
|
||||
// The testcase makes use of folder watching, and causes
|
||||
// hang. This behavior is documented. Skip this for AIX.
|
||||
|
||||
if (isAIX) {
|
||||
test.skip('folder watch capability is limited in AIX.');
|
||||
}
|
||||
|
||||
const platformTimeout = (ms) => ms * (process.platform === 'win32' ? 2 : 1);
|
||||
|
||||
test('Watch a file (not a folder) using fs.watch', async () => {
|
||||
// Create a temporary directory for testing
|
||||
const testDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'test-'));
|
||||
const rootDirectory = await fs.promises.mkdtemp(path.join(testDir, path.sep));
|
||||
const testDirectory = path.join(rootDirectory, 'test-6');
|
||||
await fs.promises.mkdir(testDirectory);
|
||||
|
||||
const filePath = path.join(testDirectory, 'only-file.txt');
|
||||
await fs.promises.writeFile(filePath, 'hello');
|
||||
|
||||
let watcherClosed = false;
|
||||
let interval;
|
||||
|
||||
const watcher = fs.watch(filePath, { recursive: true });
|
||||
|
||||
const watchPromise = new Promise((resolve) => {
|
||||
watcher.on('change', function(event, filename) {
|
||||
expect(event).toBe('change');
|
||||
|
||||
if (filename === path.basename(filePath)) {
|
||||
clearInterval(interval);
|
||||
interval = null;
|
||||
watcher.close();
|
||||
watcherClosed = true;
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
interval = setInterval(() => {
|
||||
fs.writeFileSync(filePath, 'world');
|
||||
}, platformTimeout(10));
|
||||
|
||||
await watchPromise;
|
||||
|
||||
expect(watcherClosed).toBe(true);
|
||||
expect(interval).toBeNull();
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-watch-recursive-watch-file.js
|
||||
29
test/js/node/test/parallel/fs-watch-ref-unref.test.js
Normal file
29
test/js/node/test/parallel/fs-watch-ref-unref.test.js
Normal file
@@ -0,0 +1,29 @@
|
||||
//#FILE: test-fs-watch-ref-unref.js
|
||||
//#SHA1: ffceabfd7f8fef655b05735b8bba7fb059609980
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
if (process.platform === 'os400') {
|
||||
test.skip('IBMi does not support `fs.watch()`');
|
||||
}
|
||||
|
||||
test('fs.watch() can be unref()ed and ref()ed', () => {
|
||||
const watcher = fs.watch(__filename, () => {
|
||||
// This callback should not be called
|
||||
expect(true).toBe(false);
|
||||
});
|
||||
|
||||
watcher.unref();
|
||||
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
watcher.ref();
|
||||
watcher.unref();
|
||||
resolve();
|
||||
}, process.platform === 'win32' ? 100 : 50);
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-watch-ref-unref.js
|
||||
27
test/js/node/test/parallel/fs-watch-stop-sync.test.js
Normal file
27
test/js/node/test/parallel/fs-watch-stop-sync.test.js
Normal file
@@ -0,0 +1,27 @@
|
||||
//#FILE: test-fs-watch-stop-sync.js
|
||||
//#SHA1: 8285d2bd43d2f9be7be525417cf51f9336b2f379
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
// This test checks that the `stop` event is emitted asynchronously.
|
||||
//
|
||||
// If it isn't asynchronous, then the listener will be called during the
|
||||
// execution of `watch.stop()`. That would be a bug.
|
||||
//
|
||||
// If it is asynchronous, then the listener will be removed before the event is
|
||||
// emitted.
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
test('stop event is emitted asynchronously', () => {
|
||||
const listener = jest.fn();
|
||||
|
||||
const watch = fs.watchFile(__filename, jest.fn());
|
||||
watch.once('stop', listener);
|
||||
watch.stop();
|
||||
watch.removeListener('stop', listener);
|
||||
|
||||
expect(listener).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-watch-stop-sync.js
|
||||
70
test/js/node/test/parallel/fs-write-file-buffer.test.js
Normal file
70
test/js/node/test/parallel/fs-write-file-buffer.test.js
Normal file
@@ -0,0 +1,70 @@
|
||||
//#FILE: test-fs-write-file-buffer.js
|
||||
//#SHA1: f721ad0f6969d6cf1ba78f96ccf9600a7f93458d
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
let data = [
|
||||
'/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcH',
|
||||
'Bw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/',
|
||||
'2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e',
|
||||
'Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAQABADASIAAhEBAxEB/8QA',
|
||||
'HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUF',
|
||||
'BAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK',
|
||||
'FhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1',
|
||||
'dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG',
|
||||
'x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEB',
|
||||
'AQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAEC',
|
||||
'AxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRom',
|
||||
'JygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE',
|
||||
'hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU',
|
||||
'1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDhfBUFl/wk',
|
||||
'OmPqKJJZw3aiZFBw4z93jnkkc9u9dj8XLfSI/EBt7DTo7ea2Ox5YXVo5FC7g',
|
||||
'Tjq24nJPXNVtO0KATRvNHCIg3zoWJWQHqp+o4pun+EtJ0zxBq8mnLJa2d1L5',
|
||||
'0NvnKRjJBUE5PAx3NYxxUY0pRtvYHSc5Ka2X9d7H/9k='];
|
||||
|
||||
data = data.join('\n');
|
||||
|
||||
let tmpdir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpdir = fs.mkdtempSync(path.join(process.env.TEST_TMPDIR || '/tmp', 'test-fs-write-file-buffer-'));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fs.rmSync(tmpdir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test('writeFileSync with Buffer', () => {
|
||||
const buf = Buffer.from(data, 'base64');
|
||||
const testFile = path.join(tmpdir, 'test.jpg');
|
||||
|
||||
fs.writeFileSync(testFile, buf);
|
||||
|
||||
expect(fs.existsSync(testFile)).toBe(true);
|
||||
expect(fs.readFileSync(testFile)).toEqual(buf);
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-write-file-buffer.js
|
||||
25
test/js/node/test/parallel/fs-write-no-fd.test.js
Normal file
25
test/js/node/test/parallel/fs-write-no-fd.test.js
Normal file
@@ -0,0 +1,25 @@
|
||||
//#FILE: test-fs-write-no-fd.js
|
||||
//#SHA1: eade06241743a0d7e72b5239633e1ddd947f3a28
|
||||
//-----------------
|
||||
'use strict';
|
||||
const fs = require('fs');
|
||||
|
||||
test('fs.write with null fd and Buffer throws TypeError', () => {
|
||||
expect(() => {
|
||||
fs.write(null, Buffer.allocUnsafe(1), 0, 1, () => {});
|
||||
}).toThrow(expect.objectContaining({
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
|
||||
test('fs.write with null fd and string throws TypeError', () => {
|
||||
expect(() => {
|
||||
fs.write(null, '1', 0, 1, () => {});
|
||||
}).toThrow(expect.objectContaining({
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-write-no-fd.js
|
||||
@@ -0,0 +1,38 @@
|
||||
//#FILE: test-fs-write-stream-close-without-callback.js
|
||||
//#SHA1: 63e0c345b440c8cfb157aa84340f387cf314e20f
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const tmpdir = path.join(os.tmpdir(), 'test-fs-write-stream-close-without-callback');
|
||||
|
||||
beforeEach(() => {
|
||||
// Create a fresh temporary directory before each test
|
||||
if (!fs.existsSync(tmpdir)) {
|
||||
fs.mkdirSync(tmpdir, { recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Clean up the temporary directory after each test
|
||||
if (fs.existsSync(tmpdir)) {
|
||||
fs.rmSync(tmpdir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('fs.WriteStream can be closed without a callback', () => {
|
||||
const filePath = path.join(tmpdir, 'nocallback');
|
||||
const s = fs.createWriteStream(filePath);
|
||||
|
||||
s.end('hello world');
|
||||
s.close();
|
||||
|
||||
// We don't need to assert anything here as the test is checking
|
||||
// that the above operations don't throw an error
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-write-stream-close-without-callback.js
|
||||
76
test/js/node/test/parallel/fs-write-stream-end.test.js
Normal file
76
test/js/node/test/parallel/fs-write-stream-end.test.js
Normal file
@@ -0,0 +1,76 @@
|
||||
//#FILE: test-fs-write-stream-end.js
|
||||
//#SHA1: a4194cfb1f416f5fddd5edc55b7d867db14a5320
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const tmpdir = path.join(__dirname, 'tmp');
|
||||
|
||||
beforeAll(() => {
|
||||
if (!fs.existsSync(tmpdir)) {
|
||||
fs.mkdirSync(tmpdir, { recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
fs.rmSync(tmpdir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test('end without data', (done) => {
|
||||
const file = path.join(tmpdir, 'write-end-test0.txt');
|
||||
const stream = fs.createWriteStream(file);
|
||||
stream.end();
|
||||
stream.on('close', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('end with data', (done) => {
|
||||
const file = path.join(tmpdir, 'write-end-test1.txt');
|
||||
const stream = fs.createWriteStream(file);
|
||||
stream.end('a\n', 'utf8');
|
||||
stream.on('close', () => {
|
||||
const content = fs.readFileSync(file, 'utf8');
|
||||
expect(content).toBe('a\n');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('end triggers open and finish events', (done) => {
|
||||
const file = path.join(tmpdir, 'write-end-test2.txt');
|
||||
const stream = fs.createWriteStream(file);
|
||||
stream.end();
|
||||
|
||||
let calledOpen = false;
|
||||
stream.on('open', () => {
|
||||
calledOpen = true;
|
||||
});
|
||||
stream.on('finish', () => {
|
||||
expect(calledOpen).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-write-stream-end.js
|
||||
66
test/js/node/test/parallel/fs-write-sync.test.js
Normal file
66
test/js/node/test/parallel/fs-write-sync.test.js
Normal file
@@ -0,0 +1,66 @@
|
||||
//#FILE: test-fs-write-sync.js
|
||||
//#SHA1: 4ae5fa7550eefe258b9c1de798f4a4092e9d15d1
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const filename = path.join(os.tmpdir(), 'write.txt');
|
||||
|
||||
beforeEach(() => {
|
||||
try {
|
||||
fs.unlinkSync(filename);
|
||||
} catch (err) {
|
||||
// Ignore errors if file doesn't exist
|
||||
}
|
||||
});
|
||||
|
||||
test('fs.writeSync with various parameter combinations', () => {
|
||||
const parameters = [Buffer.from('bár'), 0, Buffer.byteLength('bár')];
|
||||
|
||||
// The first time fs.writeSync is called with all parameters provided.
|
||||
// After that, each pop in the cycle removes the final parameter. So:
|
||||
// - The 2nd time fs.writeSync with a buffer, without the length parameter.
|
||||
// - The 3rd time fs.writeSync with a buffer, without the offset and length
|
||||
// parameters.
|
||||
while (parameters.length > 0) {
|
||||
const fd = fs.openSync(filename, 'w');
|
||||
|
||||
let written = fs.writeSync(fd, '');
|
||||
expect(written).toBe(0);
|
||||
|
||||
fs.writeSync(fd, 'foo');
|
||||
|
||||
written = fs.writeSync(fd, ...parameters);
|
||||
expect(written).toBeGreaterThan(3);
|
||||
fs.closeSync(fd);
|
||||
|
||||
expect(fs.readFileSync(filename, 'utf-8')).toBe('foobár');
|
||||
|
||||
parameters.pop();
|
||||
}
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-write-sync.js
|
||||
43
test/js/node/test/parallel/fs-writestream-open-write.test.js
Normal file
43
test/js/node/test/parallel/fs-writestream-open-write.test.js
Normal file
@@ -0,0 +1,43 @@
|
||||
//#FILE: test-fs-writestream-open-write.js
|
||||
//#SHA1: a4cb8508ae1f366c94442a43312a817f00b68de6
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
// Regression test for https://github.com/nodejs/node/issues/51993
|
||||
|
||||
let tmpdir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-fs-writestream-open-write-'));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fs.rmSync(tmpdir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test('fs.createWriteStream opens and writes correctly', (done) => {
|
||||
const file = path.join(tmpdir, 'test-fs-writestream-open-write.txt');
|
||||
|
||||
const w = fs.createWriteStream(file);
|
||||
|
||||
w.on('open', () => {
|
||||
w.write('hello');
|
||||
|
||||
process.nextTick(() => {
|
||||
w.write('world');
|
||||
w.end();
|
||||
});
|
||||
});
|
||||
|
||||
w.on('close', () => {
|
||||
expect(fs.readFileSync(file, 'utf8')).toBe('helloworld');
|
||||
fs.unlinkSync(file);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-writestream-open-write.js
|
||||
@@ -0,0 +1,36 @@
|
||||
//#FILE: test-http-upgrade-reconsume-stream.js
|
||||
//#SHA1: 4117d0b2212d192173b5bd6bf2ef7fe82f627079
|
||||
//-----------------
|
||||
"use strict";
|
||||
|
||||
const tls = require("tls");
|
||||
const http = require("http");
|
||||
|
||||
// Tests that, after the HTTP parser stopped owning a socket that emits an
|
||||
// 'upgrade' event, another C++ stream can start owning it (e.g. a TLSSocket).
|
||||
|
||||
test("HTTP upgrade and TLSSocket creation", done => {
|
||||
const server = http.createServer(expect.any(Function));
|
||||
|
||||
server.on("upgrade", (request, socket, head) => {
|
||||
// This should not crash.
|
||||
new tls.TLSSocket(socket);
|
||||
server.close();
|
||||
socket.destroy();
|
||||
done();
|
||||
});
|
||||
|
||||
server.listen(0, () => {
|
||||
http
|
||||
.get({
|
||||
port: server.address().port,
|
||||
headers: {
|
||||
"Connection": "Upgrade",
|
||||
"Upgrade": "websocket",
|
||||
},
|
||||
})
|
||||
.on("error", () => {});
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-http-upgrade-reconsume-stream.js
|
||||
@@ -0,0 +1,59 @@
|
||||
//#FILE: test-http-url.parse-auth-with-header-in-request.js
|
||||
//#SHA1: 396adc5e441a57d24b11a42513c834b6b11ea7ff
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
const http = require("http");
|
||||
const url = require("url");
|
||||
|
||||
test("http url parse auth with header in request", async () => {
|
||||
function check(request) {
|
||||
// The correct authorization header is be passed
|
||||
expect(request.headers.authorization).toBe("NoAuthForYOU");
|
||||
}
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
// Run the check function
|
||||
check(request);
|
||||
response.writeHead(200, {});
|
||||
response.end("ok");
|
||||
server.close();
|
||||
});
|
||||
|
||||
await new Promise(resolve => {
|
||||
server.listen(0, () => {
|
||||
const testURL = url.parse(`http://asdf:qwer@localhost:${server.address().port}`);
|
||||
// The test here is if you set a specific authorization header in the
|
||||
// request we should not override that with basic auth
|
||||
testURL.headers = {
|
||||
Authorization: "NoAuthForYOU",
|
||||
};
|
||||
|
||||
// make the request
|
||||
http.request(testURL).end();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-http-url.parse-auth-with-header-in-request.js
|
||||
56
test/js/node/test/parallel/http-url.parse-auth.test.js
Normal file
56
test/js/node/test/parallel/http-url.parse-auth.test.js
Normal file
@@ -0,0 +1,56 @@
|
||||
//#FILE: test-http-url.parse-auth.js
|
||||
//#SHA1: 97f9b1c737c705489b2d6402750034291a9f6f63
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
const http = require("http");
|
||||
const url = require("url");
|
||||
|
||||
test("HTTP URL parse auth", async () => {
|
||||
function check(request) {
|
||||
// The correct authorization header is be passed
|
||||
expect(request.headers.authorization).toBe("Basic dXNlcjpwYXNzOg==");
|
||||
}
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
// Run the check function
|
||||
check(request);
|
||||
response.writeHead(200, {});
|
||||
response.end("ok");
|
||||
server.close();
|
||||
});
|
||||
|
||||
await new Promise(resolve => {
|
||||
server.listen(0, () => {
|
||||
const port = server.address().port;
|
||||
// username = "user", password = "pass:"
|
||||
const testURL = url.parse(`http://user:pass%3A@localhost:${port}`);
|
||||
|
||||
// make the request
|
||||
http.request(testURL).end();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-http-url.parse-auth.js
|
||||
65
test/js/node/test/parallel/http-url.parse-basic.test.js
Normal file
65
test/js/node/test/parallel/http-url.parse-basic.test.js
Normal file
@@ -0,0 +1,65 @@
|
||||
//#FILE: test-http-url.parse-basic.js
|
||||
//#SHA1: f2f2841de1c82e38067e73196926090f350d89c6
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
const http = require("http");
|
||||
const url = require("url");
|
||||
|
||||
let testURL;
|
||||
|
||||
// Make sure the basics work
|
||||
function check(request) {
|
||||
// Default method should still be 'GET'
|
||||
expect(request.method).toBe("GET");
|
||||
// There are no URL params, so you should not see any
|
||||
expect(request.url).toBe("/");
|
||||
// The host header should use the url.parse.hostname
|
||||
expect(request.headers.host).toBe(`${testURL.hostname}:${testURL.port}`);
|
||||
}
|
||||
|
||||
test("HTTP URL parsing basics", async () => {
|
||||
const server = http.createServer((request, response) => {
|
||||
// Run the check function
|
||||
check(request);
|
||||
response.writeHead(200, {});
|
||||
response.end("ok");
|
||||
server.close();
|
||||
});
|
||||
|
||||
await new Promise(resolve => {
|
||||
server.listen(0, () => {
|
||||
testURL = url.parse(`http://localhost:${server.address().port}`);
|
||||
|
||||
// make the request
|
||||
const clientRequest = http.request(testURL);
|
||||
// Since there is a little magic with the agent
|
||||
// make sure that an http request uses the http.Agent
|
||||
expect(clientRequest.agent).toBeInstanceOf(http.Agent);
|
||||
clientRequest.end();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-http-url.parse-basic.js
|
||||
54
test/js/node/test/parallel/http-url.parse-path.test.js
Normal file
54
test/js/node/test/parallel/http-url.parse-path.test.js
Normal file
@@ -0,0 +1,54 @@
|
||||
//#FILE: test-http-url.parse-path.js
|
||||
//#SHA1: 9eb246a6c09b70b76260a83bec4bb25452d38b7d
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
const http = require("http");
|
||||
const url = require("url");
|
||||
|
||||
test("HTTP request URL parsing", async () => {
|
||||
function check(request) {
|
||||
// A path should come over
|
||||
expect(request.url).toBe("/asdf");
|
||||
}
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
// Run the check function
|
||||
check(request);
|
||||
response.writeHead(200, {});
|
||||
response.end("ok");
|
||||
server.close();
|
||||
});
|
||||
|
||||
await new Promise(resolve => {
|
||||
server.listen(0, () => {
|
||||
const testURL = url.parse(`http://localhost:${server.address().port}/asdf`);
|
||||
|
||||
// make the request
|
||||
http.request(testURL).end();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-http-url.parse-path.js
|
||||
59
test/js/node/test/parallel/http-url.parse-post.test.js
Normal file
59
test/js/node/test/parallel/http-url.parse-post.test.js
Normal file
@@ -0,0 +1,59 @@
|
||||
//#FILE: test-http-url.parse-post.js
|
||||
//#SHA1: e0e7f97c725fb9eaa6058365bef5021e9710e857
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
const http = require("http");
|
||||
const url = require("url");
|
||||
|
||||
let testURL;
|
||||
|
||||
function check(request) {
|
||||
// url.parse should not mess with the method
|
||||
expect(request.method).toBe("POST");
|
||||
// Everything else should be right
|
||||
expect(request.url).toBe("/asdf?qwer=zxcv");
|
||||
// The host header should use the url.parse.hostname
|
||||
expect(request.headers.host).toBe(`${testURL.hostname}:${testURL.port}`);
|
||||
}
|
||||
|
||||
test("http.request with url.parse and POST method", done => {
|
||||
const server = http.createServer((request, response) => {
|
||||
// Run the check function
|
||||
check(request);
|
||||
response.writeHead(200, {});
|
||||
response.end("ok");
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
|
||||
server.listen(0, () => {
|
||||
testURL = url.parse(`http://localhost:${server.address().port}/asdf?qwer=zxcv`);
|
||||
testURL.method = "POST";
|
||||
|
||||
// make the request
|
||||
http.request(testURL).end();
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-http-url.parse-post.js
|
||||
55
test/js/node/test/parallel/http-url.parse-search.test.js
Normal file
55
test/js/node/test/parallel/http-url.parse-search.test.js
Normal file
@@ -0,0 +1,55 @@
|
||||
//#FILE: test-http-url.parse-search.js
|
||||
//#SHA1: 11d08b9c62625b7b554d5fb46d63c4aaa77c1a7c
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
const http = require("http");
|
||||
const url = require("url");
|
||||
|
||||
test("http url parse search", async () => {
|
||||
function check(request) {
|
||||
// A path should come over with params
|
||||
expect(request.url).toBe("/asdf?qwer=zxcv");
|
||||
}
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
// Run the check function
|
||||
check(request);
|
||||
response.writeHead(200, {});
|
||||
response.end("ok");
|
||||
server.close();
|
||||
});
|
||||
|
||||
await new Promise(resolve => {
|
||||
server.listen(0, () => {
|
||||
const port = server.address().port;
|
||||
const testURL = url.parse(`http://localhost:${port}/asdf?qwer=zxcv`);
|
||||
|
||||
// make the request
|
||||
http.request(testURL).end();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-http-url.parse-search.js
|
||||
61
test/js/node/test/parallel/http-write-empty-string.test.js
Normal file
61
test/js/node/test/parallel/http-write-empty-string.test.js
Normal file
@@ -0,0 +1,61 @@
|
||||
//#FILE: test-http-write-empty-string.js
|
||||
//#SHA1: 779199784d3142e353324041eeb30924c7e4d5b1
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
const http = require("http");
|
||||
|
||||
test("HTTP server writing empty string", async () => {
|
||||
const server = http.createServer(function (request, response) {
|
||||
console.log(`responding to ${request.url}`);
|
||||
|
||||
response.writeHead(200, { "Content-Type": "text/plain" });
|
||||
response.write("1\n");
|
||||
response.write("");
|
||||
response.write("2\n");
|
||||
response.write("");
|
||||
response.end("3\n");
|
||||
|
||||
this.close();
|
||||
});
|
||||
|
||||
await new Promise(resolve => {
|
||||
server.listen(0, () => {
|
||||
http.get({ port: server.address().port }, res => {
|
||||
let response = "";
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
res.setEncoding("ascii");
|
||||
res.on("data", chunk => {
|
||||
response += chunk;
|
||||
});
|
||||
res.on("end", () => {
|
||||
expect(response).toBe("1\n2\n3\n");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-http-write-empty-string.js
|
||||
30
test/js/node/test/parallel/http-zerolengthbuffer.test.js
Normal file
30
test/js/node/test/parallel/http-zerolengthbuffer.test.js
Normal file
@@ -0,0 +1,30 @@
|
||||
//#FILE: test-http-zerolengthbuffer.js
|
||||
//#SHA1: 28fff143238744f829f63936c8902047ad2c2fc5
|
||||
//-----------------
|
||||
"use strict";
|
||||
// Serving up a zero-length buffer should work.
|
||||
|
||||
const http = require("http");
|
||||
|
||||
test("Serve zero-length buffer", done => {
|
||||
const server = http.createServer((req, res) => {
|
||||
const buffer = Buffer.alloc(0);
|
||||
res.writeHead(200, { "Content-Type": "text/html", "Content-Length": buffer.length });
|
||||
res.end(buffer);
|
||||
});
|
||||
|
||||
server.listen(0, () => {
|
||||
http.get({ port: server.address().port }, res => {
|
||||
const dataHandler = jest.fn();
|
||||
res.on("data", dataHandler);
|
||||
|
||||
res.on("end", () => {
|
||||
expect(dataHandler).not.toHaveBeenCalled();
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-http-zerolengthbuffer.js
|
||||
18
test/js/node/test/parallel/module-builtin.test.js
Normal file
18
test/js/node/test/parallel/module-builtin.test.js
Normal file
@@ -0,0 +1,18 @@
|
||||
//#FILE: test-module-builtin.js
|
||||
//#SHA1: 18114886f66eccc937942a815feca25d9b324a37
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const { builtinModules } = require('module');
|
||||
|
||||
test('builtinModules includes modules in lib/ (even deprecated ones)', () => {
|
||||
expect(builtinModules).toContain('http');
|
||||
expect(builtinModules).toContain('sys');
|
||||
});
|
||||
|
||||
test('builtinModules does not include internal modules', () => {
|
||||
const internalModules = builtinModules.filter((mod) => mod.startsWith('internal/'));
|
||||
expect(internalModules).toHaveLength(0);
|
||||
});
|
||||
|
||||
//<#END_FILE: test-module-builtin.js
|
||||
37
test/js/node/test/parallel/module-cache.test.js
Normal file
37
test/js/node/test/parallel/module-cache.test.js
Normal file
@@ -0,0 +1,37 @@
|
||||
//#FILE: test-module-cache.js
|
||||
//#SHA1: ff0f4c6ca37e23c009f98bba966e9daee2dcaef6
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
let tmpdir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-module-cache-'));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fs.rmSync(tmpdir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test('throws MODULE_NOT_FOUND when file does not exist', () => {
|
||||
const filePath = path.join(tmpdir, 'test-module-cache.json');
|
||||
expect(() => require(filePath)).toThrow(expect.objectContaining({
|
||||
code: 'MODULE_NOT_FOUND',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
|
||||
test('requires JSON file successfully after creation', () => {
|
||||
const filePath = path.join(tmpdir, 'test-module-cache.json');
|
||||
fs.writeFileSync(filePath, '[]');
|
||||
|
||||
const content = require(filePath);
|
||||
expect(Array.isArray(content)).toBe(true);
|
||||
expect(content.length).toBe(0);
|
||||
});
|
||||
|
||||
//<#END_FILE: test-module-cache.js
|
||||
39
test/js/node/test/parallel/net-server-unref.test.js
Normal file
39
test/js/node/test/parallel/net-server-unref.test.js
Normal file
@@ -0,0 +1,39 @@
|
||||
//#FILE: test-net-server-unref.js
|
||||
//#SHA1: bb2f989bf01182d804d6a8a0d0f33950f357c617
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
const net = require('net');
|
||||
|
||||
test('net server unref', () => {
|
||||
const s = net.createServer();
|
||||
s.listen(0);
|
||||
s.unref();
|
||||
|
||||
const mockCallback = jest.fn();
|
||||
setTimeout(mockCallback, 1000).unref();
|
||||
|
||||
expect(mockCallback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
//<#END_FILE: test-net-server-unref.js
|
||||
@@ -0,0 +1,40 @@
|
||||
//#FILE: test-net-socket-close-after-end.js
|
||||
//#SHA1: d3abfad3599a4245fb35f5589c55bb56a43ca3f7
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const net = require('net');
|
||||
|
||||
test('socket emits "end" before "close"', (done) => {
|
||||
const server = net.createServer();
|
||||
|
||||
server.on('connection', (socket) => {
|
||||
let endEmitted = false;
|
||||
|
||||
socket.once('readable', () => {
|
||||
setTimeout(() => {
|
||||
socket.read();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
socket.on('end', () => {
|
||||
endEmitted = true;
|
||||
});
|
||||
|
||||
socket.on('close', () => {
|
||||
expect(endEmitted).toBe(true);
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
|
||||
socket.end('foo');
|
||||
});
|
||||
|
||||
server.listen(() => {
|
||||
const socket = net.createConnection(server.address().port, () => {
|
||||
socket.end('foo');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-net-socket-close-after-end.js
|
||||
@@ -0,0 +1,35 @@
|
||||
//#FILE: test-net-socket-connect-without-cb.js
|
||||
//#SHA1: 2441c4dfe4351f2e9a02cd08df36e4703096864a
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const net = require('net');
|
||||
|
||||
// This test ensures that socket.connect can be called without callback
|
||||
// which is optional.
|
||||
|
||||
test('socket.connect without callback', (done) => {
|
||||
const server = net.createServer((conn) => {
|
||||
conn.end();
|
||||
server.close();
|
||||
}).listen(0, () => {
|
||||
const client = new net.Socket();
|
||||
|
||||
client.on('connect', () => {
|
||||
client.end();
|
||||
done();
|
||||
});
|
||||
|
||||
const address = server.address();
|
||||
if (process.version.startsWith('v') && !process.versions.bun && address.family === 'IPv6') {
|
||||
// Necessary to pass CI running inside containers.
|
||||
client.connect(address.port);
|
||||
} else {
|
||||
client.connect(address);
|
||||
}
|
||||
});
|
||||
|
||||
expect(server).toBeDefined();
|
||||
});
|
||||
|
||||
//<#END_FILE: test-net-socket-connect-without-cb.js
|
||||
65
test/js/node/test/parallel/net-socket-timeout-unref.test.js
Normal file
65
test/js/node/test/parallel/net-socket-timeout-unref.test.js
Normal file
@@ -0,0 +1,65 @@
|
||||
//#FILE: test-net-socket-timeout-unref.js
|
||||
//#SHA1: 1583fd33473989bba11fead2493c70a79d9ff48e
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
|
||||
// Test that unref'ed sockets with timeouts do not prevent exit.
|
||||
|
||||
const net = require('net');
|
||||
|
||||
test('unref\'ed sockets with timeouts do not prevent exit', () => {
|
||||
const server = net.createServer((c) => {
|
||||
c.write('hello');
|
||||
c.unref();
|
||||
});
|
||||
server.listen(0);
|
||||
server.unref();
|
||||
|
||||
let connections = 0;
|
||||
const sockets = [];
|
||||
const delays = [8, 5, 3, 6, 2, 4];
|
||||
|
||||
delays.forEach((T) => {
|
||||
const socket = net.createConnection(server.address().port, 'localhost');
|
||||
socket.on('connect', () => {
|
||||
if (++connections === delays.length) {
|
||||
sockets.forEach((s) => {
|
||||
s.socket.setTimeout(s.timeout, () => {
|
||||
s.socket.destroy();
|
||||
throw new Error('socket timed out unexpectedly');
|
||||
});
|
||||
|
||||
s.socket.unref();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
sockets.push({ socket: socket, timeout: T * 1000 });
|
||||
});
|
||||
|
||||
// We don't need to explicitly assert anything here.
|
||||
// The test will pass if the process exits without throwing an error.
|
||||
});
|
||||
|
||||
//<#END_FILE: test-net-socket-timeout-unref.js
|
||||
34
test/js/node/test/parallel/net-socket-write-error.test.js
Normal file
34
test/js/node/test/parallel/net-socket-write-error.test.js
Normal file
@@ -0,0 +1,34 @@
|
||||
//#FILE: test-net-socket-write-error.js
|
||||
//#SHA1: a69bb02fc98fc265ad23ff03e7ae16e9c984202d
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const net = require('net');
|
||||
|
||||
test('net socket write error', (done) => {
|
||||
const server = net.createServer().listen(0, connectToServer);
|
||||
|
||||
function connectToServer() {
|
||||
const client = net.createConnection(this.address().port, () => {
|
||||
client.on('error', () => {
|
||||
throw new Error('Error event should not be emitted');
|
||||
});
|
||||
|
||||
expect(() => {
|
||||
client.write(1337);
|
||||
}).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
|
||||
client.destroy();
|
||||
})
|
||||
.on('close', () => {
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//<#END_FILE: test-net-socket-write-error.js
|
||||
26
test/js/node/test/parallel/net-writable.test.js
Normal file
26
test/js/node/test/parallel/net-writable.test.js
Normal file
@@ -0,0 +1,26 @@
|
||||
//#FILE: test-net-writable.js
|
||||
//#SHA1: dfbbbc883e83311b16b93fc9e06d214552cb6448
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const net = require('net');
|
||||
|
||||
test('net writable after end event', (done) => {
|
||||
const server = net.createServer((s) => {
|
||||
server.close();
|
||||
s.end();
|
||||
});
|
||||
|
||||
server.listen(0, '127.0.0.1', () => {
|
||||
const socket = net.connect(server.address().port, '127.0.0.1');
|
||||
socket.on('end', () => {
|
||||
expect(socket.writable).toBe(true);
|
||||
socket.write('hello world');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
expect.assertions(1);
|
||||
});
|
||||
|
||||
//<#END_FILE: test-net-writable.js
|
||||
37
test/js/node/test/parallel/net-write-after-end-nt.test.js
Normal file
37
test/js/node/test/parallel/net-write-after-end-nt.test.js
Normal file
@@ -0,0 +1,37 @@
|
||||
//#FILE: test-net-write-after-end-nt.js
|
||||
//#SHA1: 086a5699d5eff4953af4e9f19757b8489e915579
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const net = require('net');
|
||||
|
||||
// This test ensures those errors caused by calling `net.Socket.write()`
|
||||
// after sockets ending will be emitted in the next tick.
|
||||
test('net.Socket.write() after end emits error in next tick', (done) => {
|
||||
const server = net.createServer((socket) => {
|
||||
socket.end();
|
||||
}).listen(() => {
|
||||
const client = net.connect(server.address().port, () => {
|
||||
let hasError = false;
|
||||
client.on('error', (err) => {
|
||||
hasError = true;
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
client.on('end', () => {
|
||||
const ret = client.write('hello');
|
||||
|
||||
expect(ret).toBe(false);
|
||||
expect(hasError).toBe(false);
|
||||
|
||||
// Check that the error is emitted in the next tick
|
||||
setImmediate(() => {
|
||||
expect(hasError).toBe(true);
|
||||
});
|
||||
});
|
||||
client.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-net-write-after-end-nt.js
|
||||
64
test/js/node/test/parallel/net-write-connect-write.test.js
Normal file
64
test/js/node/test/parallel/net-write-connect-write.test.js
Normal file
@@ -0,0 +1,64 @@
|
||||
//#FILE: test-net-write-connect-write.js
|
||||
//#SHA1: 8d6e9a30cc58bee105db15dc48c8a13c451629be
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
const net = require('net');
|
||||
|
||||
test('net write connect write', async () => {
|
||||
const server = net.createServer((socket) => {
|
||||
socket.pipe(socket);
|
||||
});
|
||||
|
||||
await new Promise((resolve) => {
|
||||
server.listen(0, resolve);
|
||||
});
|
||||
|
||||
const conn = net.connect(server.address().port);
|
||||
let received = '';
|
||||
|
||||
conn.setEncoding('utf8');
|
||||
conn.write('before');
|
||||
|
||||
await new Promise((resolve) => {
|
||||
conn.on('connect', () => {
|
||||
conn.write(' after');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
await new Promise((resolve) => {
|
||||
conn.on('data', (buf) => {
|
||||
received += buf;
|
||||
conn.end();
|
||||
});
|
||||
|
||||
conn.on('end', () => {
|
||||
server.close();
|
||||
expect(received).toBe('before after');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-net-write-connect-write.js
|
||||
@@ -0,0 +1,43 @@
|
||||
//#FILE: test-net-write-fully-async-buffer.js
|
||||
//#SHA1: b26773ed4c8c5bafaaa8a4513b25d1806a72ae5f
|
||||
//-----------------
|
||||
'use strict';
|
||||
// Flags: --expose-gc
|
||||
|
||||
// Note: This is a variant of test-net-write-fully-async-hex-string.js.
|
||||
// This always worked, but it seemed appropriate to add a test that checks the
|
||||
// behavior for Buffers, too.
|
||||
const net = require('net');
|
||||
|
||||
const data = Buffer.alloc(1000000);
|
||||
|
||||
test('net write fully async buffer', (done) => {
|
||||
const server = net.createServer((conn) => {
|
||||
conn.resume();
|
||||
}).listen(0, () => {
|
||||
const conn = net.createConnection(server.address().port, () => {
|
||||
let count = 0;
|
||||
|
||||
function writeLoop() {
|
||||
if (count++ === 200) {
|
||||
conn.destroy();
|
||||
server.close();
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
while (conn.write(Buffer.from(data)));
|
||||
global.gc({ type: 'minor' });
|
||||
// The buffer allocated above should still be alive.
|
||||
}
|
||||
|
||||
conn.on('drain', writeLoop);
|
||||
|
||||
writeLoop();
|
||||
});
|
||||
});
|
||||
|
||||
expect(server.listening).toBe(true);
|
||||
});
|
||||
|
||||
//<#END_FILE: test-net-write-fully-async-buffer.js
|
||||
@@ -0,0 +1,47 @@
|
||||
//#FILE: test-net-write-fully-async-hex-string.js
|
||||
//#SHA1: e5b365bb794f38e7153fc41ebfaf991031f85423
|
||||
//-----------------
|
||||
'use strict';
|
||||
// Flags: --expose-gc
|
||||
|
||||
// Regression test for https://github.com/nodejs/node/issues/8251.
|
||||
const net = require('net');
|
||||
|
||||
const data = Buffer.alloc(1000000).toString('hex');
|
||||
|
||||
test('net write fully async hex string', (done) => {
|
||||
const server = net.createServer((conn) => {
|
||||
conn.resume();
|
||||
}).listen(0, () => {
|
||||
const conn = net.createConnection(server.address().port, () => {
|
||||
let count = 0;
|
||||
|
||||
function writeLoop() {
|
||||
if (count++ === 20) {
|
||||
conn.destroy();
|
||||
server.close();
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
while (conn.write(data, 'hex'));
|
||||
global.gc({ type: 'minor' });
|
||||
// The buffer allocated inside the .write() call should still be alive.
|
||||
}
|
||||
|
||||
conn.on('drain', writeLoop);
|
||||
|
||||
writeLoop();
|
||||
});
|
||||
});
|
||||
|
||||
expect.assertions(2);
|
||||
server.on('listening', () => {
|
||||
expect(server.address().port).toBeGreaterThan(0);
|
||||
});
|
||||
server.on('connection', () => {
|
||||
expect(true).toBe(true); // Connection established
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-net-write-fully-async-hex-string.js
|
||||
23
test/js/node/test/parallel/url-canparse-whatwg.test.js
Normal file
23
test/js/node/test/parallel/url-canparse-whatwg.test.js
Normal file
@@ -0,0 +1,23 @@
|
||||
//#FILE: test-url-canParse-whatwg.js
|
||||
//#SHA1: e1170e8b8d0057443bfb307c64dbd27b204ac2f0
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
test('URL.canParse requires one argument', () => {
|
||||
expect(() => {
|
||||
URL.canParse();
|
||||
}).toThrow(expect.objectContaining({
|
||||
code: 'ERR_MISSING_ARGS',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
|
||||
test('URL.canParse works with v8 fast api', () => {
|
||||
// This test is to ensure that the v8 fast api works.
|
||||
for (let i = 0; i < 1e5; i++) {
|
||||
expect(URL.canParse('https://www.example.com/path/?query=param#hash')).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
//<#END_FILE: test-url-canParse-whatwg.js
|
||||
39
test/js/node/test/parallel/url-domain-ascii-unicode.test.js
Normal file
39
test/js/node/test/parallel/url-domain-ascii-unicode.test.js
Normal file
@@ -0,0 +1,39 @@
|
||||
//#FILE: test-url-domain-ascii-unicode.js
|
||||
//#SHA1: 717d40eef6d2d8f5adccf01fe09dc43f8b776e13
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const url = require('url');
|
||||
|
||||
const domainToASCII = url.domainToASCII;
|
||||
const domainToUnicode = url.domainToUnicode;
|
||||
|
||||
const domainWithASCII = [
|
||||
['ıíd', 'xn--d-iga7r'],
|
||||
['يٴ', 'xn--mhb8f'],
|
||||
['www.ϧƽəʐ.com', 'www.xn--cja62apfr6c.com'],
|
||||
['новини.com', 'xn--b1amarcd.com'],
|
||||
['名がドメイン.com', 'xn--v8jxj3d1dzdz08w.com'],
|
||||
['افغانستا.icom.museum', 'xn--mgbaal8b0b9b2b.icom.museum'],
|
||||
['الجزائر.icom.fake', 'xn--lgbbat1ad8j.icom.fake'],
|
||||
['भारत.org', 'xn--h2brj9c.org'],
|
||||
];
|
||||
|
||||
describe('URL domain ASCII and Unicode conversion', () => {
|
||||
// Skip the entire test suite if Intl is not available
|
||||
beforeAll(() => {
|
||||
if (typeof Intl === 'undefined') {
|
||||
throw new Error('missing Intl');
|
||||
}
|
||||
});
|
||||
|
||||
test.each(domainWithASCII)('converts %s <-> %s', (domain, ascii) => {
|
||||
const domainConvertedToASCII = domainToASCII(domain);
|
||||
expect(domainConvertedToASCII).toBe(ascii);
|
||||
|
||||
const asciiConvertedToUnicode = domainToUnicode(ascii);
|
||||
expect(asciiConvertedToUnicode).toBe(domain);
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-url-domain-ascii-unicode.js
|
||||
18
test/js/node/test/parallel/url-revokeobjecturl.test.js
Normal file
18
test/js/node/test/parallel/url-revokeobjecturl.test.js
Normal file
@@ -0,0 +1,18 @@
|
||||
//#FILE: test-url-revokeobjecturl.js
|
||||
//#SHA1: 573bfad806102976807ad71fef71b079005d8bfa
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
// Test ensures that the function receives the url argument.
|
||||
|
||||
test('URL.revokeObjectURL() throws with missing argument', () => {
|
||||
expect(() => {
|
||||
URL.revokeObjectURL();
|
||||
}).toThrow(expect.objectContaining({
|
||||
code: 'ERR_MISSING_ARGS',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
|
||||
//<#END_FILE: test-url-revokeobjecturl.js
|
||||
48
test/js/node/test/parallel/url-urltooptions.test.js
Normal file
48
test/js/node/test/parallel/url-urltooptions.test.js
Normal file
@@ -0,0 +1,48 @@
|
||||
//#FILE: test-url-urltooptions.js
|
||||
//#SHA1: 0ba1cb976ec5888306f7c820a39afcb93b882d03
|
||||
//-----------------
|
||||
'use strict';
|
||||
|
||||
const { URL } = require('url');
|
||||
const { urlToHttpOptions } = require('url');
|
||||
|
||||
describe('urlToHttpOptions', () => {
|
||||
test('converts URL object to HTTP options', () => {
|
||||
const urlObj = new URL('http://user:pass@foo.bar.com:21/aaa/zzz?l=24#test');
|
||||
const opts = urlToHttpOptions(urlObj);
|
||||
|
||||
expect(opts).not.toBeInstanceOf(URL);
|
||||
expect(opts.protocol).toBe('http:');
|
||||
expect(opts.auth).toBe('user:pass');
|
||||
expect(opts.hostname).toBe('foo.bar.com');
|
||||
expect(opts.port).toBe(21);
|
||||
expect(opts.path).toBe('/aaa/zzz?l=24');
|
||||
expect(opts.pathname).toBe('/aaa/zzz');
|
||||
expect(opts.search).toBe('?l=24');
|
||||
expect(opts.hash).toBe('#test');
|
||||
});
|
||||
|
||||
test('handles IPv6 hostname correctly', () => {
|
||||
const { hostname } = urlToHttpOptions(new URL('http://[::1]:21'));
|
||||
expect(hostname).toBe('::1');
|
||||
});
|
||||
|
||||
test('handles copied URL object with missing data properties', () => {
|
||||
const urlObj = new URL('http://user:pass@foo.bar.com:21/aaa/zzz?l=24#test');
|
||||
const copiedUrlObj = { ...urlObj };
|
||||
const copiedOpts = urlToHttpOptions(copiedUrlObj);
|
||||
|
||||
expect(copiedOpts).not.toBeInstanceOf(URL);
|
||||
expect(copiedOpts.protocol).toBeUndefined();
|
||||
expect(copiedOpts.auth).toBeUndefined();
|
||||
expect(copiedOpts.hostname).toBeUndefined();
|
||||
expect(copiedOpts.port).toBeNaN();
|
||||
expect(copiedOpts.path).toBe('');
|
||||
expect(copiedOpts.pathname).toBeUndefined();
|
||||
expect(copiedOpts.search).toBeUndefined();
|
||||
expect(copiedOpts.hash).toBeUndefined();
|
||||
expect(copiedOpts.href).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-url-urltooptions.js
|
||||
79
test/js/node/test/parallel/util-deprecate.test.js
Normal file
79
test/js/node/test/parallel/util-deprecate.test.js
Normal file
@@ -0,0 +1,79 @@
|
||||
//#FILE: test-util-deprecate.js
|
||||
//#SHA1: 43c232bacd8dcc9f39194125c071db2ab14dfb51
|
||||
//-----------------
|
||||
"use strict";
|
||||
|
||||
const util = require("util");
|
||||
|
||||
// Tests basic functionality of util.deprecate().
|
||||
|
||||
// Mock process.on for warnings
|
||||
const mockWarningListener = jest.fn();
|
||||
const mockExitListener = jest.fn();
|
||||
process.on = jest.fn((event, listener) => {
|
||||
if (event === "warning") mockWarningListener.mockImplementation(listener);
|
||||
if (event === "exit") mockExitListener.mockImplementation(listener);
|
||||
});
|
||||
|
||||
const expectedWarnings = new Map();
|
||||
|
||||
test("Emits deprecation only once if same function is called", () => {
|
||||
const msg = "fhqwhgads";
|
||||
const fn = util.deprecate(() => {}, msg);
|
||||
expectedWarnings.set(msg, { code: undefined, count: 1 });
|
||||
fn();
|
||||
fn();
|
||||
});
|
||||
|
||||
test("Emits deprecation twice for different functions", () => {
|
||||
const msg = "sterrance";
|
||||
const fn1 = util.deprecate(() => {}, msg);
|
||||
const fn2 = util.deprecate(() => {}, msg);
|
||||
expectedWarnings.set(msg, { code: undefined, count: 2 });
|
||||
fn1();
|
||||
fn2();
|
||||
});
|
||||
|
||||
test("Emits deprecation only once if optional code is the same, even for different functions", () => {
|
||||
const msg = "cannonmouth";
|
||||
const code = "deprecatesque";
|
||||
const fn1 = util.deprecate(() => {}, msg, code);
|
||||
const fn2 = util.deprecate(() => {}, msg, code);
|
||||
expectedWarnings.set(msg, { code, count: 1 });
|
||||
fn1();
|
||||
fn2();
|
||||
fn1();
|
||||
fn2();
|
||||
});
|
||||
|
||||
test("Handles warnings correctly", () => {
|
||||
expectedWarnings.forEach((expected, message) => {
|
||||
for (let i = 0; i < expected.count; i++) {
|
||||
mockWarningListener({
|
||||
name: "DeprecationWarning",
|
||||
message: message,
|
||||
code: expected.code,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
expect(mockWarningListener).toHaveBeenCalledTimes(
|
||||
Array.from(expectedWarnings.values()).reduce((acc, curr) => acc + curr.count, 0),
|
||||
);
|
||||
|
||||
mockWarningListener.mock.calls.forEach(([warning]) => {
|
||||
expect(warning.name).toBe("DeprecationWarning");
|
||||
expect(expectedWarnings.has(warning.message)).toBe(true);
|
||||
const expected = expectedWarnings.get(warning.message);
|
||||
expect(warning.code).toBe(expected.code);
|
||||
expected.count--;
|
||||
if (expected.count === 0) {
|
||||
expectedWarnings.delete(warning.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test("All warnings are processed", () => {
|
||||
mockExitListener();
|
||||
expect(expectedWarnings.size).toBe(0);
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
//#FILE: test-util-inspect-getters-accessing-this.js
|
||||
//#SHA1: 92c41c06f838da46cbbfcd7f695a19784af3f581
|
||||
//-----------------
|
||||
"use strict";
|
||||
|
||||
const { inspect } = require("util");
|
||||
|
||||
// This test ensures that util.inspect logs getters
|
||||
// which access this.
|
||||
|
||||
test("util.inspect logs getters accessing this", () => {
|
||||
class X {
|
||||
constructor() {
|
||||
this._y = 123;
|
||||
}
|
||||
|
||||
get y() {
|
||||
return this._y;
|
||||
}
|
||||
}
|
||||
|
||||
const result = inspect(new X(), {
|
||||
getters: true,
|
||||
showHidden: true,
|
||||
});
|
||||
|
||||
expect(result).toBe("X { _y: 123, [y]: [Getter: 123] }");
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/nodejs/node/issues/37054
|
||||
test("util.inspect handles circular references in getters", () => {
|
||||
class A {
|
||||
constructor(B) {
|
||||
this.B = B;
|
||||
}
|
||||
get b() {
|
||||
return this.B;
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
constructor() {
|
||||
this.A = new A(this);
|
||||
}
|
||||
get a() {
|
||||
return this.A;
|
||||
}
|
||||
}
|
||||
|
||||
const result = inspect(new B(), {
|
||||
depth: 1,
|
||||
getters: true,
|
||||
showHidden: true,
|
||||
});
|
||||
|
||||
expect(result).toBe(
|
||||
"<ref *1> B {\n" +
|
||||
" A: A { B: [Circular *1], [b]: [Getter] [Circular *1] },\n" +
|
||||
" [a]: [Getter] A { B: [Circular *1], [b]: [Getter] [Circular *1] }\n" +
|
||||
"}",
|
||||
);
|
||||
});
|
||||
26
test/js/node/test/parallel/util-inspect-long-running.test.js
Normal file
26
test/js/node/test/parallel/util-inspect-long-running.test.js
Normal file
@@ -0,0 +1,26 @@
|
||||
//#FILE: test-util-inspect-long-running.js
|
||||
//#SHA1: 2e4cbb5743a4dfcf869e84ce6d58795f96465aeb
|
||||
//-----------------
|
||||
"use strict";
|
||||
|
||||
// Test that huge objects don't crash due to exceeding the maximum heap size.
|
||||
|
||||
const util = require("util");
|
||||
|
||||
test("util.inspect handles huge objects without crashing", () => {
|
||||
// Create a difficult to stringify object. Without the artificial limitation
|
||||
// this would crash or throw an maximum string size error.
|
||||
let last = {};
|
||||
const obj = last;
|
||||
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
last.next = { circular: obj, last, obj: { a: 1, b: 2, c: true } };
|
||||
last = last.next;
|
||||
obj[i] = last;
|
||||
}
|
||||
|
||||
// If this doesn't throw, we consider the test passed
|
||||
expect(() => {
|
||||
util.inspect(obj, { depth: Infinity });
|
||||
}).not.toThrow();
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
//#FILE: test-util-primordial-monkeypatching.js
|
||||
//#SHA1: 72e754f1abd435e598620901f26b087e0bf9d5a7
|
||||
//-----------------
|
||||
"use strict";
|
||||
|
||||
// Monkeypatch Object.keys() so that it throws an unexpected error. This tests
|
||||
// that `util.inspect()` is unaffected by monkey-patching `Object`.
|
||||
|
||||
const util = require("util");
|
||||
|
||||
test("util.inspect() is unaffected by monkey-patching Object.keys()", () => {
|
||||
const originalObjectKeys = Object.keys;
|
||||
|
||||
// Monkey-patch Object.keys
|
||||
Object.keys = () => {
|
||||
throw new Error("fhqwhgads");
|
||||
};
|
||||
|
||||
try {
|
||||
expect(util.inspect({})).toBe("{}");
|
||||
} finally {
|
||||
// Restore original Object.keys to avoid affecting other tests
|
||||
Object.keys = originalObjectKeys;
|
||||
}
|
||||
});
|
||||
39
test/js/node/test/parallel/zlib-close-after-write.test.js
Normal file
39
test/js/node/test/parallel/zlib-close-after-write.test.js
Normal file
@@ -0,0 +1,39 @@
|
||||
//#FILE: test-zlib-close-after-write.js
|
||||
//#SHA1: 7fad593914e2a23d73598e4366e685b9aa91cc24
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
const zlib = require("zlib");
|
||||
|
||||
test("zlib close after write", done => {
|
||||
zlib.gzip("hello", (err, out) => {
|
||||
expect(err).toBeNull();
|
||||
|
||||
const unzip = zlib.createGunzip();
|
||||
unzip.write(out);
|
||||
|
||||
unzip.close(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
16
test/js/node/test/parallel/zlib-create-raw.test.js
Normal file
16
test/js/node/test/parallel/zlib-create-raw.test.js
Normal file
@@ -0,0 +1,16 @@
|
||||
//#FILE: test-zlib-create-raw.js
|
||||
//#SHA1: 187539d5696ec6b7c567dfba0d1528c4b65d1e0a
|
||||
//-----------------
|
||||
"use strict";
|
||||
|
||||
const zlib = require("zlib");
|
||||
|
||||
test("zlib.createInflateRaw() creates an instance of InflateRaw", () => {
|
||||
const inflateRaw = zlib.createInflateRaw();
|
||||
expect(inflateRaw).toBeInstanceOf(zlib.InflateRaw);
|
||||
});
|
||||
|
||||
test("zlib.createDeflateRaw() creates an instance of DeflateRaw", () => {
|
||||
const deflateRaw = zlib.createDeflateRaw();
|
||||
expect(deflateRaw).toBeInstanceOf(zlib.DeflateRaw);
|
||||
});
|
||||
36
test/js/node/test/parallel/zlib-deflate-raw-inherits.test.js
Normal file
36
test/js/node/test/parallel/zlib-deflate-raw-inherits.test.js
Normal file
@@ -0,0 +1,36 @@
|
||||
//#FILE: test-zlib-deflate-raw-inherits.js
|
||||
//#SHA1: 9e1873864f4af27abf3a8a36a87edd2d036805d8
|
||||
//-----------------
|
||||
"use strict";
|
||||
|
||||
const { DeflateRaw } = require("zlib");
|
||||
const { Readable } = require("stream");
|
||||
|
||||
// Validates that zlib.DeflateRaw can be inherited
|
||||
// with Object.setPrototypeOf
|
||||
|
||||
test("DeflateRaw can be inherited with Object.setPrototypeOf", done => {
|
||||
function NotInitialized(options) {
|
||||
DeflateRaw.call(this, options);
|
||||
this.prop = true;
|
||||
}
|
||||
Object.setPrototypeOf(NotInitialized.prototype, DeflateRaw.prototype);
|
||||
Object.setPrototypeOf(NotInitialized, DeflateRaw);
|
||||
|
||||
const dest = new NotInitialized();
|
||||
|
||||
const read = new Readable({
|
||||
read() {
|
||||
this.push(Buffer.from("a test string"));
|
||||
this.push(null);
|
||||
},
|
||||
});
|
||||
|
||||
read.pipe(dest);
|
||||
dest.on("finish", () => {
|
||||
expect(dest.prop).toBe(true);
|
||||
expect(dest instanceof DeflateRaw).toBe(true);
|
||||
done();
|
||||
});
|
||||
dest.resume();
|
||||
});
|
||||
64
test/js/node/test/parallel/zlib-dictionary-fail.test.js
Normal file
64
test/js/node/test/parallel/zlib-dictionary-fail.test.js
Normal file
@@ -0,0 +1,64 @@
|
||||
//#FILE: test-zlib-dictionary-fail.js
|
||||
//#SHA1: e9c6d383f9b0a202067a125c016f1ef3cd5be558
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
const zlib = require("zlib");
|
||||
|
||||
// String "test" encoded with dictionary "dict".
|
||||
const input = Buffer.from([0x78, 0xbb, 0x04, 0x09, 0x01, 0xa5]);
|
||||
|
||||
test("Inflate stream without dictionary", done => {
|
||||
const stream = zlib.createInflate();
|
||||
|
||||
stream.on("error", err => {
|
||||
expect(err.message).toMatch(/Missing dictionary/);
|
||||
done();
|
||||
});
|
||||
|
||||
stream.write(input);
|
||||
});
|
||||
|
||||
test("Inflate stream with incorrect dictionary", done => {
|
||||
const stream = zlib.createInflate({ dictionary: Buffer.from("fail") });
|
||||
|
||||
stream.on("error", err => {
|
||||
expect(err.message).toMatch(/Bad dictionary/);
|
||||
done();
|
||||
});
|
||||
|
||||
stream.write(input);
|
||||
});
|
||||
|
||||
test("InflateRaw stream with incorrect dictionary", done => {
|
||||
const stream = zlib.createInflateRaw({ dictionary: Buffer.from("fail") });
|
||||
|
||||
stream.on("error", err => {
|
||||
// It's not possible to separate invalid dict and invalid data when using
|
||||
// the raw format
|
||||
expect(err.message).toMatch(/(invalid|Operation-Ending-Supplemental Code is 0x12)/);
|
||||
done();
|
||||
});
|
||||
|
||||
stream.write(input);
|
||||
});
|
||||
35
test/js/node/test/parallel/zlib-empty-buffer.test.js
Normal file
35
test/js/node/test/parallel/zlib-empty-buffer.test.js
Normal file
@@ -0,0 +1,35 @@
|
||||
//#FILE: test-zlib-empty-buffer.js
|
||||
//#SHA1: 7a2e8687dcd6e4bd815aa22c2bbff08251d9d91a
|
||||
//-----------------
|
||||
"use strict";
|
||||
|
||||
const zlib = require("zlib");
|
||||
const { inspect, promisify } = require("util");
|
||||
|
||||
const emptyBuffer = Buffer.alloc(0);
|
||||
|
||||
describe("Zlib Empty Buffer", () => {
|
||||
const testCases = [
|
||||
["deflateRawSync", "inflateRawSync", "raw sync"],
|
||||
["deflateSync", "inflateSync", "deflate sync"],
|
||||
["gzipSync", "gunzipSync", "gzip sync"],
|
||||
["brotliCompressSync", "brotliDecompressSync", "br sync"],
|
||||
["deflateRaw", "inflateRaw", "raw"],
|
||||
["deflate", "inflate", "deflate"],
|
||||
["gzip", "gunzip", "gzip"],
|
||||
["brotliCompress", "brotliDecompress", "br"],
|
||||
];
|
||||
|
||||
testCases.forEach(([compressMethod, decompressMethod, methodName]) => {
|
||||
test(`${methodName} compression and decompression`, async () => {
|
||||
const compress = methodName.includes("sync") ? zlib[compressMethod] : promisify(zlib[compressMethod]);
|
||||
|
||||
const decompress = methodName.includes("sync") ? zlib[decompressMethod] : promisify(zlib[decompressMethod]);
|
||||
|
||||
const compressed = await compress(emptyBuffer);
|
||||
const decompressed = await decompress(compressed);
|
||||
|
||||
expect(decompressed).toEqual(emptyBuffer);
|
||||
});
|
||||
});
|
||||
});
|
||||
119
test/js/node/test/parallel/zlib-from-string.test.js
Normal file
119
test/js/node/test/parallel/zlib-from-string.test.js
Normal file
@@ -0,0 +1,119 @@
|
||||
//#FILE: test-zlib-from-string.js
|
||||
//#SHA1: 0514669607bbf01e20f41875fa716660ebfcf28b
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
// Test compressing and uncompressing a string with zlib
|
||||
|
||||
const zlib = require("zlib");
|
||||
|
||||
const inputString =
|
||||
"ΩΩLorem ipsum dolor sit amet, consectetur adipiscing eli" +
|
||||
"t. Morbi faucibus, purus at gravida dictum, libero arcu " +
|
||||
"convallis lacus, in commodo libero metus eu nisi. Nullam" +
|
||||
" commodo, neque nec porta placerat, nisi est fermentum a" +
|
||||
"ugue, vitae gravida tellus sapien sit amet tellus. Aenea" +
|
||||
"n non diam orci. Proin quis elit turpis. Suspendisse non" +
|
||||
" diam ipsum. Suspendisse nec ullamcorper odio. Vestibulu" +
|
||||
"m arcu mi, sodales non suscipit id, ultrices ut massa. S" +
|
||||
"ed ac sem sit amet arcu malesuada fermentum. Nunc sed. ";
|
||||
const expectedBase64Deflate =
|
||||
"eJxdUUtOQzEMvMoc4OndgT0gJCT2buJWlpI4jePeqZfpmX" +
|
||||
"AKLRKbLOzx/HK73q6vOrhCunlF1qIDJhNUeW5I2ozT5OkD" +
|
||||
"lKWLJWkncJG5403HQXAkT3Jw29B9uIEmToMukglZ0vS6oc" +
|
||||
"iBh4JG8sV4oVLEUCitK2kxq1WzPnChHDzsaGKy491LofoA" +
|
||||
"bWh8do43oeuYhB5EPCjcLjzYJo48KrfQBvnJecNFJvHT1+" +
|
||||
"RSQsGoC7dn2t/xjhduTA1NWyQIZR0pbHwMDatnD+crPqKS" +
|
||||
"qGPHp1vnlsWM/07ubf7bheF7kqSj84Bm0R1fYTfaK8vqqq" +
|
||||
"fKBtNMhe3OZh6N95CTvMX5HJJi4xOVzCgUOIMSLH7wmeOH" +
|
||||
"aFE4RdpnGavKtrB5xzfO/Ll9";
|
||||
const expectedBase64Gzip =
|
||||
"H4sIAAAAAAAAA11RS05DMQy8yhzg6d2BPSAkJPZu4laWkjiN4" +
|
||||
"96pl+mZcAotEpss7PH8crverq86uEK6eUXWogMmE1R5bkjajN" +
|
||||
"Pk6QOUpYslaSdwkbnjTcdBcCRPcnDb0H24gSZOgy6SCVnS9Lq" +
|
||||
"hyIGHgkbyxXihUsRQKK0raTGrVbM+cKEcPOxoYrLj3Uuh+gBt" +
|
||||
"aHx2jjeh65iEHkQ8KNwuPNgmjjwqt9AG+cl5w0Um8dPX5FJCw" +
|
||||
"agLt2fa3/GOF25MDU1bJAhlHSlsfAwNq2cP5ys+opKoY8enW+" +
|
||||
"eWxYz/Tu5t/tuF4XuSpKPzgGbRHV9hN9ory+qqp8oG00yF7c5" +
|
||||
"mHo33kJO8xfkckmLjE5XMKBQ4gxIsfvCZ44doUThF2mcZq8q2" +
|
||||
"sHnHNzRtagj5AQAA";
|
||||
|
||||
test("deflate and inflate", async () => {
|
||||
const buffer = await new Promise((resolve, reject) => {
|
||||
zlib.deflate(inputString, (err, buffer) => {
|
||||
if (err) reject(err);
|
||||
else resolve(buffer);
|
||||
});
|
||||
});
|
||||
|
||||
const inflated = await new Promise((resolve, reject) => {
|
||||
zlib.inflate(buffer, (err, inflated) => {
|
||||
if (err) reject(err);
|
||||
else resolve(inflated);
|
||||
});
|
||||
});
|
||||
|
||||
expect(inflated.toString()).toBe(inputString);
|
||||
});
|
||||
|
||||
test("gzip and gunzip", async () => {
|
||||
const buffer = await new Promise((resolve, reject) => {
|
||||
zlib.gzip(inputString, (err, buffer) => {
|
||||
if (err) reject(err);
|
||||
else resolve(buffer);
|
||||
});
|
||||
});
|
||||
|
||||
const gunzipped = await new Promise((resolve, reject) => {
|
||||
zlib.gunzip(buffer, (err, gunzipped) => {
|
||||
if (err) reject(err);
|
||||
else resolve(gunzipped);
|
||||
});
|
||||
});
|
||||
|
||||
expect(gunzipped.toString()).toBe(inputString);
|
||||
});
|
||||
|
||||
test("unzip deflated data", async () => {
|
||||
const buffer = Buffer.from(expectedBase64Deflate, "base64");
|
||||
const unzipped = await new Promise((resolve, reject) => {
|
||||
zlib.unzip(buffer, (err, unzipped) => {
|
||||
if (err) reject(err);
|
||||
else resolve(unzipped);
|
||||
});
|
||||
});
|
||||
|
||||
expect(unzipped.toString()).toBe(inputString);
|
||||
});
|
||||
|
||||
test("unzip gzipped data", async () => {
|
||||
const buffer = Buffer.from(expectedBase64Gzip, "base64");
|
||||
const unzipped = await new Promise((resolve, reject) => {
|
||||
zlib.unzip(buffer, (err, unzipped) => {
|
||||
if (err) reject(err);
|
||||
else resolve(unzipped);
|
||||
});
|
||||
});
|
||||
|
||||
expect(unzipped.toString()).toBe(inputString);
|
||||
});
|
||||
19
test/js/node/test/parallel/zlib-no-stream.test.js
Normal file
19
test/js/node/test/parallel/zlib-no-stream.test.js
Normal file
@@ -0,0 +1,19 @@
|
||||
//#FILE: test-zlib-no-stream.js
|
||||
//#SHA1: 5755924e9363a20243c326747623e8e266f81625
|
||||
//-----------------
|
||||
/* eslint-disable node-core/required-modules */
|
||||
/* eslint-disable node-core/require-common-first */
|
||||
|
||||
"use strict";
|
||||
|
||||
// We are not loading common because it will load the stream module,
|
||||
// defeating the purpose of this test.
|
||||
|
||||
const { gzipSync } = require("zlib");
|
||||
|
||||
// Avoid regressions such as https://github.com/nodejs/node/issues/36615
|
||||
|
||||
test("gzipSync should not throw", () => {
|
||||
// This must not throw
|
||||
expect(() => gzipSync("fooobar")).not.toThrow();
|
||||
});
|
||||
21
test/js/node/test/parallel/zlib-not-string-or-buffer.test.js
Normal file
21
test/js/node/test/parallel/zlib-not-string-or-buffer.test.js
Normal file
@@ -0,0 +1,21 @@
|
||||
//#FILE: test-zlib-not-string-or-buffer.js
|
||||
//#SHA1: d07db97d9393df2ab9453800ae80f2921d93b6e2
|
||||
//-----------------
|
||||
"use strict";
|
||||
|
||||
// Check the error condition testing for passing something other than a string
|
||||
// or buffer.
|
||||
|
||||
const zlib = require("zlib");
|
||||
|
||||
test("zlib.deflateSync throws for invalid input types", () => {
|
||||
[undefined, null, true, false, 0, 1, [1, 2, 3], { foo: "bar" }].forEach(input => {
|
||||
expect(() => zlib.deflateSync(input)).toThrow(
|
||||
expect.objectContaining({
|
||||
code: "ERR_INVALID_ARG_TYPE",
|
||||
name: "TypeError",
|
||||
message: expect.any(String),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
164
test/js/node/test/parallel/zlib-random-byte-pipes.test.js
Normal file
164
test/js/node/test/parallel/zlib-random-byte-pipes.test.js
Normal file
@@ -0,0 +1,164 @@
|
||||
//#FILE: test-zlib-random-byte-pipes.js
|
||||
//#SHA1: ef7e7d3683660b911f9e24a6f40947a47be3dbba
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
|
||||
const crypto = require("crypto");
|
||||
const stream = require("stream");
|
||||
const zlib = require("zlib");
|
||||
|
||||
const Stream = stream.Stream;
|
||||
|
||||
// Emit random bytes, and keep a shasum
|
||||
class RandomReadStream extends Stream {
|
||||
constructor(opt) {
|
||||
super();
|
||||
|
||||
this.readable = true;
|
||||
this._paused = false;
|
||||
this._processing = false;
|
||||
|
||||
this._hasher = crypto.createHash("sha1");
|
||||
opt = opt || {};
|
||||
|
||||
// base block size.
|
||||
opt.block = opt.block || 256 * 1024;
|
||||
|
||||
// Total number of bytes to emit
|
||||
opt.total = opt.total || 256 * 1024 * 1024;
|
||||
this._remaining = opt.total;
|
||||
|
||||
// How variable to make the block sizes
|
||||
opt.jitter = opt.jitter || 1024;
|
||||
|
||||
this._opt = opt;
|
||||
|
||||
this._process = this._process.bind(this);
|
||||
|
||||
process.nextTick(this._process);
|
||||
}
|
||||
|
||||
pause() {
|
||||
this._paused = true;
|
||||
this.emit("pause");
|
||||
}
|
||||
|
||||
resume() {
|
||||
// console.error("rrs resume");
|
||||
this._paused = false;
|
||||
this.emit("resume");
|
||||
this._process();
|
||||
}
|
||||
|
||||
_process() {
|
||||
if (this._processing) return;
|
||||
if (this._paused) return;
|
||||
|
||||
this._processing = true;
|
||||
|
||||
if (!this._remaining) {
|
||||
this._hash = this._hasher.digest("hex").toLowerCase().trim();
|
||||
this._processing = false;
|
||||
|
||||
this.emit("end");
|
||||
return;
|
||||
}
|
||||
|
||||
// Figure out how many bytes to output
|
||||
// if finished, then just emit end.
|
||||
let block = this._opt.block;
|
||||
const jitter = this._opt.jitter;
|
||||
if (jitter) {
|
||||
block += Math.ceil(Math.random() * jitter - jitter / 2);
|
||||
}
|
||||
block = Math.min(block, this._remaining);
|
||||
const buf = Buffer.allocUnsafe(block);
|
||||
for (let i = 0; i < block; i++) {
|
||||
buf[i] = Math.random() * 256;
|
||||
}
|
||||
|
||||
this._hasher.update(buf);
|
||||
|
||||
this._remaining -= block;
|
||||
|
||||
this._processing = false;
|
||||
|
||||
this.emit("data", buf);
|
||||
process.nextTick(this._process);
|
||||
}
|
||||
}
|
||||
|
||||
// A filter that just verifies a shasum
|
||||
class HashStream extends Stream {
|
||||
constructor() {
|
||||
super();
|
||||
this.readable = this.writable = true;
|
||||
this._hasher = crypto.createHash("sha1");
|
||||
}
|
||||
|
||||
write(c) {
|
||||
// Simulate the way that an fs.ReadStream returns false
|
||||
// on *every* write, only to resume a moment later.
|
||||
this._hasher.update(c);
|
||||
process.nextTick(() => this.resume());
|
||||
return false;
|
||||
}
|
||||
|
||||
resume() {
|
||||
this.emit("resume");
|
||||
process.nextTick(() => this.emit("drain"));
|
||||
}
|
||||
|
||||
end(c) {
|
||||
if (c) {
|
||||
this.write(c);
|
||||
}
|
||||
this._hash = this._hasher.digest("hex").toLowerCase().trim();
|
||||
this.emit("data", this._hash);
|
||||
this.emit("end");
|
||||
}
|
||||
}
|
||||
|
||||
test("zlib random byte pipes", async () => {
|
||||
const testCases = [
|
||||
[zlib.createGzip, zlib.createGunzip],
|
||||
[zlib.createBrotliCompress, zlib.createBrotliDecompress],
|
||||
];
|
||||
|
||||
for (const [createCompress, createDecompress] of testCases) {
|
||||
const inp = new RandomReadStream({ total: 1024, block: 256, jitter: 16 });
|
||||
const out = new HashStream();
|
||||
const gzip = createCompress();
|
||||
const gunz = createDecompress();
|
||||
|
||||
inp.pipe(gzip).pipe(gunz).pipe(out);
|
||||
|
||||
await new Promise(resolve => {
|
||||
out.on("data", c => {
|
||||
expect(c).toBe(inp._hash);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
28
test/js/node/test/parallel/zlib-sync-no-event.test.js
Normal file
28
test/js/node/test/parallel/zlib-sync-no-event.test.js
Normal file
@@ -0,0 +1,28 @@
|
||||
//#FILE: test-zlib-sync-no-event.js
|
||||
//#SHA1: 382796f607eb25a85aa067e0dbc3d5103d321def
|
||||
//-----------------
|
||||
"use strict";
|
||||
const zlib = require("zlib");
|
||||
|
||||
const message = "Come on, Fhqwhgads.";
|
||||
const buffer = Buffer.from(message);
|
||||
|
||||
test("Gzip and Gunzip synchronously without emitting events", () => {
|
||||
const zipper = new zlib.Gzip();
|
||||
const closeSpy = jest.fn();
|
||||
zipper.on("close", closeSpy);
|
||||
|
||||
const zipped = zipper._processChunk(buffer, zlib.constants.Z_FINISH);
|
||||
|
||||
const unzipper = new zlib.Gunzip();
|
||||
const unzipperCloseSpy = jest.fn();
|
||||
unzipper.on("close", unzipperCloseSpy);
|
||||
|
||||
const unzipped = unzipper._processChunk(zipped, zlib.constants.Z_FINISH);
|
||||
|
||||
expect(zipped.toString()).not.toBe(message);
|
||||
expect(unzipped.toString()).toBe(message);
|
||||
|
||||
expect(closeSpy).not.toHaveBeenCalled();
|
||||
expect(unzipperCloseSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
87
test/js/node/test/parallel/zlib-truncated.test.js
Normal file
87
test/js/node/test/parallel/zlib-truncated.test.js
Normal file
@@ -0,0 +1,87 @@
|
||||
//#FILE: test-zlib-truncated.js
|
||||
//#SHA1: 79f9bcf3c52b3d0736ebe457652d579a856d1f7b
|
||||
//-----------------
|
||||
"use strict";
|
||||
// Tests zlib streams with truncated compressed input
|
||||
|
||||
const zlib = require("zlib");
|
||||
|
||||
const inputString =
|
||||
"ΩΩLorem ipsum dolor sit amet, consectetur adipiscing eli" +
|
||||
"t. Morbi faucibus, purus at gravida dictum, libero arcu " +
|
||||
"convallis lacus, in commodo libero metus eu nisi. Nullam" +
|
||||
" commodo, neque nec porta placerat, nisi est fermentum a" +
|
||||
"ugue, vitae gravida tellus sapien sit amet tellus. Aenea" +
|
||||
"n non diam orci. Proin quis elit turpis. Suspendisse non" +
|
||||
" diam ipsum. Suspendisse nec ullamcorper odio. Vestibulu" +
|
||||
"m arcu mi, sodales non suscipit id, ultrices ut massa. S" +
|
||||
"ed ac sem sit amet arcu malesuada fermentum. Nunc sed. ";
|
||||
|
||||
const errMessage = /unexpected end of file/;
|
||||
|
||||
[
|
||||
{ comp: "gzip", decomp: "gunzip", decompSync: "gunzipSync" },
|
||||
{ comp: "gzip", decomp: "unzip", decompSync: "unzipSync" },
|
||||
{ comp: "deflate", decomp: "inflate", decompSync: "inflateSync" },
|
||||
{ comp: "deflateRaw", decomp: "inflateRaw", decompSync: "inflateRawSync" },
|
||||
].forEach(function (methods) {
|
||||
test(`Test ${methods.comp} compression and ${methods.decomp} decompression`, async () => {
|
||||
const compressed = await new Promise((resolve, reject) => {
|
||||
zlib[methods.comp](inputString, (err, result) => {
|
||||
if (err) reject(err);
|
||||
else resolve(result);
|
||||
});
|
||||
});
|
||||
|
||||
const truncated = compressed.slice(0, compressed.length / 2);
|
||||
const toUTF8 = buffer => buffer.toString("utf-8");
|
||||
|
||||
// sync sanity
|
||||
const decompressed = zlib[methods.decompSync](compressed);
|
||||
expect(toUTF8(decompressed)).toBe(inputString);
|
||||
|
||||
// async sanity
|
||||
await new Promise((resolve, reject) => {
|
||||
zlib[methods.decomp](compressed, (err, result) => {
|
||||
if (err) reject(err);
|
||||
else {
|
||||
expect(toUTF8(result)).toBe(inputString);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Sync truncated input test
|
||||
expect(() => {
|
||||
zlib[methods.decompSync](truncated);
|
||||
}).toThrow(expect.objectContaining({ message: expect.stringMatching(errMessage) }));
|
||||
|
||||
// Async truncated input test
|
||||
await expect(
|
||||
new Promise((resolve, reject) => {
|
||||
zlib[methods.decomp](truncated, (err, result) => {
|
||||
if (err) reject(err);
|
||||
else resolve(result);
|
||||
});
|
||||
}),
|
||||
).rejects.toThrow(expect.objectContaining({ message: expect.stringMatching(errMessage) }));
|
||||
|
||||
const syncFlushOpt = { finishFlush: zlib.constants.Z_SYNC_FLUSH };
|
||||
|
||||
// Sync truncated input test, finishFlush = Z_SYNC_FLUSH
|
||||
const result = toUTF8(zlib[methods.decompSync](truncated, syncFlushOpt));
|
||||
expect(result).toBe(inputString.slice(0, result.length));
|
||||
|
||||
// Async truncated input test, finishFlush = Z_SYNC_FLUSH
|
||||
await new Promise((resolve, reject) => {
|
||||
zlib[methods.decomp](truncated, syncFlushOpt, (err, decompressed) => {
|
||||
if (err) reject(err);
|
||||
else {
|
||||
const result = toUTF8(decompressed);
|
||||
expect(result).toBe(inputString.slice(0, result.length));
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
//#FILE: test-zlib-unzip-one-byte-chunks.js
|
||||
//#SHA1: 3c242140501ae0e8e9277c68696c231a04070018
|
||||
//-----------------
|
||||
"use strict";
|
||||
const zlib = require("zlib");
|
||||
|
||||
test("unzip one byte chunks", done => {
|
||||
const data = Buffer.concat([zlib.gzipSync("abc"), zlib.gzipSync("def")]);
|
||||
|
||||
const resultBuffers = [];
|
||||
|
||||
const unzip = zlib
|
||||
.createUnzip()
|
||||
.on("error", err => {
|
||||
expect(err).toBeFalsy();
|
||||
})
|
||||
.on("data", data => resultBuffers.push(data))
|
||||
.on("finish", () => {
|
||||
const unzipped = Buffer.concat(resultBuffers).toString();
|
||||
expect(unzipped).toBe("abcdef");
|
||||
done();
|
||||
});
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
// Write each single byte individually.
|
||||
unzip.write(Buffer.from([data[i]]));
|
||||
}
|
||||
|
||||
unzip.end();
|
||||
});
|
||||
54
test/js/node/test/parallel/zlib-zero-byte.test.js
Normal file
54
test/js/node/test/parallel/zlib-zero-byte.test.js
Normal file
@@ -0,0 +1,54 @@
|
||||
//#FILE: test-zlib-zero-byte.js
|
||||
//#SHA1: 54539c28619fb98230547ba0929ddad146f15bc5
|
||||
//-----------------
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"use strict";
|
||||
const zlib = require("zlib");
|
||||
|
||||
for (const Compressor of [zlib.Gzip, zlib.BrotliCompress]) {
|
||||
test(`${Compressor.name} compresses empty buffer`, async () => {
|
||||
const gz = new Compressor();
|
||||
const emptyBuffer = Buffer.alloc(0);
|
||||
let received = 0;
|
||||
|
||||
gz.on("data", c => {
|
||||
received += c.length;
|
||||
});
|
||||
|
||||
const endPromise = new Promise(resolve => {
|
||||
gz.on("end", resolve);
|
||||
});
|
||||
|
||||
const finishPromise = new Promise(resolve => {
|
||||
gz.on("finish", resolve);
|
||||
});
|
||||
|
||||
gz.write(emptyBuffer);
|
||||
gz.end();
|
||||
|
||||
await Promise.all([endPromise, finishPromise]);
|
||||
|
||||
const expected = Compressor === zlib.Gzip ? 20 : 1;
|
||||
expect(received).toBe(expected);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user