• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #ifndef ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_VARIABLE_SECOND_TEST_H
17 #define ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_VARIABLE_SECOND_TEST_H
18 
19 #include "test/utils/test_util.h"
20 
21 namespace panda::ecmascript::tooling::test {
22 class JsVariableSecondTest : public TestEvents {
23 public:
JsVariableSecondTest()24     JsVariableSecondTest()
25     {
26         breakpoint = [this](const JSPtLocation &location) {
27             ASSERT_TRUE(location.GetMethodId().IsValid());
28             ASSERT_LOCATION_EQ(location, location_);
29             ++breakpointCounter_;
30             debugger_->NotifyPaused(location, PauseReason::INSTRUMENTATION);
31             TestUtil::SuspendUntilContinue(DebugEvent::BREAKPOINT, location);
32             return true;
33         };
34 
35         loadModule = [this](std::string_view moduleName) {
36             std::string panfaFile = DEBUGGER_ABC_DIR "variable_second.abc";
37             std::string sourceFile = DEBUGGER_JS_DIR "variable_second.js";
38             static_cast<JsVariableSecondTestChannel *>(channel_)->Initial(vm_, runtime_);
39             runtime_->Enable();
40             // 125: breakpointer line
41             location_ = TestUtil::GetLocation(sourceFile.c_str(), 125, 0, panfaFile.c_str());
42             ASSERT_TRUE(location_.GetMethodId().IsValid());
43             TestUtil::SuspendUntilContinue(DebugEvent::LOAD_MODULE);
44             ASSERT_EQ(moduleName, panfaFile);
45             ASSERT_TRUE(debugger_->NotifyScriptParsed(0, panfaFile));
46             auto condFuncRef = FunctionRef::Undefined(vm_);
47             auto ret = debugInterface_->SetBreakpoint(location_, condFuncRef);
48             ASSERT_TRUE(ret);
49             return true;
50         };
51 
52         scenario = [this]() {
53             TestUtil::WaitForLoadModule();
54             TestUtil::Continue();
55             TestUtil::WaitForBreakpoint(location_);
56             TestUtil::Continue();
57             auto ret = debugInterface_->RemoveBreakpoint(location_);
58             ASSERT_TRUE(ret);
59             ASSERT_EXITED();
60             return true;
61         };
62 
63         vmDeath = [this]() {
64             ASSERT_EQ(breakpointCounter_, 1U);  // 1: break point counter
65             return true;
66         };
67 
68         channel_ = new JsVariableSecondTestChannel();
69     }
70 
GetEntryPoint()71     std::pair<std::string, std::string> GetEntryPoint() override
72     {
73         std::string panfaFile = DEBUGGER_ABC_DIR "variable_second.abc";
74         return {panfaFile, entryPoint_};
75     }
~JsVariableSecondTest()76     ~JsVariableSecondTest()
77     {
78         delete channel_;
79         channel_ = nullptr;
80     }
81 
82 private:
83     class JsVariableSecondTestChannel : public TestChannel {
84     public:
85         JsVariableSecondTestChannel() = default;
86         ~JsVariableSecondTestChannel() = default;
Initial(const EcmaVM * vm,RuntimeImpl * runtime)87         void Initial(const EcmaVM *vm, RuntimeImpl *runtime)
88         {
89             vm_ = vm;
90             runtime_ = runtime;
91         }
92 
SendNotification(const PtBaseEvents & events)93         void SendNotification(const PtBaseEvents &events) override
94         {
95             const static std::vector<std::function<bool(const PtBaseEvents &events)>> eventList = {
96                 [](const PtBaseEvents &events) -> bool {
97                     std::string sourceFile = DEBUGGER_JS_DIR "variable_second.js";
98                     auto parsed = static_cast<const ScriptParsed *>(&events);
99                     std::string str = parsed->ToJson()->Stringify();
100                     std::cout << "JsVariableSecondTestChannel: SendNotification 0:\n" << str << std::endl;
101 
102                     ASSERT_EQ(parsed->GetName(), "Debugger.scriptParsed");
103                     ASSERT_EQ(parsed->GetUrl(), sourceFile);
104                     return true;
105                 },
106                 [this](const PtBaseEvents &events) -> bool {
107                     auto paused = static_cast<const Paused *>(&events);
108                     std::string str = paused->ToJson()->Stringify();
109                     std::cout << "JsVariableSecondTestChannel: SendNotification 1:\n" << str << std::endl;
110 
111                     ASSERT_EQ(paused->GetName(), "Debugger.paused");
112                     auto frame = paused->GetCallFrames()->at(0).get();
113                     ASSERT_EQ(frame->GetFunctionName(), "foo");
114                     auto scopes = frame->GetScopeChain();
115                     ASSERT_EQ(scopes->size(), 2U);  // 2: contain local and global
116                     for (uint32_t i = 0; i < scopes->size(); i++) {
117                         auto scope = scopes->at(i).get();
118                         if (scope->GetType() != Scope::Type::Local()) {
119                             continue;
120                         }
121                         auto localId = scope->GetObject()->GetObjectId();
122                         GetPropertiesParams params;
123                         params.SetObjectId(localId).SetOwnProperties(true);
124                         std::vector<std::unique_ptr<PropertyDescriptor>> outPropertyDesc;
125                         runtime_->GetProperties(params, &outPropertyDesc, {}, {}, {});
126                         for (const auto &property : outPropertyDesc) {
127                             std::cout << "=====================================" << std::endl;
128                             std::cout << property->GetName() << std::endl;
129                             auto value = property->GetValue();
130                             std::vector<std::string> infos;
131                             PushValueInfo(value, infos);
132                             if (value->GetType() == RemoteObject::TypeName::Object) {
133                                 std::vector<std::unique_ptr<PropertyDescriptor>> outPropertyDescInner;
134                                 ASSERT_TRUE(value->HasObjectId());
135                                 params.SetObjectId(value->GetObjectId()).SetOwnProperties(true);
136                                 runtime_->GetProperties(params, &outPropertyDescInner, {}, {}, {});
137                                 if (outPropertyDescInner.size() == 0) {
138                                     infos.push_back("none");
139                                 }
140                                 for (const auto &propertyInner : outPropertyDescInner) {
141                                     std::cout << "###########################################" << std::endl;
142                                     std::cout << propertyInner->GetName() << std::endl;
143                                     infos.push_back(propertyInner->GetName());
144                                     auto innerValue = propertyInner->GetValue();
145                                     PushValueInfo(innerValue, infos);
146                                 }
147                             }
148                             ASSERT_EQ(infos.size(), variableMap_.at(property->GetName()).size());
149                             for (uint32_t j = 0; j < infos.size(); j++) {
150                                 ASSERT_EQ(infos[j], variableMap_.at(property->GetName())[j]);
151                             }
152                         }
153                     }
154                     return true;
155                 }
156             };
157 
158             ASSERT_TRUE(eventList[index_](events));
159             index_++;
160         }
161 
162     private:
163         NO_COPY_SEMANTIC(JsVariableSecondTestChannel);
164         NO_MOVE_SEMANTIC(JsVariableSecondTestChannel);
165 
PushValueInfo(RemoteObject * value,std::vector<std::string> & infos)166         void PushValueInfo(RemoteObject *value, std::vector<std::string> &infos)
167         {
168             std::cout << "type: " << value->GetType() << std::endl;
169             infos.push_back(value->GetType());
170             if (value->HasObjectId()) {
171                 std::cout << "id: " << value->GetObjectId() << std::endl;
172             }
173             if (value->HasSubType()) {
174                 std::cout << "sub type: " << value->GetSubType() << std::endl;
175                 infos.push_back(value->GetSubType());
176             }
177             if (value->HasClassName()) {
178                 std::cout << "class name: " << value->GetClassName() << std::endl;
179                 infos.push_back(value->GetClassName());
180             }
181             if (value->HasDescription()) {
182                 std::cout << "desc: " << value->GetDescription() << std::endl;
183                 infos.push_back(value->GetDescription());
184             }
185             if (value->HasValue()) {
186                 std::cout << "type: " <<
187                     value->GetValue()->Typeof(vm_)->ToString() << std::endl;
188                 std::cout << "tostring: " <<
189                     value->GetValue()->ToString(vm_)->ToString() << std::endl;
190                 infos.push_back(value->GetValue()->ToString(vm_)->ToString());
191             }
192         }
193 
194         /*
195         * Expect map type: map<name, value list>
196         * value list (optional):
197         *    type
198         *    subType
199         *    className
200         *    description
201         *    value tostring
202         *
203         * if is object value, will push back key and value.
204         *
205         * for example:
206         * var abc = 1
207         *     { "abc", { "number", "1", "1" } }
208         * var obj = { "key": "2" }
209         *     { "obj0", { "object", "Object", "Object", "[object Object]", "key", "string", "2", "2" } }
210         */
211         const std::map<std::string, std::vector<std::string>> variableMap_ = {
212             { "nop", { "undefined" } },
213             { "foo", { "function", "Function", "function foo( { [js code] }",
214                        "Cannot get source code of funtion"} },
215             { "string0", { "string", "helloworld", "helloworld" } },
216             { "boolean0", { "object", "Object", "Boolean{[[PrimitiveValue]]: false}", "false", "[[PrimitiveValue]]",
217                             "boolean", "false", "false" } },
218             { "number0", { "number", "1", "1" } },
219             { "obj0", { "object", "Object", "Object", "[object Object]",
220                         "key0", "string", "value0", "value0",
221                         "key1", "number", "100", "100" } },
222             { "arraybuffer0", { "object", "arraybuffer", "Arraybuffer", "ArrayBuffer(24)", "[object ArrayBuffer]",
223                                 "[[Int8Array]]", "object", "Object", "Int8Array(24)",
224                                 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "[[Uint8Array]]", "object",
225                                 "Object", "Uint8Array(24)", "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
226                                 "[[Uint8ClampedArray]]", "object", "Object", "Object",
227                                 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "[[Int16Array]]", "object",
228                                 "Object", "Int16Array(12)", "0,0,0,0,0,0,0,0,0,0,0,0", "[[Uint16Array]]", "object",
229                                 "Object", "Object", "0,0,0,0,0,0,0,0,0,0,0,0", "[[Int32Array]]", "object", "Object",
230                                 "Int32Array(6)", "0,0,0,0,0,0", "[[Uint32Array]]", "object", "Object", "Object",
231                                 "0,0,0,0,0,0", "[[Float32Array]]", "object", "Object", "Object", "0,0,0,0,0,0",
232                                 "[[Float64Array]]", "object", "Object", "Object", "0,0,0", "[[BigInt64Array]]",
233                                 "object", "Object", "Object", "0,0,0", "[[BigUint64Array]]", "object", "Object",
234                                 "Object", "0,0,0" } },
235             { "function0", { "function", "Function", "function function0( { [js code] }",
236                              "Cannot get source code of funtion" } },
237             { "generator0", { "function", "Generator", "function* generator0( { [js code] }",
238                               "Cannot get source code of funtion" } },
239             { "map0", { "object", "map", "Map", "Map(0)", "[object Map]", "size", "number", "0", "0", "[[Entries]]",
240                         "object", "array", "Array", "Array(0)", "" } },
241             { "set0", { "object", "set", "Set", "Set(0)", "[object Set]", "size", "number", "0", "0", "[[Entries]]",
242                         "object", "array", "Array", "Array(0)", "" } },
243             { "undefined0", { "undefined" } },
244             { "array0", { "object", "array", "Array", "Array(2)", "Apple,Banana", "0", "string", "Apple", "Apple",
245                           "1", "string", "Banana", "Banana", "length", "number", "2", "2" } },
246             { "regexp0", { "object", "regexp", "RegExp", "/^\\d+\\.\\d+$/i", "/^\\d+\\.\\d+$/i", "global", "boolean",
247                            "false", "false", "ignoreCase", "boolean", "true", "true", "multiline", "boolean", "false",
248                            "false", "dotAll", "boolean", "false", "false", "hasIndices", "boolean", "false", "false",
249                            "unicode", "boolean", "false", "false", "sticky", "boolean", "false", "false", "flags",
250                            "string", "i", "i", "source", "string", "^\\d+\\.\\d+$", "^\\d+\\.\\d+$", "lastIndex",
251                            "number", "0", "0" } },
252             { "uint8array0", { "object", "Object", "Uint8Array(24)",
253                                "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "         0", "number", "0", "0",
254                                "         1", "number", "0", "0", "         2", "number", "0", "0", "         3",
255                                "number", "0", "0", "         4", "number", "0", "0", "         5", "number", "0",
256                                "0", "         6", "number", "0", "0", "         7", "number", "0", "0", "         8",
257                                "number", "0", "0", "         9", "number", "0", "0", "        10", "number", "0",
258                                "0", "        11", "number", "0", "0", "        12", "number", "0", "0", "        13",
259                                "number", "0", "0", "        14", "number", "0", "0", "        15", "number", "0",
260                                "0", "        16", "number", "0", "0", "        17", "number", "0", "0", "        18",
261                                "number", "0", "0", "        19", "number", "0", "0", "        20", "number", "0",
262                                "0", "        21", "number", "0", "0", "        22", "number", "0", "0", "        23",
263                                "number", "0", "0" } },
264             { "dataview0", { "object", "dataview", "Dataview", "DataView(24)", "[object DataView]", "buffer",
265                              "object", "arraybuffer", "Arraybuffer", "ArrayBuffer(24)", "[object ArrayBuffer]",
266                              "byteLength", "number", "24", "24", "byteOffset", "number", "0", "0" } },
267             { "bigint0", { "bigint", "999n", "999" } },
268             { "typedarray0", { "object", "Object", "Uint8Array(0)", "", "none" } },
269             { "sharedarraybuffer0", { "object", "Object", "SharedArrayBuffer(32)", "[object SharedArrayBuffer]",
270                                       "[[Int8Array]]", "object", "Object", "Int8Array(32)",
271                                       "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
272                                       "[[Uint8Array]]", "object", "Object", "Uint8Array(32)",
273                                       "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
274                                       "[[Int16Array]]", "object", "Object", "Int16Array(16)",
275                                       "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "[[Int32Array]]", "object", "Object",
276                                       "Int32Array(8)", "0,0,0,0,0,0,0,0", "[[ArrayBufferByteLength]]", "number", "32",
277                                       "32", "byteLength", "number", "32", "32" } },
278             { "weakref0", { "object", "Object", "WeakRef {}", "[object WeakRef]", "none" } },
279             { "iterator0", { "function", "Function", "function [Symbol.iterator]( { [native code] }",
280                              "function [Symbol.iterator]() { [native code] }" } },
281             { "array1", { "object", "array", "Array", "Array(3)", "banana,apple,peach", "0", "string", "banana",
282                           "banana", "1", "string", "apple", "apple", "2", "string", "peach", "peach", "length",
283                           "number", "3", "3" } },
284             { "array2", { "object", "array", "Array", "Array(3)", "banana,apple,peach", "0", "string", "banana",
285                           "banana", "1", "string", "apple", "apple", "2", "string", "peach", "peach", "length",
286                           "number", "3", "3" } },
287             { "array3", { "object", "array", "Array", "Array(1)", "apple", "0", "string", "apple", "apple",
288                           "length", "number", "1", "1" } },
289             { "array4", { "string", "banana", "banana" } },
290             { "array5", { "object", "array", "Array", "Array(1)", "", "length", "number", "1", "1" } },
291             { "array6", { "object", "array", "Array", "Array(1)", "helloworld", "0", "string", "helloworld",
292                           "helloworld", "length", "number", "1", "1" } },
293             { "array7", { "object", "array", "Array", "Array(1)", "false", "0", "object", "Object",
294                           "Boolean{[[PrimitiveValue]]: false}", "false", "length", "number", "1", "1" } },
295             { "array8", { "object", "array", "Array", "Array(1)", "[object Object]", "0", "object", "Object",
296                           "Object", "[object Object]", "length", "number", "1", "1" } },
297             { "array9", { "object", "array", "Array", "Array(1)", "Cannot get source code of funtion", "0", "function",
298                           "Function", "function function0( { [js code] }", "Cannot get source code of funtion",
299                           "length", "number", "1", "1" } },
300             { "array10", { "object", "array", "Array", "Array(1)", "[object Map]", "0", "object", "map", "Map",
301                            "Map(0)", "[object Map]", "length", "number", "1", "1" } },
302             { "array11", { "object", "array", "Array", "Array(1)", "[object Set]", "0", "object", "set", "Set",
303                            "Set(0)", "[object Set]", "length", "number", "1", "1" } },
304             { "array12", { "object", "array", "Array", "Array(1)", "", "0", "undefined", "length", "number",
305                            "1", "1" } },
306             { "array13", { "object", "array", "Array", "Array(1)", "Apple,Banana", "0", "object", "array", "Array",
307                            "Array(2)", "Apple,Banana", "length", "number", "1", "1" } },
308             { "array14", { "object", "array", "Array", "Array(1)", "Cannot get source code of funtion", "0",
309                            "function", "Generator", "function* generator0( { [js code] }",
310                            "Cannot get source code of funtion", "length", "number", "1", "1" } },
311             { "array15", { "object", "array", "Array", "Array(1)", "/^\\d+\\.\\d+$/i", "0", "object", "regexp",
312                            "RegExp", "/^\\d+\\.\\d+$/i", "/^\\d+\\.\\d+$/i", "length", "number", "1", "1" } },
313             { "array16", { "object", "array", "Array", "Array(1)", "[object ArrayBuffer]", "0", "object",
314                            "arraybuffer", "Arraybuffer", "ArrayBuffer(24)", "[object ArrayBuffer]",
315                            "length", "number", "1", "1" } },
316             { "array17", { "object", "array", "Array", "Array(1)",
317                            "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", "0", "object", "Object",
318                            "Uint8Array(24)", "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
319                            "length", "number", "1", "1" } },
320             { "array18", { "object", "array", "Array", "Array(1)", "[object DataView]", "0", "object", "dataview",
321                            "Dataview", "DataView(24)", "[object DataView]", "length", "number", "1", "1" } },
322             { "array19", { "object", "array", "Array", "Array(1)", "999", "0", "bigint", "999n", "999", "length",
323                            "number", "1", "1" } },
324             { "array20", { "object", "array", "Array", "Array(3)", "banana,apple,peach", "0", "string", "banana",
325                            "banana", "1", "string", "apple", "apple", "2", "string", "peach", "peach", "length",
326                            "number", "3", "3" } },
327             { "array21", { "string", "banana", "banana" } },
328             { "typedarray1", { "object", "Object", "Int8Array(0)", "", "none" } },
329             { "typedarray2", { "object", "Object", "Object", "", "none" } },
330             { "typedarray3", { "object", "Object", "Int16Array(0)", "", "none" } },
331             { "typedarray4", { "object", "Object", "Object", "", "none" } },
332             { "typedarray5", { "object", "Object", "Int32Array(0)", "", "none" } },
333             { "typedarray6", { "object", "Object", "Object", "", "none" } },
334             { "typedarray7", { "object", "Object", "Object", "", "none" } },
335             { "typedarray8", { "object", "Object", "Object", "", "none" } },
336             { "typedarray9", { "object", "Object", "Object", "", "none" } },
337             { "typedarray10", { "object", "Object", "Object", "", "none" } },
338             { "typedarray11", { "object", "Object", "Uint8Array(1)", "0", "         0", "number", "0", "0" } },
339             { "iterator1", { "function", "Function", "function values( { [native code] }",
340                              "function values() { [native code] }" } },
341             { "iterator3", { "function", "Function", "function values( { [native code] }",
342                              "function values() { [native code] }" } },
343             { "iterator2", { "function", "Function", "function entries( { [native code] }",
344                              "function entries() { [native code] }" } },
345             { "iterator4", { "function", "Function", "function values( { [native code] }",
346                              "function values() { [native code] }" } },
347             { "iterator5", { "function", "Function", "function [Symbol.iterator]( { [native code] }",
348                              "function [Symbol.iterator]() { [native code] }" } },
349             { "iterator6", { "function", "Function", "function values( { [native code] }",
350                              "function values() { [native code] }" } },
351             { "iterator7", { "function", "Function", "function values( { [native code] }",
352                              "function values() { [native code] }" } },
353             { "iterator8", { "function", "Function", "function values( { [native code] }",
354                              "function values() { [native code] }" } },
355             { "iterator9", { "function", "Function", "function values( { [native code] }",
356                              "function values() { [native code] }" } },
357             { "iterator10", { "function", "Function", "function values( { [native code] }",
358                               "function values() { [native code] }" } },
359             { "iterator11", { "function", "Function", "function values( { [native code] }",
360                               "function values() { [native code] }" } },
361             { "iterator12", { "function", "Function", "function values( { [native code] }",
362                               "function values() { [native code] }" } },
363             { "iterator13", { "function", "Function", "function values( { [native code] }",
364                               "function values() { [native code] }" } },
365             { "iterator14", { "function", "Function", "function values( { [native code] }",
366                               "function values() { [native code] }" } },
367             { "iterator15", { "function", "Function", "function values( { [native code] }",
368                               "function values() { [native code] }" } },
369             { "iterator16", { "function", "Function", "function values( { [native code] }",
370                               "function values() { [native code] }" } },
371             { "iterator17", { "undefined" } },
372             { "iterator18", { "undefined" } },
373             { "iterator19", { "undefined" } },
374             { "weakMap0", { "object", "weakmap", "Weakmap", "WeakMap(0)", "[object WeakMap]", "size", "number",
375                             "0", "0", "[[Entries]]", "object", "array", "Array", "Array(0)", "" } },
376             { "p1", { "object", "Object", "Number{[[PrimitiveValue]]: 1}", "1", "[[PrimitiveValue]]", "number",
377                       "1", "1" } },
378             { "p2", { "object", "Object", "Number{[[PrimitiveValue]]: 2}", "2", "[[PrimitiveValue]]", "number",
379                       "2", "2" } },
380             { "weakMap1", { "object", "weakmap", "Weakmap", "WeakMap(2) {Object => 'hello', Object => 'world'}",
381                             "[object WeakMap]", "size", "number", "2", "2", "[[Entries]]", "object", "array",
382                             "Array", "Array(2)", "[object Object],[object Object]" } },
383             { "weakMap2", { "object", "weakmap", "Weakmap", "WeakMap(0)", "[object WeakMap]", "size", "number",
384                             "0", "0", "[[Entries]]", "object", "array", "Array", "Array(0)", "",
385                             "0", "string", "hello", "hello" } },
386             { "weakMap3", { "object", "weakmap", "Weakmap", "WeakMap(1) {Object => 'weakMap0'}", "[object WeakMap]",
387                             "size", "number", "1", "1", "[[Entries]]", "object", "array", "Array", "Array(1)",
388                             "[object Object]" } },
389             { "weakMap4", { "object", "weakmap", "Weakmap", "WeakMap(2) {Object => 37, Object => 'azerty'}",
390                             "[object WeakMap]", "size", "number", "2", "2", "[[Entries]]", "object", "array",
391                             "Array", "Array(2)", "[object Object],[object Object]" } },
392             { "weakMap5", { "object", "weakmap", "Weakmap", "WeakMap(1) {Object => undefined}", "[object WeakMap]",
393                             "size", "number", "1", "1", "[[Entries]]", "object", "array", "Array", "Array(1)",
394                             "[object Object]" } },
395             { "weakSet0", { "object", "weakset", "Weakset", "WeakSet(0)", "[object WeakSet]", "size", "number",
396                             "0", "0", "[[Entries]]", "object", "array", "Array", "Array(0)", "" } },
397             { "weakSet1", { "object", "weakset", "Weakset", "WeakSet(1) {Object}", "[object WeakSet]", "size",
398                             "number", "1", "1", "[[Entries]]", "object", "array", "Array", "Array(1)",
399                             "[object Object]" } },
400             { "weakSet2", { "object", "weakset", "Weakset", "WeakSet(2) {Object, Object}", "[object WeakSet]",
401                             "size", "number", "2", "2", "[[Entries]]", "object", "array", "Array", "Array(2)",
402                             "[object Object],[object Object]" } },
403         };
404 
405         int32_t index_ {0};
406         const EcmaVM *vm_ {nullptr};
407         RuntimeImpl *runtime_ {nullptr};
408     };
409 
410     std::string entryPoint_ = "_GLOBAL::func_main_0";
411     JSPtLocation location_ {nullptr, JSPtLocation::EntityId(0), 0};
412     size_t breakpointCounter_ = 0;
413 };
414 
GetJsVariableSecondTest()415 std::unique_ptr<TestEvents> GetJsVariableSecondTest()
416 {
417     return std::make_unique<JsVariableSecondTest>();
418 }
419 }  // namespace panda::ecmascript::tooling::test
420 
421 #endif  // ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_VARIABLE_TEST_H
422