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 21namespace panda::ecmascript::tooling::test { 22class JsContainerTest : public TestActions { 23public: 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 154 std::pair<std::string, std::string> GetEntryPoint() override 155 { 156 return {pandaFile_, entryPoint_}; 157 } 158 ~JsContainerTest() = default; 159 160private: 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 264std::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