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 // 166: breakpointer line
41 int32_t line = 166;
42 location_ = TestUtil::GetLocation(sourceFile.c_str(), line, 0, panfaFile.c_str());
43 ASSERT_TRUE(location_.GetMethodId().IsValid());
44 TestUtil::SuspendUntilContinue(DebugEvent::LOAD_MODULE);
45 ASSERT_EQ(moduleName, panfaFile);
46 ASSERT_TRUE(debugger_->NotifyScriptParsed(0, panfaFile));
47 auto condFuncRef = FunctionRef::Undefined(vm_);
48 auto ret = debugInterface_->SetBreakpoint(location_, condFuncRef);
49 ASSERT_TRUE(ret);
50 return true;
51 };
52
53 scenario = [this]() {
54 TestUtil::WaitForLoadModule();
55 TestUtil::Continue();
56 TestUtil::WaitForBreakpoint(location_);
57 TestUtil::Continue();
58 auto ret = debugInterface_->RemoveBreakpoint(location_);
59 ASSERT_TRUE(ret);
60 ASSERT_EXITED();
61 return true;
62 };
63
64 vmDeath = [this]() {
65 ASSERT_EQ(breakpointCounter_, 1U); // 1: break point counter
66 return true;
67 };
68
69 channel_ = new JsVariableSecondTestChannel();
70 }
71
72 std::pair<std::string, std::string> GetEntryPoint() override
73 {
74 std::string panfaFile = DEBUGGER_ABC_DIR "variable_second.abc";
75 return {panfaFile, entryPoint_};
76 }
~JsVariableSecondTest()77 ~JsVariableSecondTest()
78 {
79 delete channel_;
80 channel_ = nullptr;
81 }
82
83 private:
84 class JsVariableSecondTestChannel : public TestChannel {
85 public:
86 JsVariableSecondTestChannel() = default;
87 ~JsVariableSecondTestChannel() = default;
Initial(const EcmaVM *vm, RuntimeImpl *runtime)88 void Initial(const EcmaVM *vm, RuntimeImpl *runtime)
89 {
90 vm_ = vm;
91 runtime_ = runtime;
92 }
93
94 void SendNotification(const PtBaseEvents &events) override
95 {
96 const static std::vector<std::function<bool(const PtBaseEvents &events)>> eventList = {
97 [](const PtBaseEvents &events) -> bool {
98 std::string sourceFile = DEBUGGER_JS_DIR "variable_second.js";
99 auto parsed = static_cast<const ScriptParsed *>(&events);
100 std::string str = parsed->ToJson()->Stringify();
101 std::cout << "JsVariableSecondTestChannel: SendNotification 0:\n" << str << std::endl;
102
103 ASSERT_EQ(parsed->GetName(), "Debugger.scriptParsed");
104 ASSERT_EQ(parsed->GetUrl(), sourceFile);
105 return true;
106 },
107 [this](const PtBaseEvents &events) -> bool {
108 auto paused = static_cast<const Paused *>(&events);
109 std::string str = paused->ToJson()->Stringify();
110 std::cout << "JsVariableSecondTestChannel: SendNotification 1:\n" << str << std::endl;
111
112 ASSERT_EQ(paused->GetName(), "Debugger.paused");
113 auto frame = paused->GetCallFrames()->at(0).get();
114 ASSERT_EQ(frame->GetFunctionName(), "foo");
115 auto scopes = frame->GetScopeChain();
116 ASSERT_EQ(scopes->size(), 2U); // 2: contain local and global
117 for (uint32_t i = 0; i < scopes->size(); i++) {
118 auto scope = scopes->at(i).get();
119 if (scope->GetType() != Scope::Type::Local()) {
120 continue;
121 }
122 auto localId = scope->GetObject()->GetObjectId();
123 GetPropertiesParams params;
124 params.SetObjectId(localId).SetOwnProperties(true);
125 std::vector<std::unique_ptr<PropertyDescriptor>> outPropertyDesc;
126 runtime_->GetProperties(params, &outPropertyDesc, {}, {}, {});
127 for (const auto &property : outPropertyDesc) {
128 std::cout << "=====================================" << std::endl;
129 std::cout << property->GetName() << std::endl;
130 auto value = property->GetValue();
131 std::vector<std::string> infos;
132 PushValueInfo(value, infos);
133 if (value->GetType() == RemoteObject::TypeName::Object) {
134 std::vector<std::unique_ptr<PropertyDescriptor>> outPropertyDescInner;
135 ASSERT_TRUE(value->HasObjectId());
136 params.SetObjectId(value->GetObjectId()).SetOwnProperties(true);
137 runtime_->GetProperties(params, &outPropertyDescInner, {}, {}, {});
138 if (outPropertyDescInner.size() == 0) {
139 infos.push_back("none");
140 }
141 for (const auto &propertyInner : outPropertyDescInner) {
142 std::cout << "###########################################" << std::endl;
143 std::cout << propertyInner->GetName() << std::endl;
144 infos.push_back(propertyInner->GetName());
145 auto innerValue = propertyInner->GetValue();
146 PushValueInfo(innerValue, infos);
147 }
148 }
149 ASSERT_EQ(infos.size(), variableMap_.at(property->GetName()).size());
150 for (uint32_t j = 0; j < infos.size(); j++) {
151 ASSERT_EQ(infos[j], variableMap_.at(property->GetName())[j]);
152 }
153 }
154 }
155 return true;
156 }
157 };
158
159 ASSERT_TRUE(eventList[index_](events));
160 index_++;
161 }
162
163 private:
164 NO_COPY_SEMANTIC(JsVariableSecondTestChannel);
165 NO_MOVE_SEMANTIC(JsVariableSecondTestChannel);
166
PushValueInfo(RemoteObject *value, std::vector<std::string> &infos)167 void PushValueInfo(RemoteObject *value, std::vector<std::string> &infos)
168 {
169 std::cout << "type: " << value->GetType() << std::endl;
170 infos.push_back(value->GetType());
171 if (value->HasObjectId()) {
172 std::cout << "id: " << value->GetObjectId() << std::endl;
173 }
174 if (value->HasSubType()) {
175 std::cout << "sub type: " << value->GetSubType() << std::endl;
176 infos.push_back(value->GetSubType());
177 }
178 if (value->HasClassName()) {
179 std::cout << "class name: " << value->GetClassName() << std::endl;
180 infos.push_back(value->GetClassName());
181 }
182 if (value->HasDescription()) {
183 std::cout << "desc: " << value->GetDescription() << std::endl;
184 infos.push_back(value->GetDescription());
185 }
186 if (value->HasValue()) {
187 std::cout << "type: " <<
188 value->GetValue()->Typeof(vm_)->ToString(vm_) << std::endl;
189 std::cout << "tostring: " <<
190 value->GetValue()->ToString(vm_)->ToString(vm_) << std::endl;
191 infos.push_back(value->GetValue()->ToString(vm_)->ToString(vm_));
192 }
193 }
194
195 /*
196 * Expect map type: map<name, value list>
197 * value list (optional):
198 * type
199 * subType
200 * className
201 * description
202 * value tostring
203 *
204 * if is object value, will push back key and value.
205 *
206 * for example:
207 * var abc = 1
208 * { "abc", { "number", "1", "1" } }
209 * var obj = { "key": "2" }
210 * { "obj0", { "object", "Object", "Object", "[object Object]", "key", "string", "2", "2" } }
211 */
212 const std::map<std::string, std::vector<std::string>> variableMap_ = {
213 { "nop", { "undefined" } },
214 { "foo", { "function", "Function", "function foo( { [js code] }",
215 "Cannot get source code of funtion"} },
216 { "string0", { "string", "helloworld", "helloworld" } },
217 { "boolean0", { "object", "Object", "Boolean{[[PrimitiveValue]]: false}", "false", "[[PrimitiveValue]]",
218 "boolean", "false", "false" } },
219 { "number0", { "number", "1", "1" } },
220 { "obj0", { "object", "Object", "Object", "[object Object]",
221 "key0", "string", "value0", "value0",
222 "key1", "number", "100", "100" } },
223 { "arraybuffer0", { "object", "arraybuffer", "Arraybuffer", "Arraybuffer(24)", "[object ArrayBuffer]",
224 "[[Int8Array]]", "object", "Object", "Int8Array(24)",
225 "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",
226 "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",
227 "[[Uint8ClampedArray]]", "object", "Object", "Uint8ClampedArray",
228 "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",
229 "Object", "Int16Array(12)", "0,0,0,0,0,0,0,0,0,0,0,0", "[[Uint16Array]]", "object",
230 "Object", "Uint16Array", "0,0,0,0,0,0,0,0,0,0,0,0",
231 "[[Int32Array]]", "object", "Object",
232 "Int32Array(6)", "0,0,0,0,0,0", "[[Uint32Array]]", "object", "Object", "Uint32Array",
233 "0,0,0,0,0,0", "[[Float32Array]]", "object", "Object", "Float32Array", "0,0,0,0,0,0",
234 "[[Float64Array]]", "object", "Object", "Float64Array", "0,0,0", "[[BigInt64Array]]",
235 "object", "Object", "BigInt64Array", "0,0,0", "[[BigUint64Array]]", "object", "Object",
236 "BigUint64Array", "0,0,0" } },
237 { "function0", { "function", "Function", "function function0( { [js code] }",
238 "Cannot get source code of funtion" } },
239 { "generator0", { "function", "Generator", "function* generator0( { [js code] }",
240 "Cannot get source code of funtion" } },
241 { "map0", { "object", "map", "Map", "Map(0)", "[object Map]", "size", "number", "0", "0", "[[Entries]]",
242 "object", "array", "Array", "Array(0)", "" } },
243 { "set0", { "object", "set", "Set", "Set(0)", "[object Set]", "size", "number", "0", "0", "[[Entries]]",
244 "object", "array", "Array", "Array(0)", "" } },
245 { "undefined0", { "undefined" } },
246 { "array0", { "object", "array", "Array", "Array(2)", "Apple,Banana", "0", "string", "Apple", "Apple",
247 "1", "string", "Banana", "Banana", "length", "number", "2", "2" } },
248 { "regexp0", { "object", "regexp", "RegExp", "/^\\d+\\.\\d+$/i", "/^\\d+\\.\\d+$/i", "global", "boolean",
249 "false", "false", "ignoreCase", "boolean", "true", "true", "multiline", "boolean", "false",
250 "false", "dotAll", "boolean", "false", "false", "hasIndices", "boolean", "false", "false",
251 "unicode", "boolean", "false", "false", "sticky", "boolean", "false", "false", "flags",
252 "string", "i", "i", "source", "string", "^\\d+\\.\\d+$", "^\\d+\\.\\d+$", "lastIndex",
253 "number", "0", "0" } },
254 { "uint8array0", { "object", "Object", "Uint8Array(24)",
255 "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",
256 "1", "number", "0", "0", "2", "number", "0", "0", "3", "number", "0", "0", "4",
257 "number", "0", "0", "5", "number", "0", "0", "6", "number", "0", "0", "7",
258 "number", "0", "0", "8", "number", "0", "0", "9", "number", "0", "0", "10",
259 "number", "0", "0", "11", "number", "0", "0", "12", "number", "0", "0", "13",
260 "number", "0", "0", "14", "number", "0", "0", "15", "number", "0", "0", "16",
261 "number", "0", "0", "17", "number", "0", "0", "18", "number", "0", "0", "19",
262 "number", "0", "0", "20", "number", "0", "0", "21", "number", "0", "0", "22",
263 "number", "0", "0", "23", "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", "Uint8ClampedArray", "", "none" } },
330 { "typedarray3", { "object", "Object", "Int16Array(0)", "", "none" } },
331 { "typedarray4", { "object", "Object", "Uint16Array", "", "none" } },
332 { "typedarray5", { "object", "Object", "Int32Array(0)", "", "none" } },
333 { "typedarray6", { "object", "Object", "Uint32Array", "", "none" } },
334 { "typedarray7", { "object", "Object", "Float32Array", "", "none" } },
335 { "typedarray8", { "object", "Object", "Float64Array", "", "none" } },
336 { "typedarray9", { "object", "Object", "BigInt64Array", "", "none" } },
337 { "typedarray10", { "object", "Object", "BigUint64Array", "", "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]",
375 "[[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]", "[[Entries]]", "object", "array",
382 "Array", "Array(2)", "[object Object],[object Object]" } },
383 { "weakMap2", { "object", "weakmap", "Weakmap", "WeakMap(0)", "[object WeakMap]", "[[Entries]]",
384 "object", "array", "Array", "Array(0)", "", "0", "string", "hello", "hello" } },
385 { "weakMap3", { "object", "weakmap", "Weakmap", "WeakMap(1) {Object => 'weakMap0'}", "[object WeakMap]",
386 "[[Entries]]", "object", "array", "Array", "Array(1)", "[object Object]" } },
387 { "weakMap4", { "object", "weakmap", "Weakmap", "WeakMap(2) {Object => 37, Object => 'azerty'}",
388 "[object WeakMap]", "[[Entries]]", "object", "array",
389 "Array", "Array(2)", "[object Object],[object Object]" } },
390 { "weakMap5", { "object", "weakmap", "Weakmap", "WeakMap(1) {Object => undefined}", "[object WeakMap]",
391 "[[Entries]]", "object", "array", "Array", "Array(1)", "[object Object]" } },
392 { "weakSet0", { "object", "weakset", "Weakset", "WeakSet(0)", "[object WeakSet]",
393 "[[Entries]]", "object", "array", "Array", "Array(0)", "" } },
394 { "weakSet1", { "object", "weakset", "Weakset", "WeakSet(1) {Object}", "[object WeakSet]",
395 "[[Entries]]", "object", "array", "Array", "Array(1)", "[object Object]" } },
396 { "weakSet2", { "object", "weakset", "Weakset", "WeakSet(2) {Object, Object}", "[object WeakSet]",
397 "[[Entries]]", "object", "array", "Array", "Array(2)",
398 "[object Object],[object Object]" } },
399 { "Parent", { "function", "Function", "function Parent( { [js code] }",
400 "Cannot get source code of funtion" } },
401 { "class1", { "object", "Object", "customClass", "[object Object]", "_a", "number", "1", "1",
402 "_b", "number", "2", "2", "child", "object", "Object", "Child", "[object Object]", "print",
403 "function", "Function", "function ( { [js code] }", "Cannot get source code of funtion" } },
404 { "parent", { "object", "Object", "Parent", "[object Object]", "name", "string", "parent", "parent",
405 "age", "number", "50", "50" } },
406 { "customClass", { "function", "Function", "function customClass( { [js code] }",
407 "Cannot get source code of funtion" } },
408 { "child", { "object", "Object", "Child", "[object Object]", "name", "string", "child", "child",
409 "age", "number", "15", "15", "idNumber", "string", "1234", "1234" } },
410 { "class2", { "object", "Object", "Object", "[object Object]", "name", "string", "class2", "class2" } },
411 { "Child", { "function", "Function", "function Child( { [js code] }",
412 "Cannot get source code of funtion" } },
413 };
414
415 int32_t index_ {0};
416 const EcmaVM *vm_ {nullptr};
417 RuntimeImpl *runtime_ {nullptr};
418 };
419
420 std::string entryPoint_ = "_GLOBAL::func_main_0";
421 JSPtLocation location_ {nullptr, JSPtLocation::EntityId(0), 0};
422 size_t breakpointCounter_ = 0;
423 };
424
GetJsVariableSecondTest()425 std::unique_ptr<TestEvents> GetJsVariableSecondTest()
426 {
427 return std::make_unique<JsVariableSecondTest>();
428 }
429 } // namespace panda::ecmascript::tooling::test
430
431 #endif // ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_VARIABLE_TEST_H
432