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