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:sharedcollectionsexception
18 * @tc.desc:test sharedcollectionsexception
19 * @tc.type: FUNC
20 * @tc.require: issueI8QUU0
21 */
22
23// @ts-nocheck
24declare function print(str: any): string;
25
26class NormalClass {
27    public num: number = 0;
28    constructor(num: number) {
29        this.num = num;
30    }
31}
32
33function bindErrorTest() {
34    print("Start bindErrorTest");
35    const array1 = new SendableArray<number>(5, 12, 8, 130, 44);
36    const normal = new NormalClass(10);
37    const unbouondAt = array1.at;
38    const boundAt = unbouondAt.bind(normal);
39    try {
40        boundAt(2);
41        print("call boundAt success.");
42    } catch (err) {
43        print("call boundAt fail. err: " + err + ", errCode: " + err.code);
44    }
45
46    const unboundConcat = array1.concat;
47    const boundConcat = unboundConcat.bind(normal);
48    try {
49        boundConcat();
50        print("Call boundConcat succeed.");
51    } catch (err) {
52        print("Call boundConcat fail. err: " + err + ", errCode: " + err.code);
53    }
54
55    const unboundEntries = array1.entries;
56    const boundEntries = unboundEntries.bind(normal);
57    try {
58        boundEntries();
59        print("Call boundEntries succeed.");
60    } catch (err) {
61        print("Call boundEntries failed. err: " + err + ", errCode: " + err.code);
62    }
63
64    const unboundFill = array1.fill;
65    const boundFill = unboundFill.bind(normal);
66    try {
67        boundFill();
68        print("Call boundFill succeed.");
69    } catch (err) {
70        print("Call boundFill failed. err: " + err + ", errCode: " + err.code);
71    }
72
73    const unboundFilter = array1.filter;
74    const boundFilter = unboundFilter.bind(normal);
75    try {
76        boundFilter();
77        print("Call boundFilter succeed.");
78    } catch (err) {
79        print("Call boundFilter failed. err: " + err + ", errCode: " + err.code);
80    }
81
82    const unboundFind = array1.find;
83    const boundFind = unboundFind.bind(normal);
84    try {
85        boundFind();
86        print("Call boundFind succeed.");
87    } catch (err) {
88        print("Call boundFind failed. err: " + err + ", errCode: " + err.code);
89    }
90
91    const unboundFindIndex = array1.findIndex;
92    const boundFindIndex = unboundFindIndex.bind(normal);
93    try {
94        boundFindIndex();
95        print("Call boundFindIndex succeed.");
96    } catch (err) {
97        print("Call boundFindIndex failed. err: " + err + ", errCode: " + err.code);
98    }
99
100    const unboundForEach = array1.forEach;
101    const boundForEach = unboundForEach.bind(normal);
102    try {
103        boundForEach();
104        print("Call boundForEach succeed.");
105    } catch (err) {
106        print("Call boundForEach failed. err: " + err + ", errCode: " + err.code);
107    }
108
109    const unboundIndexOf = array1.indexOf;
110    const boundIndexOf = unboundIndexOf.bind(normal);
111    try {
112        boundIndexOf();
113        print("Call boundIndexOf succeed.");
114    } catch (err) {
115        print("Call boundIndexOf failed. err: " + err + ", errCode: " + err.code);
116    }
117
118    const unboundJoin = array1.join;
119    const boundJoin = unboundJoin.bind(normal);
120    try {
121        boundJoin();
122        print("Call boundJoin succeed.");
123    } catch (err) {
124        print("Call boundJoin failed. err: " + err + ", errCode: " + err.code);
125    }
126
127    const unboundKeys = array1.keys;
128    const boundKeys = unboundKeys.bind(normal);
129    try {
130        boundKeys();
131        print("Call boundKeys succeed.");
132    } catch (err) {
133        print("Call boundKeys failed. err: " + err + ", errCode: " + err.code);
134    }
135
136    const unboundMap = array1.map;
137    const boundMap = unboundMap.bind(normal);
138    try {
139        boundMap();
140        print("Call boundMap succeed.");
141    } catch (err) {
142        print("Call boundMap failed. err: " + err + ", errCode: " + err.code);
143    }
144
145    const unboundPop = array1.pop;
146    const boundPop = unboundPop.bind(normal);
147    try {
148        boundPop();
149        print("Call boundPop succeed.");
150    } catch (err) {
151        print("Call boundPop failed. err: " + err + ", errCode: " + err.code);
152    }
153
154    const unboundPush = array1.push;
155    const boundPush = unboundPush.bind(normal);
156    try {
157        boundPush();
158        print("Call boundPush succeed.");
159    } catch (err) {
160        print("Call boundPush failed. err: " + err + ", errCode: " + err.code);
161    }
162
163    const unboundReduce = array1.reduce;
164    const boundReduce = unboundReduce.bind(normal);
165    try {
166        boundReduce();
167        print("Call boundReduce succeed.");
168    } catch (err) {
169        print("Call boundReduce failed. err: " + err + ", errCode: " + err.code);
170    }
171
172    const unboundShift = array1.shift;
173    const boundShift = unboundShift.bind(normal);
174    try {
175        boundShift();
176        print("Call boundShift succeed.");
177    } catch (err) {
178        print("Call boundShift failed. err: " + err + ", errCode: " + err.code);
179    }
180
181    const unboundSlice = array1.slice;
182    const boundSlice = unboundSlice.bind(normal);
183    try {
184        boundSlice();
185        print("Call boundSlice succeed.");
186    } catch (err) {
187        print("Call boundSlice failed. err: " + err + ", errCode: " + err.code);
188    }
189
190    const unboundSort = array1.sort;
191    const boundSort = unboundSort.bind(normal);
192    try {
193        boundSort();
194        print("Call boundSort succeed.");
195    } catch (err) {
196        print("Call boundSort failed. err: " + err + ", errCode: " + err.code);
197    }
198
199    const unboundToString = array1.toString;
200    const boundToString = unboundToString.bind(normal);
201    try {
202        boundToString();
203        print("Call boundToString succeed.");
204    } catch (err) {
205        print("Call boundToString failed. err: " + err + ", errCode: " + err.code);
206    }
207
208    const unboundUnshift = array1.unshift;
209    const boundUnshift = unboundUnshift.bind(normal);
210    try {
211        boundUnshift();
212        print("Call boundUnshift succeed.");
213    } catch (err) {
214        print("Call boundUnshift failed. err: " + err + ", errCode: " + err.code);
215    }
216
217    const unboundValues = array1.values;
218    const boundValues = unboundValues.bind(normal);
219    try {
220        boundValues();
221        print("Call boundValues succeed.");
222    } catch (err) {
223        print("Call boundValues failed. err: " + err + ", errCode: " + err.code);
224    }
225
226    const unboundIncludes = array1.includes;
227    const boundIncludes = unboundIncludes.bind(normal);
228    try {
229        boundIncludes();
230        print("Call boundIncludes succeed.");
231    } catch (err) {
232        print("Call boundIncludes failed. err: " + err + ", errCode: " + err.code);
233    }
234
235    const unboundShrinkTo = array1.shrinkTo;
236    const boundShrinkTo = unboundShrinkTo.bind(normal);
237    try {
238        boundShrinkTo();
239        print("Call boundShrinkTo succeed.");
240    } catch (err) {
241        print("Call boundShrinkTo failed. err: " + err + ", errCode: " + err.code);
242    }
243
244    const unboundExtendTo = array1.extendTo;
245    const boundExtendTo = unboundExtendTo.bind(normal);
246    try {
247        boundExtendTo();
248        print("Call boundExtendTo succeed.");
249    } catch (err) {
250        print("Call boundExtendTo failed. err: " + err + ", errCode: " + err.code);
251    }
252}
253
254// SendableMap ut
255function bindErrorTestMap() {
256    print("Start map bindErrorTest");
257    const map0 = new SendableMap<string>([['key', 'value']]);
258    const normal = new NormalClass(10);
259
260    const unboundClear = map0.clear;
261    const boundClear = unboundClear.bind(normal);
262    try {
263        boundClear();
264        print("Call boundClear succeed.");
265    } catch (err) {
266        print("Call boundClear failed. err: " + err + ", errCode: " + err.code);
267    }
268
269    const unboundDelete = map0.delete;
270    const boundDelete = unboundDelete.bind(normal);
271    try {
272        boundDelete();
273        print("Call boundDelete succeed.");
274    } catch (err) {
275        print("Call boundDelete failed. err: " + err + ", errCode: " + err.code);
276    }
277
278    const unboundEntries = map0.entries;
279    const boundEntries = unboundEntries.bind(normal);
280    try {
281        boundEntries();
282        print("Call boundEntries succeed.");
283    } catch (err) {
284        print("Call boundEntries failed. err: " + err + ", errCode: " + err.code);
285    }
286
287    const unboundForEach = map0.forEach;
288    const boundForEach = unboundForEach.bind(normal);
289    try {
290        boundForEach();
291        print("Call boundForEach succeed.");
292    } catch (err) {
293        print("Call boundForEach failed. err: " + err + ", errCode: " + err.code);
294    }
295
296    const unboundGet = map0.get;
297    const boundGet = unboundGet.bind(normal);
298    try {
299        boundGet();
300        print("Call boundGet succeed.");
301    } catch (err) {
302        print("Call boundGet failed. err: " + err + ", errCode: " + err.code);
303    }
304
305    const unboundHas = map0.has;
306    const boundHas = unboundHas.bind(normal);
307    try {
308        boundHas();
309        print("Call boundHas succeed.");
310    } catch (err) {
311        print("Call boundHas failed. err: " + err + ", errCode: " + err.code);
312    }
313
314    const unboundKeys = map0.keys;
315    const boundKeys = unboundKeys.bind(normal);
316    try {
317        boundKeys();
318        print("Call boundKeys succeed.");
319    } catch (err) {
320        print("Call boundKeys failed. err: " + err + ", errCode: " + err.code);
321    }
322
323    const unboundSet = map0.set;
324    const boundSet = unboundSet.bind(normal);
325    try {
326        boundSet();
327        print("Call boundSet succeed.");
328    } catch (err) {
329        print("Call boundSet failed. err: " + err + ", errCode: " + err.code);
330    }
331
332    const unboundValues = map0.values;
333    const boundValues = unboundValues.bind(normal);
334    try {
335        boundValues();
336        print("Call boundValues succeed.");
337    } catch (err) {
338        print("Call boundValues failed. err: " + err + ", errCode: " + err.code);
339    }
340}
341
342// SendableSet ut
343function bindErrorTestSet() {
344    print("Start set bindErrorTest");
345    const set0 = new SendableSet<number>([0, 1, 2]);
346    const normal = new NormalClass(10);
347
348    const unboundAdd = set0.add;
349    const boundAdd = unboundAdd.bind(normal);
350    try {
351        boundAdd();
352        print("Call boundAdd succeed.");
353    } catch (err) {
354        print("Call boundAdd failed. err: " + err + ", errCode: " + err.code);
355    }
356
357    const unboundClear = set0.clear;
358    const boundClear = unboundClear.bind(normal);
359    try {
360        boundClear();
361        print("Call boundClear succeed.");
362    } catch (err) {
363        print("Call boundClear failed. err: " + err + ", errCode: " + err.code);
364    }
365
366    const unboundDelete = set0.delete;
367    const boundDelete = unboundDelete.bind(normal);
368    try {
369        boundDelete();
370        print("Call boundDelete succeed.");
371    } catch (err) {
372        print("Call boundDelete failed. err: " + err + ", errCode: " + err.code);
373    }
374
375    const unboundEntries = set0.entries;
376    const boundEntries = unboundEntries.bind(normal);
377    try {
378        boundEntries();
379        print("Call boundEntries succeed.");
380    } catch (err) {
381        print("Call boundEntries failed. err: " + err + ", errCode: " + err.code);
382    }
383
384    const unboundForEach = set0.forEach;
385    const boundForEach = unboundForEach.bind(normal);
386    try {
387        boundForEach();
388        print("Call boundForEach succeed.");
389    } catch (err) {
390        print("Call boundForEach failed. err: " + err + ", errCode: " + err.code);
391    }
392
393    const unboundHas = set0.has;
394    const boundHas = unboundHas.bind(normal);
395    try {
396        boundHas();
397        print("Call boundHas succeed.");
398    } catch (err) {
399        print("Call boundHas failed. err: " + err + ", errCode: " + err.code);
400    }
401
402    const unboundValues = set0.values;
403    const boundValues = unboundValues.bind(normal);
404    try {
405        boundValues();
406        print("Call boundValues succeed.");
407    } catch (err) {
408        print("Call boundValues failed. err: " + err + ", errCode: " + err.code);
409    }
410}
411
412// for SendableArray
413function createErrorTest(): void {
414    print("Start createErrorTest");
415    try {
416        const arr = new SendableArray<string>(-1);
417        print("Init with small first element: -1 success.");
418    } catch (err) {
419        print("Init with small first element: -1, err: " + err + ", errCode: " + err.code);
420    }
421
422    try {
423        const arr = new SendableArray<string>(0xffff);
424        print("Init with big first element: 0xffff success.");
425    } catch (err) {
426        print("Init with big first element: 0xffff, err: " + err + ", errCode: " + err.code);
427    }
428
429    try {
430        const arr = new SendableArray<string>(0xffffffffff);
431        print("Init exceed max length success.");
432    } catch (err) {
433        print("Init exceed max length: err: " + err + ", errCode: " + err.code);
434    }
435
436    try {
437        const arr = new SendableArray<NormalClass>(new NormalClass(1), new NormalClass(2));
438        print("Create with non-sendable element success.");
439    } catch (err) {
440        print("Create with non-sendable element fail. err: " + err + ", errCode: " + err.code);
441    }
442}
443
444function fromErrorTest(): void {
445    print("Start fromErrorTest");
446    try {
447        SendableArray.from<NormalClass>(Array.from([new NormalClass(1), new NormalClass(2)]));
448        print("Create from non-sendable iterator success.");
449    } catch (err) {
450        print("Create from non-sendable iterator fail. err: " + err + ", errCode: " + err.code);
451    }
452
453    try {
454        SendableArray.from<NormalClass>([new NormalClass(1), new NormalClass(2)]);
455        print("Create from non-sendable element success.");
456    } catch (err) {
457        print("Create from non-sendable element fail. err: " + err + ", errCode: " + err.code);
458    }
459    try {
460        SendableArray.from<number, NormalClass>([1, 2, 3], (x: number) => new NormalClass(x));
461        print("Create from mapper: non-sendable element success.");
462    } catch (err) {
463        print("Create from mapper: non-sendable element fail. err: " + err + ", errCode: " + err.code);
464    }
465}
466
467function staticCreateErrorTest(): void {
468    print("Start staticCreateErrorTest");
469    try {
470        SendableArray.create<NormalClass>(4, new NormalClass(1), new NormalClass(2));
471        print("Static create with non-sendable initialValue success.");
472    } catch (err) {
473        print("Static create from non-sendable initialValue fail. err: " + err + ", errCode: " + err.code);
474    }
475}
476
477function atErrorTest() {
478    print("Start atErrorTest");
479    const array1 = new SendableArray<number>(5, 12, 8, 130, 44);
480    try {
481        print("at invalid index success: " + array1.at("hi"));
482    } catch (err) {
483        print("at invalid index: err: " + err + ", errCode: " + err.code);
484    }
485}
486
487function concatErrorTest(): void {
488    print("Start concatErrorTest");
489    let array: SendableArray<number> = new SendableArray<number>(1, 3, 5);
490    let normalArray = new Array<NormalClass>(new NormalClass(2), new NormalClass(4), new NormalClass(6));
491
492    try {
493        array.concat(normalArray);
494        print("concat with non-sendable array success.");
495    } catch (err) {
496        print("concat with non-sendable array fail.err: " + err + ", errCode: " + err.code);
497    }
498
499    try {
500        array.concat(new NormalClass(2));
501        print("concat with non-sendable element success.");
502    } catch (err) {
503        print("concat with non-sendable element fail. err: " + err + ", errCode: " + err.code);
504    }
505}
506
507function directCallConstructor() {
508    print("Start directCallConstructor");
509
510    try {
511        SendableArray<number>();
512        print('direct call SendableArray ctor with empty success.');
513    } catch (err) {
514        print('direct call SendableArray ctor with empty fail. err: ' + err + ', errCode: ' + err.code);
515    }
516
517    try {
518        SendableArray<number>(5);
519        print('direct call SendableArray ctor with length.');
520    } catch (err) {
521        print('direct call SendableArray ctor with length fail. err: ' + err + ', errCode: ' + err.code);
522    }
523
524    try {
525        SendableArray<number>(5, 10);
526        print('direct call SendableArray ctor with elements.');
527    } catch (err) {
528        print('direct call SendableArray ctor with elements fail. err: ' + err + ', errCode: ' + err.code);
529    }
530}
531
532function directCallConstructorMap() {
533    print("Start map directCallConstructor");
534
535    try {
536        SendableMap<number, number>();
537        print('direct call SendableMap ctor with empty success.');
538    } catch (err) {
539        print('direct call SendableMap ctor with empty fail. err: ' + err + ', errCode: ' + err.code);
540    }
541
542    try {
543        SendableMap<number, number>(5);
544        print('direct call SendableMap ctor with length.');
545    } catch (err) {
546        print('direct call SendableMap ctor with length fail. err: ' + err + ', errCode: ' + err.code);
547    }
548
549    try {
550        SendableMap<number, number>([[5, 10]]);
551        print('direct call SendableMap ctor with elements.');
552    } catch (err) {
553        print('direct call SendableMap ctor with elements fail. err: ' + err + ', errCode: ' + err.code);
554    }
555}
556
557function directCallConstructorSet() {
558    print("Start set directCallConstructor");
559
560    try {
561        SendableSet<number>();
562        print('direct call SendableSet ctor with empty success.');
563    } catch (err) {
564        print('direct call SendableSet ctor with empty fail. err: ' + err + ', errCode: ' + err.code);
565    }
566
567    try {
568        SendableSet<number>(5);
569        print('direct call SendableSet ctor with length.');
570    } catch (err) {
571        print('direct call SendableSet ctor with length fail. err: ' + err + ', errCode: ' + err.code);
572    }
573
574    try {
575        SendableSet<number>(5, 10);
576        print('direct call SendableSet ctor with elements.');
577    } catch (err) {
578        print('direct call SendableSet ctor with elements fail. err: ' + err + ', errCode: ' + err.code);
579    }
580}
581
582function fillErrorTest() {
583    print("Start Test fillErrorTest")
584    const array1 = new SendableArray<number>(1, 2, 3, 4);
585    try {
586        array1.fill(new NormalClass(2), 2, 4);
587        print("fill array with non-sendable object and position success.");
588    } catch (err) {
589        print("fill array with non-sendable object and position fail. err: " + err + ", errCode: " + err.code);
590    }
591
592    try {
593        array1.fill(new NormalClass(3), 1);
594        print("fill array with non-sendable object and start position success.");
595    } catch (err) {
596        print("fill array with non-sendable object and start position fail. err: " + err + ", errCode: " + err.code);
597    }
598    try {
599        array1.fill(new NormalClass(4));
600        print("fill array with non-sendable object success.");
601    } catch (err) {
602        print("fill array with non-sendable object fail. err: " + err + ", errCode: " + err.code);
603    }
604}
605
606function mapErrorTest() {
607    print("Start mapErrorTest")
608    const array = new SendableArray<number>(1, 4, 9, 16);
609    try {
610        array.map<NormalClass>((x: number) => new NormalClass(x));
611        print("map array with non-sendable success.");
612    } catch (err) {
613        print("map array with non-sendable fail. err: " + err + ", errCode: " + err.code);
614    }
615}
616
617function pushErrorTest() {
618    print("Start pushErrorTest")
619    let array: SendableArray<number> = new SendableArray<number>(1, 3, 5);
620    try {
621        array.push(new NormalClass(5));
622        print("push array with non-sendable element success.");
623    } catch (err) {
624        print("push array with non-sendable element fail. err: " + err + ", errCode: " + err.code);
625    }
626}
627
628function unshiftErrorTest() {
629    print("Start Test unshiftErrorTest")
630    const array = new SendableArray<number>(1, 2, 3);
631    try {
632        array.unshift(new NormalClass(4), new NormalClass(5));
633        print("unshift array with non-sendable element success.");
634    } catch (err) {
635        print("unshift array with non-sendable element fail. err: " + err + ", errCode: " + err.code);
636    }
637}
638
639function extendToErrorTest() {
640    print("Start Test extendToErrorTest")
641    const array = new SendableArray<number>(1, 2, 3);
642    try {
643        array.extendTo(5, new NormalClass(4));
644        print("extendTo array with non-sendable element success.");
645    } catch (err) {
646        print("extendTo array with non-sendable element fail. err: " + err + ", errCode: " + err.code);
647    }
648}
649
650function concurrencyErrorTest() {
651    const array1 = new SendableArray<number>(1, 2, 3);
652    try {
653        array1.forEach((key: number, _: number, array: SendableArray) => {
654          array.push(5);
655        });
656      } catch (err) {
657        print("add element while iterate array fail. err: " + err + ", errCode: " + err.code);
658      }
659      try {
660        array1.forEach((key: number, _: number, array: SendableArray) => {
661          if (key % 2 == 0) {
662            array.pop();
663          }
664        });
665      } catch (err) {
666        print("pop element while iterate array fail. err: " + err + ", errCode: " + err.code);
667      }
668      try {
669        array1.forEach((key: number, _: number, array: SendableArray) => {
670          array.shrinkTo(0);
671        });
672      } catch (err) {
673        print("shrink while iterate array fail. err: " + err + ", errCode: " + err.code);
674      }
675      try {
676        array1.forEach((key: number, _: number, array: SendableArray) => {
677          array.extendTo(array1.length + 1, 100);
678        });
679      } catch (err) {
680        print("extend while iterate array fail. err: " + err + ", errCode: " + err.code);
681      }
682}
683
684// common bindTest
685bindErrorTest();
686print('Start Test SendableMap');
687bindErrorTestMap();
688
689print('Start Test SendableSet');
690bindErrorTestSet();
691
692print('Start Test SendableArray');
693createErrorTest();
694fromErrorTest();
695atErrorTest();
696concatErrorTest();
697fillErrorTest()
698mapErrorTest()
699pushErrorTest()
700unshiftErrorTest()
701staticCreateErrorTest();
702extendToErrorTest();
703directCallConstructor();
704directCallConstructorMap();
705directCallConstructorSet();
706concurrencyErrorTest();
707