mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 17:57:35 +00:00
LibJS: Implement Iterator.prototype.toArray
This commit is contained in:
parent
acc05480e8
commit
35380b2aef
4 changed files with 94 additions and 0 deletions
|
@ -512,6 +512,7 @@ namespace JS {
|
||||||
P(timeZone) \
|
P(timeZone) \
|
||||||
P(timeZoneName) \
|
P(timeZoneName) \
|
||||||
P(timeZones) \
|
P(timeZones) \
|
||||||
|
P(toArray) \
|
||||||
P(toDateString) \
|
P(toDateString) \
|
||||||
P(toExponential) \
|
P(toExponential) \
|
||||||
P(toFixed) \
|
P(toFixed) \
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
#include <LibJS/Runtime/AbstractOperations.h>
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
|
#include <LibJS/Runtime/Array.h>
|
||||||
#include <LibJS/Runtime/FunctionObject.h>
|
#include <LibJS/Runtime/FunctionObject.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
#include <LibJS/Runtime/IteratorHelper.h>
|
#include <LibJS/Runtime/IteratorHelper.h>
|
||||||
|
@ -36,6 +37,7 @@ ThrowCompletionOr<void> IteratorPrototype::initialize(Realm& realm)
|
||||||
define_native_function(realm, vm.names.drop, drop, 1, attr);
|
define_native_function(realm, vm.names.drop, drop, 1, attr);
|
||||||
define_native_function(realm, vm.names.flatMap, flat_map, 1, attr);
|
define_native_function(realm, vm.names.flatMap, flat_map, 1, attr);
|
||||||
define_native_function(realm, vm.names.reduce, reduce, 1, attr);
|
define_native_function(realm, vm.names.reduce, reduce, 1, attr);
|
||||||
|
define_native_function(realm, vm.names.toArray, to_array, 0, attr);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -516,4 +518,36 @@ JS_DEFINE_NATIVE_FUNCTION(IteratorPrototype::reduce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3.1.3.8 Iterator.prototype.toArray ( ), https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.toarray
|
||||||
|
JS_DEFINE_NATIVE_FUNCTION(IteratorPrototype::to_array)
|
||||||
|
{
|
||||||
|
auto& realm = *vm.current_realm();
|
||||||
|
|
||||||
|
// 1. Let O be the this value.
|
||||||
|
// 2. If O is not an Object, throw a TypeError exception.
|
||||||
|
auto object = TRY(this_object(vm));
|
||||||
|
|
||||||
|
// 3. Let iterated be ? GetIteratorDirect(O).
|
||||||
|
auto iterated = TRY(get_iterator_direct(vm, object));
|
||||||
|
|
||||||
|
// 4. Let items be a new empty List.
|
||||||
|
Vector<Value> items;
|
||||||
|
|
||||||
|
// 5. Repeat,
|
||||||
|
while (true) {
|
||||||
|
// a. Let next be ? IteratorStep(iterated).
|
||||||
|
auto next = TRY(iterator_step(vm, iterated));
|
||||||
|
|
||||||
|
// b. If next is false, return CreateArrayFromList(items).
|
||||||
|
if (!next)
|
||||||
|
return Array::create_from(realm, items);
|
||||||
|
|
||||||
|
// c. Let value be ? IteratorValue(next).
|
||||||
|
auto value = TRY(iterator_value(vm, *next));
|
||||||
|
|
||||||
|
// d. Append value to items.
|
||||||
|
TRY_OR_THROW_OOM(vm, items.try_append(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ private:
|
||||||
JS_DECLARE_NATIVE_FUNCTION(drop);
|
JS_DECLARE_NATIVE_FUNCTION(drop);
|
||||||
JS_DECLARE_NATIVE_FUNCTION(flat_map);
|
JS_DECLARE_NATIVE_FUNCTION(flat_map);
|
||||||
JS_DECLARE_NATIVE_FUNCTION(reduce);
|
JS_DECLARE_NATIVE_FUNCTION(reduce);
|
||||||
|
JS_DECLARE_NATIVE_FUNCTION(to_array);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
describe("errors", () => {
|
||||||
|
test("iterator's next method throws", () => {
|
||||||
|
function TestError() {}
|
||||||
|
|
||||||
|
class TestIterator extends Iterator {
|
||||||
|
next() {
|
||||||
|
throw new TestError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
new TestIterator().toArray();
|
||||||
|
}).toThrow(TestError);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("value returned by iterator's next method throws", () => {
|
||||||
|
function TestError() {}
|
||||||
|
|
||||||
|
class TestIterator extends Iterator {
|
||||||
|
next() {
|
||||||
|
return {
|
||||||
|
done: false,
|
||||||
|
get value() {
|
||||||
|
throw new TestError();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
new TestIterator().toArray();
|
||||||
|
}).toThrow(TestError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("normal behavior", () => {
|
||||||
|
test("length is 0", () => {
|
||||||
|
expect(Iterator.prototype.toArray).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("empty list", () => {
|
||||||
|
function* generator() {}
|
||||||
|
|
||||||
|
const result = generator().toArray();
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("non-empty list", () => {
|
||||||
|
function* generator() {
|
||||||
|
yield 1;
|
||||||
|
yield 2;
|
||||||
|
yield 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = generator().toArray();
|
||||||
|
expect(result).toEqual([1, 2, 3]);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue