blob: b170c130d7081fcc24275d5b029f364c383e6b66 [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 +000016namespace clang {
Sam McCallb536a2a2017-12-19 12:23:48 +000017namespace clangd {
Sam McCallb536a2a2017-12-19 12:23:48 +000018namespace {
19
20MATCHER_P2(Pos, Line, Col, "") {
21 return arg.line == Line && arg.character == Col;
22}
23
Sam McCalla4962cc2018-04-27 11:59:28 +000024// The = → 🡆 below are ASCII (1 byte), BMP (3 bytes), and astral (4 bytes).
Sam McCallb536a2a2017-12-19 12:23:48 +000025const char File[] = R"(0:0 = 0
Sam McCalla4962cc2018-04-27 11:59:28 +0000261:0 8
272:0 🡆 18)";
Sam McCallb536a2a2017-12-19 12:23:48 +000028
Ilya Biryukov7beea3a2018-02-14 10:52:04 +000029/// A helper to make tests easier to read.
30Position position(int line, int character) {
31 Position Pos;
32 Pos.line = line;
33 Pos.character = character;
34 return Pos;
35}
36
Kadir Cetinkayaa9c9d002018-08-13 08:23:01 +000037Range range(const std::pair<int, int> p1, const std::pair<int, int> p2) {
38 Range range;
39 range.start = position(p1.first, p1.second);
40 range.end = position(p2.first, p2.second);
41 return range;
42}
43
Sam McCall71891122018-10-23 11:51:53 +000044TEST(SourceCodeTests, lspLength) {
45 EXPECT_EQ(lspLength(""), 0UL);
46 EXPECT_EQ(lspLength("ascii"), 5UL);
47 // BMP
48 EXPECT_EQ(lspLength("↓"), 1UL);
49 EXPECT_EQ(lspLength("¥"), 1UL);
50 // astral
51 EXPECT_EQ(lspLength("😂"), 2UL);
52}
53
Sam McCallb536a2a2017-12-19 12:23:48 +000054TEST(SourceCodeTests, PositionToOffset) {
55 // line out of bounds
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000056 EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), llvm::Failed());
Sam McCallb536a2a2017-12-19 12:23:48 +000057 // first line
Simon Marchi766338a2018-03-21 14:36:46 +000058 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, -1)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000059 llvm::Failed()); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000060 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 0)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000061 llvm::HasValue(0)); // first character
Simon Marchi766338a2018-03-21 14:36:46 +000062 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 3)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000063 llvm::HasValue(3)); // middle character
Simon Marchi766338a2018-03-21 14:36:46 +000064 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 6)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000065 llvm::HasValue(6)); // last character
Simon Marchi766338a2018-03-21 14:36:46 +000066 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000067 llvm::HasValue(7)); // the newline itself
Simon Marchi766338a2018-03-21 14:36:46 +000068 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000069 llvm::HasValue(7));
Simon Marchi766338a2018-03-21 14:36:46 +000070 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000071 llvm::HasValue(7)); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000072 EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000073 llvm::Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +000074 // middle line
Simon Marchi766338a2018-03-21 14:36:46 +000075 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, -1)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000076 llvm::Failed()); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000077 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 0)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000078 llvm::HasValue(8)); // first character
Simon Marchi766338a2018-03-21 14:36:46 +000079 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000080 llvm::HasValue(11)); // middle character
Simon Marchi766338a2018-03-21 14:36:46 +000081 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000082 llvm::HasValue(11));
Simon Marchi766338a2018-03-21 14:36:46 +000083 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 6)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000084 llvm::HasValue(16)); // last character
Simon Marchi766338a2018-03-21 14:36:46 +000085 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 7)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000086 llvm::HasValue(17)); // the newline itself
Simon Marchi766338a2018-03-21 14:36:46 +000087 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000088 llvm::HasValue(17)); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000089 EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000090 llvm::Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +000091 // last line
Simon Marchi766338a2018-03-21 14:36:46 +000092 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, -1)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000093 llvm::Failed()); // out of range
Simon Marchi766338a2018-03-21 14:36:46 +000094 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 0)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000095 llvm::HasValue(18)); // first character
Simon Marchi766338a2018-03-21 14:36:46 +000096 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 3)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000097 llvm::HasValue(21)); // middle character
Sam McCalla4962cc2018-04-27 11:59:28 +000098 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000099 llvm::Failed()); // middle of surrogate pair
Sam McCalla4962cc2018-04-27 11:59:28 +0000100 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000101 llvm::HasValue(26)); // middle of surrogate pair
Sam McCalla4962cc2018-04-27 11:59:28 +0000102 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 6), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000103 llvm::HasValue(26)); // end of surrogate pair
Simon Marchi766338a2018-03-21 14:36:46 +0000104 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 8)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000105 llvm::HasValue(28)); // last character
Sam McCalla4962cc2018-04-27 11:59:28 +0000106 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 9)),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000107 llvm::HasValue(29)); // EOF
Sam McCalla4962cc2018-04-27 11:59:28 +0000108 EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 10), false),
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000109 llvm::Failed()); // out of range
Sam McCallb536a2a2017-12-19 12:23:48 +0000110 // line out of bounds
Ilya Biryukovf2001aa2019-01-07 15:45:19 +0000111 EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), llvm::Failed());
112 EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), llvm::Failed());
Sam McCallb536a2a2017-12-19 12:23:48 +0000113}
114
115TEST(SourceCodeTests, OffsetToPosition) {
116 EXPECT_THAT(offsetToPosition(File, 0), Pos(0, 0)) << "start of file";
117 EXPECT_THAT(offsetToPosition(File, 3), Pos(0, 3)) << "in first line";
118 EXPECT_THAT(offsetToPosition(File, 6), Pos(0, 6)) << "end of first line";
119 EXPECT_THAT(offsetToPosition(File, 7), Pos(0, 7)) << "first newline";
120 EXPECT_THAT(offsetToPosition(File, 8), Pos(1, 0)) << "start of second line";
Sam McCalla4962cc2018-04-27 11:59:28 +0000121 EXPECT_THAT(offsetToPosition(File, 12), Pos(1, 4)) << "before BMP char";
122 EXPECT_THAT(offsetToPosition(File, 13), Pos(1, 5)) << "in BMP char";
123 EXPECT_THAT(offsetToPosition(File, 15), Pos(1, 5)) << "after BMP char";
124 EXPECT_THAT(offsetToPosition(File, 16), Pos(1, 6)) << "end of second line";
125 EXPECT_THAT(offsetToPosition(File, 17), Pos(1, 7)) << "second newline";
126 EXPECT_THAT(offsetToPosition(File, 18), Pos(2, 0)) << "start of last line";
127 EXPECT_THAT(offsetToPosition(File, 21), Pos(2, 3)) << "in last line";
128 EXPECT_THAT(offsetToPosition(File, 22), Pos(2, 4)) << "before astral char";
129 EXPECT_THAT(offsetToPosition(File, 24), Pos(2, 6)) << "in astral char";
130 EXPECT_THAT(offsetToPosition(File, 26), Pos(2, 6)) << "after astral char";
131 EXPECT_THAT(offsetToPosition(File, 28), Pos(2, 8)) << "end of last line";
132 EXPECT_THAT(offsetToPosition(File, 29), Pos(2, 9)) << "EOF";
133 EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 9)) << "out of bounds";
Sam McCallb536a2a2017-12-19 12:23:48 +0000134}
135
Kadir Cetinkayaa9c9d002018-08-13 08:23:01 +0000136TEST(SourceCodeTests, IsRangeConsecutive) {
137 EXPECT_TRUE(IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 3}, {2, 4})));
138 EXPECT_FALSE(
139 IsRangeConsecutive(range({0, 2}, {0, 3}), range({2, 3}, {2, 4})));
140 EXPECT_FALSE(
141 IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5})));
142}
143
Sam McCallb536a2a2017-12-19 12:23:48 +0000144} // namespace
145} // namespace clangd
146} // namespace clang