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 #ifndef ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_WATCH_BASIC_TYPE_TEST_H
17 #define ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_WATCH_BASIC_TYPE_TEST_H
18
19 #include "tooling/dynamic/test/client_utils/test_util.h"
20
21 namespace panda::ecmascript::tooling::test {
22 class JsWatchBasicTypeTest : public TestActions {
23 public:
JsWatchBasicTypeTest()24 JsWatchBasicTypeTest()
25 {
26 testAction = {
27 {SocketAction::SEND, "enable"},
28 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
29 {SocketAction::SEND, "runtime-enable"},
30 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
31 {SocketAction::SEND, "run"},
32 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
33 // load watch_variable.js
34 {SocketAction::RECV, "Debugger.scriptParsed", ActionRule::STRING_CONTAIN},
35 // break on start
36 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE,
37 [](auto recv, auto, auto) -> bool {
38 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
39 DebuggerClient debuggerClient(0);
40 debuggerClient.RecvReply(std::move(json));
41 return true;
42 }},
43
44 // set breakpoint
45 {SocketAction::SEND, "b " DEBUGGER_JS_DIR "watch_variable.js 47"},
46 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
47
48 // hit breakpoint after resume first time
49 {SocketAction::SEND, "resume"},
50 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
51 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
52 {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN},
53
54 // watch
55 {SocketAction::SEND, "watch number0"},
56 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE,
57 [this](auto recv, auto, auto) -> bool { return RecvWatchVaribleInfo(recv, "number", "1"); }},
58 {SocketAction::SEND, "watch string0"},
59 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE,
60 [this](auto recv, auto, auto) -> bool {
61 return RecvWatchVaribleInfo(recv, "string", "helloworld");
62 }},
63 {SocketAction::SEND, "watch boolean0"},
64 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE,
65 [this](auto recv, auto, auto) -> bool {
66 return RecvWatchVaribleInfo(recv, "boolean", "false");
67 }},
68 {SocketAction::SEND, "watch undefined0"},
69 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE,
70 [this](auto recv, auto, auto) -> bool { return RecvWatchVaribleInfo(recv, "undefined"); }},
71 {SocketAction::SEND, "watch null0"},
72 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE,
73 [this](auto recv, auto, auto) -> bool { return RecvWatchNullInfo(recv); }},
74 {SocketAction::SEND, "watch symbol0"},
75 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE,
76 [this](auto recv, auto, auto) -> bool {
77 return RecvWatchVaribleInfo(recv, "symbol", "Symbol(symbol0)");
78 }},
79 {SocketAction::SEND, "watch bigint0"},
80 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE,
81 [this](auto recv, auto, auto) -> bool {
82 return RecvWatchVaribleInfo(recv, "bigint", "999n");
83 }},
84
85 {SocketAction::SEND, "resume"},
86 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
87 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
88 {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN},
89
90 // reply success and run
91 {SocketAction::SEND, "success"},
92 {SocketAction::SEND, "resume"},
93 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
94 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
95 };
96 }
97
98 bool RecvWatchVaribleInfo(std::string recv, std::string var_type, std::string var_value = "undefined")
99 {
100 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
101 Result ret;
102 int id = 0;
103 ret = json->GetInt("id", &id);
104 if (ret != Result::SUCCESS) {
105 return false;
106 }
107
108 std::unique_ptr<PtJson> result = nullptr;
109 ret = json->GetObject("result", &result);
110 if (ret != Result::SUCCESS) {
111 return false;
112 }
113
114 std::unique_ptr<PtJson> watchResult = nullptr;
115 ret = result->GetObject("result", &watchResult);
116 if (ret != Result::SUCCESS) {
117 return false;
118 }
119
120 std::string type = "";
121 ret = watchResult->GetString("type", &type);
122 if (ret != Result::SUCCESS || type != var_type) {
123 return false;
124 }
125 if (type == "undefined") {
126 return true;
127 }
128
129 std::string value = "";
130 ret = watchResult->GetString("unserializableValue", &value);
131 if (ret != Result::SUCCESS || value != var_value) {
132 return false;
133 }
134
135 std::string description = "";
136 ret = watchResult->GetString("description", &description);
137 if (ret != Result::SUCCESS || description != var_value) {
138 return false;
139 }
140
141 DebuggerClient debuggerClient(0);
142 debuggerClient.RecvReply(std::move(json));
143 return true;
144 }
145
RecvWatchNullInfo(std::string recv)146 bool RecvWatchNullInfo(std::string recv)
147 {
148 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
149 Result ret;
150 int id = 0;
151 ret = json->GetInt("id", &id);
152 if (ret != Result::SUCCESS) {
153 return false;
154 }
155
156 std::unique_ptr<PtJson> result = nullptr;
157 ret = json->GetObject("result", &result);
158 if (ret != Result::SUCCESS) {
159 return false;
160 }
161
162 std::unique_ptr<PtJson> watchResult = nullptr;
163 ret = result->GetObject("result", &watchResult);
164 if (ret != Result::SUCCESS) {
165 return false;
166 }
167
168 std::string type = "";
169 ret = watchResult->GetString("type", &type);
170 if (ret != Result::SUCCESS || type != "object") {
171 return false;
172 }
173 if (type == "undefined") {
174 return true;
175 }
176
177 std::string subtype = "";
178 ret = watchResult->GetString("subtype", &subtype);
179 if (ret != Result::SUCCESS || subtype != "null") {
180 return false;
181 }
182
183 DebuggerClient debuggerClient(0);
184 debuggerClient.RecvReply(std::move(json));
185 return true;
186 }
187
GetEntryPoint()188 std::pair<std::string, std::string> GetEntryPoint() override
189 {
190 return {pandaFile_, entryPoint_};
191 }
192 ~JsWatchBasicTypeTest() = default;
193
194 private:
195 std::string pandaFile_ = DEBUGGER_ABC_DIR "watch_variable.abc";
196 std::string sourceFile_ = DEBUGGER_JS_DIR "watch_variable.js";
197 std::string entryPoint_ = "watch_variable";
198 };
199
GetJsWatchBasicTypeTest()200 std::unique_ptr<TestActions> GetJsWatchBasicTypeTest()
201 {
202 return std::make_unique<JsWatchBasicTypeTest>();
203 }
204 } // namespace panda::ecmascript::tooling::test
205
206 #endif // ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_WATCH_BASIC_TYPE_TEST_H
207