1 /**
2 * Copyright (c) 2022 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 "expect_pauses.h"
17 #include "client.h"
18 #include "json_object_matcher.h"
19 #include "test_method.h"
20
21 #include "macros.h"
22 #include "method.h"
23 #include "utils/json_parser.h"
24 #include "utils/utf.h"
25
26 #include "gtest/gtest.h"
27 #include "gmock/gmock.h"
28
29 #include <algorithm>
30 #include <initializer_list>
31 #include <iterator>
32 #include <memory>
33 #include <vector>
34
35 using testing::_;
36 using testing::Matcher;
37
38 namespace panda::tooling::inspector::test {
CallFrame(Method * method,size_t lineNumber)39 Pause::CallFrame CallFrame(Method *method, size_t lineNumber)
40 {
41 return {utf::Mutf8AsCString(method->GetName().data), lineNumber};
42 }
43
CallFrame(const TestMethod & method,size_t lineNumber)44 Pause::CallFrame CallFrame(const TestMethod &method, size_t lineNumber)
45 {
46 return {utf::Mutf8AsCString(method.Get()->GetName().data), lineNumber};
47 }
48
49 namespace {
50 class OnPause {
51 public:
52 // google-explicit-constructor conflicts with CodeCheck w.r.t. initializer_list constructors.
OnPause(std::initializer_list<Pause> pauses)53 explicit OnPause(std::initializer_list<Pause> pauses) // NOLINT(google-explicit-constructor)
54 : pauses_(new std::vector<Pause>(std::rbegin(pauses), std::rend(pauses)))
55 {
56 }
57
~OnPause()58 ~OnPause()
59 {
60 if (pauses_.use_count() == 1) {
61 EXPECT_TRUE(pauses_->empty());
62 }
63 }
64
65 DEFAULT_COPY_SEMANTIC(OnPause);
66 DEFAULT_MOVE_SEMANTIC(OnPause);
67
68 void operator()(const JsonObject &result);
69
70 private:
71 std::shared_ptr<std::vector<Pause>> pauses_;
72 };
73 } // namespace
74
operator ()(const JsonObject & result)75 void OnPause::operator()(const JsonObject &result)
76 {
77 ASSERT_FALSE(pauses_->empty());
78
79 std::vector<Matcher<JsonObject::JsonObjPointer>> callFrameMatchers;
80
81 std::transform(
82 pauses_->back().callFrames.begin(), pauses_->back().callFrames.end(), std::back_inserter(callFrameMatchers),
83 [](auto &callFrame) {
84 return Pointee(JsonProperties(
85 JsonProperty<JsonObject::StringT> {"callFrameId", _},
86 JsonProperty<JsonObject::StringT> {"functionName", callFrame.functionName},
87 JsonProperty<JsonObject::JsonObjPointer> {
88 "location",
89 Pointee(JsonProperties(JsonProperty<JsonObject::StringT> {"scriptId", _},
90 JsonProperty<JsonObject::NumT> {"lineNumber", callFrame.lineNumber}))},
91 JsonProperty<JsonObject::StringT> {"url", _}, JsonProperty<JsonObject::ArrayT> {"scopeChain", _},
92 JsonProperty<JsonObject::JsonObjPointer> {
93 "this", Pointee(JsonProperties(JsonProperty<JsonObject::StringT> {"type", "undefined"}))}));
94 });
95
96 auto resultMatcher =
97 JsonProperties(JsonProperty<JsonObject::StringT> {"reason", pauses_->back().reason},
98 JsonProperty<JsonObject::ArrayT> {"callFrames", JsonElementsAreArray(callFrameMatchers)});
99
100 EXPECT_THAT(result, resultMatcher);
101
102 pauses_->pop_back();
103 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) due to bug in clang-tidy #3553 (gtest repo)
104 }
105
ExpectPauses(Client & client,std::initializer_list<Pause> pauses)106 void ExpectPauses(Client &client, std::initializer_list<Pause> pauses)
107 {
108 client.OnCall("Debugger.paused", OnPause(pauses));
109 }
110 } // namespace panda::tooling::inspector::test
111