blob: c17ce46c776ceffc69f775989428b6f30a8641ea [file] [log] [blame]
Sam McCallb536a2a2017-12-19 12:23:48 +00001//===-- SourceCodeTests.cpp ------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Sam McCallb536a2a2017-12-19 12:23:48 +00006//
7//===----------------------------------------------------------------------===//
8#include "SourceCode.h"
Simon Marchi766338a2018-03-21 14:36:46 +00009#include "llvm/Support/Error.h"
Sam McCallb536a2a2017-12-19 12:23:48 +000010#include "llvm/Support/raw_os_ostream.h"
Simon Marchi766338a2018-03-21 14:36:46 +000011#include "llvm/Testing/Support/Error.h"
Sam McCallb536a2a2017-12-19 12:23:48 +000012#include "gmock/gmock.h"
13#include "gtest/gtest.h"
14
Sam McCallc008af62018-10-20 15:30:37 +000015namespace clang {
Sam McCallb536a2a2017-12-19 12:23:48 +000016namespace clangd {
Sam McCallb536a2a2017-12-19 12:23:48 +000017namespace {
18
19MATCHER_P2(Pos, Line, Col, "") {
20 return arg.line == Line && arg.character == Col;
21}
22
Sam McCalla4962cc2018-04-27 11:59:28 +000023// The = → 🡆 below are ASCII (1 byte), BMP (3 bytes), and astral (4 bytes).
Sam McCallb536a2a2017-12-19 12:23:48 +000024const char File[] = R"(0:0 = 0
Sam McCalla4962cc2018-04-27 11:59:28 +0000251:0 8
262:0 🡆 18)";
Sam McCallb536a2a2017-12-19 12:23:48 +000027
Ilya Biryukov7beea3a2018-02-14 10:52:04 +000028/// A helper to make tests easier to read.
29Position position(int line, int character) {
30 Position Pos;
31 Pos.line = line;
32 Pos.character = character;
33 return Pos;
34}
35
Kadir Cetinkayaa9c9d002018-08-13 08:23:01 +000036Range range(const std::pair<int, int> p1, const std::pair<int, int> p2) {
37 Range range;
38 range.start = position(p1.first, p1.second);
39 range.end = position(p2.first, p2.second);
40 return range;
41}
42
Sam McCall71891122018-10-23 11:51:53 +000043TEST(SourceCodeTests, lspLength) {
44 EXPECT_EQ(lspLength(""), 0UL);
45 EXPECT_EQ(lspLength("ascii"), 5UL);
46 // BMP
47 EXPECT_EQ(lspLength("↓"), 1UL);
48 EXPECT_EQ(lspLength("¥"), 1UL);
49 // astral
50 EXPECT_EQ(lspLength("😂"), 2UL);
51}
52
Sam McCallb536a2a2017-12-19 12:23:48 +000053TEST(SourceCodeTests, PositionToOffset) {
54 // line out of bounds
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000055 EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), llvm::Failed());
Sam McCallb536a2a2017-12-19 12:23:48 +000056 // first line
Simon Marchi766338a2018-03-21 14:36:46 +000057 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, -1)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000058 llvm::Failed()); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000059 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 0)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000060 llvm::HasValue(0)); // first character
Simon Marchi766338a2018-03-21 14:36:46 +000061 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 3)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000062 llvm::HasValue(3)); // middle character
Simon Marchi766338a2018-03-21 14:36:46 +000063 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 6)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000064 llvm::HasValue(6)); // last character
Simon Marchi766338a2018-03-21 14:36:46 +000065 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000066 llvm::HasValue(7)); // the newline itself
Simon Marchi766338a2018-03-21 14:36:46 +000067 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000068 llvm::HasValue(7));
Simon Marchi766338a2018-03-21 14:36:46 +000069 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000070 llvm::HasValue(7)); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000071 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000072 llvm::Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +000073 // middle line
Simon Marchi766338a2018-03-21 14:36:46 +000074 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, -1)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000075 llvm::Failed()); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000076 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 0)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000077 llvm::HasValue(8)); // first character
Simon Marchi766338a2018-03-21 14:36:46 +000078 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000079 llvm::HasValue(11)); // middle character
Simon Marchi766338a2018-03-21 14:36:46 +000080 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000081 llvm::HasValue(11));
Simon Marchi766338a2018-03-21 14:36:46 +000082 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 6)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000083 llvm::HasValue(16)); // last character
Simon Marchi766338a2018-03-21 14:36:46 +000084 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 7)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000085 llvm::HasValue(17)); // the newline itself
Simon Marchi766338a2018-03-21 14:36:46 +000086 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000087 llvm::HasValue(17)); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000088 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000089 llvm::Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +000090 // last line
Simon Marchi766338a2018-03-21 14:36:46 +000091 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, -1)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000092 llvm::Failed()); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000093 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 0)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000094 llvm::HasValue(18)); // first character
Simon Marchi766338a2018-03-21 14:36:46 +000095 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 3)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000096 llvm::HasValue(21)); // middle character
Sam McCalla4962cc2018-04-27 11:59:28 +000097 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000098 llvm::Failed()); // middle of surrogate pair
Sam McCalla4962cc2018-04-27 11:59:28 +000099 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000100 llvm::HasValue(26)); // middle of surrogate pair
Sam McCalla4962cc2018-04-27 11:59:28 +0000101 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 6), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000102 llvm::HasValue(26)); // end of surrogate pair
Simon Marchi766338a2018-03-21 14:36:46 +0000103 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 8)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000104 llvm::HasValue(28)); // last character
Sam McCalla4962cc2018-04-27 11:59:28 +0000105 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 9)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000106 llvm::HasValue(29)); // EOF
Sam McCalla4962cc2018-04-27 11:59:28 +0000107 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 10), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000108 llvm::Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +0000109 // line out of bounds
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000110 EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), llvm::Failed());
111 EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), llvm::Failed());
Sam McCallb536a2a2017-12-19 12:23:48 +0000112}
113
114TEST(SourceCodeTests, OffsetToPosition) {
115 EXPECT_THAT(offsetToPosition(File, 0), Pos(0, 0)) << "start of file";
116 EXPECT_THAT(offsetToPosition(File, 3), Pos(0, 3)) << "in first line";
117 EXPECT_THAT(offsetToPosition(File, 6), Pos(0, 6)) << "end of first line";
118 EXPECT_THAT(offsetToPosition(File, 7), Pos(0, 7)) << "first newline";
119 EXPECT_THAT(offsetToPosition(File, 8), Pos(1, 0)) << "start of second line";
Sam McCalla4962cc2018-04-27 11:59:28 +0000120 EXPECT_THAT(offsetToPosition(File, 12), Pos(1, 4)) << "before BMP char";
121 EXPECT_THAT(offsetToPosition(File, 13), Pos(1, 5)) << "in BMP char";
122 EXPECT_THAT(offsetToPosition(File, 15), Pos(1, 5)) << "after BMP char";
123 EXPECT_THAT(offsetToPosition(File, 16), Pos(1, 6)) << "end of second line";
124 EXPECT_THAT(offsetToPosition(File, 17), Pos(1, 7)) << "second newline";
125 EXPECT_THAT(offsetToPosition(File, 18), Pos(2, 0)) << "start of last line";
126 EXPECT_THAT(offsetToPosition(File, 21), Pos(2, 3)) << "in last line";
127 EXPECT_THAT(offsetToPosition(File, 22), Pos(2, 4)) << "before astral char";
128 EXPECT_THAT(offsetToPosition(File, 24), Pos(2, 6)) << "in astral char";
129 EXPECT_THAT(offsetToPosition(File, 26), Pos(2, 6)) << "after astral char";
130 EXPECT_THAT(offsetToPosition(File, 28), Pos(2, 8)) << "end of last line";
131 EXPECT_THAT(offsetToPosition(File, 29), Pos(2, 9)) << "EOF";
132 EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 9)) << "out of bounds";
Sam McCallb536a2a2017-12-19 12:23:48 +0000133}
134
Kadir Cetinkayaa9c9d002018-08-13 08:23:01 +0000135TEST(SourceCodeTests, IsRangeConsecutive) {
Haojian Wuaa3ed5a2019-01-25 15:14:03 +0000136 EXPECT_TRUE(isRangeConsecutive(range({2, 2}, {2, 3}), range({2, 3}, {2, 4})));
Kadir Cetinkayaa9c9d002018-08-13 08:23:01 +0000137 EXPECT_FALSE(
Haojian Wuaa3ed5a2019-01-25 15:14:03 +0000138 isRangeConsecutive(range({0, 2}, {0, 3}), range({2, 3}, {2, 4})));
Kadir Cetinkayaa9c9d002018-08-13 08:23:01 +0000139 EXPECT_FALSE(
Haojian Wuaa3ed5a2019-01-25 15:14:03 +0000140 isRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5})));
Kadir Cetinkayaa9c9d002018-08-13 08:23:01 +0000141}
142
Sam McCallb536a2a2017-12-19 12:23:48 +0000143} // namespace
144} // namespace clangd
145} // namespace clang