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:sendableset
18 * @tc.desc:test sendableset
19 * @tc.type: FUNC
20 * @tc.require: issue#I93TZC
21 */
22
23// @ts-nocheck
24declare function print(str: any): string;
25
26function FillSet(set: SendableSet): void {
27  for (let i = 0; i < 5; i++) {
28    set.add(i);
29  }
30}
31let sharedSet: SendableSet = new SendableSet<number>();
32
33// Basic tests
34print("===Basic test begin===")
35FillSet(sharedSet);
36print("set size is " + sharedSet.size);
37print(SendableSet[Symbol.species] == SendableSet);
38print(SendableSet.name == 'SendableSet');
39print(SendableSet[Symbol.species] == Set);
40
41const keyIter = sharedSet.keys();
42let nextEntry = keyIter.next();
43print("keys next:" + nextEntry.value + ", done: " + nextEntry.done);
44nextEntry = keyIter.next();
45print("keys next:" + nextEntry.value + ", done: " + nextEntry.done);
46nextEntry = keyIter.next();
47print("keys next:" + nextEntry.value + ", done: " + nextEntry.done);
48nextEntry = keyIter.next();
49print("keys next:" + nextEntry.value + ", done: " + nextEntry.done);
50nextEntry = keyIter.next();
51print("keys next:" + nextEntry.value + ", done: " + nextEntry.done);
52nextEntry = keyIter.next();
53print("keys next:" + nextEntry.value + ", done: " + nextEntry.done);
54
55const valueIter = sharedSet.keys();
56nextEntry = valueIter.next();
57print("values next:" + nextEntry.value + ", done: " + nextEntry.done);
58nextEntry = valueIter.next();
59print("values next:" + nextEntry.value + ", done: " + nextEntry.done);
60nextEntry = valueIter.next();
61print("values next:" + nextEntry.value + ", done: " + nextEntry.done);
62nextEntry = valueIter.next();
63print("values next:" + nextEntry.value + ", done: " + nextEntry.done);
64nextEntry = valueIter.next();
65print("values next:" + nextEntry.value + ", done: " + nextEntry.done);
66nextEntry = valueIter.next();
67print("values next:" + nextEntry.value + ", done: " + nextEntry.done);
68
69sharedSet.forEach((key: number, value: number, set: SendableSet) => {
70  print('set key[forEach]:' + 'key:' + key + ', value:' + value);
71});
72
73print(sharedSet[Symbol.toStringTag] == 'SendableSet');
74for (let iter of sharedSet[Symbol.iterator]()) {
75  print("set key[Symbol.iterator]:" + iter);
76}
77print(sharedSet[Symbol.iterator] == sharedSet.values);
78print(sharedSet[Symbol.iterator] == sharedSet.keys);
79
80print(sharedSet.has(4));
81sharedSet.add(4);
82print(sharedSet.size == 5);
83print(sharedSet.has(10));
84sharedSet.add(10);
85print(sharedSet.size == 6);
86print(sharedSet.has(10));
87sharedSet.delete(10);
88print(sharedSet.has(10));
89print(sharedSet.size == 5);
90sharedSet.clear();
91print(sharedSet.size == 0);
92try {
93  sharedSet["extension"] = "value";
94} catch(e) {
95  print("add extension(.): " + e);
96}
97try {
98  sharedSet.extension = "value";
99} catch(e) {
100  print("add extension([]): " + e);
101}
102
103print("===Basic test end===");
104
105// No Expected Concurrent modification exception while iterating using iterators
106print("===Concurrent modification during iteration Test(iterator) begin===")
107sharedSet.clear();
108FillSet(sharedSet);
109print("set size is " + sharedSet.size);
110
111const iterator = sharedSet.entries();
112for (const [key, _] of iterator) {
113  print("set key[for-of]: " + key);
114}
115try {
116  const iterator = sharedSet.entries();
117  for (const [key, _] of iterator) {
118    if (key == 1) {
119      sharedSet.add(key + 5);
120    }
121  }
122  print("Add Scenario[for-of] updated size: " + sharedSet.size);
123} catch (e) {
124  print("Add Scenario[for-of]: " + e);
125}
126try {
127  const iterator = sharedSet.entries();
128  for (const [key, _] of iterator) {
129    if (key % 2 == 0) {
130      sharedSet.delete(key);
131    }
132  }
133  print("Delete Scenario[for-of] updated size: " + sharedSet.size);
134} catch (e) {
135  print("Delete Scenario[for-of]: " + e);
136}
137try {
138  const iterator = sharedSet.entries();
139  for (const [key, _] of iterator) {
140    sharedSet.clear();
141  }
142  print("Clear Scenario[for-of] updated size: " + sharedSet.size);
143} catch (e) {
144  print("Clear Scenario[for-of]: " + e);
145}
146
147sharedSet.clear();
148FillSet(sharedSet);
149print("set size is " + sharedSet.size);
150try {
151  const iterator = sharedSet.entries();
152  sharedSet.add(6);
153  iterator.next();
154  print("Add Scenario[next()] updated size: " + sharedSet.size);
155} catch (e) {
156  print("Add Scenario[next()]: " + e);
157}
158try {
159  const iterator = sharedSet.entries();
160  sharedSet.delete(6);
161  iterator.next();
162  print("Delete Scenario[next()] updated size: " + sharedSet.size);
163} catch (e) {
164  print("Delete Scenario[next()]: " + e);
165}
166try {
167  const iterator = sharedSet.entries();
168  sharedSet.clear();
169  iterator.next();
170  print("Clear Scenario[next()] updated size: " + sharedSet.size);
171} catch (e) {
172  print("Clear Scenario[next()]: " + e);
173}
174print("===Concurrent modification during iteration Test(iterator) end===")
175
176// Expected Concurrent modification exception while iterating using forEach
177print("===Concurrent modification during iteration Test(forEach) begin===")
178sharedSet.clear();
179FillSet(sharedSet);
180print("set size is " + sharedSet.size);
181sharedSet.forEach((key: number, _: number, set: SendableSet) => {
182  print('set key[forEach]: ' + key);
183});
184try {
185  sharedSet.forEach((key: number, _: number, set: SendableSet) => {
186    set.add(key + 5);
187  });
188} catch (e) {
189  print("Add Scenario[forEach]: " + e + ", errCode: " + e.code);
190}
191try {
192  sharedSet.forEach((key: number, _: number, set: SendableSet) => {
193    if (key % 2 == 0) {
194      set.delete(key);
195    }
196  });
197} catch (e) {
198  print("Delete Scenario[forEach]: " + e + ", errCode: " + e.code);
199}
200try {
201  sharedSet.forEach((key: number, _: number, set: SendableSet) => {
202    set.clear();
203  });
204} catch (e) {
205  print("Clear Scenario[forEach]: " + e + ", errCode: " + e.code);
206}
207print("===Concurrent modification during iteration Test(forEach) end===");
208
209print("===Type check begin===");
210class SObject {
211  constructor() {
212    "use sendable"
213  }
214};
215
216try {
217  let sObj = new SObject();
218  sharedSet = new SendableSet(['str', 1, sObj, undefined, true, null]);
219  print("sharedSet add[shared] element success");
220} catch (e) {
221  print("sharedSet add[unshared]: " + e + ", errCode: " + e.code);
222}
223
224try {
225  let obj = {}
226  sharedSet = new SendableSet([obj]);
227} catch (e) {
228  print("sharedSet add[unshared]: " + e + ", errCode: " + e.code);
229}
230
231try {
232  let sym = Symbol("testSymbol")
233  sharedSet = new SendableSet([sym, 2]);
234} catch (e) {
235  print("sharedSet add[unshared]: " + e + ", errCode: " + e.code);
236}
237print("===Type check end===");
238
239print("===Class inheritance test begin ===");
240class SubSendableSet<T> extends SendableSet {
241  desc: string = "I'am SubSendableSet";
242  constructor(entries?: T[] | null) {
243    'use sendable';
244    super(entries);
245  }
246}
247
248let subSharedset = new SubSendableSet<number>();
249subSharedset.add(1);
250print(subSharedset.has(1));
251print(subSharedset.size);
252
253subSharedset = new SubSendableSet<number>([1, 2, 3]);
254print(subSharedset.has(1));
255print(subSharedset.has(2));
256print(subSharedset.has(3));
257print(subSharedset.size);
258
259try {
260  let obj = {};
261  subSharedset = new SubSendableSet<Object>([obj]);
262  print(subSharedset.size);
263} catch (e) {
264  print('SubSendableSet add[unshared]: ' + e + ', errCode: ' + e.code);
265}
266
267subSharedset = new SubSendableSet<string>(['one', 'two', 'three']);
268for (const [key, _] of subSharedset.entries()) {
269  print('SubSendableSet key[for-of]: ' + key);
270}
271
272try {
273  subSharedset = new SubSendableSet<number>([1, 2, 3, 4]);
274  print(subSharedset.size);
275  subSharedset.forEach((key: number, _: number, set: SubSendableSet) => {
276    if (key % 2 == 0) {
277      set.delete(key);
278    }
279  });
280} catch (e) {
281  print('SubSendableSet Delete Scenario[forEach]: ' + e + ', errCode: ' + e.code);
282}
283
284class SubSubSendableSet<T> extends SubSendableSet {
285  constructor(entries?: T[] | null) {
286    'use sendable';
287    super(entries);
288  }
289}
290
291let subSubSendableSet = new SubSubSendableSet<number>([1, 2, 3]);
292print(subSubSendableSet.has(1));
293print(subSubSendableSet.has(2));
294print(subSubSendableSet.has(3));
295print(subSubSendableSet.size);
296
297try {
298  subSubSendableSet['extension'] = 'value';
299} catch(e) {
300  print("add extension(.): " + e);
301}
302try {
303  subSubSendableSet.extension = 'value';
304} catch(e) {
305  print("add extension([]): " + e);
306}
307
308try {
309  let obj = {};
310  subSubSendableSet = new SubSubSendableSet<Object>([obj]);
311  print(subSubSendableSet.size);
312} catch (e) {
313  print('SubSubSendableSet add[unshared]: ' + e + ', errCode: ' + e.code);
314}
315
316try {
317  subSubSendableSet = new SubSubSendableSet<number>([1, 2, 3, 4]);
318  subSubSendableSet.forEach((key: number, _: number, set: SubSubSendableSet) => {
319    if (key % 2 == 0) {
320      set.delete(key);
321    }
322  });
323} catch (e) {
324  print('SubSubSendableSet Delete Scenario[forEach]: ' + e + ', errCode: ' + e.code);
325}
326
327print("=== An iterable object to convert to an ArkTS Set  begin===")
328sharedSet.clear();
329FillSet(sharedSet);
330try {
331  
332  const iterator = sharedSet.entries();
333  let sharedSet1: SendableSet = new SendableSet<>(iterator);
334  sharedSet1.forEach((key: number, _: number, set: SendableSet) => {
335    print("set key[forEach]: " + key);
336  })
337} catch (e) {
338  print("SendableSetConstructor Scenario[next()]: " + e);
339}
340
341print("===Class inheritance test end ===");
342