• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16print('======== Testing fromIndex ========');
17{
18    const arr = [-10, 42, 42, 42, 42, -20];
19    const numberIndices = [
20          4,  4.1,  4.5,  4.9,                      // All truncated to  4
21         -0, -0.1, -0.5, -0.9, -1 + Number.EPSILON, // All truncated to  0
22         -1, -1.1, -1.5, -1.9, -2 + Number.EPSILON, // All truncated to -1
23        1/0, -1/0,  0/0,  NaN, // +inf, -inf, NaN, NaN
24    ];
25    const objN = { valueOf() { return 2; } };
26    const objS = { valueOf() { return "3.456" } };
27    const objB = { valueOf() { return 4n; } };
28    const objNN = { valueOf() { return objN; } };
29    const nonNumberIndices = [
30        null, undefined,
31        "1", "1.234", "2.0?", "~3.0~",
32        new Number(2),
33        objN,
34        new String("3.123"),
35        objS,
36        objNN,
37    ];
38    const erroneousIndices = [
39        4n, objB,
40    ];
41
42    for (const fnName of ['indexOf', 'lastIndexOf', 'includes']) {
43        print(`---- Testing Array.prototype.${fnName} ----`);
44        const fn = Array.prototype[fnName];
45        print(`Result with numberIndices: ${numberIndices.map((i) => fn.call(arr, 42, i))}`);
46        print(`Result with nonNumberIndices: ${nonNumberIndices.map((i) => fn.call(arr, 42, i))}`);
47        for (const i of erroneousIndices) {
48            try {
49                const result = fn.call(arr, 42, i);
50                print(`Unexpected result: ${result} (Expects: TypeError)`);
51            } catch (e) {
52                if (e instanceof TypeError) {
53                    print(`OK: TypeError raised for ${typeof i} index`);
54                } else {
55                    print(`ERROR: Unexpected type of exception raised`);
56                    throw e;
57                }
58            }
59        }
60    }
61}
62
63print('======== Testing comparision ========');
64{
65    const obj = { x: 1, y: 2 };
66    const objN = { valueOf() { return 0; } };
67    const arr = [
68        1, 1.0, -1.0, // 1
69        0, 0.0, -0.0, // 0
70        1/0, -1/0,    // inf
71        0/0,  NaN,    // NaN
72        true, false, null,      // Special values
73        /* hole */,
74        "1", "0", "1.0", "0.0", // string
75        1n, 0n,                 // bigint
76        obj, objN,              // object
77        new Number(0),          // Boxing number
78        new String("1"),        // Boxing string
79    ];
80    const targets = [
81        1, 1.0, -1.0, // 1
82        0, 0.0, -0.0, // 0
83        1/0, -1/0,    // inf
84        0/0,  NaN,    // NaN
85        true, false, null, undefined, // Special values
86        "1", "0", "1.0", "0.0", // string
87        1n, 0n,                 // bigint
88        obj, objN,              // object
89        Math.sqrt(-1),  // Another NaN
90        { x: 1, y: 2 }, // Another object
91        { valueOf() { return 0; } }, // Another object
92        new Number(0),      // Boxing number
93        new String("1"),    // Boxing string
94    ];
95    for (let i = 0; i < targets.length; i++) {
96        const x = targets[i];
97        const res1 = arr.indexOf(x);
98        const res2 = arr.lastIndexOf(x);
99        const res3 = arr.includes(x);
100        print(`[${i}] Target = ${x} (${typeof x}): indexOf => ${res1} lastIndexOf => ${res2} includes => ${res3}`);
101    }
102    // Fills the hole with undefined
103    arr[12] = undefined;
104    {
105        const res1 = arr.indexOf(undefined);
106        const res2 = arr.lastIndexOf(undefined);
107        const res3 = arr.includes(undefined);
108        print(`Index = undefined: indexOf => ${res1} lastIndexOf => ${res2} includes => ${res3}`);
109    }
110}
111
112let makeElementSeed = 0;
113function makeElement(type) {
114    makeElementSeed += 1;
115    if (type === 'int') {
116        return (makeElementSeed * 5 + 1) % 11;
117    } else if (type === 'double') {
118        return (makeElementSeed * 0.625 + 1) % 1.375;
119    } else if (type === 'string') {
120        return ((makeElementSeed * 5 + 1) % 11).toString();
121    } else if (type === 'bigint') {
122        return BigInt((makeElementSeed * 5 + 1) % 11);
123    } else {
124        return { value: (makeElementSeed * 5 + 1) % 11 };
125    }
126}
127
128print('======== Testing with non-generic ElementsKind ========');
129{
130    const intArr = [];
131    for (let i = 0; i < 11; i++) {
132        intArr[i] = makeElement('int');
133    }
134    const doubleArr = [];
135    for (let i = 0; i < 11; i++) {
136        doubleArr[i] = makeElement('double');
137    }
138    const strArr = [];
139    for (let i = 0; i < 11; i++) {
140        strArr[i] = makeElement('string');
141    }
142    const bigintArr = [];
143    for (let i = 0; i < 11; i++) {
144        bigintArr[i] = makeElement('bigint');
145    }
146
147    const targets = [
148        1, 1.0, 1.125, '1', 1n
149    ];
150    const allCases = [
151        ['intArr', intArr],
152        ['doubleArr', doubleArr],
153        ['strArr', strArr],
154        ['bigintArr', bigintArr],
155    ];
156    for (const [name, arr] of allCases) {
157        print(`ElementsKind of ${name} = ${ArkTools.getElementsKind(arr)}`);
158        for (let i = 0; i < targets.length; i++) {
159            const x = targets[i];
160            const res1 = arr.indexOf(x);
161            const res2 = arr.lastIndexOf(x);
162            const res3 = arr.includes(x);
163            print(`[${name}] Target = ${x} (${typeof x}):`,
164                  `indexOf => ${res1} lastIndexOf => ${res2} includes => ${res3}`);
165        }
166    }
167}
168