1/*
2 * Copyright (c) 2024 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
16/*
17 * @tc.name:mapget
18 * @tc.desc: test Map.get
19 * @tc.type: FUNC
20 * @tc.require: issueI97M5M
21 */
22let map = new Map();
23
24map.set('key', 'value');
25print(map.get('key'))
26
27for (let i = 0; i < 3; ++i) {
28    map.set(i, -i);
29}
30
31for (let i = 0; i < 4; ++i) {
32    let value = map.get(i);
33    print(value);
34}
35
36map = new Map();
37let key = Number.parseFloat("1392210229");
38map.set(key, "success");
39let value = map.get(key);
40print(value);
41
42
43function check(key) {
44    let irHash = ArkTools.hashCode(key);
45    let rtHash = ArkTools.hashCode(key, true);
46    if (irHash != rtHash) {
47        throw new Error("Mismatch hash for " + key + ": expected " + rtHash + ", but got " + irHash);
48    }
49}
50
51function checkIntAsDouble(intKey) {
52    intKey /= 2;
53    intKey += 0.5;
54    intKey *= 2;
55    intKey -= 1;
56    check(intKey);
57}
58
59check(0);
60check(1);
61check(1 << 30);
62check((1 << 30) - 1);
63check(-1);
64check(1.5);
65check(-1.5);
66check(Number.EPSILON);
67check(Number.NaN);
68check(Number.MIN_VALUE);
69check(Number.MAX_VALUE);
70check(Number.MIN_SAFE_INTEGER);
71check(Number.MIN_SAFE_INTEGER - 1);
72check(Number.MAX_SAFE_INTEGER);
73check(Number.MAX_SAFE_INTEGER + 1);
74check(Number.NaN);
75check(Number.POSITIVE_INFINITY);
76check(Number.NEGATIVE_INFINITY);
77check(Number.parseFloat("+0.0"));
78check(Number.parseFloat("-0.0"));
79check(true);
80check(false);
81check(undefined);
82check(null);
83check("");
84check("ab");
85check({});
86check(12n);
87checkIntAsDouble(0);
88checkIntAsDouble(1);
89checkIntAsDouble(-1);
90checkIntAsDouble(-1234);
91checkIntAsDouble(1234);
92checkIntAsDouble(1 << 29);
93checkIntAsDouble(-(1 << 29));
94checkIntAsDouble(1 << 30);
95checkIntAsDouble(-(1 << 30));
96check(Symbol.iterator);
97
98// regression test
99check(Number.parseFloat("1392210229"));
100
101/*
102 * @tc.name:MapConstructor,species
103 * @tc.desc: test MapConstructor,species
104 * @tc.type: FUNC
105 */
106const maps = [
107    new Map([["ark_stringKey", "ark_stringValue"]]),
108    new Map([[1, "ark_numberValue"]]),
109    new Map([[true, "ark_booleanValue"]]),
110    new Map([[{}, "ark_objectValue"]]),
111    new Map([[null, "ark_nullValue"]]),
112    new Map([[undefined, "ark_undefinedValue"]]),
113    new Map([[NaN, "ark_NaNValue"]]),
114    new Map([[Infinity, "ark_infinityValue"]]),
115    new Map([[-Infinity, "ark_negativeInfinityValue"]]),
116    new Map([[RegExp("ark_regexKey"), "ark_regexValue"]]),
117    new Map([[new Map(), "ark_mapValue"]]),
118    new Map([[new Set(), "ark_setValue"]]),
119    new Map([[Array.from([1, 2, 3]), "ark_arrayValue"]]),
120    new Map([["ark_unicodeKey �", "ark_unicodeValue �"]])
121];
122
123maps.forEach((map, index) => {
124    print("Map " + (index + 1) + ":");
125    map.forEach((value, key) => {
126        print("Key: " + key + ", Value: " + value);
127    });
128});
129
130let result =  Map[Symbol.species];
131print(result);
132
133/*
134 * @tc.name:forEach,get,has,keys,set,clear
135 * @tc.name:delete,values,size,entries
136 * @tc.type: FUNC
137 */
138const combinedMap = new Map([
139    ["ark_stringKey", "ark_stringValue"],
140    [1, "ark_numberValue"],
141    [true, "ark_booleanValue"],
142    [{}, "ark_objectValue"],
143    [null, "ark_nullValue"],
144    [undefined, "ark_undefinedValue"],
145    [NaN, "ark_NaNValue"],
146    [Infinity, "ark_infinityValue"],
147    [-Infinity, "ark_negativeInfinityValue"],
148    [RegExp("ark_regexKey"), "ark_regexValue"],
149    [new Map(), "ark_mapValue"],
150    [new Set(), "ark_setValue"],
151    [Array.from([1, 2, 3]), "ark_arrayValue"],
152    ["ark_unicodeKey �", "ark_unicodeValue �"]
153]);
154
155const newMap = new Map();
156
157const keysArray = Array.from(combinedMap.keys());
158keysArray.forEach(key => {
159  print("Keys: " + key);
160});
161
162const valuesArray = Array.from(combinedMap.values());
163valuesArray.forEach(value => {
164  print("Value: " + value);
165});
166
167const entriesArray = Array.from(combinedMap.entries());
168entriesArray.forEach(entry => {
169  const [key, value] = entry;
170  print("Key: " + key + ", Value: " + value);
171});
172
173combinedMap.forEach((value, key) => {
174    const retrievedValue = combinedMap.get(key);
175    const hasKey = combinedMap.has(key);
176    newMap.set(key, value);
177    print("Key: " + key + ", Retrieved Value: " + retrievedValue);
178    print("Key: " + key + ", Exists: " + hasKey);
179    combinedMap.delete(key);
180});
181
182print(combinedMap.size);
183newMap.clear();
184print(newMap.size);
185
186const testMap = new Map([
187  ["key1", "value1"],
188  ["key2", "value2"],
189]);
190const emptyMap = new Map();
191
192try {
193  const abnormalMap = new Map(5);
194} catch (error) {
195  print("Caught an error: " + error);
196}
197
198try {
199    const value = testMap.get(NaN);
200    const result1 = testMap.has(NaN);
201    const result2 = testMap.has();
202    testMap.set(NaN, "value");
203    testMap.set("key", "value1");
204    testMap.set("key", "value2");
205    emptyMap.clear();
206    emptyMap.delete(NaN);
207    print("Exception usage, but does not throw an error");
208} catch (error) {
209    print("Caught an error: " + error);
210}
211
212try {
213  testMap.forEach(5);
214} catch (error) {
215  print("Caught an error: " + error);
216}
217
218try {
219  testMap.forEach((value, key) => {
220      if (key === "key2") {
221          throw new Error("Encountered key2");
222      }
223      print("Key: " + key + ", Value: " + value);
224  });
225} catch (error) {
226  print("Caught an error: " + error);
227}
228
229// Map.clear tests
230map = new Map();
231map.set(1, null);
232map.set(2, null);
233map.set(3, null);
234let beginNotTought = map.entries();
235let midNotTought = map.entries();
236midNotTought.next();
237let begin = map.entries(); // points to (1, null)
238let mid = map.entries(); // points to (2, null)
239mid.next();
240let last = map.entries(); // points to (3, null)
241last.next();
242last.next();
243let end = map.entries(); // points to the end
244while (end.next().done) {
245}
246map.clear();
247if (map.size != 0) {
248    throw new Error("Map size must be 0");
249}
250if (!begin.next().done) {
251    throw new Error("Invalid 'begin' iterator");
252}
253if (!mid.next().done) {
254    throw new Error("Invalid 'mid' iterator");
255}
256if (!last.next().done) {
257    throw new Error("Invalid 'last' iterator");
258}
259if (!end.next().done) {
260    throw new Error("Invalid 'end' iterator");
261}
262map.set(-1, null);
263map.set(-2, null);
264map.set(-3, null);
265let v = beginNotTought.next();
266if (v.done) {
267    throw new Error("Invalid 'beginNotTought' iterator");
268}
269if (v.value[0] != -1) {
270    throw new Error("Invalid 'beginNotTought' iterator's value");
271}
272v = midNotTought.next();
273if (v.done) {
274    throw new Error("Invalid 'midNotTought' iterator");
275}
276if (v.value[0] != -1) {
277    throw new Error("Invalid 'midNotTought' iterator's value");
278}
279if (!begin.next().done) {
280    throw new Error("Invalid 'begin' iterator");
281}
282if (!mid.next().done) {
283    throw new Error("Invalid 'mid' iterator");
284}
285if (!last.next().done) {
286    throw new Error("Invalid 'last' iterator");
287}
288if (!end.next().done) {
289    throw new Error("Invalid 'end' iterator");
290}
291