diff options
author | Jo-Philipp Wich <jo@mein.io> | 2023-01-23 11:36:31 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2023-01-23 11:36:31 +0100 |
commit | f1be0d725735fd8dd489494b00e954a93223f722 (patch) | |
tree | 2a433e6506d6cd3a61bf75f4829de46f22c9a9af | |
parent | 48a6eac1da1584ea784fd7d53f761baa87ae84d2 (diff) |
types: fix array unshift operations and add test coverage
- Fix `ucv_array_unshift()` improperly rejecting operation on empty arrays
- Fix `uc_unshift()` improperly reversing maintaining argument order
- Add missing test coverage for `push()`, `pop()`, `unshift()` and
`shift()` array operations.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r-- | lib.c | 6 | ||||
-rw-r--r-- | tests/custom/03_stdlib/65_push | 52 | ||||
-rw-r--r-- | tests/custom/03_stdlib/66_unshift | 52 | ||||
-rw-r--r-- | tests/custom/03_stdlib/67_pop | 37 | ||||
-rw-r--r-- | tests/custom/03_stdlib/68_shift | 37 | ||||
-rw-r--r-- | types.c | 2 |
6 files changed, 182 insertions, 4 deletions
@@ -464,18 +464,18 @@ static uc_value_t * uc_unshift(uc_vm_t *vm, size_t nargs) { uc_value_t *arr = uc_fn_arg(0); - uc_value_t *item = NULL; + uc_value_t *item; size_t i; if (!assert_mutable_array(vm, arr)) return NULL; for (i = 1; i < nargs; i++) { - item = uc_fn_arg(i); + item = uc_fn_arg(nargs - i); ucv_array_unshift(arr, ucv_get(item)); } - return ucv_get(item); + return (nargs > 1) ? ucv_get(uc_fn_arg(nargs - 1)) : NULL; } static uc_value_t * diff --git a/tests/custom/03_stdlib/65_push b/tests/custom/03_stdlib/65_push new file mode 100644 index 0000000..c6707dd --- /dev/null +++ b/tests/custom/03_stdlib/65_push @@ -0,0 +1,52 @@ +The `push()` function appends the given argument(s) to the end of the given array +while maintaining their order. + +Returns the last pushed value. + +Returns `null` if the given destination argment is not an array. + +Throws a type exception if the given array is immuatable. + +-- Testcase -- +{% + let arr = []; + + printf("%.J\n", [ + // push one element + push(arr, 123), + + // push multiple elements + push(arr, 1, 2, 3), + + // push null values + push(arr, null, null, 4), + + // push no-op + push(arr), + + // push with invalid destination + push({}, 1, 2, 3) + ]); + + printf("%.J\n", arr); +%} +-- End -- + +-- Expect stdout -- +[ + 123, + 3, + 4, + null, + null +] +[ + 123, + 1, + 2, + 3, + null, + null, + 4 +] +-- End -- diff --git a/tests/custom/03_stdlib/66_unshift b/tests/custom/03_stdlib/66_unshift new file mode 100644 index 0000000..9771661 --- /dev/null +++ b/tests/custom/03_stdlib/66_unshift @@ -0,0 +1,52 @@ +The `unshift()` function places the given argument(s) at the begin of the +given array while maintaining their order. + +Returns the last added value. + +Returns `null` if the given destination argment is not an array. + +Throws a type exception if the given array is immuatable. + +-- Testcase -- +{% + let arr = []; + + printf("%.J\n", [ + // add one element + unshift(arr, 123), + + // add multiple elements + unshift(arr, 1, 2, 3), + + // add null values + unshift(arr, null, null, 4), + + // no-op + unshift(arr), + + // invalid destination + unshift({}, 1, 2, 3) + ]); + + printf("%.J\n", arr); +%} +-- End -- + +-- Expect stdout -- +[ + 123, + 3, + 4, + null, + null +] +[ + null, + null, + 4, + 1, + 2, + 3, + 123 +] +-- End -- diff --git a/tests/custom/03_stdlib/67_pop b/tests/custom/03_stdlib/67_pop new file mode 100644 index 0000000..1af11fa --- /dev/null +++ b/tests/custom/03_stdlib/67_pop @@ -0,0 +1,37 @@ +The `pop()` function removes the last element of the given source array. + +Returns the removed value. + +Returns `null` if the given source argment is not an array. + +Throws a type exception if the given array is immuatable. + +-- Testcase -- +{% + let arr = [ 1, null, 3 ]; + + printf("%.J\n", [ + // remove one element + pop(arr), + + // remove a null element + pop(arr), + + // invalid source + pop({ test: true }) + ]); + + printf("%.J\n", arr); +%} +-- End -- + +-- Expect stdout -- +[ + 3, + null, + null +] +[ + 1 +] +-- End -- diff --git a/tests/custom/03_stdlib/68_shift b/tests/custom/03_stdlib/68_shift new file mode 100644 index 0000000..7b0df89 --- /dev/null +++ b/tests/custom/03_stdlib/68_shift @@ -0,0 +1,37 @@ +The `shift()` function removes the first element of the given source array. + +Returns the removed value. + +Returns `null` if the given source argment is not an array. + +Throws a type exception if the given array is immuatable. + +-- Testcase -- +{% + let arr = [ 1, null, 3 ]; + + printf("%.J\n", [ + // remove one element + shift(arr), + + // remove a null element + shift(arr), + + // invalid source + shift({ test: true }) + ]); + + printf("%.J\n", arr); +%} +-- End -- + +-- Expect stdout -- +[ + 1, + null, + null +] +[ + 3 +] +-- End -- @@ -772,7 +772,7 @@ ucv_array_unshift(uc_value_t *uv, uc_value_t *item) uc_array_t *array = (uc_array_t *)uv; size_t i; - if (ucv_type(uv) != UC_ARRAY || array->count == 0) + if (ucv_type(uv) != UC_ARRAY) return NULL; array->count++; |