1 | //===- Transport.cpp - LSP JSON transport unit tests ----------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "mlir/Tools/lsp-server-support/Transport.h" |
10 | #include "llvm/ADT/ScopeExit.h" |
11 | #include "llvm/Support/FileSystem.h" |
12 | #include "gmock/gmock.h" |
13 | #include "gtest/gtest.h" |
14 | |
15 | using namespace mlir; |
16 | using namespace mlir::lsp; |
17 | using namespace testing; |
18 | |
19 | namespace { |
20 | |
21 | TEST(TransportTest, SendReply) { |
22 | std::string out; |
23 | llvm::raw_string_ostream os(out); |
24 | JSONTransport transport(nullptr, os); |
25 | MessageHandler handler(transport); |
26 | |
27 | transport.reply(id: 1989, result: nullptr); |
28 | EXPECT_THAT(out, HasSubstr("\"id\":1989" )); |
29 | EXPECT_THAT(out, HasSubstr("\"result\":null" )); |
30 | } |
31 | |
32 | TEST(TransportTest, MethodNotFound) { |
33 | auto tempOr = llvm::sys::fs::TempFile::create(Model: "lsp-unittest-%%%%%%.json" ); |
34 | ASSERT_TRUE((bool)tempOr); |
35 | auto discardTemp = |
36 | llvm::make_scope_exit(F: [&]() { ASSERT_FALSE((bool)tempOr->discard()); }); |
37 | |
38 | { |
39 | std::error_code ec; |
40 | llvm::raw_fd_ostream os(tempOr->TmpName, ec); |
41 | ASSERT_FALSE(ec); |
42 | os << "{\"jsonrpc\":\"2.0\",\"id\":29,\"method\":\"ack\"}\n" ; |
43 | os.close(); |
44 | } |
45 | |
46 | std::string out; |
47 | llvm::raw_string_ostream os(out); |
48 | std::FILE *in = std::fopen(filename: tempOr->TmpName.c_str(), modes: "r" ); |
49 | auto closeIn = llvm::make_scope_exit(F: [&]() { std::fclose(stream: in); }); |
50 | |
51 | JSONTransport transport(in, os, JSONStreamStyle::Delimited); |
52 | MessageHandler handler(transport); |
53 | |
54 | bool gotEOF = false; |
55 | llvm::Error err = llvm::handleErrors( |
56 | E: transport.run(handler), Hs: [&](const llvm::ECError &ecErr) { |
57 | gotEOF = ecErr.convertToErrorCode() == std::errc::io_error; |
58 | }); |
59 | llvm::consumeError(Err: 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\"" )); |
64 | } |
65 | } // namespace |
66 | |