Skip to content

Commit

Permalink
stream: initial port of test262 tests
Browse files Browse the repository at this point in the history
PR-URL: #41775
Reviewed-By: Nitzan Uziely <linkgoron@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
benjamingr authored and ruyadorno committed Feb 8, 2022
1 parent 44ca20b commit f8d2955
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 7 deletions.
6 changes: 3 additions & 3 deletions lib/internal/streams/operators.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ function map(fn, options) {
}.call(this);
}

function asIndexedPairs(options) {
function asIndexedPairs(options = undefined) {
if (options != null && typeof options !== 'object') {
throw new ERR_INVALID_ARG_TYPE('options', ['Object']);
}
Expand Down Expand Up @@ -350,7 +350,7 @@ function toIntegerOrInfinity(number) {
return number;
}

function drop(number, options) {
function drop(number, options = undefined) {
if (options != null && typeof options !== 'object') {
throw new ERR_INVALID_ARG_TYPE('options', ['Object']);
}
Expand All @@ -374,7 +374,7 @@ function drop(number, options) {
}.call(this);
}

function take(number, options) {
function take(number, options = undefined) {
if (options != null && typeof options !== 'object') {
throw new ERR_INVALID_ARG_TYPE('options', ['Object']);
}
Expand Down
33 changes: 29 additions & 4 deletions lib/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ const {
streamReturningOperators,
promiseReturningOperators,
} = require('internal/streams/operators');

const {
codes: {
ERR_ILLEGAL_CONSTRUCTOR,
},
} = require('internal/errors');
const compose = require('internal/streams/compose');
const { pipeline } = require('internal/streams/pipeline');
const { destroyer } = require('internal/streams/destroy');
Expand All @@ -51,15 +57,34 @@ Stream.isReadable = utils.isReadable;
Stream.Readable = require('internal/streams/readable');
for (const key of ObjectKeys(streamReturningOperators)) {
const op = streamReturningOperators[key];
Stream.Readable.prototype[key] = function(...args) {
function fn(...args) {
if (new.target) {
throw ERR_ILLEGAL_CONSTRUCTOR();
}
return Stream.Readable.from(ReflectApply(op, this, args));
};
}
ObjectDefineProperty(fn, 'name', { value: op.name });
ObjectDefineProperty(fn, 'length', { value: op.length });
ObjectDefineProperty(Stream.Readable.prototype, key, {
value: fn,
enumerable: false,
configurable: true,
writable: false,
});
}
for (const key of ObjectKeys(promiseReturningOperators)) {
const op = promiseReturningOperators[key];
Stream.Readable.prototype[key] = function(...args) {
function fn(...args) {
return ReflectApply(op, this, args);
};
}
ObjectDefineProperty(fn, 'name', { value: op.name });
ObjectDefineProperty(fn, 'length', { value: op.length });
ObjectDefineProperty(Stream.Readable.prototype, key, {
value: fn,
enumerable: false,
configurable: true,
writable: false,
});
}
Stream.Writable = require('internal/streams/writable');
Stream.Duplex = require('internal/streams/duplex');
Expand Down
115 changes: 115 additions & 0 deletions test/parallel/test-stream-iterator-helpers-test262-tests.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import '../common/index.mjs';
import { Readable } from 'stream';
import assert from 'assert';

// These tests are manually ported from the draft PR for the test262 test suite
// Authored by Rick Waldron in https://github.com/tc39/test262/pull/2818/files

// test262 license:
// The << Software identified by reference to the Ecma Standard* ("Software)">>
// is protected by copyright and is being made available under the
// "BSD License", included below. This Software may be subject to third party
// rights (rights from parties other than Ecma International), including patent
// rights, and no licenses under such third party rights are granted under this
// license even if the third party concerned is a member of Ecma International.
// SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT
// http://www.ecma-international.org/memento/codeofconduct.htm FOR INFORMATION
// REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA
// INTERNATIONAL STANDARDS*

// Copyright (C) 2012-2013 Ecma International
// All rights reserved.

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the authors nor Ecma International may be used to
// endorse or promote products derived from this software without specific
// prior written permission.

// THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
// NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// * Ecma International Standards hereafter means Ecma International Standards
// as well as Ecma Technical Reports


// Note all the tests that check AsyncIterator's prototype itself and things
// that happen before stream conversion were not ported.
{
// asIndexedPairs/is-function
assert.strictEqual(typeof Readable.prototype.asIndexedPairs, 'function');
// asIndexedPairs/indexed-pairs.js
const iterator = Readable.from([0, 1]);
const indexedPairs = iterator.asIndexedPairs();

for await (const [i, v] of indexedPairs) {
assert.strictEqual(i, v);
}
// asIndexedPairs/length.js
assert.strictEqual(Readable.prototype.asIndexedPairs.length, 0);
// asIndexedPairs/name.js
assert.strictEqual(Readable.prototype.asIndexedPairs.name, 'asIndexedPairs');
const descriptor = Object.getOwnPropertyDescriptor(
Readable.prototype,
'asIndexedPairs'
);
assert.strictEqual(descriptor.enumerable, false);
assert.strictEqual(descriptor.configurable, true);
assert.strictEqual(descriptor.writable, false);
}
{
// drop/length
assert.strictEqual(Readable.prototype.drop.length, 1);
const descriptor = Object.getOwnPropertyDescriptor(
Readable.prototype,
'drop'
);
assert.strictEqual(descriptor.enumerable, false);
assert.strictEqual(descriptor.configurable, true);
assert.strictEqual(descriptor.writable, false);
// drop/limit-equals-total
const iterator = Readable.from([1, 2]).drop(2);
const result = await iterator[Symbol.asyncIterator]().next();
assert.deepStrictEqual(result, { done: true, value: undefined });
// drop/limit-greater-than-total.js
const iterator2 = Readable.from([1, 2]).drop(3);
const result2 = await iterator2[Symbol.asyncIterator]().next();
assert.deepStrictEqual(result2, { done: true, value: undefined });
// drop/limit-less-than-total.js
const iterator3 = Readable.from([1, 2]).drop(1);
const result3 = await iterator3[Symbol.asyncIterator]().next();
assert.deepStrictEqual(result3, { done: false, value: 2 });
// drop/limit-rangeerror
assert.throws(() => Readable.from([1]).drop(-1), RangeError);
assert.throws(() => {
Readable.from([1]).drop({
valueOf() {
throw new Error('boom');
}
});
}, /boom/);
// drop/limit-tointeger
const two = await Readable.from([1, 2]).drop({ valueOf: () => 1 }).toArray();
assert.deepStrictEqual(two, [2]);
// drop/name
assert.strictEqual(Readable.prototype.drop.name, 'drop');
// drop/non-constructible
assert.throws(() => new Readable.prototype.drop(1), TypeError);
// drop/proto
const proto = Object.getPrototypeOf(Readable.prototype.drop);
assert.strictEqual(proto, Function.prototype);

}

0 comments on commit f8d2955

Please sign in to comment.