-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
307 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
'use strict'; | ||
|
||
require('./shim')(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
'use strict'; | ||
|
||
var $TypeError = require('es-errors/type'); | ||
|
||
var AdvanceStringIndex = require('es-abstract/2024/AdvanceStringIndex'); | ||
var Call = require('es-abstract/2024/Call'); | ||
var CompletionRecord = require('es-abstract/2024/CompletionRecord'); | ||
var CreateIteratorFromClosure = require('../aos/CreateIteratorFromClosure'); | ||
var GetIteratorDirect = require('../aos/GetIteratorDirect'); | ||
var GetMethod = require('es-abstract/2024/GetMethod'); | ||
var IsArray = require('es-abstract/2024/IsArray'); | ||
var IteratorClose = require('es-abstract/2024/IteratorClose'); | ||
var IteratorStepValue = require('es-abstract/2024/IteratorStepValue'); | ||
var ThrowCompletion = require('es-abstract/2024/ThrowCompletion'); | ||
var Type = require('es-abstract/2024/Type'); | ||
|
||
var forEach = require('es-abstract/helpers/forEach'); | ||
var getIteratorMethod = require('es-abstract/helpers/getIteratorMethod'); | ||
|
||
var iterHelperProto = require('../IteratorHelperPrototype'); | ||
|
||
var SLOT = require('internal-slot'); | ||
|
||
module.exports = function concat() { | ||
if (this instanceof concat) { | ||
throw new $TypeError('`Iterator.concat` is not a constructor'); | ||
} | ||
|
||
var iterables = []; // step 1 | ||
|
||
forEach(arguments, function (item) { // step 2 | ||
if (Type(item) !== 'Object') { | ||
throw new $TypeError('`Iterator.concat` requires all arguments to be objects'); // step 2.1 | ||
} | ||
// var method = GetMethod(item, Symbol.iterator); // step 2.2 | ||
var method = getIteratorMethod( | ||
{ | ||
AdvanceStringIndex: AdvanceStringIndex, | ||
GetMethod: GetMethod, | ||
IsArray: IsArray | ||
}, | ||
item | ||
); | ||
if (typeof method === 'undefined') { | ||
throw new $TypeError('`Iterator.concat` requires all arguments to be iterable'); // step 2.3 | ||
} | ||
iterables[iterables.length] = { '[[OpenMethod]]': method, '[[Iterable]]': item }; // step 2.4 | ||
}); | ||
|
||
var sentinel = {}; | ||
var innerIterator = sentinel; | ||
var closeIfAbrupt = function (abruptCompletion) { | ||
if (!(abruptCompletion instanceof CompletionRecord)) { | ||
throw new $TypeError('`abruptCompletion` must be a Completion Record'); | ||
} | ||
if (innerIterator !== sentinel) { | ||
IteratorClose( | ||
innerIterator, | ||
abruptCompletion | ||
); | ||
} | ||
}; | ||
|
||
var index = 0; | ||
var closure = function () { // step 3 | ||
if (index < iterables.length) { | ||
// forEach(iterables, function (iterable) { // step 3.a | ||
var iteratorRecord; | ||
if (innerIterator === sentinel) { | ||
var iterable = iterables[index]; | ||
var iter = Call(iterable['[[OpenMethod]]'], iterable['[[Iterable]]']); // step 3.a.i | ||
if (Type(iter) !== 'Object') { | ||
closeIfAbrupt(ThrowCompletion(new $TypeError('???'))); // step 3.a.ii | ||
} | ||
iteratorRecord = GetIteratorDirect(iter); // step 3.a.iii | ||
innerIterator = iteratorRecord; | ||
} else { | ||
iteratorRecord = innerIterator; | ||
} | ||
|
||
// var innerAlive = true; // step 3.a.iv | ||
// while (innerAlive) { // step 3.a.v | ||
if (innerIterator !== sentinel) { | ||
// step 3.a.v.3.a | ||
var innerValue; | ||
try { | ||
innerValue = IteratorStepValue(iteratorRecord); // step 5.b.ix.4.a | ||
} catch (e) { | ||
// innerAlive = false; | ||
innerIterator = sentinel; | ||
index += 1; | ||
closeIfAbrupt(ThrowCompletion(e)); // step 3.a.v.3.b | ||
} | ||
if (iteratorRecord['[[Done]]']) { | ||
// innerAlive = false; | ||
innerIterator = sentinel; | ||
index += 1; | ||
return closure(); | ||
} | ||
return innerValue; // // step 3.a.v.3.a | ||
} | ||
// }); | ||
} | ||
|
||
// return ReturnCompletion(undefined); // step 3.b | ||
return sentinel; | ||
}; | ||
SLOT.set(closure, '[[Sentinel]]', sentinel); // for the userland implementation | ||
SLOT.set(closure, '[[CloseIfAbrupt]]', closeIfAbrupt); // for the userland implementation | ||
|
||
return CreateIteratorFromClosure(closure, 'Iterator Helper', iterHelperProto, []); // step 4 | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
'use strict'; | ||
|
||
var callBind = require('call-bind'); | ||
var define = require('define-properties'); | ||
|
||
var implementation = require('./implementation'); | ||
var getPolyfill = require('./polyfill'); | ||
var shim = require('./shim'); | ||
|
||
var bound = callBind(getPolyfill(), null); | ||
|
||
define(bound, { | ||
getPolyfill: getPolyfill, | ||
implementation: implementation, | ||
shim: shim | ||
}); | ||
|
||
module.exports = bound; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
'use strict'; | ||
|
||
var implementation = require('./implementation'); | ||
|
||
var $Iterator = require('../Iterator'); | ||
|
||
module.exports = function getPolyfill() { | ||
return typeof $Iterator.concat === 'function' ? $Iterator.concat : implementation; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
'use strict'; | ||
|
||
var getPolyfill = require('./polyfill'); | ||
var define = require('define-properties'); | ||
|
||
var getIteratorPolyfill = require('../Iterator/polyfill'); | ||
|
||
module.exports = function shimIteratorConcat() { | ||
var $Iterator = getIteratorPolyfill(); | ||
var polyfill = getPolyfill(); | ||
define( | ||
$Iterator, | ||
{ concat: polyfill }, | ||
{ concat: function () { return $Iterator.concat !== polyfill; } } | ||
); | ||
|
||
return polyfill; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
[ | ||
"Iterator", | ||
"Iterator.concat", | ||
"Iterator.from", | ||
"Iterator.prototype", | ||
"Iterator.prototype.constructor", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
'use strict'; | ||
|
||
var defineProperties = require('define-properties'); | ||
var test = require('tape'); | ||
var callBind = require('call-bind'); | ||
var functionsHaveNames = require('functions-have-names')(); | ||
var forEach = require('for-each'); | ||
var debug = require('object-inspect'); | ||
var v = require('es-value-fixtures'); | ||
var hasSymbols = require('has-symbols/shams')(); | ||
var mockProperty = require('mock-property'); | ||
|
||
var index = require('../Iterator.concat'); | ||
var impl = require('../Iterator.concat/implementation'); | ||
var from = require('../Iterator.from/polyfill')(); | ||
|
||
var isEnumerable = Object.prototype.propertyIsEnumerable; | ||
|
||
var testIterator = require('./helpers/testIterator'); | ||
|
||
module.exports = { | ||
tests: function (concat, name, t) { | ||
t['throws']( | ||
function () { return new concat(); }, // eslint-disable-line new-cap | ||
TypeError, | ||
'`' + name + '` itself is not a constructor' | ||
); | ||
t['throws']( | ||
function () { return new concat({}); }, // eslint-disable-line new-cap | ||
TypeError, | ||
'`' + name + '` itself is not a constructor, with an argument' | ||
); | ||
|
||
forEach(v.primitives.concat(v.objects), function (nonIterator) { | ||
t['throws']( | ||
function () { concat(nonIterator); }, | ||
TypeError, | ||
debug(nonIterator) + ' is not an iterable Object' | ||
); | ||
}); | ||
|
||
t.test('actual iteration', { skip: !hasSymbols }, function (st) { | ||
forEach(v.nonFunctions, function (nonFunction) { | ||
var badIterable = {}; | ||
badIterable[Symbol.iterator] = nonFunction; | ||
st['throws']( | ||
function () { concat([], badIterable, []).next(); }, | ||
TypeError, | ||
debug(badIterable) + ' is not a function' | ||
); | ||
}); | ||
|
||
forEach(v.strings, function (string) { | ||
st['throws']( | ||
function () { concat(string); }, | ||
TypeError, | ||
'non-objects are not considered iterable' | ||
); | ||
var stringIt = concat(['a'], [string], ['c']); | ||
testIterator(stringIt, ['a', string, 'c'], st, 'string iterator: ' + debug(string)); | ||
}); | ||
|
||
var arrayIt = concat([1, 2, 3]); | ||
st.equal(typeof arrayIt.next, 'function', 'has a `next` function'); | ||
|
||
st.test('real iterators', { skip: !hasSymbols }, function (s2t) { | ||
var iter = [1, 2][Symbol.iterator](); | ||
testIterator(concat(iter, [3]), [1, 2, 3], s2t, 'array iterator + array yields combined results'); | ||
|
||
s2t.end(); | ||
}); | ||
|
||
st.test('observability in a replaced String iterator', function (s2t) { | ||
var originalStringIterator = String.prototype[Symbol.iterator]; | ||
var observedType; | ||
s2t.teardown(mockProperty(String.prototype, Symbol.iterator, { | ||
get: function () { | ||
'use strict'; // eslint-disable-line strict, lines-around-directive | ||
|
||
observedType = typeof this; | ||
return originalStringIterator; | ||
} | ||
})); | ||
|
||
concat(from('')); | ||
s2t.equal(observedType, 'string', 'string primitive -> primitive receiver in Symbol.iterator getter'); | ||
concat(from(Object(''))); | ||
s2t.equal(observedType, 'object', 'boxed string -> boxed string in Symbol.iterator getter'); | ||
|
||
s2t.end(); | ||
}); | ||
|
||
st.end(); | ||
}); | ||
}, | ||
index: function () { | ||
test('Iterator.concat: index', function (t) { | ||
module.exports.tests(index, 'Iterator.concat', t); | ||
|
||
t.end(); | ||
}); | ||
}, | ||
implementation: function () { | ||
test('Iterator.concat: implementation', function (t) { | ||
module.exports.tests(impl, 'Iterator.concat', t); | ||
|
||
t.end(); | ||
}); | ||
}, | ||
shimmed: function () { | ||
test('Iterator.concat: shimmed', function (t) { | ||
t.test('Function name', { skip: !functionsHaveNames }, function (st) { | ||
st.equal(Iterator.concat.name, 'concat', 'Iterator.concat has name "concat"'); | ||
st.end(); | ||
}); | ||
|
||
t.test('enumerability', { skip: !defineProperties.supportsDescriptors }, function (et) { | ||
et.equal(false, isEnumerable.call(Iterator, 'concat'), 'Iterator.concat is not enumerable'); | ||
et.end(); | ||
}); | ||
|
||
module.exports.tests(callBind(Iterator.concat, Iterator), 'Iterator.concat', t); | ||
|
||
t.end(); | ||
}); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters