blob: 9fe923db45b154b9572a0aa7e398b336b1ee9ab0 [file] [log] [blame]
Sam McCallb536a2a2017-12-19 12:23:48 +00001//===-- SourceCodeTests.cpp ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "SourceCode.h"
Simon Marchi766338a2018-03-21 14:36:46 +000010#include "llvm/Support/Error.h"
Sam McCallb536a2a2017-12-19 12:23:48 +000011#include "llvm/Support/raw_os_ostream.h"
Simon Marchi766338a2018-03-21 14:36:46 +000012#include "llvm/Testing/Support/Error.h"
Sam McCallb536a2a2017-12-19 12:23:48 +000013#include "gmock/gmock.h"
14#include "gtest/gtest.h"
15
Sam McCallc008af62018-10-20 15:30:37 +000016using namespace llvm;
17namespace clang {
Sam McCallb536a2a2017-12-19 12:23:48 +000018namespace clangd {
Sam McCallb536a2a2017-12-19 12:23:48 +000019namespace {
20
21MATCHER_P2(Pos, Line, Col, "") {
22 return arg.line == Line && arg.character == Col;
23}
24
Sam McCalla4962cc2018-04-27 11:59:28 +000025// The = → 🡆 below are ASCII (1 byte), BMP (3 bytes), and astral (4 bytes).
Sam McCallb536a2a2017-12-19 12:23:48 +000026const char File[] = R"(0:0 = 0
Sam McCalla4962cc2018-04-27 11:59:28 +0000271:0 8
282:0 🡆 18)";
Sam McCallb536a2a2017-12-19 12:23:48 +000029
Ilya Biryukov7beea3a2018-02-14 10:52:04 +000030/// A helper to make tests easier to read.
31Position position(int line, int character) {
32 Position Pos;
33 Pos.line = line;
34 Pos.character = character;
35 return Pos;
36}
37
Kadir Cetinkayaa9c9d002018-08-13 08:23:01 +000038Range range(const std::pair<int, int> p1, const std::pair<int, int> p2) {
39 Range range;
40 range.start = position(p1.first, p1.second);
41 range.end = position(p2.first, p2.second);
42 return range;
43}
44
Sam McCallb536a2a2017-12-19 12:23:48 +000045TEST(SourceCodeTests, PositionToOffset) {
46 // line out of bounds
Simon Marchi766338a2018-03-21 14:36:46 +000047 EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), Failed());
Sam McCallb536a2a2017-12-19 12:23:48 +000048 // first line
Simon Marchi766338a2018-03-21 14:36:46 +000049 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, -1)),
50 Failed()); // out of range
51 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 0)),
52 HasValue(0)); // first character
53 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 3)),
54 HasValue(3)); // middle character
55 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 6)),
56 HasValue(6)); // last character
57 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7)),
58 HasValue(7)); // the newline itself
59 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7), false),
60 HasValue(7));
61 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8)),
62 HasValue(7)); // out of range
63 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8), false),
64 Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +000065 // middle line
Simon Marchi766338a2018-03-21 14:36:46 +000066 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, -1)),
67 Failed()); // out of range
68 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 0)),
69 HasValue(8)); // first character
70 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3)),
71 HasValue(11)); // middle character
72 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3), false),
73 HasValue(11));
74 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 6)),
Sam McCalla4962cc2018-04-27 11:59:28 +000075 HasValue(16)); // last character
Simon Marchi766338a2018-03-21 14:36:46 +000076 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 7)),
Sam McCalla4962cc2018-04-27 11:59:28 +000077 HasValue(17)); // the newline itself
Simon Marchi766338a2018-03-21 14:36:46 +000078 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8)),
Sam McCalla4962cc2018-04-27 11:59:28 +000079 HasValue(17)); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000080 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8), false),
81 Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +000082 // last line
Simon Marchi766338a2018-03-21 14:36:46 +000083 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, -1)),
84 Failed()); // out of range
85 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 0)),
Sam McCalla4962cc2018-04-27 11:59:28 +000086 HasValue(18)); // first character
Simon Marchi766338a2018-03-21 14:36:46 +000087 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 3)),
Sam McCalla4962cc2018-04-27 11:59:28 +000088 HasValue(21)); // middle character
89 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5), false),
90 Failed()); // middle of surrogate pair
91 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5)),
92 HasValue(26)); // middle of surrogate pair
93 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 6), false),
94 HasValue(26)); // end of surrogate pair
Simon Marchi766338a2018-03-21 14:36:46 +000095 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 8)),
Sam McCalla4962cc2018-04-27 11:59:28 +000096 HasValue(28)); // last character
97 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 9)),
98 HasValue(29)); // EOF
99 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 10), false),
Simon Marchi766338a2018-03-21 14:36:46 +0000100 Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +0000101 // line out of bounds
Simon Marchi766338a2018-03-21 14:36:46 +0000102 EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), Failed());
103 EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), Failed());
Sam McCallb536a2a2017-12-19 12:23:48 +0000104}
105
106TEST(SourceCodeTests, OffsetToPosition) {
107 EXPECT_THAT(offsetToPosition(File, 0), Pos(0, 0)) << "start of file";
108 EXPECT_THAT(offsetToPosition(File, 3), Pos(0, 3)) << "in first line";
109 EXPECT_THAT(offsetToPosition(File, 6), Pos(0, 6)) << "end of first line";
110 EXPECT_THAT(offsetToPosition(File, 7), Pos(0, 7)) << "first newline";
111 EXPECT_THAT(offsetToPosition(File, 8), Pos(1, 0)) << "start of second line";
Sam McCalla4962cc2018-04-27 11:59:28 +0000112 EXPECT_THAT(offsetToPosition(File, 12), Pos(1, 4)) << "before BMP char";
113 EXPECT_THAT(offsetToPosition(File, 13), Pos(1, 5)) << "in BMP char";
114 EXPECT_THAT(offsetToPosition(File, 15), Pos(1, 5)) << "after BMP char";
115 EXPECT_THAT(offsetToPosition(File, 16), Pos(1, 6)) << "end of second line";
116 EXPECT_THAT(offsetToPosition(File, 17), Pos(1, 7)) << "second newline";
117 EXPECT_THAT(offsetToPosition(File, 18), Pos(2, 0)) << "start of last line";
118 EXPECT_THAT(offsetToPosition(File, 21), Pos(2, 3)) << "in last line";
119 EXPECT_THAT(offsetToPosition(File, 22), Pos(2, 4)) << "before astral char";
120 EXPECT_THAT(offsetToPosition(File, 24), Pos(2, 6)) << "in astral char";
121 EXPECT_THAT(offsetToPosition(File, 26), Pos(2, 6)) << "after astral char";
122 EXPECT_THAT(offsetToPosition(File, 28), Pos(2, 8)) << "end of last line";
123 EXPECT_THAT(offsetToPosition(File, 29), Pos(2, 9)) << "EOF";
124 EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 9)) << "out of bounds";
Sam McCallb536a2a2017-12-19 12:23:48 +0000125}
126
Kadir Cetinkayaa9c9d002018-08-13 08:23:01 +0000127TEST(SourceCodeTests, IsRangeConsecutive) {
128 EXPECT_TRUE(IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 3}, {2, 4})));
129 EXPECT_FALSE(
130 IsRangeConsecutive(range({0, 2}, {0, 3}), range({2, 3}, {2, 4})));
131 EXPECT_FALSE(
132 IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5})));
133}
134
Sam McCallb536a2a2017-12-19 12:23:48 +0000135} // namespace
136} // namespace clangd
137} // namespace clang