• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023-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 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
18 
19 #include "common.h"
20 #include "connection/server.h"
21 #include "types/location.h"
22 #include "inspector_server.h"
23 #include "utils/json_builder.h"
24 #include "json_object_matcher.h"
25 #include "runtime.h"
26 #include "assembly-emitter.h"
27 #include "assembly-parser.h"
28 
29 // NOLINTBEGIN
30 
31 using namespace std::placeholders;
32 
33 namespace ark::tooling::inspector::test {
34 
35 class TestServer : public Server {
36 public:
OnValidate(std::function<void ()> && handler)37     void OnValidate([[maybe_unused]] std::function<void()> &&handler) override {};
OnOpen(std::function<void ()> && handler)38     void OnOpen([[maybe_unused]] std::function<void()> &&handler) override {};
OnFail(std::function<void ()> && handler)39     void OnFail([[maybe_unused]] std::function<void()> &&handler) override {};
40 
Call(const std::string & session,const char * method_call,std::function<void (JsonObjectBuilder &)> && parameters)41     void Call(const std::string &session, const char *method_call,
42               std::function<void(JsonObjectBuilder &)> &&parameters) override
43     {
44         std::string tmp(method_call);
45         CallMock(session, tmp, std::move(parameters));
46     }
47 
OnCall(const char * method_call,std::function<void (const std::string &,JsonObjectBuilder &,const JsonObject &)> && handler)48     void OnCall(const char *method_call,
49                 std::function<void(const std::string &, JsonObjectBuilder &, const JsonObject &)> &&handler) override
50     {
51         std::string tmp(method_call);
52         OnCallMock(tmp, std::move(handler));
53     }
54 
55     MOCK_METHOD(void, CallMock,
56                 (const std::string &session, const std::string &method_call,
57                  std::function<void(JsonObjectBuilder &)> &&parameters));
58 
59     MOCK_METHOD(void, OnCallMock,
60                 (const std::string &method_call,
61                  std::function<void(const std::string &, JsonObjectBuilder &, const JsonObject &)> &&handler));
62 
RunOne()63     bool RunOne() override
64     {
65         return true;
66     };
67 };
68 
69 static PtThread g_mthread = PtThread(PtThread::NONE);
70 static const std::string g_sessionId;
71 static const std::string g_sourceFile = "source";
72 static bool g_handlerCalled = false;
73 
74 class ServerTest : public testing::Test {
75 public:
SetUp()76     void SetUp() override
77     {
78         RuntimeOptions options;
79         options.SetShouldInitializeIntrinsics(false);
80         options.SetShouldLoadBootPandaFiles(false);
81         Runtime::Create(options);
82         g_mthread = PtThread(ManagedThread::GetCurrent());
83         g_handlerCalled = false;
84     }
TearDown()85     void TearDown() override
86     {
87         Runtime::Destroy();
88     }
89     TestServer server;
90     InspectorServer inspectorServer {server};
91 };
92 
TEST_F(ServerTest,CallDebuggerResumed)93 TEST_F(ServerTest, CallDebuggerResumed)
94 {
95     inspectorServer.CallTargetAttachedToTarget(g_mthread);
96     EXPECT_CALL(server, CallMock(g_sessionId, "Debugger.resumed", testing::_)).Times(1);
97 
98     inspectorServer.CallDebuggerResumed(g_mthread);
99 }
100 
TEST_F(ServerTest,CallDebuggerScriptParsed)101 TEST_F(ServerTest, CallDebuggerScriptParsed)
102 {
103     inspectorServer.CallTargetAttachedToTarget(g_mthread);
104 
105     size_t scriptId = 4;
106     EXPECT_CALL(server, CallMock(g_sessionId, "Debugger.scriptParsed", testing::_))
107         .WillOnce([&](testing::Unused, testing::Unused, auto s) {
108             ASSERT_THAT(ToObject(std::move(s)),
109                         JsonProperties(JsonProperty<JsonObject::NumT> {"executionContextId", g_mthread.GetId()},
110                                        JsonProperty<JsonObject::StringT> {"scriptId", std::to_string(scriptId)},
111                                        JsonProperty<JsonObject::NumT> {"startLine", 0},
112                                        JsonProperty<JsonObject::NumT> {"startColumn", 0},
113                                        JsonProperty<JsonObject::NumT> {"endLine", std::numeric_limits<int>::max()},
114                                        JsonProperty<JsonObject::NumT> {"endColumn", std::numeric_limits<int>::max()},
115                                        JsonProperty<JsonObject::StringT> {"hash", ""},
116                                        JsonProperty<JsonObject::StringT> {"url", g_sourceFile.c_str()}));
117         });
118     inspectorServer.CallDebuggerScriptParsed(g_mthread, ScriptId(scriptId), g_sourceFile);
119 }
120 
TEST_F(ServerTest,DebuggerEnable)121 TEST_F(ServerTest, DebuggerEnable)
122 {
123     TestServer server1;
124     EXPECT_CALL(server1, OnCallMock("Debugger.enable", testing::_)).WillOnce([&](testing::Unused, auto handler) {
125         JsonObjectBuilder res;
126         JsonObject empty;
127         handler(g_sessionId, res, empty);
128         ASSERT_THAT(JsonObject(std::move(res).Build()),
129                     JsonProperties(JsonProperty<JsonObject::StringT> {"debuggerId", "debugger"}));
130     });
131     InspectorServer inspector_server1(server1);
132 }
133 
__anond968ae700302(auto unused, auto handler) 134 static auto g_simpleHandler = []([[maybe_unused]] auto unused, auto handler) {
135     JsonObjectBuilder res;
136     JsonObject empty;
137     handler(g_sessionId, res, empty);
138     ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
139     ASSERT_TRUE(g_handlerCalled);
140 };
141 
TEST_F(ServerTest,OnCallDebuggerPause)142 TEST_F(ServerTest, OnCallDebuggerPause)
143 {
144     inspectorServer.CallTargetAttachedToTarget(g_mthread);
145 
146     EXPECT_CALL(server, OnCallMock("Debugger.pause", testing::_)).WillOnce(g_simpleHandler);
147     inspectorServer.OnCallDebuggerPause([](PtThread thread) {
148         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
149         g_handlerCalled = true;
150     });
151 }
152 
TEST_F(ServerTest,OnCallDebuggerRemoveBreakpoint)153 TEST_F(ServerTest, OnCallDebuggerRemoveBreakpoint)
154 {
155     size_t break_id = 14;
156 
157     inspectorServer.CallTargetAttachedToTarget(g_mthread);
158 
159     EXPECT_CALL(server, OnCallMock("Debugger.removeBreakpoint", testing::_))
160         .WillOnce([&](testing::Unused, auto handler) {
161             JsonObjectBuilder res;
162             JsonObject empty;
163             handler(g_sessionId, res, empty);
164             ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
165             ASSERT_FALSE(g_handlerCalled);
166         });
167 
168     auto breaks = [break_id](PtThread thread, BreakpointId bid) {
169         ASSERT_EQ(bid, BreakpointId(break_id));
170         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
171         g_handlerCalled = true;
172     };
173     inspectorServer.OnCallDebuggerRemoveBreakpoint(std::move(breaks));
174 
175     EXPECT_CALL(server, OnCallMock("Debugger.removeBreakpoint", testing::_))
176         .WillOnce([&](testing::Unused, auto handler) {
177             JsonObjectBuilder res;
178             JsonObjectBuilder params;
179             params.AddProperty("breakpointId", std::to_string(break_id));
180             handler(g_sessionId, res, JsonObject(std::move(params).Build()));
181             ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
182             ASSERT_TRUE(g_handlerCalled);
183         });
184 
185     inspectorServer.OnCallDebuggerRemoveBreakpoint(std::move(breaks));
186 }
187 
TEST_F(ServerTest,OnCallDebuggerRestartFrame)188 TEST_F(ServerTest, OnCallDebuggerRestartFrame)
189 {
190     size_t fid = 5;
191 
192     inspectorServer.CallTargetAttachedToTarget(g_mthread);
193 
194     EXPECT_CALL(server, OnCallMock("Debugger.restartFrame", testing::_)).WillOnce([&](testing::Unused, auto handler) {
195         std::vector<testing::Matcher<JsonObject::JsonObjPointer>> callFrames;
196         JsonObjectBuilder res;
197         JsonObjectBuilder params;
198         handler(g_sessionId, res, JsonObject(std::move(params).Build()));
199         ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
200         ASSERT_FALSE(g_handlerCalled);
201     });
202 
203     inspectorServer.OnCallDebuggerRestartFrame([&](auto, auto) { g_handlerCalled = true; });
204 
205     EXPECT_CALL(server, OnCallMock("Debugger.restartFrame", testing::_)).WillOnce([&](testing::Unused, auto handler) {
206         std::vector<testing::Matcher<JsonObject::JsonObjPointer>> callFrames;
207         JsonObjectBuilder res;
208         JsonObjectBuilder params;
209         params.AddProperty("callFrameId", std::to_string(fid));
210         handler(g_sessionId, res, JsonObject(std::move(params).Build()));
211         ASSERT_THAT(JsonObject(std::move(res).Build()),
212                     JsonProperties(JsonProperty<JsonObject::ArrayT> {"callFrames", JsonElementsAreArray(callFrames)}));
213         ASSERT_TRUE(g_handlerCalled);
214     });
215 
216     inspectorServer.OnCallDebuggerRestartFrame([&](PtThread thread, FrameId id) {
217         ASSERT_EQ(id, FrameId(fid));
218         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
219         g_handlerCalled = true;
220     });
221 }
222 
TEST_F(ServerTest,OnCallDebuggerResume)223 TEST_F(ServerTest, OnCallDebuggerResume)
224 {
225     inspectorServer.CallTargetAttachedToTarget(g_mthread);
226 
227     EXPECT_CALL(server, OnCallMock("Debugger.resume", testing::_)).WillOnce(g_simpleHandler);
228     inspectorServer.OnCallDebuggerResume([](PtThread thread) {
229         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
230         g_handlerCalled = true;
231     });
232 }
233 
CreatePossibleBreakpointsRequest(ScriptId startScriptId,size_t start,ScriptId endScriptId,size_t end,bool restrictToFunction)234 static JsonObject CreatePossibleBreakpointsRequest(ScriptId startScriptId, size_t start, ScriptId endScriptId,
235                                                    size_t end, bool restrictToFunction)
236 {
237     JsonObjectBuilder params;
238     params.AddProperty("start", Location(startScriptId, start).ToJson());
239     params.AddProperty("end", Location(endScriptId, end).ToJson());
240     params.AddProperty("restrictToFunction", restrictToFunction);
241     return JsonObject(std::move(params).Build());
242 }
243 
244 static auto g_getPossibleBreakpointsHandler = [](ScriptId scriptId, size_t start, size_t end, bool restrictToFunction,
__anond968ae700d02(ScriptId scriptId, size_t start, size_t end, bool restrictToFunction, testing::Unused, auto handler) 245                                                  testing::Unused, auto handler) {
246     JsonObjectBuilder res;
247     handler(g_sessionId, res, CreatePossibleBreakpointsRequest(scriptId, start, scriptId, end, restrictToFunction));
248     std::vector<testing::Matcher<JsonObject::JsonObjPointer>> locations;
249     for (auto i = start; i < end; i++) {
250         locations.push_back(
251             testing::Pointee(JsonProperties(JsonProperty<JsonObject::StringT> {"scriptId", std::to_string(scriptId)},
252                                             JsonProperty<JsonObject::NumT> {"lineNumber", i})));
253     }
254     ASSERT_THAT(JsonObject(std::move(res).Build()),
255                 JsonProperties(JsonProperty<JsonObject::ArrayT> {"locations", JsonElementsAreArray(locations)}));
256 };
257 
DefaultFrameEnumerator(const InspectorServer::FrameInfoHandler & handler)258 static void DefaultFrameEnumerator(const InspectorServer::FrameInfoHandler &handler)
259 {
260     std::optional<RemoteObject> objThis;
261     auto scope_chain = std::vector {Scope(Scope::Type::LOCAL, RemoteObject::Number(72))};
262     handler(FrameId(0), std::to_string(0), g_sourceFile, 0, scope_chain, objThis);
263 }
264 
TEST_F(ServerTest,OnCallDebuggerGetPossibleBreakpoints)265 TEST_F(ServerTest, OnCallDebuggerGetPossibleBreakpoints)
266 {
267     auto scriptId = 0;
268     size_t start = 5;
269     size_t end = 5;
270 
271     inspectorServer.CallTargetAttachedToTarget(g_mthread);
272     inspectorServer.CallDebuggerPaused(g_mthread, {}, {}, DefaultFrameEnumerator);
273 
274     EXPECT_CALL(server, OnCallMock("Debugger.getPossibleBreakpoints", testing::_))
275         .WillOnce(std::bind(g_getPossibleBreakpointsHandler, scriptId, start, end,  // NOLINT(modernize-avoid-bind)
276                             true, _1, _2));
277     auto getLinesTrue = [](std::string_view source, size_t startLine, size_t endLine, bool restrictToFunction) {
278         std::set<size_t> result;
279         if ((source == g_sourceFile) && restrictToFunction) {
280             for (auto i = startLine; i < endLine; i++) {
281                 result.insert(i);
282             }
283         }
284         return result;
285     };
286     inspectorServer.OnCallDebuggerGetPossibleBreakpoints(getLinesTrue);
287 
288     EXPECT_CALL(server, OnCallMock("Debugger.getPossibleBreakpoints", testing::_))
289         .WillOnce(std::bind(g_getPossibleBreakpointsHandler, scriptId, start, end,  // NOLINT(modernize-avoid-bind)
290                             false, _1, _2));
291     auto getLinesFalse = [](std::string_view source, size_t startLine, size_t endLine, bool restrictToFunction) {
292         std::set<size_t> result;
293         if ((source == g_sourceFile) && !restrictToFunction) {
294             for (auto i = startLine; i < endLine; i++) {
295                 result.insert(i);
296             }
297         }
298         return result;
299     };
300     inspectorServer.OnCallDebuggerGetPossibleBreakpoints(getLinesFalse);
301 
302     EXPECT_CALL(server, OnCallMock("Debugger.getPossibleBreakpoints", testing::_))
303         .WillOnce([&](testing::Unused, auto handler) {
304             JsonObjectBuilder res;
305             handler(g_sessionId, res, CreatePossibleBreakpointsRequest(scriptId, start, scriptId + 1, end, false));
306             std::vector<testing::Matcher<JsonObject::JsonObjPointer>> locations;
307             ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
308         });
309     inspectorServer.OnCallDebuggerGetPossibleBreakpoints(getLinesFalse);
310 }
311 
TEST_F(ServerTest,OnCallDebuggerGetScriptSource)312 TEST_F(ServerTest, OnCallDebuggerGetScriptSource)
313 {
314     auto scriptId = 0;
315 
316     EXPECT_CALL(server, CallMock(g_sessionId, "Debugger.paused", testing::_))
317         .WillOnce([&](testing::Unused, testing::Unused, auto s) { ToObject(std::move(s)); });
318     EXPECT_CALL(server, CallMock(g_sessionId, "Debugger.scriptParsed", testing::_)).Times(1);
319 
320     inspectorServer.CallTargetAttachedToTarget(g_mthread);
321     inspectorServer.CallDebuggerPaused(g_mthread, {}, {}, DefaultFrameEnumerator);
322 
323     EXPECT_CALL(server, OnCallMock("Debugger.getScriptSource", testing::_))
324         .WillOnce([&](testing::Unused, auto handler) {
325             JsonObjectBuilder res;
326             JsonObjectBuilder params;
327             params.AddProperty("scriptId", std::to_string(scriptId));
328             handler(g_sessionId, res, JsonObject(std::move(params).Build()));
329             ASSERT_THAT(JsonObject(std::move(res).Build()),
330                         JsonProperties(JsonProperty<JsonObject::StringT> {"scriptSource", g_sourceFile}));
331         });
332     inspectorServer.OnCallDebuggerGetScriptSource([](auto source) {
333         std::string s(source);
334         return s;
335     });
336 
337     EXPECT_CALL(server, OnCallMock("Debugger.getScriptSource", testing::_))
338         .WillOnce([&](testing::Unused, auto handler) {
339             JsonObjectBuilder res;
340             JsonObject empty;
341             handler(g_sessionId, res, empty);
342             ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
343         });
344     inspectorServer.OnCallDebuggerGetScriptSource([](auto) { return "a"; });
345 }
346 
TEST_F(ServerTest,OnCallDebuggerStepOut)347 TEST_F(ServerTest, OnCallDebuggerStepOut)
348 {
349     inspectorServer.CallTargetAttachedToTarget(g_mthread);
350 
351     EXPECT_CALL(server, OnCallMock("Debugger.stepOut", testing::_)).WillOnce(g_simpleHandler);
352 
353     inspectorServer.OnCallDebuggerStepOut([](PtThread thread) {
354         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
355         g_handlerCalled = true;
356     });
357 }
358 
TEST_F(ServerTest,OnCallDebuggerStepInto)359 TEST_F(ServerTest, OnCallDebuggerStepInto)
360 {
361     inspectorServer.CallTargetAttachedToTarget(g_mthread);
362 
363     EXPECT_CALL(server, OnCallMock("Debugger.stepInto", testing::_)).WillOnce(g_simpleHandler);
364 
365     inspectorServer.OnCallDebuggerStepInto([](PtThread thread) {
366         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
367         g_handlerCalled = true;
368     });
369 }
370 
TEST_F(ServerTest,OnCallDebuggerStepOver)371 TEST_F(ServerTest, OnCallDebuggerStepOver)
372 {
373     inspectorServer.CallTargetAttachedToTarget(g_mthread);
374 
375     EXPECT_CALL(server, OnCallMock("Debugger.stepOver", testing::_)).WillOnce(g_simpleHandler);
376 
377     inspectorServer.OnCallDebuggerStepOver([](PtThread thread) {
378         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
379         g_handlerCalled = true;
380     });
381 }
382 
handlerForSetBreak(PtThread thread,const std::function<bool (std::string_view)> & comp,size_t line,std::set<std::string_view> & sources)383 std::optional<BreakpointId> handlerForSetBreak([[maybe_unused]] PtThread thread,
384                                                [[maybe_unused]] const std::function<bool(std::string_view)> &comp,
385                                                size_t line, [[maybe_unused]] std::set<std::string_view> &sources)
386 {
387     sources.insert("source");
388     return BreakpointId(line);
389 }
390 
handlerForSetBreakEmpty(PtThread thread,const std::function<bool (std::string_view)> & comp,size_t line,std::set<std::string_view> & sources)391 std::optional<BreakpointId> handlerForSetBreakEmpty([[maybe_unused]] PtThread thread,
392                                                     [[maybe_unused]] const std::function<bool(std::string_view)> &comp,
393                                                     [[maybe_unused]] size_t line,
394                                                     [[maybe_unused]] std::set<std::string_view> &sources)
395 {
396     sources.insert("source");
397     return {};
398 }
399 
TEST_F(ServerTest,OnCallDebuggerSetBreakpoint)400 TEST_F(ServerTest, OnCallDebuggerSetBreakpoint)
401 {
402     auto scriptId = 0;
403     size_t start = 5;
404 
405     inspectorServer.CallTargetAttachedToTarget(g_mthread);
406     inspectorServer.CallDebuggerPaused(g_mthread, {}, {}, DefaultFrameEnumerator);
407 
408     EXPECT_CALL(server, OnCallMock("Debugger.setBreakpoint", testing::_)).WillOnce([&](testing::Unused, auto handler) {
409         JsonObjectBuilder res;
410         JsonObjectBuilder params;
411         params.AddProperty("location", Location(scriptId, start).ToJson());
412         handler(g_sessionId, res, JsonObject(std::move(params).Build()));
413         ASSERT_THAT(JsonObject(std::move(res).Build()),
414                     JsonProperties(JsonProperty<JsonObject::StringT> {"breakpointId", std::to_string(start)},
415                                    JsonProperty<JsonObject::JsonObjPointer> {
416                                        "actualLocation",
417                                        testing::Pointee(JsonProperties(
418                                            JsonProperty<JsonObject::StringT> {"scriptId", std::to_string(scriptId)},
419                                            JsonProperty<JsonObject::NumT> {"lineNumber", start - 1}))}));
420     });
421 
422     inspectorServer.OnCallDebuggerSetBreakpoint(handlerForSetBreak);
423 
424     EXPECT_CALL(server, OnCallMock("Debugger.setBreakpoint", testing::_)).WillOnce([&](testing::Unused, auto handler) {
425         JsonObjectBuilder res;
426         JsonObject empty;
427         handler(g_sessionId, res, empty);
428         ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
429     });
430 
431     inspectorServer.OnCallDebuggerSetBreakpoint(handlerForSetBreak);
432 
433     EXPECT_CALL(server, OnCallMock("Debugger.setBreakpoint", testing::_)).WillOnce([&](testing::Unused, auto handler) {
434         JsonObjectBuilder res;
435         JsonObjectBuilder params;
436         params.AddProperty("location", Location(scriptId, start).ToJson());
437         handler(g_sessionId, res, JsonObject(std::move(params).Build()));
438         ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
439     });
440 
441     inspectorServer.OnCallDebuggerSetBreakpoint(handlerForSetBreakEmpty);
442 }
443 
TEST_F(ServerTest,OnCallDebuggerSetBreakpointByUrl)444 TEST_F(ServerTest, OnCallDebuggerSetBreakpointByUrl)
445 {
446     auto scriptId = 0;
447     size_t start = 5;
448 
449     inspectorServer.CallTargetAttachedToTarget(g_mthread);
450 
451     EXPECT_CALL(server, OnCallMock("Debugger.setBreakpointByUrl", testing::_))
452         .WillOnce([&](testing::Unused, auto handler) {
453             JsonObjectBuilder res;
454             JsonObjectBuilder params;
455             params.AddProperty("lineNumber", start);
456             handler(g_sessionId, res, JsonObject(std::move(params).Build()));
457             ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
458         });
459 
460     inspectorServer.OnCallDebuggerSetBreakpointByUrl(handlerForSetBreak);
461 
462     EXPECT_CALL(server, OnCallMock("Debugger.setBreakpointByUrl", testing::_))
463         .WillOnce([&](testing::Unused, auto handler) {
464             JsonObjectBuilder res;
465             JsonObjectBuilder params;
466             params.AddProperty("lineNumber", start);
467             params.AddProperty("url", "file://source");
468             handler(g_sessionId, res, JsonObject(std::move(params).Build()));
469             std::vector<testing::Matcher<JsonObject::JsonObjPointer>> locations;
470             locations.push_back(testing::Pointee(
471                 JsonProperties(JsonProperty<JsonObject::StringT> {"scriptId", std::to_string(scriptId)},
472                                JsonProperty<JsonObject::NumT> {"lineNumber", start})));
473 
474             ASSERT_THAT(
475                 JsonObject(std::move(res).Build()),
476                 JsonProperties(JsonProperty<JsonObject::StringT> {"breakpointId", std::to_string(start + 1)},
477                                JsonProperty<JsonObject::ArrayT> {"locations", JsonElementsAreArray(locations)}));
478         });
479 
480     inspectorServer.OnCallDebuggerSetBreakpointByUrl(handlerForSetBreak);
481 }
482 
TEST_F(ServerTest,OnCallDebuggerSetBreakpointsActive)483 TEST_F(ServerTest, OnCallDebuggerSetBreakpointsActive)
484 {
485     inspectorServer.CallTargetAttachedToTarget(g_mthread);
486 
487     EXPECT_CALL(server, OnCallMock("Debugger.setBreakpointsActive", testing::_))
488         .WillOnce([&](testing::Unused, auto handler) {
489             JsonObjectBuilder res;
490             JsonObject empty;
491             handler(g_sessionId, res, empty);
492             ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
493             ASSERT_FALSE(g_handlerCalled);
494         });
495 
496     inspectorServer.OnCallDebuggerSetBreakpointsActive([](auto thread, auto value) {
497         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
498         ASSERT_FALSE(value);
499         g_handlerCalled = true;
500     });
501 
502     EXPECT_CALL(server, OnCallMock("Debugger.setBreakpointsActive", testing::_))
503         .WillOnce([&](testing::Unused, auto handler) {
504             JsonObjectBuilder res;
505             JsonObjectBuilder params;
506             params.AddProperty("active", true);
507             handler(g_sessionId, res, JsonObject(std::move(params).Build()));
508             ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
509             ASSERT_TRUE(g_handlerCalled);
510             g_handlerCalled = false;
511         });
512 
513     inspectorServer.OnCallDebuggerSetBreakpointsActive([](auto thread, auto value) {
514         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
515         ASSERT_TRUE(value);
516         g_handlerCalled = true;
517     });
518 
519     EXPECT_CALL(server, OnCallMock("Debugger.setBreakpointsActive", testing::_))
520         .WillOnce([&](testing::Unused, auto handler) {
521             JsonObjectBuilder res;
522             JsonObjectBuilder params;
523             params.AddProperty("active", false);
524             handler(g_sessionId, res, JsonObject(std::move(params).Build()));
525             ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
526             ASSERT_TRUE(g_handlerCalled);
527         });
528 
529     inspectorServer.OnCallDebuggerSetBreakpointsActive([](auto thread, auto value) {
530         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
531         ASSERT_FALSE(value);
532         g_handlerCalled = true;
533     });
534 }
535 
TEST_F(ServerTest,OnCallDebuggerSetPauseOnExceptions)536 TEST_F(ServerTest, OnCallDebuggerSetPauseOnExceptions)
537 {
538     inspectorServer.CallTargetAttachedToTarget(g_mthread);
539 
540     EXPECT_CALL(server, OnCallMock("Debugger.setPauseOnExceptions", testing::_))
541         .WillOnce([&](testing::Unused, auto handler) {
542             JsonObjectBuilder res;
543             JsonObjectBuilder params;
544             params.AddProperty("state", "none");
545             handler(g_sessionId, res, JsonObject(std::move(params).Build()));
546             ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
547             ASSERT_TRUE(g_handlerCalled);
548         });
549 
550     inspectorServer.OnCallDebuggerSetPauseOnExceptions([](PtThread thread, PauseOnExceptionsState state) {
551         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
552         ASSERT_EQ(PauseOnExceptionsState::NONE, state);
553         g_handlerCalled = true;
554     });
555 }
556 
TEST_F(ServerTest,OnCallRuntimeEnable)557 TEST_F(ServerTest, OnCallRuntimeEnable)
558 {
559     inspectorServer.CallTargetAttachedToTarget(g_mthread);
560 
561     EXPECT_CALL(server, OnCallMock("Runtime.enable", testing::_)).WillOnce([&](testing::Unused, auto handler) {
562         JsonObjectBuilder res;
563         JsonObject empty;
564         handler(g_sessionId, res, empty);
565         ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
566         ASSERT_TRUE(g_handlerCalled);
567     });
568     inspectorServer.OnCallRuntimeEnable([](PtThread thread) {
569         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
570         g_handlerCalled = true;
571     });
572 }
573 
TEST_F(ServerTest,OnCallRuntimeGetProperties)574 TEST_F(ServerTest, OnCallRuntimeGetProperties)
575 {
576     auto object_id = 6;
577     auto preview = true;
578 
579     inspectorServer.CallTargetAttachedToTarget(g_mthread);
580 
581     EXPECT_CALL(server, OnCallMock("Runtime.getProperties", testing::_)).WillOnce([&](testing::Unused, auto handler) {
582         JsonObjectBuilder res;
583         JsonObjectBuilder params;
584         params.AddProperty("objectId", std::to_string(object_id));
585         params.AddProperty("generatePreview", preview);
586         handler(g_sessionId, res, JsonObject(std::move(params).Build()));
587 
588         std::vector<testing::Matcher<JsonObject::JsonObjPointer>> result;
589         result.push_back(testing::Pointee(JsonProperties(
590             JsonProperty<JsonObject::StringT> {"name", "object"},
591             JsonProperty<JsonObject::JsonObjPointer> {
592                 "value", testing::Pointee(JsonProperties(JsonProperty<JsonObject::NumT> {"value", object_id},
593                                                          JsonProperty<JsonObject::StringT> {"type", "number"}))},
594             JsonProperty<JsonObject::BoolT> {"writable", testing::_},
595             JsonProperty<JsonObject::BoolT> {"configurable", testing::_},
596             JsonProperty<JsonObject::BoolT> {"enumerable", testing::_})));
597         result.push_back(testing::Pointee(JsonProperties(
598             JsonProperty<JsonObject::StringT> {"name", "preview"},
599             JsonProperty<JsonObject::JsonObjPointer> {
600                 "value", testing::Pointee(JsonProperties(JsonProperty<JsonObject::BoolT> {"value", preview},
601                                                          JsonProperty<JsonObject::StringT> {"type", "boolean"}))},
602             JsonProperty<JsonObject::BoolT> {"writable", testing::_},
603             JsonProperty<JsonObject::BoolT> {"configurable", testing::_},
604             JsonProperty<JsonObject::BoolT> {"enumerable", testing::_})));
605         result.push_back(testing::Pointee(JsonProperties(
606             JsonProperty<JsonObject::StringT> {"name", "threadId"},
607             JsonProperty<JsonObject::JsonObjPointer> {
608                 "value", testing::Pointee(JsonProperties(JsonProperty<JsonObject::NumT> {"value", g_mthread.GetId()},
609                                                          JsonProperty<JsonObject::StringT> {"type", "number"}))},
610             JsonProperty<JsonObject::BoolT> {"writable", testing::_},
611             JsonProperty<JsonObject::BoolT> {"configurable", testing::_},
612             JsonProperty<JsonObject::BoolT> {"enumerable", testing::_})));
613 
614         ASSERT_THAT(JsonObject(std::move(res).Build()),
615                     JsonProperties(JsonProperty<JsonObject::ArrayT> {"result", JsonElementsAreArray(result)}));
616     });
617 
618     auto getProperties = [](PtThread thread, RemoteObjectId id, bool need_preview) {
619         std::vector<PropertyDescriptor> res;
620         res.push_back(PropertyDescriptor("object", RemoteObject::Number(id)));
621         res.push_back(PropertyDescriptor("preview", RemoteObject::Boolean(need_preview)));
622         res.push_back(PropertyDescriptor("threadId", RemoteObject::Number(thread.GetId())));
623         return res;
624     };
625 
626     inspectorServer.OnCallRuntimeGetProperties(getProperties);
627 }
628 
TEST_F(ServerTest,OnCallRuntimeRunIfWaitingForDebugger)629 TEST_F(ServerTest, OnCallRuntimeRunIfWaitingForDebugger)
630 {
631     inspectorServer.CallTargetAttachedToTarget(g_mthread);
632 
633     EXPECT_CALL(server, OnCallMock("Runtime.runIfWaitingForDebugger", testing::_))
634         .WillOnce([&](testing::Unused, auto handler) {
635             JsonObjectBuilder res;
636             JsonObject empty;
637             handler(g_sessionId, res, empty);
638             ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
639             ASSERT_TRUE(g_handlerCalled);
640         });
641 
642     inspectorServer.OnCallRuntimeRunIfWaitingForDebugger([](PtThread thread) {
643         ASSERT_EQ(thread.GetId(), g_mthread.GetId());
644         g_handlerCalled = true;
645     });
646 }
647 
648 }  // namespace ark::tooling::inspector::test
649 
650 // NOLINTEND
651