diff --git a/.travis.yml b/.travis.yml
index 40992555bf..f62cdac068 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,54 +1,33 @@
sudo: false
language: node_js
before_install:
- - npm install -g npm@2
- - test $NPM_LEGACY && npm install -g npm@latest-3 || npm install npm -g
+ - (test $NPM_LEGACY && npm install -g npm@2 && npm install -g npm@3) || true
notifications:
email: false
matrix:
fast_finish: true
include:
- node_js: '0.8'
- env:
- - TASK=test
- - NPM_LEGACY=true
+ env: NPM_LEGACY=true
- node_js: '0.10'
- env:
- - TASK=test
- - NPM_LEGACY=true
+ env: NPM_LEGACY=true
- node_js: '0.11'
- env:
- - TASK=test
- - NPM_LEGACY=true
+ env: NPM_LEGACY=true
- node_js: '0.12'
- env:
- - TASK=test
- - NPM_LEGACY=true
+ env: NPM_LEGACY=true
- node_js: 1
- env:
- - TASK=test
- - NPM_LEGACY=true
+ env: NPM_LEGACY=true
- node_js: 2
- env:
- - TASK=test
- - NPM_LEGACY=true
+ env: NPM_LEGACY=true
- node_js: 3
- env:
- - TASK=test
- - NPM_LEGACY=true
+ env: NPM_LEGACY=true
- node_js: 4
- env: TASK=test
- node_js: 5
- env: TASK=test
- node_js: 6
- env: TASK=test
- node_js: 7
- env: TASK=test
- node_js: 8
- env: TASK=test
- node_js: 9
- env: TASK=test
-script: "npm run $TASK"
+script: "npm run test"
env:
global:
- secure: rE2Vvo7vnjabYNULNyLFxOyt98BoJexDqsiOnfiD6kLYYsiQGfr/sbZkPMOFm9qfQG7pjqx+zZWZjGSswhTt+626C0t/njXqug7Yps4c3dFblzGfreQHp7wNX5TFsvrxd6dAowVasMp61sJcRnB2w8cUzoe3RAYUDHyiHktwqMc=
diff --git a/README.md b/README.md
index 23fe3f3e30..f1c5a9314f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# readable-stream
-***Node-core v8.11.1 streams for userland*** [](https://travis-ci.org/nodejs/readable-stream)
+***Node-core v8.17.0 streams for userland*** [](https://travis-ci.org/nodejs/readable-stream)
[](https://nodei.co/npm/readable-stream/)
@@ -18,7 +18,7 @@ npm install --save readable-stream
This package is a mirror of the Streams2 and Streams3 implementations in
Node-core.
-Full documentation may be found on the [Node.js website](https://nodejs.org/dist/v8.11.1/docs/api/stream.html).
+Full documentation may be found on the [Node.js website](https://nodejs.org/dist/v8.17.0/docs/api/stream.html).
If you want to guarantee a stable streams base, regardless of what version of
Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core, for background see [this blogpost](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html).
diff --git a/build/files.js b/build/files.js
index 9bf53a6ee4..6a5a34299a 100644
--- a/build/files.js
+++ b/build/files.js
@@ -41,7 +41,7 @@ const headRegexp = /(^module.exports = \w+;?)/m
, utilReplacement = [
/^const util = require\('util'\);/m
- , '\n/**/\nconst util = require(\'core-util-is\');\n'
+ , '\n/**/\nconst util = Object.create(require(\'core-util-is\'));\n'
+ 'util.inherits = require(\'inherits\');\n/**/\n'
]
@@ -179,7 +179,7 @@ const headRegexp = /(^module.exports = \w+;?)/m
/(?:var|const) Buffer = require\('safe-buffer'\)\.Buffer;/
, `
const Buffer = require('safe-buffer').Buffer
- const OurUint8Array = global.Uint8Array || function () {}
+ const OurUint8Array = (typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {}
function _uint8ArrayToBuffer(chunk) {
return Buffer.from(chunk);
}
diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js
index a1ca813e5a..57003c32d2 100644
--- a/lib/_stream_duplex.js
+++ b/lib/_stream_duplex.js
@@ -43,7 +43,7 @@ var objectKeys = Object.keys || function (obj) {
module.exports = Duplex;
/**/
-var util = require('core-util-is');
+var util = Object.create(require('core-util-is'));
util.inherits = require('inherits');
/**/
diff --git a/lib/_stream_passthrough.js b/lib/_stream_passthrough.js
index a9c8358848..612edb4d8b 100644
--- a/lib/_stream_passthrough.js
+++ b/lib/_stream_passthrough.js
@@ -30,7 +30,7 @@ module.exports = PassThrough;
var Transform = require('./_stream_transform');
/**/
-var util = require('core-util-is');
+var util = Object.create(require('core-util-is'));
util.inherits = require('inherits');
/**/
diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js
index bf34ac65e1..3af95cb2db 100644
--- a/lib/_stream_readable.js
+++ b/lib/_stream_readable.js
@@ -53,7 +53,7 @@ var Stream = require('./internal/streams/stream');
/**/
var Buffer = require('safe-buffer').Buffer;
-var OurUint8Array = global.Uint8Array || function () {};
+var OurUint8Array = (typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
function _uint8ArrayToBuffer(chunk) {
return Buffer.from(chunk);
}
@@ -64,7 +64,7 @@ function _isUint8Array(obj) {
/**/
/**/
-var util = require('core-util-is');
+var util = Object.create(require('core-util-is'));
util.inherits = require('inherits');
/**/
@@ -623,8 +623,8 @@ Readable.prototype.pipe = function (dest, pipeOpts) {
// also returned false.
// => Check whether `dest` is still a piping destination.
if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
- debug('false write response, pause', src._readableState.awaitDrain);
- src._readableState.awaitDrain++;
+ debug('false write response, pause', state.awaitDrain);
+ state.awaitDrain++;
increasedAwaitDrain = true;
}
src.pause();
@@ -718,7 +718,7 @@ Readable.prototype.unpipe = function (dest) {
state.flowing = false;
for (var i = 0; i < len; i++) {
- dests[i].emit('unpipe', this, unpipeInfo);
+ dests[i].emit('unpipe', this, { hasUnpiped: false });
}return this;
}
diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js
index 5d1f8b876d..fcfc105af8 100644
--- a/lib/_stream_transform.js
+++ b/lib/_stream_transform.js
@@ -68,7 +68,7 @@ module.exports = Transform;
var Duplex = require('./_stream_duplex');
/**/
-var util = require('core-util-is');
+var util = Object.create(require('core-util-is'));
util.inherits = require('inherits');
/**/
diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js
index b3f4e85a2f..e1e897ff3b 100644
--- a/lib/_stream_writable.js
+++ b/lib/_stream_writable.js
@@ -64,7 +64,7 @@ var Duplex;
Writable.WritableState = WritableState;
/**/
-var util = require('core-util-is');
+var util = Object.create(require('core-util-is'));
util.inherits = require('inherits');
/**/
@@ -81,7 +81,7 @@ var Stream = require('./internal/streams/stream');
/**/
var Buffer = require('safe-buffer').Buffer;
-var OurUint8Array = global.Uint8Array || function () {};
+var OurUint8Array = (typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
function _uint8ArrayToBuffer(chunk) {
return Buffer.from(chunk);
}
@@ -349,7 +349,7 @@ Writable.prototype.uncork = function () {
if (state.corked) {
state.corked--;
- if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
+ if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
}
};
@@ -591,7 +591,7 @@ Writable.prototype.end = function (chunk, encoding, cb) {
}
// ignore unnecessary end() calls.
- if (!state.ending && !state.finished) endWritable(this, state, cb);
+ if (!state.ending) endWritable(this, state, cb);
};
function needFinish(state) {
@@ -652,11 +652,9 @@ function onCorkedFinish(corkReq, state, err) {
cb(err);
entry = entry.next;
}
- if (state.corkedRequestsFree) {
- state.corkedRequestsFree.next = corkReq;
- } else {
- state.corkedRequestsFree = corkReq;
- }
+
+ // reuse the free corkReq.
+ state.corkedRequestsFree.next = corkReq;
}
Object.defineProperty(Writable.prototype, 'destroyed', {
diff --git a/lib/internal/streams/BufferList.js b/lib/internal/streams/BufferList.js
index aefc68bd90..5e080976c3 100644
--- a/lib/internal/streams/BufferList.js
+++ b/lib/internal/streams/BufferList.js
@@ -56,7 +56,6 @@ module.exports = function () {
BufferList.prototype.concat = function concat(n) {
if (this.length === 0) return Buffer.alloc(0);
- if (this.length === 1) return this.head.data;
var ret = Buffer.allocUnsafe(n >>> 0);
var p = this.head;
var i = 0;
diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js
index 5a0a0d88ce..85a821407f 100644
--- a/lib/internal/streams/destroy.js
+++ b/lib/internal/streams/destroy.js
@@ -15,9 +15,15 @@ function destroy(err, cb) {
if (readableDestroyed || writableDestroyed) {
if (cb) {
cb(err);
- } else if (err && (!this._writableState || !this._writableState.errorEmitted)) {
- pna.nextTick(emitErrorNT, this, err);
+ } else if (err) {
+ if (!this._writableState) {
+ pna.nextTick(emitErrorNT, this, err);
+ } else if (!this._writableState.errorEmitted) {
+ this._writableState.errorEmitted = true;
+ pna.nextTick(emitErrorNT, this, err);
+ }
}
+
return this;
}
@@ -35,9 +41,11 @@ function destroy(err, cb) {
this._destroy(err || null, function (err) {
if (!cb && err) {
- pna.nextTick(emitErrorNT, _this, err);
- if (_this._writableState) {
+ if (!_this._writableState) {
+ pna.nextTick(emitErrorNT, _this, err);
+ } else if (!_this._writableState.errorEmitted) {
_this._writableState.errorEmitted = true;
+ pna.nextTick(emitErrorNT, _this, err);
}
} else if (cb) {
cb(err);
@@ -59,6 +67,8 @@ function undestroy() {
this._writableState.destroyed = false;
this._writableState.ended = false;
this._writableState.ending = false;
+ this._writableState.finalCalled = false;
+ this._writableState.prefinished = false;
this._writableState.finished = false;
this._writableState.errorEmitted = false;
}
diff --git a/package.json b/package.json
index dbb1da6be5..514c178e92 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "readable-stream",
- "version": "2.3.6",
+ "version": "2.3.8",
"description": "Streams3, a user-land copy of the stream library from Node.js",
"main": "readable.js",
"dependencies": {
diff --git a/test/common/README.md b/test/common/README.md
index 67e4e4e48f..f9e5bdb156 100644
--- a/test/common/README.md
+++ b/test/common/README.md
@@ -26,6 +26,9 @@ This directory contains modules used to test the Node.js implementation.
* [DNS module](#dns-module)
* [Duplex pair helper](#duplex-pair-helper)
* [Fixtures module](#fixtures-module)
+* [HTTP2 module](#http2-module)
+* [Internet module](#internet-module)
+* [tmpdir module](#tmpdir-module)
* [WPT module](#wpt-module)
## Benchmark Module
@@ -249,6 +252,11 @@ Platform check for Windows.
Platform check for Windows 32-bit on Windows 64-bit.
+### isCPPSymbolsNotMapped
+* [<Boolean>]
+
+Platform check for C++ symbols are mapped or not.
+
### leakedGlobals()
* return [<Array>]
@@ -275,6 +283,17 @@ fail.
If `fn` is not provided, an empty function will be used.
+### mustCallAsync([fn][, exact])
+* `fn` [<Function>]
+* `exact` [<Number>] default = 1
+* return [<Function>]
+
+The same as `mustCall()`, except that it is also checked that the Promise
+returned by the function is fulfilled for each invocation of the function.
+
+The return value of the wrapped function is the return value of the original
+function, if necessary wrapped as a promise.
+
### mustCallAtLeast([fn][, minimum])
* `fn` [<Function>] default = () => {}
* `minimum` [<Number>] default = 1
@@ -328,11 +347,6 @@ A port number for tests to use if one is needed.
Logs '1..0 # Skipped: ' + `msg`
-### refreshTmpDir()
-* return [<String>]
-
-Deletes the testing 'tmp' directory and recreates it.
-
### restoreStderr()
Restore the original `process.stderr.write`. Used to restore `stderr` to its
@@ -385,17 +399,12 @@ Platform normalizes the `pwd` command.
Synchronous version of `spawnPwd`.
-### tmpDir
-* [<String>]
-
-The realpath of the 'tmp' directory.
-
## Countdown Module
The `Countdown` module provides a simple countdown mechanism for tests that
require a particular action to be taken after a given number of completed
tasks (for instance, shutting down an HTTP server after a specific number of
-requests).
+requests). The Countdown will fail the test if the remainder did not reach 0.
```js
@@ -428,7 +437,26 @@ called before the callback is invoked.
## DNS Module
-The `DNS` module provides a naïve DNS parser/serializer.
+The `DNS` module provides utilities related to the `dns` built-in module.
+
+### errorLookupMock(code, syscall)
+
+* `code` [<String>] Defaults to `dns.mockedErrorCode`.
+* `syscall` [<String>] Defaults to `dns.mockedSysCall`.
+* return [<Function>]
+
+
+A mock for the `lookup` option of `net.connect()` that would result in an error
+with the `code` and the `syscall` specified. Returns a function that has the
+same signature as `dns.lookup()`.
+
+### mockedErrorCode
+
+The default `code` of errors generated by `errorLookupMock`.
+
+### mockedSysCall
+
+The default `syscall` of errors generated by `errorLookupMock`.
### readDomainFromPacket(buffer, offset)
@@ -508,6 +536,151 @@ Returns the result of
Returns the result of
`fs.readFileSync(path.join(fixtures.fixturesDir, 'keys', arg), 'enc')`.
+## HTTP/2 Module
+
+The http2.js module provides a handful of utilities for creating mock HTTP/2
+frames for testing of HTTP/2 endpoints
+
+
+```js
+const http2 = require('../common/http2');
+```
+
+### Class: Frame
+
+The `http2.Frame` is a base class that creates a `Buffer` containing a
+serialized HTTP/2 frame header.
+
+
+```js
+// length is a 24-bit unsigned integer
+// type is an 8-bit unsigned integer identifying the frame type
+// flags is an 8-bit unsigned integer containing the flag bits
+// id is the 32-bit stream identifier, if any.
+const frame = new http2.Frame(length, type, flags, id);
+
+// Write the frame data to a socket
+socket.write(frame.data);
+```
+
+The serialized `Buffer` may be retrieved using the `frame.data` property.
+
+### Class: DataFrame extends Frame
+
+The `http2.DataFrame` is a subclass of `http2.Frame` that serializes a `DATA`
+frame.
+
+
+```js
+// id is the 32-bit stream identifier
+// payload is a Buffer containing the DATA payload
+// padlen is an 8-bit integer giving the number of padding bytes to include
+// final is a boolean indicating whether the End-of-stream flag should be set,
+// defaults to false.
+const frame = new http2.DataFrame(id, payload, padlen, final);
+
+socket.write(frame.data);
+```
+
+### Class: HeadersFrame
+
+The `http2.HeadersFrame` is a subclass of `http2.Frame` that serializes a
+`HEADERS` frame.
+
+
+```js
+// id is the 32-bit stream identifier
+// payload is a Buffer containing the HEADERS payload (see either
+// http2.kFakeRequestHeaders or http2.kFakeResponseHeaders).
+// padlen is an 8-bit integer giving the number of padding bytes to include
+// final is a boolean indicating whether the End-of-stream flag should be set,
+// defaults to false.
+const frame = new http2.HeadersFrame(id, payload, padlen, final);
+
+socket.write(frame.data);
+```
+
+### Class: SettingsFrame
+
+The `http2.SettingsFrame` is a subclass of `http2.Frame` that serializes an
+empty `SETTINGS` frame.
+
+
+```js
+// ack is a boolean indicating whether or not to set the ACK flag.
+const frame = new http2.SettingsFrame(ack);
+
+socket.write(frame.data);
+```
+
+### http2.kFakeRequestHeaders
+
+Set to a `Buffer` instance that contains a minimal set of serialized HTTP/2
+request headers to be used as the payload of a `http2.HeadersFrame`.
+
+
+```js
+const frame = new http2.HeadersFrame(1, http2.kFakeRequestHeaders, 0, true);
+
+socket.write(frame.data);
+```
+
+### http2.kFakeResponseHeaders
+
+Set to a `Buffer` instance that contains a minimal set of serialized HTTP/2
+response headers to be used as the payload a `http2.HeadersFrame`.
+
+
+```js
+const frame = new http2.HeadersFrame(1, http2.kFakeResponseHeaders, 0, true);
+
+socket.write(frame.data);
+```
+
+### http2.kClientMagic
+
+Set to a `Buffer` containing the preamble bytes an HTTP/2 client must send
+upon initial establishment of a connection.
+
+
+```js
+socket.write(http2.kClientMagic);
+```
+
+## Internet Module
+
+The `common/internet` module provides utilities for working with
+internet-related tests.
+
+### internet.addresses
+
+* [<Object>]
+ * `INET_HOST` [<String>] A generic host that has registered common
+ DNS records, supports both IPv4 and IPv6, and provides basic HTTP/HTTPS
+ services
+ * `INET4_HOST` [<String>] A host that provides IPv4 services
+ * `INET6_HOST` [<String>] A host that provides IPv6 services
+ * `INET4_IP` [<String>] An accessible IPv4 IP, defaults to the
+ Google Public DNS IPv4 address
+ * `INET6_IP` [<String>] An accessible IPv6 IP, defaults to the
+ Google Public DNS IPv6 address
+ * `INVALID_HOST` [<String>] An invalid host that cannot be resolved
+ * `MX_HOST` [<String>] A host with MX records registered
+ * `SRV_HOST` [<String>] A host with SRV records registered
+ * `PTR_HOST` [<String>] A host with PTR records registered
+ * `NAPTR_HOST` [<String>] A host with NAPTR records registered
+ * `SOA_HOST` [<String>] A host with SOA records registered
+ * `CNAME_HOST` [<String>] A host with CNAME records registered
+ * `NS_HOST` [<String>] A host with NS records registered
+ * `TXT_HOST` [<String>] A host with TXT records registered
+ * `DNS4_SERVER` [<String>] An accessible IPv4 DNS server
+ * `DNS6_SERVER` [<String>] An accessible IPv6 DNS server
+
+A set of addresses for internet-related tests. All properties are configurable
+via `NODE_TEST_*` environment variables. For example, to configure
+`internet.addresses.INET_HOST`, set the environment
+variable `NODE_TEST_INET_HOST` to a specified host.
+
## WPT Module
The wpt.js module is a port of parts of
@@ -517,6 +690,7 @@ Node.js
implementation with tests from
[W3C Web Platform Tests](https://github.com/w3c/web-platform-tests).
+
[<Array>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
[<ArrayBufferView[]>]: https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView
[<Boolean>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type
diff --git a/test/common/countdown.js b/test/common/countdown.js
index 411fb69d2e..7590becdcf 100644
--- a/test/common/countdown.js
+++ b/test/common/countdown.js
@@ -34,6 +34,7 @@ var objectKeys = objectKeys || function (obj) {
var assert = require('assert');
var kLimit = Symbol('limit');
var kCallback = Symbol('callback');
+var common = require('./');
var Countdown = function () {
function Countdown(limit, cb) {
@@ -42,7 +43,7 @@ var Countdown = function () {
assert.strictEqual(typeof limit, 'number');
assert.strictEqual(typeof cb, 'function');
this[kLimit] = limit;
- this[kCallback] = cb;
+ this[kCallback] = common.mustCall(cb);
}
Countdown.prototype.dec = function dec() {
diff --git a/test/common/dns.js b/test/common/dns.js
index 388c8df83d..aea1e6a947 100644
--- a/test/common/dns.js
+++ b/test/common/dns.js
@@ -29,8 +29,6 @@ var objectKeys = objectKeys || function (obj) {
};
/**/
-// Naïve DNS parser/serializer.
-
var assert = require('assert');
var os = require('os');
@@ -50,6 +48,8 @@ var classes = {
IN: 1
};
+// Naïve DNS parser/serializer.
+
function readDomainFromPacket(buffer, offset) {
assert.ok(offset < buffer.length);
var length = buffer[offset];
@@ -409,7 +409,32 @@ function writeDNSPacket(parsed) {
}));
}
-module.exports = { types: types, classes: classes, writeDNSPacket: writeDNSPacket, parseDNSPacket: parseDNSPacket };
+var mockedErrorCode = 'ENOTFOUND';
+var mockedSysCall = 'getaddrinfo';
+
+function errorLookupMock() {
+ var code = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : mockedErrorCode;
+ var syscall = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : mockedSysCall;
+
+ return function lookupWithError(host, dnsopts, cb) {
+ var err = new Error(syscall + ' ' + code + ' ' + host);
+ err.code = code;
+ err.errno = code;
+ err.syscall = syscall;
+ err.hostname = host;
+ cb(err);
+ };
+}
+
+module.exports = {
+ types: types,
+ classes: classes,
+ writeDNSPacket: writeDNSPacket,
+ parseDNSPacket: parseDNSPacket,
+ errorLookupMock: errorLookupMock,
+ mockedErrorCode: mockedErrorCode,
+ mockedSysCall: mockedSysCall
+};
function forEach(xs, f) {
for (var i = 0, l = xs.length; i < l; i++) {
diff --git a/test/common/http2.js b/test/common/http2.js
new file mode 100644
index 0000000000..dba0bd8f9b
--- /dev/null
+++ b/test/common/http2.js
@@ -0,0 +1,237 @@
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/**/
+require('babel-polyfill');
+var util = require('util');
+for (var i in util) {
+ exports[i] = util[i];
+} /**/ /**/
+if (!global.setImmediate) {
+ global.setImmediate = function setImmediate(fn) {
+ return setTimeout(fn.bind.apply(fn, arguments), 4);
+ };
+}
+if (!global.clearImmediate) {
+ global.clearImmediate = function clearImmediate(i) {
+ return clearTimeout(i);
+ };
+}
+/**/
+/* eslint-disable required-modules */
+'use strict';
+
+/**/
+var objectKeys = objectKeys || function (obj) {
+ var keys = [];
+ for (var key in obj) {
+ keys.push(key);
+ }return keys;
+};
+/**/
+
+// An HTTP/2 testing tool used to create mock frames for direct testing
+// of HTTP/2 endpoints.
+
+var kFrameData = Symbol('frame-data');
+var FLAG_EOS = 0x1;
+var FLAG_ACK = 0x1;
+var FLAG_EOH = 0x4;
+var FLAG_PADDED = 0x8;
+var PADDING = Buffer.alloc(255);
+
+var kClientMagic = Buffer.from('505249202a20485454502f322' + 'e300d0a0d0a534d0d0a0d0a', 'hex');
+
+var kFakeRequestHeaders = Buffer.from('828684410f7777772e65' + '78616d706c652e636f6d', 'hex');
+
+var kFakeResponseHeaders = Buffer.from('4803333032580770726976617465611d' + '4d6f6e2c203231204f63742032303133' + '2032303a31333a323120474d546e1768' + '747470733a2f2f7777772e6578616d70' + '6c652e636f6d', 'hex');
+
+function isUint32(val) {
+ return val >>> 0 === val;
+}
+
+function isUint24(val) {
+ return val >>> 0 === val && val <= 0xFFFFFF;
+}
+
+function isUint8(val) {
+ return val >>> 0 === val && val <= 0xFF;
+}
+
+function write32BE(array, pos, val) {
+ if (!isUint32(val)) throw new RangeError('val is not a 32-bit number');
+ array[pos++] = val >> 24 & 0xff;
+ array[pos++] = val >> 16 & 0xff;
+ array[pos++] = val >> 8 & 0xff;
+ array[pos++] = val & 0xff;
+}
+
+function write24BE(array, pos, val) {
+ if (!isUint24(val)) throw new RangeError('val is not a 24-bit number');
+ array[pos++] = val >> 16 & 0xff;
+ array[pos++] = val >> 8 & 0xff;
+ array[pos++] = val & 0xff;
+}
+
+function write8(array, pos, val) {
+ if (!isUint8(val)) throw new RangeError('val is not an 8-bit number');
+ array[pos] = val;
+}
+
+var Frame = function () {
+ function Frame(length, type, flags, id) {
+ _classCallCheck(this, Frame);
+
+ this[kFrameData] = Buffer.alloc(9);
+ write24BE(this[kFrameData], 0, length);
+ write8(this[kFrameData], 3, type);
+ write8(this[kFrameData], 4, flags);
+ write32BE(this[kFrameData], 5, id);
+ }
+
+ _createClass(Frame, [{
+ key: 'data',
+ get: function () {
+ return this[kFrameData];
+ }
+ }]);
+
+ return Frame;
+}();
+
+var SettingsFrame = function (_Frame) {
+ _inherits(SettingsFrame, _Frame);
+
+ function SettingsFrame() {
+ var ack = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+
+ _classCallCheck(this, SettingsFrame);
+
+ var flags = 0;
+ if (ack) flags |= FLAG_ACK;
+ return _possibleConstructorReturn(this, _Frame.call(this, 0, 4, flags, 0));
+ }
+
+ return SettingsFrame;
+}(Frame);
+
+var DataFrame = function (_Frame2) {
+ _inherits(DataFrame, _Frame2);
+
+ function DataFrame(id, payload) {
+ var padlen = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
+ var final = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
+
+ _classCallCheck(this, DataFrame);
+
+ var len = payload.length;
+ var flags = 0;
+ if (final) flags |= FLAG_EOS;
+ var buffers = [payload];
+ if (padlen > 0) {
+ buffers.unshift(Buffer.from([padlen]));
+ buffers.push(PADDING.slice(0, padlen));
+ len += padlen + 1;
+ flags |= FLAG_PADDED;
+ }
+
+ var _this2 = _possibleConstructorReturn(this, _Frame2.call(this, len, 0, flags, id));
+
+ buffers.unshift(_this2[kFrameData]);
+ _this2[kFrameData] = Buffer.concat(buffers);
+ return _this2;
+ }
+
+ return DataFrame;
+}(Frame);
+
+var HeadersFrame = function (_Frame3) {
+ _inherits(HeadersFrame, _Frame3);
+
+ function HeadersFrame(id, payload) {
+ var padlen = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
+ var final = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
+
+ _classCallCheck(this, HeadersFrame);
+
+ var len = payload.length;
+ var flags = FLAG_EOH;
+ if (final) flags |= FLAG_EOS;
+ var buffers = [payload];
+ if (padlen > 0) {
+ buffers.unshift(Buffer.from([padlen]));
+ buffers.push(PADDING.slice(0, padlen));
+ len += padlen + 1;
+ flags |= FLAG_PADDED;
+ }
+
+ var _this3 = _possibleConstructorReturn(this, _Frame3.call(this, len, 1, flags, id));
+
+ buffers.unshift(_this3[kFrameData]);
+ _this3[kFrameData] = Buffer.concat(buffers);
+ return _this3;
+ }
+
+ return HeadersFrame;
+}(Frame);
+
+var PingFrame = function (_Frame4) {
+ _inherits(PingFrame, _Frame4);
+
+ function PingFrame() {
+ var ack = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+
+ _classCallCheck(this, PingFrame);
+
+ var buffers = [Buffer.alloc(8)];
+
+ var _this4 = _possibleConstructorReturn(this, _Frame4.call(this, 8, 6, ack ? 1 : 0, 0));
+
+ buffers.unshift(_this4[kFrameData]);
+ _this4[kFrameData] = Buffer.concat(buffers);
+ return _this4;
+ }
+
+ return PingFrame;
+}(Frame);
+
+var AltSvcFrame = function (_Frame5) {
+ _inherits(AltSvcFrame, _Frame5);
+
+ function AltSvcFrame(size) {
+ _classCallCheck(this, AltSvcFrame);
+
+ var buffers = [Buffer.alloc(size)];
+
+ var _this5 = _possibleConstructorReturn(this, _Frame5.call(this, size, 10, 0, 0));
+
+ buffers.unshift(_this5[kFrameData]);
+ _this5[kFrameData] = Buffer.concat(buffers);
+ return _this5;
+ }
+
+ return AltSvcFrame;
+}(Frame);
+
+module.exports = {
+ Frame: Frame,
+ AltSvcFrame: AltSvcFrame,
+ DataFrame: DataFrame,
+ HeadersFrame: HeadersFrame,
+ SettingsFrame: SettingsFrame,
+ PingFrame: PingFrame,
+ kFakeRequestHeaders: kFakeRequestHeaders,
+ kFakeResponseHeaders: kFakeResponseHeaders,
+ kClientMagic: kClientMagic
+};
+
+function forEach(xs, f) {
+ for (var i = 0, l = xs.length; i < l; i++) {
+ f(xs[i], i);
+ }
+}
\ No newline at end of file
diff --git a/test/common/index.js b/test/common/index.js
index 33fa11e8d6..15cd964f84 100644
--- a/test/common/index.js
+++ b/test/common/index.js
@@ -75,13 +75,10 @@ var Timer = { now: function () {} };
var _require2 = require('./fixtures'),
fixturesDir = _require2.fixturesDir;
-var testRoot = process.env.NODE_TEST_DIR ? fs.realpathSync(process.env.NODE_TEST_DIR) : path.resolve(__dirname, '..');
+var tmpdir = require('./tmpdir');
var noop = function () {};
-// Using a `.` prefixed name, which is the convention for "hidden" on POSIX,
-// gets tools to ignore it by default or by simple rules, especially eslint.
-var tmpDirName = '.tmp';
// PORT should match the definition in test/testpy/__init__.py.
exports.PORT = +process.env.NODE_COMMON_PORT || 12346;
exports.isWindows = process.platform === 'win32';
@@ -90,8 +87,10 @@ exports.isAIX = process.platform === 'aix';
exports.isLinuxPPCBE = process.platform === 'linux' && process.arch === 'ppc64' && os.endianness() === 'BE';
exports.isSunOS = process.platform === 'sunos';
exports.isFreeBSD = process.platform === 'freebsd';
+exports.isOpenBSD = process.platform === 'openbsd';
exports.isLinux = process.platform === 'linux';
-exports.isOSX = process.platform === 'darwin';
+var isOSX = exports.isOSX = process.platform === 'darwin';
+exports.isOSXMojave = isOSX && os.release().startsWith('18');
exports.enoughTestMem = os.totalmem() > 0x70000000; /* 1.75 Gb */
var cpus = os.cpus();
@@ -122,7 +121,7 @@ if (process.env.NODE_TEST_WITH_ASYNC_HOOKS) {
var _async_wrap = process.binding('async_wrap');
process.on('exit', function () {
- // itterate through handles to make sure nothing crashes
+ // iterate through handles to make sure nothing crashes
for (var k in initHandles) {
util.inspect(initHandles[k]);
}
@@ -162,55 +161,6 @@ if (process.env.NODE_TEST_WITH_ASYNC_HOOKS) {
}).enable();*/
}
-function rimrafSync(p) {
- var st = void 0;
- try {
- st = fs.lstatSync(p);
- } catch (e) {
- if (e.code === 'ENOENT') return;
- }
-
- try {
- if (st && st.isDirectory()) rmdirSync(p, null);else fs.unlinkSync(p);
- } catch (e) {
- if (e.code === 'ENOENT') return;
- if (e.code === 'EPERM') return rmdirSync(p, e);
- if (e.code !== 'EISDIR') throw e;
- rmdirSync(p, e);
- }
-}
-
-function rmdirSync(p, originalEr) {
- try {
- fs.rmdirSync(p);
- } catch (e) {
- if (e.code === 'ENOTDIR') throw originalEr;
- if (e.code === 'ENOTEMPTY' || e.code === 'EEXIST' || e.code === 'EPERM') {
- var enc = exports.isLinux ? 'buffer' : 'utf8';
- forEach(fs.readdirSync(p, enc), function (f) {
- if (f instanceof Buffer) {
- var buf = Buffer.concat([Buffer.from(p), Buffer.from(path.sep), f]);
- rimrafSync(buf);
- } else {
- rimrafSync(path.join(p, f));
- }
- });
- fs.rmdirSync(p);
- }
- }
-}
-
-exports.refreshTmpDir = function () {
- rimrafSync(exports.tmpDir);
- fs.mkdirSync(exports.tmpDir);
-};
-
-if (process.env.TEST_THREAD_ID) {
- exports.PORT += process.env.TEST_THREAD_ID * 100;
- tmpDirName += '.' + process.env.TEST_THREAD_ID;
-}
-exports.tmpDir = path.join(testRoot, tmpDirName);
-
var opensslCli = null;
var inFreeBSDJail = null;
var localhostIPv4 = null;
@@ -307,7 +257,7 @@ if (exports.isLinux) {
} /**/
{
- var localRelative = path.relative(process.cwd(), exports.tmpDir + '/');
+ var localRelative = path.relative(process.cwd(), tmpdir.path + '/');
var pipePrefix = exports.isWindows ? '\\\\.\\pipe\\' : localRelative;
var pipeName = 'node-test.' + process.pid + '.sock';
exports.PIPE = path.join(pipePrefix, pipeName);
@@ -532,6 +482,14 @@ exports.mustCallAtLeast = function (fn, minimum) {
return _mustCallInner(fn, minimum, 'minimum');
};
+exports.mustCallAsync = function (fn, exact) {
+ return exports.mustCall(function () {
+ return Promise.resolve(fn.apply(undefined, arguments)).then(exports.mustCall(function (val) {
+ return val;
+ }));
+ }, exact);
+};
+
function _mustCallInner(fn) {
var _context;
@@ -595,7 +553,7 @@ exports.canCreateSymLink = function () {
// whoami.exe needs to be the one from System32
// If unix tools are in the path, they can shadow the one we want,
// so use the full path while executing whoami
- var whoamiPath = path.join(process.env['SystemRoot'], 'System32', 'whoami.exe');
+ var whoamiPath = path.join(process.env.SystemRoot, 'System32', 'whoami.exe');
var err = false;
var output = '';
@@ -779,7 +737,14 @@ exports.expectsError = function expectsError(fn, settings, exact) {
fn = undefined;
}
function innerFn(error) {
+ if (arguments.length !== 1) {
+ // Do not use `assert.strictEqual()` to prevent `util.inspect` from
+ // always being called.
+ assert.fail('Expected one argument, got ' + util.inspect(arguments));
+ }
assert.strictEqual(error.code, settings.code);
+ var descriptor = Object.getOwnPropertyDescriptor(error, 'message');
+ assert.strictEqual(descriptor.enumerable, false, 'The error message should be non-enumerable');
if ('type' in settings) {
var type = settings.type;
if (type !== Error && !Error.isPrototypeOf(type)) {
@@ -933,6 +898,8 @@ exports.firstInvalidFD = function firstInvalidFD() {
return fd;
};
+exports.isCPPSymbolsNotMapped = exports.isWindows || exports.isSunOS || exports.isAIX || exports.isLinuxPPCBE || exports.isFreeBSD;
+
function forEach(xs, f) {
for (var i = 0, l = xs.length; i < l; i++) {
f(xs[i], i);
diff --git a/test/common/inspector-helper.js b/test/common/inspector-helper.js
index 3e4f16573a..8937c95aa6 100644
--- a/test/common/inspector-helper.js
+++ b/test/common/inspector-helper.js
@@ -218,9 +218,10 @@ var InspectorSession = function () {
if (message.result) resolve(message.result);else reject(message.error);
} else {
if (message.method === 'Debugger.scriptParsed') {
- var script = message['params'];
- var scriptId = script['scriptId'];
- var _url = script['url'];
+ var _message$params = message.params,
+ scriptId = _message$params.scriptId,
+ _url = _message$params.url;
+
this._scriptsIdsByUrl.set(scriptId, _url);
if (_url === _MAINSCRIPT) this.mainScriptId = scriptId;
}
@@ -240,11 +241,11 @@ var InspectorSession = function () {
var _this2 = this;
var msg = JSON.parse(JSON.stringify(message)); // Clone!
- msg['id'] = this._nextId++;
+ msg.id = this._nextId++;
if (DEBUG) console.log('[sent]', JSON.stringify(msg));
var responsePromise = new Promise(function (resolve, reject) {
- _this2._commandResponsePromises.set(msg['id'], { resolve: resolve, reject: reject });
+ _this2._commandResponsePromises.set(msg.id, { resolve: resolve, reject: reject });
});
return new Promise(function (resolve) {
@@ -294,12 +295,13 @@ var InspectorSession = function () {
return notification;
};
- InspectorSession.prototype._isBreakOnLineNotification = function _isBreakOnLineNotification(message, line, url) {
- if ('Debugger.paused' === message['method']) {
- var callFrame = message['params']['callFrames'][0];
- var location = callFrame['location'];
- assert.strictEqual(url, this._scriptsIdsByUrl.get(location['scriptId']));
- assert.strictEqual(line, location['lineNumber']);
+ InspectorSession.prototype._isBreakOnLineNotification = function _isBreakOnLineNotification(message, line, expectedScriptPath) {
+ if ('Debugger.paused' === message.method) {
+ var callFrame = message.params.callFrames[0];
+ var location = callFrame.location;
+ var scriptPath = this._scriptsIdsByUrl.get(location.scriptId);
+ assert.strictEqual(scriptPath.toString(), expectedScriptPath.toString(), scriptPath + ' !== ' + expectedScriptPath);
+ assert.strictEqual(line, location.lineNumber);
return true;
}
};
@@ -314,19 +316,19 @@ var InspectorSession = function () {
InspectorSession.prototype._matchesConsoleOutputNotification = function _matchesConsoleOutputNotification(notification, type, values) {
if (!Array.isArray(values)) values = [values];
- if ('Runtime.consoleAPICalled' === notification['method']) {
- var params = notification['params'];
- if (params['type'] === type) {
+ if ('Runtime.consoleAPICalled' === notification.method) {
+ var params = notification.params;
+ if (params.type === type) {
var _i2 = 0;
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
- for (var _iterator2 = params['args'][Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+ for (var _iterator2 = params.args[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var value = _step2.value;
- if (value['value'] !== values[_i2++]) return false;
+ if (value.value !== values[_i2++]) return false;
}
} catch (err) {
_didIteratorError2 = true;
@@ -480,7 +482,7 @@ var NodeInstance = function () {
NodeInstance.prototype.connectInspectorSession = async function connectInspectorSession() {
console.log('[test]', 'Connecting to a child Node process');
var response = await this.httpGet(null, '/json/list');
- var url = response[0]['webSocketDebuggerUrl'];
+ var url = response[0].webSocketDebuggerUrl;
return this.wsHandshake(url);
};
diff --git a/test/common/internet.js b/test/common/internet.js
new file mode 100644
index 0000000000..ec9bcfbcdc
--- /dev/null
+++ b/test/common/internet.js
@@ -0,0 +1,107 @@
+/**/
+require('babel-polyfill');
+var util = require('util');
+for (var i in util) {
+ exports[i] = util[i];
+} /**/ /**/
+if (!global.setImmediate) {
+ global.setImmediate = function setImmediate(fn) {
+ return setTimeout(fn.bind.apply(fn, arguments), 4);
+ };
+}
+if (!global.clearImmediate) {
+ global.clearImmediate = function clearImmediate(i) {
+ return clearTimeout(i);
+ };
+}
+/**/
+/* eslint-disable required-modules */
+'use strict';
+
+/**/
+var objectKeys = objectKeys || function (obj) {
+ var keys = [];
+ for (var key in obj) {
+ keys.push(key);
+ }return keys;
+};
+/**/
+
+// Utilities for internet-related tests
+
+var addresses = {
+ // A generic host that has registered common DNS records,
+ // supports both IPv4 and IPv6, and provides basic HTTP/HTTPS services
+ INET_HOST: 'nodejs.org',
+ // A host that provides IPv4 services
+ INET4_HOST: 'nodejs.org',
+ // A host that provides IPv6 services
+ INET6_HOST: 'nodejs.org',
+ // An accessible IPv4 IP,
+ // defaults to the Google Public DNS IPv4 address
+ INET4_IP: '8.8.8.8',
+ // An accessible IPv6 IP,
+ // defaults to the Google Public DNS IPv6 address
+ INET6_IP: '2001:4860:4860::8888',
+ // An invalid host that cannot be resolved
+ // See https://tools.ietf.org/html/rfc2606#section-2
+ INVALID_HOST: 'something.invalid',
+ // A host with MX records registered
+ MX_HOST: 'nodejs.org',
+ // A host with SRV records registered
+ SRV_HOST: '_jabber._tcp.google.com',
+ // A host with PTR records registered
+ PTR_HOST: '8.8.8.8.in-addr.arpa',
+ // A host with NAPTR records registered
+ NAPTR_HOST: 'sip2sip.info',
+ // A host with SOA records registered
+ SOA_HOST: 'nodejs.org',
+ // A host with CNAME records registered
+ CNAME_HOST: 'blog.nodejs.org',
+ // A host with NS records registered
+ NS_HOST: 'nodejs.org',
+ // A host with TXT records registered
+ TXT_HOST: 'nodejs.org',
+ // An accessible IPv4 DNS server
+ DNS4_SERVER: '8.8.8.8',
+ // An accessible IPv4 DNS server
+ DNS6_SERVER: '2001:4860:4860::8888'
+};
+
+var _iteratorNormalCompletion = true;
+var _didIteratorError = false;
+var _iteratorError = undefined;
+
+try {
+ for (var _iterator = objectKeys(addresses)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var key = _step.value;
+
+ var envName = 'NODE_TEST_' + key;
+ if (process.env[envName]) {
+ addresses[key] = process.env[envName];
+ }
+ }
+} catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+} finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator.return) {
+ _iterator.return();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+}
+
+module.exports = {
+ addresses: addresses
+};
+
+function forEach(xs, f) {
+ for (var i = 0, l = xs.length; i < l; i++) {
+ f(xs[i], i);
+ }
+}
\ No newline at end of file
diff --git a/test/common/shared-lib-util.js b/test/common/shared-lib-util.js
new file mode 100644
index 0000000000..72c0cc719d
--- /dev/null
+++ b/test/common/shared-lib-util.js
@@ -0,0 +1,70 @@
+/**/
+require('babel-polyfill');
+var util = require('util');
+for (var i in util) {
+ exports[i] = util[i];
+} /**/ /**/
+if (!global.setImmediate) {
+ global.setImmediate = function setImmediate(fn) {
+ return setTimeout(fn.bind.apply(fn, arguments), 4);
+ };
+}
+if (!global.clearImmediate) {
+ global.clearImmediate = function clearImmediate(i) {
+ return clearTimeout(i);
+ };
+}
+/**/
+'use strict';
+
+/**/
+var objectKeys = objectKeys || function (obj) {
+ var keys = [];
+ for (var key in obj) {
+ keys.push(key);
+ }return keys;
+};
+/**/
+
+var common = require('../common');
+var path = require('path');
+
+// If node executable is linked to shared lib, need to take care about the
+// shared lib path.
+exports.addLibraryPath = function (env) {
+ if (!process.config.variables.node_shared) {
+ return;
+ }
+
+ env = env || process.env;
+
+ env.LD_LIBRARY_PATH = (env.LD_LIBRARY_PATH ? env.LD_LIBRARY_PATH + path.delimiter : '') + path.join(path.dirname(process.execPath), 'lib.target');
+ // For AIX.
+ env.LIBPATH = (env.LIBPATH ? env.LIBPATH + path.delimiter : '') + path.join(path.dirname(process.execPath), 'lib.target');
+ // For Mac OSX.
+ env.DYLD_LIBRARY_PATH = (env.DYLD_LIBRARY_PATH ? env.DYLD_LIBRARY_PATH + path.delimiter : '') + path.dirname(process.execPath);
+ // For Windows.
+ env.PATH = (env.PATH ? env.PATH + path.delimiter : '') + path.dirname(process.execPath);
+};
+
+// Get the full path of shared lib.
+exports.getSharedLibPath = function () {
+ if (common.isWindows) {
+ return path.join(path.dirname(process.execPath), 'node.dll');
+ } else if (common.isOSX) {
+ return path.join(path.dirname(process.execPath), 'libnode.' + process.config.variables.shlib_suffix);
+ } else {
+ return path.join(path.dirname(process.execPath), 'lib.target', 'libnode.' + process.config.variables.shlib_suffix);
+ }
+};
+
+// Get the binary path of stack frames.
+exports.getBinaryPath = function () {
+ return process.config.variables.node_shared ? exports.getSharedLibPath() : process.execPath;
+};
+
+function forEach(xs, f) {
+ for (var i = 0, l = xs.length; i < l; i++) {
+ f(xs[i], i);
+ }
+}
\ No newline at end of file
diff --git a/test/common/tls.js b/test/common/tls.js
new file mode 100644
index 0000000000..7f884f1470
--- /dev/null
+++ b/test/common/tls.js
@@ -0,0 +1,210 @@
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+/**/
+require('babel-polyfill');
+var util = require('util');
+for (var i in util) {
+ exports[i] = util[i];
+} /**/ /**/
+if (!global.setImmediate) {
+ global.setImmediate = function setImmediate(fn) {
+ return setTimeout(fn.bind.apply(fn, arguments), 4);
+ };
+}
+if (!global.clearImmediate) {
+ global.clearImmediate = function clearImmediate(i) {
+ return clearTimeout(i);
+ };
+}
+/**/
+/* eslint-disable required-modules, crypto-check */
+
+'use strict';
+
+/**/
+var objectKeys = objectKeys || function (obj) {
+ var keys = [];
+ for (var key in obj) {
+ keys.push(key);
+ }return keys;
+};
+/**/
+
+var crypto = require('crypto');
+var net = require('net');
+
+exports.ccs = Buffer.from('140303000101', 'hex');
+
+var TestTLSSocket = function (_net$Socket) {
+ _inherits(TestTLSSocket, _net$Socket);
+
+ function TestTLSSocket(server_cert) {
+ _classCallCheck(this, TestTLSSocket);
+
+ var _this = _possibleConstructorReturn(this, _net$Socket.call(this));
+
+ _this.server_cert = server_cert;
+ _this.version = Buffer.from('0303', 'hex');
+ _this.handshake_list = [];
+ // AES128-GCM-SHA256
+ _this.ciphers = Buffer.from('000002009c0', 'hex');
+ _this.pre_master_secret = Buffer.concat([_this.version, crypto.randomBytes(46)]);
+ _this.master_secret = null;
+ _this.write_seq = 0;
+ _this.client_random = crypto.randomBytes(32);
+
+ _this.on('handshake', function (msg) {
+ _this.handshake_list.push(msg);
+ });
+
+ _this.on('server_random', function (server_random) {
+ _this.master_secret = PRF12('sha256', _this.pre_master_secret, 'master secret', Buffer.concat([_this.client_random, server_random]), 48);
+ var key_block = PRF12('sha256', _this.master_secret, 'key expansion', Buffer.concat([server_random, _this.client_random]), 40);
+ _this.client_writeKey = key_block.slice(0, 16);
+ _this.client_writeIV = key_block.slice(32, 36);
+ });
+ return _this;
+ }
+
+ TestTLSSocket.prototype.createClientHello = function createClientHello() {
+ var compressions = Buffer.from('0100', 'hex'); // null
+ var msg = addHandshakeHeader(0x01, Buffer.concat([this.version, this.client_random, this.ciphers, compressions]));
+ this.emit('handshake', msg);
+ return addRecordHeader(0x16, msg);
+ };
+
+ TestTLSSocket.prototype.createClientKeyExchange = function createClientKeyExchange() {
+ var encrypted_pre_master_secret = crypto.publicEncrypt({
+ key: this.server_cert,
+ padding: crypto.constants.RSA_PKCS1_PADDING
+ }, this.pre_master_secret);
+ var length = Buffer.alloc(2);
+ length.writeUIntBE(encrypted_pre_master_secret.length, 0, 2);
+ var msg = addHandshakeHeader(0x10, Buffer.concat([length, encrypted_pre_master_secret]));
+ this.emit('handshake', msg);
+ return addRecordHeader(0x16, msg);
+ };
+
+ TestTLSSocket.prototype.createFinished = function createFinished() {
+ var shasum = crypto.createHash('sha256');
+ shasum.update(Buffer.concat(this.handshake_list));
+ var message_hash = shasum.digest();
+ var r = PRF12('sha256', this.master_secret, 'client finished', message_hash, 12);
+ var msg = addHandshakeHeader(0x14, r);
+ this.emit('handshake', msg);
+ return addRecordHeader(0x16, msg);
+ };
+
+ TestTLSSocket.prototype.createIllegalHandshake = function createIllegalHandshake() {
+ var illegal_handshake = Buffer.alloc(5);
+ return addRecordHeader(0x16, illegal_handshake);
+ };
+
+ TestTLSSocket.prototype.parseTLSFrame = function parseTLSFrame(buf) {
+ var offset = 0;
+ var record = buf.slice(offset, 5);
+ var type = record[0];
+ var length = record.slice(3, 5).readUInt16BE(0);
+ offset += 5;
+ var remaining = buf.slice(offset, offset + length);
+ if (type === 0x16) {
+ do {
+ remaining = this.parseTLSHandshake(remaining);
+ } while (remaining.length > 0);
+ }
+ offset += length;
+ return buf.slice(offset);
+ };
+
+ TestTLSSocket.prototype.parseTLSHandshake = function parseTLSHandshake(buf) {
+ var offset = 0;
+ var handshake_type = buf[offset];
+ if (handshake_type === 0x02) {
+ var server_random = buf.slice(6, 6 + 32);
+ this.emit('server_random', server_random);
+ }
+ offset += 1;
+ var length = buf.readUIntBE(offset, 3);
+ offset += 3;
+ var handshake = buf.slice(0, offset + length);
+ this.emit('handshake', handshake);
+ offset += length;
+ var remaining = buf.slice(offset);
+ return remaining;
+ };
+
+ TestTLSSocket.prototype.encrypt = function encrypt(plain) {
+ var type = plain.slice(0, 1);
+ var version = plain.slice(1, 3);
+ var nonce = crypto.randomBytes(8);
+ var iv = Buffer.concat([this.client_writeIV.slice(0, 4), nonce]);
+ var bob = crypto.createCipheriv('aes-128-gcm', this.client_writeKey, iv);
+ var write_seq = Buffer.alloc(8);
+ write_seq.writeUInt32BE(this.write_seq++, 4);
+ var aad = Buffer.concat([write_seq, plain.slice(0, 5)]);
+ bob.setAAD(aad);
+ var encrypted1 = bob.update(plain.slice(5));
+ var encrypted = Buffer.concat([encrypted1, bob.final()]);
+ var tag = bob.getAuthTag();
+ var length = Buffer.alloc(2);
+ length.writeUInt16BE(nonce.length + encrypted.length + tag.length, 0);
+ return Buffer.concat([type, version, length, nonce, encrypted, tag]);
+ };
+
+ return TestTLSSocket;
+}(net.Socket);
+
+function addRecordHeader(type, frame) {
+ var record_layer = Buffer.from('0003030000', 'hex');
+ record_layer[0] = type;
+ record_layer.writeUInt16BE(frame.length, 3);
+ return Buffer.concat([record_layer, frame]);
+}
+
+function addHandshakeHeader(type, msg) {
+ var handshake_header = Buffer.alloc(4);
+ handshake_header[0] = type;
+ handshake_header.writeUIntBE(msg.length, 1, 3);
+ return Buffer.concat([handshake_header, msg]);
+}
+
+function PRF12(algo, secret, label, seed, size) {
+ var newSeed = Buffer.concat([Buffer.from(label, 'utf8'), seed]);
+ return P_hash(algo, secret, newSeed, size);
+}
+
+function P_hash(algo, secret, seed, size) {
+ var result = Buffer.alloc(size);
+ var hmac = crypto.createHmac(algo, secret);
+ hmac.update(seed);
+ var a = hmac.digest();
+ var j = 0;
+ while (j < size) {
+ hmac = crypto.createHmac(algo, secret);
+ hmac.update(a);
+ hmac.update(seed);
+ var b = hmac.digest();
+ var todo = b.length;
+ if (j + todo > size) {
+ todo = size - j;
+ }
+ b.copy(result, j, 0, todo);
+ j += todo;
+ hmac = crypto.createHmac(algo, secret);
+ hmac.update(a);
+ a = hmac.digest();
+ }
+ return result;
+}
+
+exports.TestTLSSocket = TestTLSSocket;
+
+function forEach(xs, f) {
+ for (var i = 0, l = xs.length; i < l; i++) {
+ f(xs[i], i);
+ }
+}
\ No newline at end of file
diff --git a/test/common/tmpdir.js b/test/common/tmpdir.js
new file mode 100644
index 0000000000..4753cbe7e5
--- /dev/null
+++ b/test/common/tmpdir.js
@@ -0,0 +1,90 @@
+/**/
+require('babel-polyfill');
+var util = require('util');
+for (var i in util) {
+ exports[i] = util[i];
+} /**/ /**/
+if (!global.setImmediate) {
+ global.setImmediate = function setImmediate(fn) {
+ return setTimeout(fn.bind.apply(fn, arguments), 4);
+ };
+}
+if (!global.clearImmediate) {
+ global.clearImmediate = function clearImmediate(i) {
+ return clearTimeout(i);
+ };
+}
+/**/
+/* eslint-disable required-modules */
+'use strict';
+
+/**/
+var objectKeys = objectKeys || function (obj) {
+ var keys = [];
+ for (var key in obj) {
+ keys.push(key);
+ }return keys;
+};
+/**/
+
+var fs = require('fs');
+var path = require('path');
+
+function rimrafSync(p) {
+ var st = void 0;
+ try {
+ st = fs.lstatSync(p);
+ } catch (e) {
+ if (e.code === 'ENOENT') return;
+ }
+
+ try {
+ if (st && st.isDirectory()) rmdirSync(p, null);else fs.unlinkSync(p);
+ } catch (e) {
+ if (e.code === 'ENOENT') return;
+ if (e.code === 'EPERM') return rmdirSync(p, e);
+ if (e.code !== 'EISDIR') throw e;
+ rmdirSync(p, e);
+ }
+}
+
+function rmdirSync(p, originalEr) {
+ try {
+ fs.rmdirSync(p);
+ } catch (e) {
+ if (e.code === 'ENOTDIR') throw originalEr;
+ if (e.code === 'ENOTEMPTY' || e.code === 'EEXIST' || e.code === 'EPERM') {
+ var enc = process.platform === 'linux' ? 'buffer' : 'utf8';
+ forEach(fs.readdirSync(p, enc), function (f) {
+ if (f instanceof Buffer) {
+ var buf = Buffer.concat([Buffer.from(p), Buffer.from(path.sep), f]);
+ rimrafSync(buf);
+ } else {
+ rimrafSync(path.join(p, f));
+ }
+ });
+ fs.rmdirSync(p);
+ }
+ }
+}
+
+var testRoot = process.env.NODE_TEST_DIR ? fs.realpathSync(process.env.NODE_TEST_DIR) : path.resolve(__dirname, '..');
+
+// Using a `.` prefixed name, which is the convention for "hidden" on POSIX,
+// gets tools to ignore it by default or by simple rules, especially eslint.
+var tmpdirName = '.tmp';
+if (process.env.TEST_THREAD_ID) {
+ tmpdirName += '.' + process.env.TEST_THREAD_ID;
+}
+exports.path = path.join(testRoot, tmpdirName);
+
+exports.refresh = function () {
+ rimrafSync(exports.path);
+ fs.mkdirSync(exports.path);
+};
+
+function forEach(xs, f) {
+ for (var i = 0, l = xs.length; i < l; i++) {
+ f(xs[i], i);
+ }
+}
\ No newline at end of file
diff --git a/test/parallel/test-stream-buffer-list.js b/test/parallel/test-stream-buffer-list.js
index 531658e81e..54a4c7cc71 100644
--- a/test/parallel/test-stream-buffer-list.js
+++ b/test/parallel/test-stream-buffer-list.js
@@ -16,14 +16,19 @@ assert.strictEqual(emptyList.join(','), '');
assert.deepStrictEqual(emptyList.concat(0), bufferShim.alloc(0));
+var buf = bufferShim.from('foo');
+
// Test buffer list with one element.
var list = new BufferList();
-list.push('foo');
+list.push(buf);
+
+var copy = list.concat(3);
-assert.strictEqual(list.concat(1), 'foo');
+assert.notStrictEqual(copy, buf);
+assert.deepStrictEqual(copy, buf);
assert.strictEqual(list.join(','), 'foo');
var shifted = list.shift();
-assert.strictEqual(shifted, 'foo');
+assert.strictEqual(shifted, buf);
assert.deepStrictEqual(list, new BufferList());
\ No newline at end of file
diff --git a/test/parallel/test-stream-pipe-unpipe-streams.js b/test/parallel/test-stream-pipe-unpipe-streams.js
index 6cc3a10491..79f81f3d7d 100644
--- a/test/parallel/test-stream-pipe-unpipe-streams.js
+++ b/test/parallel/test-stream-pipe-unpipe-streams.js
@@ -34,4 +34,46 @@ source.unpipe(dest2);
source.unpipe(dest1);
-assert.strictEqual(source._readableState.pipes, null);
\ No newline at end of file
+assert.strictEqual(source._readableState.pipes, null);
+
+{
+ // test `cleanup()` if we unpipe all streams.
+ var _source = Readable({ read: function () {} });
+ var _dest = Writable({ write: function () {} });
+ var _dest2 = Writable({ write: function () {} });
+
+ var destCount = 0;
+ var srcCheckEventNames = ['end', 'data'];
+ var destCheckEventNames = ['close', 'finish', 'drain', 'error', 'unpipe'];
+
+ var checkSrcCleanup = common.mustCall(function () {
+ assert.strictEqual(_source._readableState.pipes, null);
+ assert.strictEqual(_source._readableState.pipesCount, 0);
+ assert.strictEqual(_source._readableState.flowing, false);
+
+ srcCheckEventNames.forEach(function (eventName) {
+ assert.strictEqual(_source.listenerCount(eventName), 0, 'source\'s \'' + eventName + '\' event listeners not removed');
+ });
+ });
+
+ function checkDestCleanup(dest) {
+ var currentDestId = ++destCount;
+ _source.pipe(dest);
+
+ var unpipeChecker = common.mustCall(function () {
+ assert.deepStrictEqual(dest.listeners('unpipe'), [unpipeChecker], 'destination{' + currentDestId + '} should have a \'unpipe\' event ' + 'listener which is `unpipeChecker`');
+ dest.removeListener('unpipe', unpipeChecker);
+ destCheckEventNames.forEach(function (eventName) {
+ assert.strictEqual(dest.listenerCount(eventName), 0, 'destination{' + currentDestId + '}\'s \'' + eventName + '\' event ' + 'listeners not removed');
+ });
+
+ if (--destCount === 0) checkSrcCleanup();
+ });
+
+ dest.on('unpipe', unpipeChecker);
+ }
+
+ checkDestCleanup(_dest);
+ checkDestCleanup(_dest2);
+ _source.unpipe();
+}
\ No newline at end of file
diff --git a/test/parallel/test-stream-transform-final-sync.js b/test/parallel/test-stream-transform-final-sync.js
index 8667612bca..ad9d265080 100644
--- a/test/parallel/test-stream-transform-final-sync.js
+++ b/test/parallel/test-stream-transform-final-sync.js
@@ -9,7 +9,7 @@ var state = 0;
/*
What you do
-var stream = new tream.Transform({
+var stream = new stream.Transform({
transform: function transformCallback(chunk, _, next) {
// part 1
this.push(chunk);
diff --git a/test/parallel/test-stream-transform-final.js b/test/parallel/test-stream-transform-final.js
index 50e0ce8a1d..2f16312951 100644
--- a/test/parallel/test-stream-transform-final.js
+++ b/test/parallel/test-stream-transform-final.js
@@ -9,7 +9,7 @@ var state = 0;
/*
What you do
-var stream = new tream.Transform({
+var stream = new stream.Transform({
transform: function transformCallback(chunk, _, next) {
// part 1
this.push(chunk);
diff --git a/test/parallel/test-stream-writable-destroy.js b/test/parallel/test-stream-writable-destroy.js
index 3aeff6c445..c00873bfb5 100644
--- a/test/parallel/test-stream-writable-destroy.js
+++ b/test/parallel/test-stream-writable-destroy.js
@@ -172,6 +172,32 @@ var _require2 = require('util'),
assert.strictEqual(_write7.destroyed, true);
}
+{
+ var writable = new Writable({
+ destroy: common.mustCall(function (err, cb) {
+ process.nextTick(cb, new Error('kaboom 1'));
+ }),
+ write: function (chunk, enc, cb) {
+ cb();
+ }
+ });
+
+ writable.on('close', common.mustNotCall());
+ writable.on('error', common.expectsError({
+ type: Error,
+ message: 'kaboom 2'
+ }));
+
+ writable.destroy();
+ assert.strictEqual(writable.destroyed, true);
+ assert.strictEqual(writable._writableState.errorEmitted, false);
+
+ // Test case where `writable.destroy()` is called again with an error before
+ // the `_destroy()` callback is called.
+ writable.destroy(new Error('kaboom 2'));
+ assert.strictEqual(writable._writableState.errorEmitted, true);
+}
+
{
var _write8 = new Writable({
write: function (chunk, enc, cb) {
@@ -214,4 +240,20 @@ var _require2 = require('util'),
_write9.destroy(_expected4, common.mustCall(function (err) {
assert.strictEqual(_expected4, err);
}));
+}
+
+{
+ // Checks that `._undestroy()` restores the state so that `final` will be
+ // called again.
+ var _write10 = new Writable({
+ write: common.mustNotCall(),
+ final: common.mustCall(function (cb) {
+ return cb();
+ }, 2)
+ });
+
+ _write10.end();
+ _write10.destroy();
+ _write10._undestroy();
+ _write10.end();
}
\ No newline at end of file
diff --git a/test/parallel/test-stream2-transform.js b/test/parallel/test-stream2-transform.js
index 62aa1d2bdb..d155c52b1f 100644
--- a/test/parallel/test-stream2-transform.js
+++ b/test/parallel/test-stream2-transform.js
@@ -177,7 +177,7 @@ var Transform = require('../../lib/_stream_transform');
}
{
- // Verify assymetric transform (expand)
+ // Verify asymmetric transform (expand)
var _pt7 = new Transform();
// emit each chunk 2 times.
@@ -209,7 +209,7 @@ var Transform = require('../../lib/_stream_transform');
}
{
- // Verify assymetric trasform (compress)
+ // Verify asymmetric transform (compress)
var _pt8 = new Transform();
// each output is the first char of 3 consecutive chunks,
@@ -265,7 +265,7 @@ var Transform = require('../../lib/_stream_transform');
// this tests for a stall when data is written to a full stream
// that has empty transforms.
{
- // Verify compex transform behavior
+ // Verify complex transform behavior
var count = 0;
var saved = null;
var _pt9 = new Transform({ highWaterMark: 3 });
diff --git a/test/parallel/test-stream3-cork-uncork.js b/test/parallel/test-stream3-cork-uncork.js
index d80e7645e1..50b2784679 100644
--- a/test/parallel/test-stream3-cork-uncork.js
+++ b/test/parallel/test-stream3-cork-uncork.js
@@ -67,7 +67,7 @@ writeChunks(inputChunks, function () {
// trigger writing out the buffer
w.uncork();
- // buffered bytes shoud be seen in current tick
+ // buffered bytes should be seen in current tick
assert.strictEqual(seenChunks.length, 4);
// did the chunks match