summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp15
-rw-r--r--Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h1
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.findIndex.js108
3 files changed, 124 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
index 123b79447b..5ee62d2ea2 100644
--- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
@@ -28,6 +28,7 @@ void TypedArrayPrototype::initialize(GlobalObject& object)
define_native_function(vm.names.at, at, 1, attr);
define_native_function(vm.names.every, every, 1, attr);
define_native_function(vm.names.find, find, 1, attr);
+ define_native_function(vm.names.findIndex, find_index, 1, attr);
}
TypedArrayPrototype::~TypedArrayPrototype()
@@ -154,6 +155,20 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::find)
return result;
}
+// 23.2.3.11 %TypedArray%.prototype.findIndex ( predicate [ , thisArg ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.findindex
+JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::find_index)
+{
+ auto result_index = -1;
+ for_each_item(vm, global_object, "findIndex", [&](auto index, auto, auto callback_result) {
+ if (callback_result.to_boolean()) {
+ result_index = index;
+ return IterationDecision::Break;
+ }
+ return IterationDecision::Continue;
+ });
+ return Value(result_index);
+}
+
// 23.2.3.1 get %TypedArray%.prototype.buffer, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.buffer
JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::buffer_getter)
{
diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h
index be4c44d8b8..3763841295 100644
--- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h
+++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h
@@ -27,6 +27,7 @@ private:
JS_DECLARE_NATIVE_FUNCTION(at);
JS_DECLARE_NATIVE_FUNCTION(every);
JS_DECLARE_NATIVE_FUNCTION(find);
+ JS_DECLARE_NATIVE_FUNCTION(find_index);
};
}
diff --git a/Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.findIndex.js b/Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.findIndex.js
new file mode 100644
index 0000000000..fa6f8db626
--- /dev/null
+++ b/Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.findIndex.js
@@ -0,0 +1,108 @@
+const TYPED_ARRAYS = [
+ Uint8Array,
+ Uint16Array,
+ Uint32Array,
+ Int8Array,
+ Int16Array,
+ Int32Array,
+ Float32Array,
+ Float64Array,
+];
+
+const BIGINT_TYPED_ARRAYS = [BigUint64Array, BigInt64Array];
+
+test("length is 1", () => {
+ TYPED_ARRAYS.forEach(T => {
+ expect(T.prototype.findIndex).toHaveLength(1);
+ });
+
+ BIGINT_TYPED_ARRAYS.forEach(T => {
+ expect(T.prototype.findIndex).toHaveLength(1);
+ });
+});
+
+describe("errors", () => {
+ function errorTests(T) {
+ test(`requires at least one argument (${T.name})`, () => {
+ expect(() => {
+ new T().findIndex();
+ }).toThrowWithMessage(
+ TypeError,
+ "TypedArray.prototype.findIndex() requires at least one argument"
+ );
+ });
+
+ test(`callback must be a function (${T.name})`, () => {
+ expect(() => {
+ new T().findIndex(undefined);
+ }).toThrowWithMessage(TypeError, "undefined is not a function");
+ });
+ }
+
+ TYPED_ARRAYS.forEach(T => errorTests(T));
+ BIGINT_TYPED_ARRAYS.forEach(T => errorTests(T));
+});
+
+describe("normal behaviour", () => {
+ test("basic functionality", () => {
+ TYPED_ARRAYS.forEach(T => {
+ const typedArray = new T([1, 2, 3]);
+
+ expect(typedArray.findIndex(value => value === 1)).toBe(0);
+ expect(typedArray.findIndex(value => value === 2)).toBe(1);
+ expect(typedArray.findIndex(value => value === 3)).toBe(2);
+ expect(typedArray.findIndex((value, index) => index === 1)).toBe(1);
+ expect(typedArray.findIndex(value => value == "1")).toBe(0);
+ expect(typedArray.findIndex(value => value === 10)).toBe(-1);
+ });
+
+ BIGINT_TYPED_ARRAYS.forEach(T => {
+ const typedArray = new T([1n, 2n, 3n]);
+
+ expect(typedArray.findIndex(value => value === 1n)).toBe(0);
+ expect(typedArray.findIndex(value => value === 2n)).toBe(1);
+ expect(typedArray.findIndex(value => value === 3n)).toBe(2);
+ expect(typedArray.findIndex((value, index) => index === 1)).toBe(1);
+ expect(typedArray.findIndex(value => value == 1)).toBe(0);
+ expect(typedArray.findIndex(value => value == "1")).toBe(0);
+ expect(typedArray.findIndex(value => value === 1)).toBe(-1);
+ });
+ });
+
+ test("never calls callback with empty array", () => {
+ function emptyTest(T) {
+ var callbackCalled = 0;
+ expect(
+ new T().findIndex(() => {
+ callbackCalled++;
+ })
+ ).toBe(-1);
+ expect(callbackCalled).toBe(0);
+ }
+
+ TYPED_ARRAYS.forEach(T => emptyTest(T));
+ BIGINT_TYPED_ARRAYS.forEach(T => emptyTest(T));
+ });
+
+ test("calls callback once for every item", () => {
+ TYPED_ARRAYS.forEach(T => {
+ var callbackCalled = 0;
+ expect(
+ new T([1, 2, 3]).findIndex(() => {
+ callbackCalled++;
+ })
+ ).toBe(-1);
+ expect(callbackCalled).toBe(3);
+ });
+
+ BIGINT_TYPED_ARRAYS.forEach(T => {
+ var callbackCalled = 0;
+ expect(
+ new T([1n, 2n, 3n]).findIndex(() => {
+ callbackCalled++;
+ })
+ ).toBe(-1);
+ expect(callbackCalled).toBe(3);
+ });
+ });
+});