1 /*
2 * Copyright (c) 2023 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_TESTCASES_JS_CLOSURE_SCOPE_TEST_H
17 #define ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_CLOSURE_SCOPE_TEST_H
18
19 #include <map>
20 #include "tooling/test/client_utils/test_util.h"
21
22 namespace panda::ecmascript::tooling::test {
23 class JsClosureScopeTest : public TestActions {
24 public:
JsClosureScopeTest()25 JsClosureScopeTest()
26 {
27 testAction = {
28 {SocketAction::SEND, "enable"},
29 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
30 {SocketAction::SEND, "runtime-enable"},
31 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
32 {SocketAction::SEND, "run"},
33 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
34 // load closure_scope.js
35 {SocketAction::RECV, "Debugger.scriptParsed", ActionRule::STRING_CONTAIN},
36 // break on start
37 {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN},
38 // set first breakpoint
39 {SocketAction::SEND, "b " DEBUGGER_JS_DIR "closure_scope.js 30"},
40 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
41 // // set second breakpoint
42 {SocketAction::SEND, "b " DEBUGGER_JS_DIR "closure_scope.js 53"},
43 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
44
45 // hit breakpoint after resume first time
46 {SocketAction::SEND, "resume"},
47 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
48 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
49 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, [] (auto recv, auto, auto) -> bool {
50 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
51 Result ret;
52 std::string method;
53 ret = json->GetString("method", &method);
54 if (ret != Result::SUCCESS || method != "Debugger.paused") {
55 return false;
56 }
57
58 DebuggerClient debuggerClient(0);
59 debuggerClient.PausedReply(std::move(json));
60 return true;
61 }},
62 {SocketAction::SEND, "print"},
63 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, [] (auto recv, auto, auto) -> bool {
64 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
65 int32_t id = 0;
66 Result ret = json->GetInt("id", &id);
67 if (ret != Result::SUCCESS) {
68 return false;
69 }
70 RuntimeClient runtimeClient(0);
71 runtimeClient.HandleGetProperties(std::move(json), id);
72 return true;
73 }},
74 {SocketAction::SEND, "print 2"},
75 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, [] (auto recv, auto, auto) -> bool {
76 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
77 Result ret;
78 int32_t id = 0;
79 ret = json->GetInt("id", &id);
80 if (ret != Result::SUCCESS) {
81 return false;
82 }
83
84 std::unique_ptr<PtJson> result = nullptr;
85 ret = json->GetObject("result", &result);
86 if (ret != Result::SUCCESS) {
87 return false;
88 }
89
90 std::unique_ptr<PtJson> innerResult;
91 ret = result->GetArray("result", &innerResult);
92 if (ret != Result::SUCCESS) {
93 return false;
94 }
95
96 std::string name;
97 ret = innerResult->Get(0)->GetString("name", &name);
98 if (ret != Result::SUCCESS || name != "v3") {
99 return false;
100 }
101
102 std::unique_ptr<PtJson> value;
103 ret = innerResult->Get(0)->GetObject("value", &value);
104 if (ret != Result::SUCCESS) {
105 return false;
106 }
107
108 std::string valueDes;
109 ret = value->GetString("description", &valueDes);
110 if (ret != Result::SUCCESS || valueDes != "4") {
111 return false;
112 }
113 return true;
114 }},
115 {SocketAction::SEND, "print 3"},
116 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, [] (auto recv, auto, auto) -> bool {
117 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
118 Result ret;
119 int32_t id = 0;
120 ret = json->GetInt("id", &id);
121 if (ret != Result::SUCCESS) {
122 return false;
123 }
124
125 std::unique_ptr<PtJson> result = nullptr;
126 ret = json->GetObject("result", &result);
127 if (ret != Result::SUCCESS) {
128 return false;
129 }
130
131 std::unique_ptr<PtJson> innerResult;
132 ret = result->GetArray("result", &innerResult);
133 if (ret != Result::SUCCESS) {
134 return false;
135 }
136
137 std::string name;
138 ret = innerResult->Get(0)->GetString("name", &name);
139 if (ret != Result::SUCCESS || name != "v2_2") {
140 return false;
141 }
142
143 std::unique_ptr<PtJson> value;
144 ret = innerResult->Get(0)->GetObject("value", &value);
145 if (ret != Result::SUCCESS) {
146 return false;
147 }
148
149 std::string valueDes;
150 ret = value->GetString("description", &valueDes);
151 if (ret != Result::SUCCESS || valueDes != "3") {
152 return false;
153 }
154
155 ret = innerResult->Get(1)->GetString("name", &name);
156 if (ret != Result::SUCCESS || name != "v2_1") {
157 return false;
158 }
159
160 ret = innerResult->Get(1)->GetObject("value", &value);
161 if (ret != Result::SUCCESS) {
162 return false;
163 }
164
165 ret = value->GetString("description", &valueDes);
166 if (ret != Result::SUCCESS || valueDes != "2") {
167 return false;
168 }
169 return true;
170 }},
171 {SocketAction::SEND, "print 4"},
172 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, [] (auto recv, auto, auto) -> bool {
173 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
174 Result ret;
175 int32_t id = 0;
176 ret = json->GetInt("id", &id);
177 if (ret != Result::SUCCESS) {
178 return false;
179 }
180
181 std::unique_ptr<PtJson> result = nullptr;
182 ret = json->GetObject("result", &result);
183 if (ret != Result::SUCCESS) {
184 return false;
185 }
186
187 std::unique_ptr<PtJson> innerResult;
188 ret = result->GetArray("result", &innerResult);
189 if (ret != Result::SUCCESS) {
190 return false;
191 }
192
193 std::string name;
194 ret = innerResult->Get(0)->GetString("name", &name);
195 if (ret != Result::SUCCESS || name != "v1") {
196 return false;
197 }
198
199 std::unique_ptr<PtJson> value;
200 ret = innerResult->Get(0)->GetObject("value", &value);
201 if (ret != Result::SUCCESS) {
202 return false;
203 }
204
205 std::string valueDes;
206 ret = value->GetString("description", &valueDes);
207 if (ret != Result::SUCCESS || valueDes != "1") {
208 return false;
209 }
210 return true;
211 }},
212
213 // hit breakpoint after resume second time
214 {SocketAction::SEND, "resume"},
215 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
216 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
217 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, [] (auto recv, auto, auto) -> bool {
218 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
219 Result ret;
220 std::string method;
221 ret = json->GetString("method", &method);
222 if (ret != Result::SUCCESS || method != "Debugger.paused") {
223 return false;
224 }
225 DebuggerClient debuggerClient(0);
226 debuggerClient.PausedReply(std::move(json));
227 return true;
228 }},
229 {SocketAction::SEND, "print"},
230 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, [] (auto recv, auto, auto) -> bool {
231 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
232 int32_t id = 0;
233 Result ret = json->GetInt("id", &id);
234 if (ret != Result::SUCCESS) {
235 return false;
236 }
237 RuntimeClient runtimeClient(0);
238 runtimeClient.HandleGetProperties(std::move(json), id);
239 return true;
240 }},
241 {SocketAction::SEND, "print 2"},
242 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, [] (auto recv, auto, auto) -> bool {
243 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
244 Result ret;
245 int32_t id = 0;
246 ret = json->GetInt("id", &id);
247 if (ret != Result::SUCCESS) {
248 return false;
249 }
250
251 std::unique_ptr<PtJson> result = nullptr;
252 ret = json->GetObject("result", &result);
253 if (ret != Result::SUCCESS) {
254 return false;
255 }
256
257 std::unique_ptr<PtJson> innerResult;
258 ret = result->GetArray("result", &innerResult);
259 if (ret != Result::SUCCESS) {
260 return false;
261 }
262
263 std::string name;
264 ret = innerResult->Get(0)->GetString("name", &name);
265 if (ret != Result::SUCCESS || name != "i") {
266 return false;
267 }
268
269 std::unique_ptr<PtJson> value;
270 ret = innerResult->Get(0)->GetObject("value", &value);
271 if (ret != Result::SUCCESS) {
272 return false;
273 }
274
275 std::string valueDes;
276 ret = value->GetString("description", &valueDes);
277 if (ret != Result::SUCCESS || valueDes != "5") {
278 return false;
279 }
280 return true;
281 }},
282 {SocketAction::SEND, "print 3"},
283 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, [] (auto recv, auto, auto) -> bool {
284 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
285 Result ret;
286 int32_t id = 0;
287 ret = json->GetInt("id", &id);
288 if (ret != Result::SUCCESS) {
289 return false;
290 }
291
292 std::unique_ptr<PtJson> result = nullptr;
293 ret = json->GetObject("result", &result);
294 if (ret != Result::SUCCESS) {
295 return false;
296 }
297
298 std::unique_ptr<PtJson> innerResult;
299 ret = result->GetArray("result", &innerResult);
300 if (ret != Result::SUCCESS) {
301 return false;
302 }
303
304 std::string name;
305 ret = innerResult->Get(0)->GetString("name", &name);
306 if (ret != Result::SUCCESS || name != "a") {
307 return false;
308 }
309
310 std::unique_ptr<PtJson> value;
311 ret = innerResult->Get(0)->GetObject("value", &value);
312 if (ret != Result::SUCCESS) {
313 return false;
314 }
315
316 std::string valueDes;
317 ret = value->GetString("description", &valueDes);
318 if (ret != Result::SUCCESS || valueDes != "10") {
319 return false;
320 }
321 return true;
322 }},
323 // reply success and run
324 {SocketAction::SEND, "success"},
325 {SocketAction::SEND, "resume"},
326 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
327 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
328 };
329 }
330
331 std::pair<std::string, std::string> GetEntryPoint() override
332 {
333 return {pandaFile_, entryPoint_};
334 }
335 ~JsClosureScopeTest() = default;
336
337 private:
338 std::string pandaFile_ = DEBUGGER_ABC_DIR "closure_scope.abc";
339 std::string sourceFile_ = DEBUGGER_JS_DIR "closure_scope.js";
340 std::string entryPoint_ = "_GLOBAL::func_main_0";
341 };
342
GetJsClosureScopeTest()343 std::unique_ptr<TestActions> GetJsClosureScopeTest()
344 {
345 return std::make_unique<JsClosureScopeTest>();
346 }
347 } // namespace panda::ecmascript::tooling::test
348
349 #endif // ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_CLOSURE_SCOPE_TEST_H
350