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_STEPINTO_LOOP_TEST_H 17#define ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_STEPINTO_LOOP_TEST_H 18 19#include "tooling/test/client_utils/test_util.h" 20 21namespace panda::ecmascript::tooling::test { 22class JsStepintoLoopTest : public TestActions { 23public: 24 JsStepintoLoopTest() 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 common_func.js 34 {SocketAction::RECV, "Debugger.scriptParsed", ActionRule::STRING_CONTAIN}, 35 // break on start 36 {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN}, 37 // set first breakpoint 38 {SocketAction::SEND, "b " DEBUGGER_JS_DIR "common_func.js 27"}, 39 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, 40 [](auto recv, auto, auto) -> bool { 41 std::unique_ptr<PtJson> json = PtJson::Parse(recv); 42 DebuggerClient debuggerClient(0); 43 debuggerClient.RecvReply(std::move(json)); 44 return true; 45 }}, 46 47 // hit breakpoint after resume first time 48 {SocketAction::SEND, "resume"}, 49 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 50 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 51 {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN}, 52 53 {SocketAction::SEND, "si"}, 54 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 55 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 56 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 57 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "for_loop", 27); }}, 58 59 {SocketAction::SEND, "si"}, 60 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 61 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 62 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 63 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "for_loop", 28); }}, 64 65 {SocketAction::SEND, "si"}, 66 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 67 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 68 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 69 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "for_loop", 26); }}, 70 71 {SocketAction::SEND, "si"}, 72 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 73 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 74 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 75 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "for_loop", 27); }}, 76 77 {SocketAction::SEND, "si"}, 78 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 79 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 80 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 81 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "for_loop", 28); }}, 82 83 {SocketAction::SEND, "si"}, 84 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 85 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 86 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 87 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "for_loop", 26); }}, 88 89 {SocketAction::SEND, "delete 1"}, 90 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 91 92 {SocketAction::SEND, "b " DEBUGGER_JS_DIR "common_func.js 35"}, 93 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, 94 [](auto recv, auto, auto) -> bool { 95 std::unique_ptr<PtJson> json = PtJson::Parse(recv); 96 DebuggerClient debuggerClient(0); 97 debuggerClient.RecvReply(std::move(json)); 98 return true; 99 }}, 100 {SocketAction::SEND, "resume"}, 101 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 102 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 103 {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN}, 104 105 {SocketAction::SEND, "si"}, 106 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 107 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 108 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 109 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "while_loop", 35); }}, 110 111 {SocketAction::SEND, "si"}, 112 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 113 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 114 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 115 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "while_loop", 36); }}, 116 117 {SocketAction::SEND, "si"}, 118 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 119 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 120 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 121 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "while_loop", 37); }}, 122 {SocketAction::SEND, "si"}, 123 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 124 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 125 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 126 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "while_loop", 38); }}, 127 128 {SocketAction::SEND, "si"}, 129 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 130 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 131 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 132 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "while_loop", 35); }}, 133 {SocketAction::SEND, "si"}, 134 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 135 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 136 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 137 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "while_loop", 36); }}, 138 139 {SocketAction::SEND, "si"}, 140 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 141 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 142 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 143 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "while_loop", 37); }}, 144 {SocketAction::SEND, "si"}, 145 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 146 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 147 {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE, 148 [this](auto recv, auto, auto) -> bool { return RecvStepintoInfo(recv, "while_loop", 38); }}, 149 150 {SocketAction::SEND, "delete 1"}, 151 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 152 {SocketAction::SEND, "resume"}, 153 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 154 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 155 {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN}, 156 157 // reply success and run 158 {SocketAction::SEND, "success"}, 159 {SocketAction::SEND, "resume"}, 160 {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN}, 161 {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess}, 162 }; 163 } 164 165 bool RecvStepintoInfo(std::string recv, std::string funcName, int lineNumber) 166 { 167 std::unique_ptr<PtJson> json = PtJson::Parse(recv); 168 Result ret; 169 std::string method = ""; 170 ret = json->GetString("method", &method); 171 if (ret != Result::SUCCESS || method != "Debugger.paused") { 172 return false; 173 } 174 175 std::unique_ptr<PtJson> params = nullptr; 176 ret = json->GetObject("params", ¶ms); 177 if (ret != Result::SUCCESS) { 178 return false; 179 } 180 181 std::unique_ptr<PtJson> callFrames = nullptr; 182 ret = params->GetArray("callFrames", &callFrames); 183 if (ret != Result::SUCCESS) { 184 return false; 185 } 186 187 std::string functionName = ""; 188 ret = callFrames->Get(0)->GetString("functionName", &functionName); 189 if (ret != Result::SUCCESS || functionName != funcName) { 190 return false; 191 } 192 193 std::unique_ptr<PtJson> location = nullptr; 194 ret = callFrames->Get(0)->GetObject("location", &location); 195 if (ret != Result::SUCCESS) { 196 return false; 197 } 198 199 int lineNum = 0; 200 ret = location->GetInt("lineNumber", &lineNum); 201 if (ret != Result::SUCCESS || lineNum != lineNumber) { 202 return false; 203 } 204 205 DebuggerClient debuggerClient(0); 206 debuggerClient.PausedReply(std::move(json)); 207 return true; 208 } 209 210 std::pair<std::string, std::string> GetEntryPoint() override 211 { 212 return {pandaFile_, entryPoint_}; 213 } 214 ~JsStepintoLoopTest() = default; 215 216private: 217 std::string pandaFile_ = DEBUGGER_ABC_DIR "common_func.abc"; 218 std::string sourceFile_ = DEBUGGER_JS_DIR "common_func.js"; 219 std::string entryPoint_ = "_GLOBAL::func_main_0"; 220}; 221 222std::unique_ptr<TestActions> GetJsStepintoLoopTest() 223{ 224 return std::make_unique<JsStepintoLoopTest>(); 225} 226} // namespace panda::ecmascript::tooling::test 227 228#endif // ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_STEPINTO_LOOP_TEST_H 229