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