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_CONTAINER_TEST_H
17 #define ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_CONTAINER_TEST_H
18
19 #include "tooling/test/client_utils/test_util.h"
20
21 namespace panda::ecmascript::tooling::test {
22 class JsContainerTest : public TestActions {
23 public:
JsContainerTest()24 JsContainerTest()
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 sample.js
34 {SocketAction::RECV, "Debugger.scriptParsed", ActionRule::STRING_CONTAIN},
35 // break on start
36 {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN},
37 // set breakpoint
38 {SocketAction::SEND, "b " DEBUGGER_JS_DIR "container.js 368"},
39 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
40 // hit breakpoint after resume first time
41 {SocketAction::SEND, "resume"},
42 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
43 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
44 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, [this] (auto recv, auto, auto) -> bool {
45 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
46 Result ret;
47 std::string method;
48 ret = json->GetString("method", &method);
49 if (ret != Result::SUCCESS || method != "Debugger.paused") {
50 return false;
51 }
52
53 std::unique_ptr<PtJson> params = nullptr;
54 ret = json->GetObject("params", ¶ms);
55 if (ret != Result::SUCCESS) {
56 return false;
57 }
58
59 std::unique_ptr<PtJson> hitBreakpoints = nullptr;
60 ret = params->GetArray("hitBreakpoints", &hitBreakpoints);
61 if (ret != Result::SUCCESS) {
62 return false;
63 }
64
65 std::string breakpoint;
66 breakpoint = hitBreakpoints->Get(0)->GetString();
67 if (ret != Result::SUCCESS || breakpoint.find(sourceFile_) == std::string::npos ||
68 breakpoint.find("367") == std::string::npos) {
69 return false;
70 }
71
72 DebuggerClient debuggerClient(0);
73 debuggerClient.PausedReply(std::move(json));
74 return true;
75 }},
76
77 {SocketAction::SEND, "print"},
78 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, [this] (auto recv, auto, auto) -> bool {
79 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
80 Result ret;
81 int32_t id = 0;
82 ret = json->GetInt("id", &id);
83 if (ret != Result::SUCCESS) {
84 return false;
85 }
86
87 std::unique_ptr<PtJson> result = nullptr;
88 ret = json->GetObject("result", &result);
89 if (ret != Result::SUCCESS) {
90 return false;
91 }
92
93 std::unique_ptr<PtJson> innerResult;
94 ret = result->GetArray("result", &innerResult);
95 if (ret != Result::SUCCESS) {
96 return false;
97 }
98
99 std::string name;
100 std::unique_ptr<PtJson> value;
101 std::string type;
102 std::string className;
103 std::string unserializableValue;
104 std::string description;
105 for (int32_t i = 0; i < innerResult->GetSize(); i++) {
106 std::vector<std::string> infos;
107 ret = innerResult->Get(i)->GetString("name", &name);
108 if (ret != Result::SUCCESS) {
109 return false;
110 }
111
112 ret = innerResult->Get(i)->GetObject("value", &value);
113 if (ret != Result::SUCCESS) {
114 return false;
115 }
116
117 ret = value->GetString("type", &type);
118 if (ret == Result::SUCCESS) {
119 infos.push_back(type);
120 }
121
122 ret = value->GetString("className", &className);
123 if (ret == Result::SUCCESS) {
124 infos.push_back(className);
125 }
126
127 ret = value->GetString("unserializableValue", &unserializableValue);
128 if (ret == Result::SUCCESS) {
129 infos.push_back(unserializableValue);
130 }
131
132 ret = value->GetString("description", &description);
133 if (ret == Result::SUCCESS) {
134 infos.push_back(description);
135 }
136
137 for (uint32_t j = 0; j < infos.size(); j++) {
138 if (infos[j] != this->variableMap_.at(name)[j]) {
139 return false;
140 }
141 }
142 }
143 return true;
144 }},
145
146 // reply success and run
147 {SocketAction::SEND, "success"},
148 {SocketAction::SEND, "resume"},
149 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
150 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
151 };
152 }
153
GetEntryPoint()154 std::pair<std::string, std::string> GetEntryPoint() override
155 {
156 return {pandaFile_, entryPoint_};
157 }
158 ~JsContainerTest() = default;
159
160 private:
161 std::string pandaFile_ = DEBUGGER_ABC_DIR "container.abc";
162 std::string sourceFile_ = DEBUGGER_JS_DIR "container.js";
163 std::string entryPoint_ = "_GLOBAL::func_main_0";
164
165 const std::map<std::string, std::vector<std::string>> variableMap_ = {
166 { "nop", { "undefined" } },
167 { "foo", { "function", "Function", "function foo( { [js code] }",
168 "function foo( { [js code] }" } },
169 { "ArrayList", { "function", "Function", "function ArrayList( { [native code] }",
170 "function ArrayList( { [native code] }" } },
171 { "Deque", { "function", "Function", "function Deque( { [native code] }",
172 "function Deque( { [native code] }" } },
173 { "HashMap", { "function", "Function", "function HashMap( { [native code] }",
174 "function HashMap( { [native code] }" } },
175 { "HashSet", { "function", "Function", "function HashSet( { [native code] }",
176 "function HashSet( { [native code] }" } },
177 { "LightWeightMap", { "function", "Function", "function LightWeightMap( { [native code] }",
178 "function LightWeightMap( { [native code] }" } },
179 { "LightWeightSet", { "function", "Function", "function LightWeightSet( { [native code] }",
180 "function LightWeightSet( { [native code] }" } },
181 { "LinkedList", { "function", "Function", "function LinkedList( { [native code] }",
182 "function LinkedList( { [native code] }" } },
183 { "List", { "function", "Function", "function List( { [native code] }",
184 "function List( { [native code] }" } },
185 { "PlainArray", { "function", "Function", "function PlainArray( { [native code] }",
186 "function PlainArray( { [native code] }" } },
187 { "Queue", { "function", "Function", "function Queue( { [native code] }",
188 "function Queue( { [native code] }" } },
189 { "Stack", { "function", "Function", "function Stack( { [native code] }",
190 "function Stack( { [native code] }" } },
191 { "TreeMap", { "function", "Function", "function TreeMap( { [native code] }",
192 "function TreeMap( { [native code] }" } },
193 { "TreeSet", { "function", "Function", "function TreeSet( { [native code] }",
194 "function TreeSet( { [native code] }" } },
195 { "Vector", { "function", "Function", "function Vector( { [native code] }",
196 "function Vector( { [native code] }" } },
197 { "arrayList", { "object", "Object", "ArrayList", "ArrayList" } },
198 { "deque", { "object", "Object", "Deque", "Deque" } },
199 { "hashMap", { "object", "Object", "HashMap", "HashMap" } },
200 { "hashSet", { "object", "Object", "HashSet", "HashSet" } },
201 { "lightWeightMap", { "object", "Object", "LightWeightMap", "LightWeightMap" } },
202 { "lightWeightSet", { "object", "Object", "LightWeightSet", "LightWeightSet" } },
203 { "linkedList", { "object", "Object", "LinkedList", "LinkedList" } },
204 { "list", { "object", "Object", "List", "List" } },
205 { "plainArray", { "object", "Object", "PlainArray", "PlainArray" } },
206 { "queue", { "object", "Object", "Queue", "Queue" } },
207 { "stack", { "object", "Object", "Stack", "Stack" } },
208 { "treeMap", { "object", "Object", "TreeMap", "TreeMap" } },
209 { "treeSet", { "object", "Object", "TreeSet", "TreeSet" } },
210 { "vector", { "object", "Object", "Vector", "Vector" } },
211 { "boolean0", { "boolean", "false", "false" } },
212 { "boolean1", { "boolean", "true", "true" } },
213 { "boolean2", { "boolean", "false", "false" } },
214 { "boolean3", { "boolean", "true", "true" } },
215 { "number0", { "number", "1888", "1888" } },
216 { "number1", { "number", "177", "177" } },
217 { "number2", { "number", "-1", "-1" } },
218 { "number3", { "number", "-1", "-1" } },
219 { "number4", { "number", "222", "222" } },
220 { "number5", { "number", "-2", "-2" } },
221 { "number6", { "number", "566", "566" } },
222 { "number7", { "number", "588", "588" } },
223 { "number8", { "number", "588", "588" } },
224 { "number9", { "number", "0", "0" } },
225 { "number10", { "number", "-1", "-1" } },
226 { "number11", { "number", "88", "88" } },
227 { "number12", { "number", "18", "18" } },
228 { "number13", { "number", "322", "322" } },
229 { "number14", { "number", "8", "8" } },
230 { "number15", { "number", "4", "4" } },
231 { "number16", { "number", "8", "8" } },
232 { "number17", { "number", "5", "5" } },
233 { "number18", { "number", "188", "188" } },
234 { "number19", { "number", "8", "8" } },
235 { "number20", { "number", "388", "388" } },
236 { "number21", { "number", "0", "0" } },
237 { "number22", { "number", "5", "5" } },
238 { "number23", { "number", "18", "18" } },
239 { "number24", { "number", "1388", "1388" } },
240 { "number25", { "number", "6", "6" } },
241 { "number26", { "number", "0", "0" } },
242 { "number27", { "number", "857", "857" } },
243 { "string0", { "string", "two", "two" } },
244 { "string1", { "string", "change", "change" } },
245 { "string2", { "string", "three", "three" } },
246 { "string3", { "string", "array", "array" } },
247 { "string4", { "string", "male", "male" } },
248 { "string5", { "string", "one", "one" } },
249 { "sendableArray", { "object", "Object", "SendableArray [Sendable]", "SendableArray [Sendable]" } },
250 { "sendableArray0", { "number", "1", "1" } },
251 { "sendableArray1", { "number", "2", "2" } },
252 { "sendableArraySize", { "number", "2", "2" } },
253 { "sendableMap", { "object", "Object", "SendableMap [Sendable]", "SendableMap [Sendable]" } },
254 { "sendableMap0", { "number", "1", "1" } },
255 { "sendableMap1", { "number", "2", "2" } },
256 { "sendableMapSize", { "number", "2", "2" } },
257 { "sendableSet", { "object", "Object", "SendableSet [Sendable]", "SendableSet [Sendable]" } },
258 { "sendableSet0", { "boolean", "true", "true" } },
259 { "sendableSet1", { "boolean", "true", "true" } },
260 { "sendableSetSize", { "number", "2", "2" } },
261 };
262 };
263
GetJsContainerTest()264 std::unique_ptr<TestActions> GetJsContainerTest()
265 {
266 return std::make_unique<JsContainerTest>();
267 }
268 } // namespace panda::ecmascript::tooling::test
269
270 #endif // ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_CONTAINER_TEST_H
271