Skip to content

Commit f8d2955

Browse files
benjamingrruyadorno
authored andcommitted
stream: initial port of test262 tests
PR-URL: #41775 Reviewed-By: Nitzan Uziely <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 44ca20b commit f8d2955

File tree

3 files changed

+147
-7
lines changed

3 files changed

+147
-7
lines changed

lib/internal/streams/operators.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ function map(fn, options) {
166166
}.call(this);
167167
}
168168

169-
function asIndexedPairs(options) {
169+
function asIndexedPairs(options = undefined) {
170170
if (options != null && typeof options !== 'object') {
171171
throw new ERR_INVALID_ARG_TYPE('options', ['Object']);
172172
}
@@ -350,7 +350,7 @@ function toIntegerOrInfinity(number) {
350350
return number;
351351
}
352352

353-
function drop(number, options) {
353+
function drop(number, options = undefined) {
354354
if (options != null && typeof options !== 'object') {
355355
throw new ERR_INVALID_ARG_TYPE('options', ['Object']);
356356
}
@@ -374,7 +374,7 @@ function drop(number, options) {
374374
}.call(this);
375375
}
376376

377-
function take(number, options) {
377+
function take(number, options = undefined) {
378378
if (options != null && typeof options !== 'object') {
379379
throw new ERR_INVALID_ARG_TYPE('options', ['Object']);
380380
}

lib/stream.js

+29-4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ const {
3535
streamReturningOperators,
3636
promiseReturningOperators,
3737
} = require('internal/streams/operators');
38+
39+
const {
40+
codes: {
41+
ERR_ILLEGAL_CONSTRUCTOR,
42+
},
43+
} = require('internal/errors');
3844
const compose = require('internal/streams/compose');
3945
const { pipeline } = require('internal/streams/pipeline');
4046
const { destroyer } = require('internal/streams/destroy');
@@ -51,15 +57,34 @@ Stream.isReadable = utils.isReadable;
5157
Stream.Readable = require('internal/streams/readable');
5258
for (const key of ObjectKeys(streamReturningOperators)) {
5359
const op = streamReturningOperators[key];
54-
Stream.Readable.prototype[key] = function(...args) {
60+
function fn(...args) {
61+
if (new.target) {
62+
throw ERR_ILLEGAL_CONSTRUCTOR();
63+
}
5564
return Stream.Readable.from(ReflectApply(op, this, args));
56-
};
65+
}
66+
ObjectDefineProperty(fn, 'name', { value: op.name });
67+
ObjectDefineProperty(fn, 'length', { value: op.length });
68+
ObjectDefineProperty(Stream.Readable.prototype, key, {
69+
value: fn,
70+
enumerable: false,
71+
configurable: true,
72+
writable: false,
73+
});
5774
}
5875
for (const key of ObjectKeys(promiseReturningOperators)) {
5976
const op = promiseReturningOperators[key];
60-
Stream.Readable.prototype[key] = function(...args) {
77+
function fn(...args) {
6178
return ReflectApply(op, this, args);
62-
};
79+
}
80+
ObjectDefineProperty(fn, 'name', { value: op.name });
81+
ObjectDefineProperty(fn, 'length', { value: op.length });
82+
ObjectDefineProperty(Stream.Readable.prototype, key, {
83+
value: fn,
84+
enumerable: false,
85+
configurable: true,
86+
writable: false,
87+
});
6388
}
6489
Stream.Writable = require('internal/streams/writable');
6590
Stream.Duplex = require('internal/streams/duplex');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import '../common/index.mjs';
2+
import { Readable } from 'stream';
3+
import assert from 'assert';
4+
5+
// These tests are manually ported from the draft PR for the test262 test suite
6+
// Authored by Rick Waldron in https://github.com/tc39/test262/pull/2818/files
7+
8+
// test262 license:
9+
// The << Software identified by reference to the Ecma Standard* ("Software)">>
10+
// is protected by copyright and is being made available under the
11+
// "BSD License", included below. This Software may be subject to third party
12+
// rights (rights from parties other than Ecma International), including patent
13+
// rights, and no licenses under such third party rights are granted under this
14+
// license even if the third party concerned is a member of Ecma International.
15+
// SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT
16+
// http://www.ecma-international.org/memento/codeofconduct.htm FOR INFORMATION
17+
// REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA
18+
// INTERNATIONAL STANDARDS*
19+
20+
// Copyright (C) 2012-2013 Ecma International
21+
// All rights reserved.
22+
23+
// Redistribution and use in source and binary forms, with or without
24+
// modification, are permitted provided that the following conditions are met:
25+
// 1. Redistributions of source code must retain the above copyright notice,
26+
// this list of conditions and the following disclaimer.
27+
// 2. Redistributions in binary form must reproduce the above copyright
28+
// notice, this list of conditions and the following disclaimer in the
29+
// documentation and/or other materials provided with the distribution.
30+
// 3. Neither the name of the authors nor Ecma International may be used to
31+
// endorse or promote products derived from this software without specific
32+
// prior written permission.
33+
34+
// THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS
35+
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36+
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
37+
// NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT,
38+
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
39+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
40+
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
41+
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42+
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
43+
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44+
//
45+
// * Ecma International Standards hereafter means Ecma International Standards
46+
// as well as Ecma Technical Reports
47+
48+
49+
// Note all the tests that check AsyncIterator's prototype itself and things
50+
// that happen before stream conversion were not ported.
51+
{
52+
// asIndexedPairs/is-function
53+
assert.strictEqual(typeof Readable.prototype.asIndexedPairs, 'function');
54+
// asIndexedPairs/indexed-pairs.js
55+
const iterator = Readable.from([0, 1]);
56+
const indexedPairs = iterator.asIndexedPairs();
57+
58+
for await (const [i, v] of indexedPairs) {
59+
assert.strictEqual(i, v);
60+
}
61+
// asIndexedPairs/length.js
62+
assert.strictEqual(Readable.prototype.asIndexedPairs.length, 0);
63+
// asIndexedPairs/name.js
64+
assert.strictEqual(Readable.prototype.asIndexedPairs.name, 'asIndexedPairs');
65+
const descriptor = Object.getOwnPropertyDescriptor(
66+
Readable.prototype,
67+
'asIndexedPairs'
68+
);
69+
assert.strictEqual(descriptor.enumerable, false);
70+
assert.strictEqual(descriptor.configurable, true);
71+
assert.strictEqual(descriptor.writable, false);
72+
}
73+
{
74+
// drop/length
75+
assert.strictEqual(Readable.prototype.drop.length, 1);
76+
const descriptor = Object.getOwnPropertyDescriptor(
77+
Readable.prototype,
78+
'drop'
79+
);
80+
assert.strictEqual(descriptor.enumerable, false);
81+
assert.strictEqual(descriptor.configurable, true);
82+
assert.strictEqual(descriptor.writable, false);
83+
// drop/limit-equals-total
84+
const iterator = Readable.from([1, 2]).drop(2);
85+
const result = await iterator[Symbol.asyncIterator]().next();
86+
assert.deepStrictEqual(result, { done: true, value: undefined });
87+
// drop/limit-greater-than-total.js
88+
const iterator2 = Readable.from([1, 2]).drop(3);
89+
const result2 = await iterator2[Symbol.asyncIterator]().next();
90+
assert.deepStrictEqual(result2, { done: true, value: undefined });
91+
// drop/limit-less-than-total.js
92+
const iterator3 = Readable.from([1, 2]).drop(1);
93+
const result3 = await iterator3[Symbol.asyncIterator]().next();
94+
assert.deepStrictEqual(result3, { done: false, value: 2 });
95+
// drop/limit-rangeerror
96+
assert.throws(() => Readable.from([1]).drop(-1), RangeError);
97+
assert.throws(() => {
98+
Readable.from([1]).drop({
99+
valueOf() {
100+
throw new Error('boom');
101+
}
102+
});
103+
}, /boom/);
104+
// drop/limit-tointeger
105+
const two = await Readable.from([1, 2]).drop({ valueOf: () => 1 }).toArray();
106+
assert.deepStrictEqual(two, [2]);
107+
// drop/name
108+
assert.strictEqual(Readable.prototype.drop.name, 'drop');
109+
// drop/non-constructible
110+
assert.throws(() => new Readable.prototype.drop(1), TypeError);
111+
// drop/proto
112+
const proto = Object.getPrototypeOf(Readable.prototype.drop);
113+
assert.strictEqual(proto, Function.prototype);
114+
115+
}

0 commit comments

Comments
 (0)