10#include "llvm/Testing/Support/Error.h"
11#include "gmock/gmock.h"
12#include "gtest/gtest.h"
19using testing::ElementsAre;
20using testing::HasSubstr;
21using testing::IsEmpty;
22using testing::UnorderedElementsAre;
29bool fromJSON(
const llvm::json::Value &V,
Foo &F, llvm::json::Path P) {
30 return fromJSON(V, F.X, P.field(
"X"));
32llvm::json::Value
toJSON(
const Foo &F) {
return F.X; }
37llvm::unique_function<void(llvm::Expected<T>)>
38capture(std::optional<llvm::Expected<T>> &
Out) {
40 return [&
Out](llvm::Expected<T> V) {
Out.emplace(std::move(V)); };
43struct OutgoingRecorder :
public LSPBinder::RawOutgoing {
44 llvm::StringMap<std::vector<llvm::json::Value>>
Received;
46 void callMethod(llvm::StringRef
Method, llvm::json::Value Params,
47 Callback<llvm::json::Value> Reply)
override {
50 return Reply(
error(
"Params={0}", Params));
53 void notify(llvm::StringRef
Method, llvm::json::Value Params)
override {
57 std::vector<llvm::json::Value> take(llvm::StringRef
Method) {
64TEST(LSPBinderTest, IncomingCalls) {
65 LSPBinder::RawHandlers RawHandlers;
66 OutgoingRecorder RawOutgoing;
67 LSPBinder Binder{RawHandlers, RawOutgoing};
69 void plusOne(
const Foo &Params, Callback<Foo> Reply) {
70 Reply(
Foo{Params.X + 1});
72 void fail(
const Foo &Params, Callback<Foo> Reply) {
73 Reply(
error(
"X={0}", Params.X));
75 void notify(
const Foo &Params) {
76 LastNotify = Params.X;
84 Binder.method(
"plusOne", &H, &Handler::plusOne);
85 Binder.method(
"fail", &H, &Handler::fail);
86 Binder.notification(
"notify", &H, &Handler::notify);
87 Binder.command(
"cmdPlusOne", &H, &Handler::plusOne);
88 ASSERT_THAT(RawHandlers.MethodHandlers.keys(),
89 UnorderedElementsAre(
"plusOne",
"fail"));
90 ASSERT_THAT(RawHandlers.NotificationHandlers.keys(),
91 UnorderedElementsAre(
"notify"));
92 ASSERT_THAT(RawHandlers.CommandHandlers.keys(),
93 UnorderedElementsAre(
"cmdPlusOne"));
94 std::optional<llvm::Expected<llvm::json::Value>> Reply;
96 auto &RawPlusOne = RawHandlers.MethodHandlers[
"plusOne"];
97 RawPlusOne(1, capture(Reply));
98 ASSERT_TRUE(Reply.has_value());
99 EXPECT_THAT_EXPECTED(*Reply, llvm::HasValue(2));
100 RawPlusOne(
"foo", capture(Reply));
101 ASSERT_TRUE(Reply.has_value());
102 EXPECT_THAT_EXPECTED(
103 *Reply, llvm::FailedWithMessage(HasSubstr(
104 "failed to decode plusOne request: expected integer")));
106 auto &RawFail = RawHandlers.MethodHandlers[
"fail"];
107 RawFail(2, capture(Reply));
108 ASSERT_TRUE(Reply.has_value());
109 EXPECT_THAT_EXPECTED(*Reply, llvm::FailedWithMessage(
"X=2"));
111 auto &RawNotify = RawHandlers.NotificationHandlers[
"notify"];
113 EXPECT_EQ(H.LastNotify, 42);
114 EXPECT_EQ(H.NotifyCount, 1);
116 EXPECT_EQ(H.LastNotify, 42);
117 EXPECT_EQ(H.NotifyCount, 1);
119 auto &RawCmdPlusOne = RawHandlers.CommandHandlers[
"cmdPlusOne"];
120 RawCmdPlusOne(1, capture(Reply));
121 ASSERT_TRUE(Reply.has_value());
122 EXPECT_THAT_EXPECTED(*Reply, llvm::HasValue(2));
125 EXPECT_THAT(RawOutgoing.Received, IsEmpty());
128TEST(LSPBinderTest, OutgoingCalls) {
129 LSPBinder::RawHandlers RawHandlers;
130 OutgoingRecorder RawOutgoing;
131 LSPBinder Binder{RawHandlers, RawOutgoing};
133 LSPBinder::OutgoingMethod<Foo, Foo> Echo;
134 Echo = Binder.outgoingMethod(
"echo");
135 LSPBinder::OutgoingMethod<Foo, std::string> WrongSignature;
136 WrongSignature = Binder.outgoingMethod(
"wrongSignature");
137 LSPBinder::OutgoingMethod<Foo, Foo> Fail;
138 Fail = Binder.outgoingMethod(
"fail");
140 std::optional<llvm::Expected<Foo>> Reply;
141 Echo(
Foo{2}, capture(Reply));
142 EXPECT_THAT(RawOutgoing.take(
"echo"), ElementsAre(llvm::json::Value(2)));
143 ASSERT_TRUE(Reply.has_value());
144 EXPECT_THAT_EXPECTED(*Reply, llvm::HasValue(
Foo{2}));
147 std::optional<llvm::Expected<std::string>> WrongTypeReply;
148 WrongSignature(
Foo{2}, capture(WrongTypeReply));
149 EXPECT_THAT(RawOutgoing.take(
"wrongSignature"),
150 ElementsAre(llvm::json::Value(2)));
151 ASSERT_TRUE(Reply.has_value());
152 EXPECT_THAT_EXPECTED(*WrongTypeReply,
153 llvm::FailedWithMessage(
154 HasSubstr(
"failed to decode wrongSignature reply")));
156 Fail(
Foo{2}, capture(Reply));
157 EXPECT_THAT(RawOutgoing.take(
"fail"), ElementsAre(llvm::json::Value(2)));
158 ASSERT_TRUE(Reply.has_value());
159 EXPECT_THAT_EXPECTED(*Reply, llvm::FailedWithMessage(
"Params=2"));
CompiledFragmentImpl & Out
llvm::StringMap< std::vector< llvm::json::Value > > Received
llvm::Error error(std::error_code, std::string &&)
llvm::Error error(std::error_code EC, const char *Fmt, Ts &&... Vals)
bool operator==(const Inclusion &LHS, const Inclusion &RHS)
llvm::json::Value toJSON(const FuzzyFindRequest &Request)
TEST(BackgroundQueueTest, Priority)
bool fromJSON(const llvm::json::Value &Parameters, FuzzyFindRequest &Request, llvm::json::Path P)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//