diff options
author | Angel <angel@ttm.sh> | 2020-05-26 20:31:22 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-26 20:34:44 +0200 |
commit | 199a6b40b3e7ae997d6ecfde6276c86cc2a1dd30 (patch) | |
tree | 036ceeb78c37490f1aa6c269393019e60f3a2bdc /Libraries | |
parent | d1bc1f5783f31a9339c192e889a24ccd82813b4f (diff) | |
download | serenity-199a6b40b3e7ae997d6ecfde6276c86cc2a1dd30.zip |
LibJS: Add Array.prototype.fill
Diffstat (limited to 'Libraries')
-rw-r--r-- | Libraries/LibJS/Runtime/ArrayPrototype.cpp | 48 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/ArrayPrototype.h | 1 | ||||
-rw-r--r-- | Libraries/LibJS/Tests/Array.prototype.fill.js | 24 | ||||
-rw-r--r-- | Libraries/LibJS/Tests/test-common.js | 15 |
4 files changed, 88 insertions, 0 deletions
diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index 297f791afc..b6c372ccab 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -68,6 +68,7 @@ ArrayPrototype::ArrayPrototype() put_native_function("some", some, 1, attr); put_native_function("every", every, 1, attr); put_native_function("splice", splice, 2, attr); + put_native_function("fill", fill, 1, attr); put("length", Value(0), Attribute::Configurable); } @@ -743,4 +744,51 @@ Value ArrayPrototype::splice(Interpreter& interpreter) return removed_elements; } +Value ArrayPrototype::fill(Interpreter& interpreter) +{ + auto *this_object = interpreter.this_value().to_object(interpreter); + if (!this_object) + return {}; + + ssize_t length = get_length(interpreter, *this_object); + if (interpreter.exception()) + return {}; + + ssize_t relative_start = 0; + ssize_t relative_end = length; + + if (interpreter.argument_count() >= 2) { + relative_start = interpreter.argument(1).to_i32(interpreter); + if (interpreter.exception()) + return {}; + } + + if (interpreter.argument_count() >= 3) { + relative_end = interpreter.argument(2).to_i32(interpreter); + if (interpreter.exception()) + return {}; + } + + size_t from, to; + + if (relative_start < 0) + from = max(length + relative_start, 0L); + else + from = min(relative_start, length); + + if (relative_end < 0) + to = max(length + relative_end, 0L); + else + to = min(relative_end, length); + + for (size_t i = from; i < to; i++) { + this_object->put_by_index(i, interpreter.argument(0)); + if (interpreter.exception()) + return {}; + } + + return this_object; } + +} + diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.h b/Libraries/LibJS/Runtime/ArrayPrototype.h index 854788ed54..81750751da 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.h +++ b/Libraries/LibJS/Runtime/ArrayPrototype.h @@ -61,6 +61,7 @@ private: static Value some(Interpreter&); static Value every(Interpreter&); static Value splice(Interpreter&); + static Value fill(Interpreter&); }; } diff --git a/Libraries/LibJS/Tests/Array.prototype.fill.js b/Libraries/LibJS/Tests/Array.prototype.fill.js new file mode 100644 index 0000000000..c70960b802 --- /dev/null +++ b/Libraries/LibJS/Tests/Array.prototype.fill.js @@ -0,0 +1,24 @@ +load("test-common.js"); + +try { + assert(Array.prototype.fill.length === 1); + + var array = [1, 2, 3, 4]; + assertArrayEquals(array.fill(0, 2, 4), [1, 2, 0, 0]); + assertArrayEquals(array.fill(5, 1), [1, 5, 5, 5]); + assertArrayEquals(array.fill(6), [6, 6, 6, 6]); + + assertArrayEquals([1, 2, 3].fill(4), [4, 4, 4]); + assertArrayEquals([1, 2, 3].fill(4, 1), [1, 4, 4]); + assertArrayEquals([1, 2, 3].fill(4, 1, 2), [1, 4, 3]); + assertArrayEquals([1, 2, 3].fill(4, 3, 3), [1, 2, 3]); + assertArrayEquals([1, 2, 3].fill(4, -3, -2), [4, 2, 3]); + assertArrayEquals([1, 2, 3].fill(4, NaN, NaN), [1, 2, 3]); + assertArrayEquals([1, 2, 3].fill(4, 3, 5), [1, 2, 3]); + assertArrayEquals(Array(3).fill(4), [4, 4, 4]); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} + diff --git a/Libraries/LibJS/Tests/test-common.js b/Libraries/LibJS/Tests/test-common.js index 7be49e77bb..0a14352b97 100644 --- a/Libraries/LibJS/Tests/test-common.js +++ b/Libraries/LibJS/Tests/test-common.js @@ -50,6 +50,21 @@ function assertThrowsError(testFunction, options) { } } +/** + * Ensures the provided arrays contain exactly the same items. + * @param {Array} a First array + * @param {Array} b Second array + */ +function assertArrayEquals(a, b) { + if (a.length != b.length) + throw new AssertionError("Array lengths do not match"); + + for (var i = 0; i < a.length; i++) { + if (a[i] !== b[i]) + throw new AssertionError("Elements do not match"); + } +} + const assertVisitsAll = (testFunction, expectedOutput) => { const visited = []; testFunction(value => visited.push(value)); |