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_MODULE_TEST_H
17 #define ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_WATCH_MODULE_TEST_H
18
19 #include "tooling/dynamic/test/client_utils/test_util.h"
20 #include "ecmascript/tests/test_helper.h"
21
22 namespace panda::ecmascript::tooling::test {
23 class JsWatchModuleTest : public TestActions {
24 public:
JsWatchModuleTest()25 JsWatchModuleTest()
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 local_export.js
35 {SocketAction::RECV, "Debugger.scriptParsed", ActionRule::STRING_CONTAIN},
36 {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN},
37 {SocketAction::SEND, "resume"},
38 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
39 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
40 // load module_watch.js
41 {SocketAction::RECV, "Debugger.scriptParsed", ActionRule::STRING_CONTAIN},
42 // break on start
43 {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN},
44
45 // set breakpoint
46 {SocketAction::SEND, "b " DEBUGGER_JS_DIR "module_watch.js 26"},
47 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
48
49 // hit breakpoint after resume first time
50 {SocketAction::SEND, "resume"},
51 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
52 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
53 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE,
54 [this](auto recv, auto, auto) -> bool {
55 return RecvHitBreakInfo(recv, 25);
56 }
57 },
58 {SocketAction::SEND, "p o 1"},
59 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE,
60 [this] (auto recv, auto, auto) -> bool {
61 return GetPropertiesInfo(recv);
62 }
63 },
64 // reply success and run
65 {SocketAction::SEND, "success"},
66 {SocketAction::SEND, "resume"},
67 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
68 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
69 };
70 }
GetPropertiesInfo(std::string recv)71 bool GetPropertiesInfo(std::string recv)
72 {
73 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
74
75 std::unique_ptr<PtJson> result;
76 GTEST_LOG_(ERROR) << "JsWatchModuleTestChannel: SendNotification 3:\n" << json->Stringify();
77 int id;
78 Result ret = json->GetInt("id", &id);
79 if (ret != Result::SUCCESS) {
80 return false;
81 }
82
83 ret = json->GetObject("result", &result);
84 if (ret != Result::SUCCESS) {
85 return false;
86 }
87
88 std::unique_ptr<PtJson> innerResult;
89 ret = result->GetArray("result", &innerResult);
90 if (ret != Result::SUCCESS) {
91 return false;
92 }
93 std::unique_ptr<PtJson> value;
94 GTEST_LOG_(ERROR) << "JsWatchModuleTestChannel: object:\n" << innerResult->Get(1)->Stringify();
95 ret = innerResult->Get(1)->GetObject("value", &value);
96 if (ret != Result::SUCCESS) {
97 return false;
98 }
99 std::string type;
100 ret = value->GetString("type", &type);
101 if (ret != Result::SUCCESS) {
102 return false;
103 }
104 GTEST_LOG_(ERROR) << "JsWatchModuleTestChannel: type:\n" << type.c_str();
105 if (type == "undefined") {
106 return false;
107 }
108 RuntimeClient runtimeClient(0);
109 runtimeClient.HandleGetProperties(std::move(json), id);
110 return true;
111 }
RecvHitBreakInfo(std::string recv,int line)112 bool RecvHitBreakInfo(std::string recv, int line)
113 {
114 std::unique_ptr<PtJson> json = PtJson::Parse(recv);
115 Result ret;
116 std::string method = "";
117 ret = json->GetString("method", &method);
118 if (ret != Result::SUCCESS || method != "Debugger.paused") {
119 return false;
120 }
121
122 std::unique_ptr<PtJson> params = nullptr;
123 ret = json->GetObject("params", ¶ms);
124 if (ret != Result::SUCCESS) {
125 return false;
126 }
127
128 std::unique_ptr<PtJson> hitBreakpoints = nullptr;
129 ret = params->GetArray("hitBreakpoints", &hitBreakpoints);
130 if (ret != Result::SUCCESS) {
131 return false;
132 }
133
134 std::string breakpoint = "";
135 breakpoint = hitBreakpoints->Get(0)->GetString();
136 if (ret != Result::SUCCESS || breakpoint.find(sourceFile_) == std::string::npos ||
137 breakpoint.find(std::to_string(line)) == std::string::npos) {
138 return false;
139 }
140 return true;
141 }
142
GetEntryPoint()143 std::pair<std::string, std::string> GetEntryPoint() override
144 {
145 return {pandaFile_, entryPoint_};
146 }
147 ~JsWatchModuleTest() = default;
148
149 private:
150 std::string pandaFile_ = DEBUGGER_ABC_DIR "module_watch.abc";
151 std::string sourceFile_ = DEBUGGER_JS_DIR "module_watch.js";
152 std::string entryPoint_ = "module_watch";
153 };
154
GetJsWatchModuleTest()155 std::unique_ptr<TestActions> GetJsWatchModuleTest()
156 {
157 return std::make_unique<JsWatchModuleTest>();
158 }
159 } // namespace panda::ecmascript::tooling::test
160
161 #endif // ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_WATCH_MODULE_TEST_H
162