7
7
// ===----------------------------------------------------------------------===//
8
8
9
9
#include " mlir/Tools/lsp-server-support/Transport.h"
10
- #include " llvm/ADT/ScopeExit.h"
10
+ #include " mlir/Tools/lsp-server-support/Logging.h"
11
+ #include " mlir/Tools/lsp-server-support/Protocol.h"
11
12
#include " llvm/Support/FileSystem.h"
12
13
#include " gmock/gmock.h"
13
14
#include " gtest/gtest.h"
@@ -29,37 +30,92 @@ TEST(TransportTest, SendReply) {
29
30
EXPECT_THAT (out, HasSubstr (" \" result\" :null" ));
30
31
}
31
32
32
- TEST (TransportTest, MethodNotFound) {
33
- auto tempOr = llvm::sys::fs::TempFile::create (" lsp-unittest-%%%%%%.json" );
34
- ASSERT_TRUE ((bool )tempOr);
35
- auto discardTemp =
36
- llvm::make_scope_exit ([&]() { ASSERT_FALSE ((bool )tempOr->discard ()); });
33
+ class TransportInputTest : public Test {
34
+ std::optional<llvm::sys::fs::TempFile> inputTempFile;
35
+ std::FILE *in = nullptr ;
36
+ std::string output = " " ;
37
+ llvm::raw_string_ostream os;
38
+ std::optional<JSONTransport> transport = std::nullopt;
39
+ std::optional<MessageHandler> messageHandler = std::nullopt;
37
40
38
- {
41
+ protected:
42
+ TransportInputTest () : os(output) {}
43
+
44
+ void SetUp () override {
45
+ auto tempOr = llvm::sys::fs::TempFile::create (" lsp-unittest-%%%%%%.json" );
46
+ ASSERT_TRUE ((bool )tempOr);
47
+ llvm::sys::fs::TempFile t = std::move (*tempOr);
48
+ inputTempFile = std::move (t);
49
+
50
+ in = std::fopen (inputTempFile->TmpName .c_str (), " r" );
51
+ transport.emplace (in, os, JSONStreamStyle::Delimited);
52
+ messageHandler.emplace (*transport);
53
+ }
54
+
55
+ void TearDown () override {
56
+ EXPECT_FALSE (inputTempFile->discard ());
57
+ EXPECT_EQ (std::fclose (in), 0 );
58
+ }
59
+
60
+ void writeInput (StringRef buffer) {
39
61
std::error_code ec;
40
- llvm::raw_fd_ostream os (tempOr ->TmpName , ec);
62
+ llvm::raw_fd_ostream os (inputTempFile ->TmpName , ec);
41
63
ASSERT_FALSE (ec);
42
- os << " { \" jsonrpc \" : \" 2.0 \" , \" id \" :29, \" method \" : \" ack \" } \n " ;
64
+ os << buffer ;
43
65
os.close ();
44
66
}
45
67
46
- std::string out;
47
- llvm::raw_string_ostream os (out);
48
- std::FILE *in = std::fopen (tempOr->TmpName .c_str (), " r" );
49
- auto closeIn = llvm::make_scope_exit ([&]() { std::fclose (in); });
68
+ StringRef getOutput () const { return output; }
69
+ MessageHandler &getMessageHandler () { return *messageHandler; }
50
70
51
- JSONTransport transport (in, os, JSONStreamStyle::Delimited);
52
- MessageHandler handler (transport);
71
+ void runTransport () {
72
+ bool gotEOF = false ;
73
+ llvm::Error err = llvm::handleErrors (
74
+ transport->run (*messageHandler), [&](const llvm::ECError &ecErr) {
75
+ gotEOF = ecErr.convertToErrorCode () == std::errc::io_error;
76
+ });
77
+ llvm::consumeError (std::move (err));
78
+ EXPECT_TRUE (gotEOF);
79
+ }
80
+ };
81
+
82
+ TEST_F (TransportInputTest, RequestWithInvalidParams) {
83
+ struct Handler {
84
+ void onMethod (const TextDocumentItem ¶ms,
85
+ mlir::lsp::Callback<TextDocumentIdentifier> callback) {}
86
+ } handler;
87
+ getMessageHandler ().method (" invalid-params-request" , &handler,
88
+ &Handler::onMethod);
89
+
90
+ writeInput (" {\" jsonrpc\" :\" 2.0\" ,\" id\" :92,"
91
+ " \" method\" :\" invalid-params-request\" ,\" params\" :{}}\n " );
92
+ runTransport ();
93
+ EXPECT_THAT (getOutput (), HasSubstr (" error" ));
94
+ EXPECT_THAT (getOutput (), HasSubstr (" missing value at (root).uri" ));
95
+ }
96
+
97
+ TEST_F (TransportInputTest, NotificationWithInvalidParams) {
98
+ // JSON parsing errors are only reported via error logging. As a result, this
99
+ // test can't make any expectations -- but it prints the output anyway, by way
100
+ // of demonstration.
101
+ Logger::setLogLevel (Logger::Level::Error);
102
+
103
+ struct Handler {
104
+ void onNotification (const TextDocumentItem ¶ms) {}
105
+ } handler;
106
+ getMessageHandler ().notification (" invalid-params-notification" , &handler,
107
+ &Handler::onNotification);
108
+
109
+ writeInput (" {\" jsonrpc\" :\" 2.0\" ,\" method\" :\" invalid-params-notification\" ,"
110
+ " \" params\" :{}}\n " );
111
+ runTransport ();
112
+ }
53
113
54
- bool gotEOF = false ;
55
- llvm::Error err = llvm::handleErrors (
56
- transport.run (handler), [&](const llvm::ECError &ecErr) {
57
- gotEOF = ecErr.convertToErrorCode () == std::errc::io_error;
58
- });
59
- llvm::consumeError (std::move (err));
60
- EXPECT_TRUE (gotEOF);
61
- EXPECT_THAT (out, HasSubstr (" \" id\" :29" ));
62
- EXPECT_THAT (out, HasSubstr (" \" error\" " ));
63
- EXPECT_THAT (out, HasSubstr (" \" message\" :\" method not found: ack\" " ));
114
+ TEST_F (TransportInputTest, MethodNotFound) {
115
+ writeInput (" {\" jsonrpc\" :\" 2.0\" ,\" id\" :29,\" method\" :\" ack\" }\n " );
116
+ runTransport ();
117
+ EXPECT_THAT (getOutput (), HasSubstr (" \" id\" :29" ));
118
+ EXPECT_THAT (getOutput (), HasSubstr (" \" error\" " ));
119
+ EXPECT_THAT (getOutput (), HasSubstr (" \" message\" :\" method not found: ack\" " ));
64
120
}
65
121
} // namespace
0 commit comments