blob: 4a97fa00a091ac9ceae142e91a0b7fc527722f58 [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
16namespace clang{
17namespace clangd {
Sam McCallb536a2a2017-12-19 12:23:48 +000018namespace {
19
Simon Marchi766338a2018-03-21 14:36:46 +000020using llvm::Failed;
21using llvm::HasValue;
22
Sam McCallb536a2a2017-12-19 12:23:48 +000023MATCHER_P2(Pos, Line, Col, "") {
24 return arg.line == Line && arg.character == Col;
25}
26
Sam McCalla4962cc2018-04-27 11:59:28 +000027// The = → 🡆 below are ASCII (1 byte), BMP (3 bytes), and astral (4 bytes).
Sam McCallb536a2a2017-12-19 12:23:48 +000028const char File[] = R"(0:0 = 0
Sam McCalla4962cc2018-04-27 11:59:28 +0000291:0 8
302:0 🡆 18)";
Sam McCallb536a2a2017-12-19 12:23:48 +000031
Ilya Biryukov7beea3a2018-02-14 10:52:04 +000032/// A helper to make tests easier to read.
33Position position(int line, int character) {
34 Position Pos;
35 Pos.line = line;
36 Pos.character = character;
37 return Pos;
38}
39
Kadir Cetinkayaa9c9d002018-08-13 08:23:01 +000040Range range(const std::pair<int, int> p1, const std::pair<int, int> p2) {
41 Range range;
42 range.start = position(p1.first, p1.second);
43 range.end = position(p2.first, p2.second);
44 return range;
45}
46
Sam McCallb536a2a2017-12-19 12:23:48 +000047TEST(SourceCodeTests, PositionToOffset) {
48 // line out of bounds
Simon Marchi766338a2018-03-21 14:36:46 +000049 EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), Failed());
Sam McCallb536a2a2017-12-19 12:23:48 +000050 // first line
Simon Marchi766338a2018-03-21 14:36:46 +000051 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, -1)),
52 Failed()); // out of range
53 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 0)),
54 HasValue(0)); // first character
55 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 3)),
56 HasValue(3)); // middle character
57 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 6)),
58 HasValue(6)); // last character
59 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7)),
60 HasValue(7)); // the newline itself
61 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7), false),
62 HasValue(7));
63 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8)),
64 HasValue(7)); // out of range
65 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8), false),
66 Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +000067 // middle line
Simon Marchi766338a2018-03-21 14:36:46 +000068 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, -1)),
69 Failed()); // out of range
70 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 0)),
71 HasValue(8)); // first character
72 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3)),
73 HasValue(11)); // middle character
74 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3), false),
75 HasValue(11));
76 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 6)),
Sam McCalla4962cc2018-04-27 11:59:28 +000077 HasValue(16)); // last character
Simon Marchi766338a2018-03-21 14:36:46 +000078 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 7)),
Sam McCalla4962cc2018-04-27 11:59:28 +000079 HasValue(17)); // the newline itself
Simon Marchi766338a2018-03-21 14:36:46 +000080 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8)),
Sam McCalla4962cc2018-04-27 11:59:28 +000081 HasValue(17)); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000082 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8), false),
83 Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +000084 // last line
Simon Marchi766338a2018-03-21 14:36:46 +000085 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, -1)),
86 Failed()); // out of range
87 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 0)),
Sam McCalla4962cc2018-04-27 11:59:28 +000088 HasValue(18)); // first character
Simon Marchi766338a2018-03-21 14:36:46 +000089 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 3)),
Sam McCalla4962cc2018-04-27 11:59:28 +000090 HasValue(21)); // middle character
91 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5), false),
92 Failed()); // middle of surrogate pair
93 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5)),
94 HasValue(26)); // middle of surrogate pair
95 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 6), false),
96 HasValue(26)); // end of surrogate pair
Simon Marchi766338a2018-03-21 14:36:46 +000097 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 8)),
Sam McCalla4962cc2018-04-27 11:59:28 +000098 HasValue(28)); // last character
99 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 9)),
100 HasValue(29)); // EOF
101 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 10), false),
Simon Marchi766338a2018-03-21 14:36:46 +0000102 Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +0000103 // line out of bounds
Simon Marchi766338a2018-03-21 14:36:46 +0000104 EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), Failed());
105 EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), Failed());
Sam McCallb536a2a2017-12-19 12:23:48 +0000106}
107
108TEST(SourceCodeTests, OffsetToPosition) {
109 EXPECT_THAT(offsetToPosition(File, 0), Pos(0, 0)) << "start of file";
110 EXPECT_THAT(offsetToPosition(File, 3), Pos(0, 3)) << "in first line";
111 EXPECT_THAT(offsetToPosition(File, 6), Pos(0, 6)) << "end of first line";
112 EXPECT_THAT(offsetToPosition(File, 7), Pos(0, 7)) << "first newline";
113 EXPECT_THAT(offsetToPosition(File, 8), Pos(1, 0)) << "start of second line";
Sam McCalla4962cc2018-04-27 11:59:28 +0000114 EXPECT_THAT(offsetToPosition(File, 12), Pos(1, 4)) << "before BMP char";
115 EXPECT_THAT(offsetToPosition(File, 13), Pos(1, 5)) << "in BMP char";
116 EXPECT_THAT(offsetToPosition(File, 15), Pos(1, 5)) << "after BMP char";
117 EXPECT_THAT(offsetToPosition(File, 16), Pos(1, 6)) << "end of second line";
118 EXPECT_THAT(offsetToPosition(File, 17), Pos(1, 7)) << "second newline";
119 EXPECT_THAT(offsetToPosition(File, 18), Pos(2, 0)) << "start of last line";
120 EXPECT_THAT(offsetToPosition(File, 21), Pos(2, 3)) << "in last line";
121 EXPECT_THAT(offsetToPosition(File, 22), Pos(2, 4)) << "before astral char";
122 EXPECT_THAT(offsetToPosition(File, 24), Pos(2, 6)) << "in astral char";
123 EXPECT_THAT(offsetToPosition(File, 26), Pos(2, 6)) << "after astral char";
124 EXPECT_THAT(offsetToPosition(File, 28), Pos(2, 8)) << "end of last line";
125 EXPECT_THAT(offsetToPosition(File, 29), Pos(2, 9)) << "EOF";
126 EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 9)) << "out of bounds";
Sam McCallb536a2a2017-12-19 12:23:48 +0000127}
128
Kadir Cetinkayaa9c9d002018-08-13 08:23:01 +0000129TEST(SourceCodeTests, IsRangeConsecutive) {
130 EXPECT_TRUE(IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 3}, {2, 4})));
131 EXPECT_FALSE(
132 IsRangeConsecutive(range({0, 2}, {0, 3}), range({2, 3}, {2, 4})));
133 EXPECT_FALSE(
134 IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5})));
135}
136
Sam McCallb536a2a2017-12-19 12:23:48 +0000137} // namespace
138} // namespace clangd
139} // namespace clang