1 //===- unittest/Format/SortImportsTestJS.cpp - JS import sort unit tests --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "FormatTestUtils.h"
11 #include "clang/Format/Format.h"
12 #include "llvm/Support/Debug.h"
13 #include "gtest/gtest.h"
15 #define DEBUG_TYPE "format-test"
21 class SortImportsTestJS : public ::testing::Test {
23 std::string sort(StringRef Code, unsigned Offset = 0, unsigned Length = 0) {
24 StringRef FileName = "input.js";
26 Length = Code.size() - Offset;
27 std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
29 applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName));
30 EXPECT_TRUE(static_cast<bool>(Sorted));
31 auto Formatted = applyAllReplacements(
32 *Sorted, reformat(Style, *Sorted, Ranges, FileName));
33 EXPECT_TRUE(static_cast<bool>(Formatted));
37 void verifySort(llvm::StringRef Expected, llvm::StringRef Code,
38 unsigned Offset = 0, unsigned Length = 0) {
39 std::string Result = sort(Code, Offset, Length);
40 EXPECT_EQ(Expected.str(), Result) << "Expected:\n"
41 << Expected << "\nActual:\n"
45 FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
48 TEST_F(SortImportsTestJS, AlreadySorted) {
49 verifySort("import {sym} from 'a';\n"
50 "import {sym} from 'b';\n"
51 "import {sym} from 'c';\n"
54 "import {sym} from 'a';\n"
55 "import {sym} from 'b';\n"
56 "import {sym} from 'c';\n"
61 TEST_F(SortImportsTestJS, BasicSorting) {
62 verifySort("import {sym} from 'a';\n"
63 "import {sym} from 'b';\n"
64 "import {sym} from 'c';\n"
67 "import {sym} from 'a';\n"
68 "import {sym} from 'c';\n"
69 "import {sym} from 'b';\n"
73 TEST_F(SortImportsTestJS, DefaultBinding) {
74 verifySort("import A from 'a';\n"
75 "import B from 'b';\n"
78 "import B from 'b';\n"
79 "import A from 'a';\n"
83 TEST_F(SortImportsTestJS, DefaultAndNamedBinding) {
84 verifySort("import A, {a} from 'a';\n"
85 "import B, {b} from 'b';\n"
88 "import B, {b} from 'b';\n"
89 "import A, {a} from 'a';\n"
93 TEST_F(SortImportsTestJS, WrappedImportStatements) {
94 verifySort("import {sym1, sym2} from 'a';\n"
95 "import {sym} from 'b';\n"
108 TEST_F(SortImportsTestJS, SeparateMainCodeBody) {
109 verifySort("import {sym} from 'a';"
112 "import {sym} from 'a'; let x = 1;\n");
115 TEST_F(SortImportsTestJS, Comments) {
116 verifySort("/** @fileoverview This is a great file. */\n"
117 "// A very important import follows.\n"
118 "import {sym} from 'a'; /* more comments */\n"
119 "import {sym} from 'b'; // from //foo:bar\n",
120 "/** @fileoverview This is a great file. */\n"
121 "import {sym} from 'b'; // from //foo:bar\n"
122 "// A very important import follows.\n"
123 "import {sym} from 'a'; /* more comments */\n");
124 verifySort("import {sym} from 'a';\n"
125 "import {sym} from 'b';\n"
127 "/** Comment on variable. */\n"
129 "import {sym} from 'b';\n"
130 "import {sym} from 'a';\n"
132 "/** Comment on variable. */\n"
136 TEST_F(SortImportsTestJS, SortStar) {
137 verifySort("import * as foo from 'a';\n"
138 "import {sym} from 'a';\n"
139 "import * as bar from 'b';\n",
140 "import {sym} from 'a';\n"
141 "import * as foo from 'a';\n"
142 "import * as bar from 'b';\n");
145 TEST_F(SortImportsTestJS, AliasesSymbols) {
146 verifySort("import {sym1 as alias1} from 'b';\n"
147 "import {sym2 as alias2, sym3 as alias3} from 'c';\n",
148 "import {sym2 as alias2, sym3 as alias3} from 'c';\n"
149 "import {sym1 as alias1} from 'b';\n");
152 TEST_F(SortImportsTestJS, SortSymbols) {
153 verifySort("import {sym1, sym2 as a, sym3} from 'b';\n",
154 "import {sym2 as a, sym1, sym3} from 'b';\n");
155 verifySort("import {sym1 /* important! */, /*!*/ sym2 as a} from 'b';\n",
156 "import {/*!*/ sym2 as a, sym1 /* important! */} from 'b';\n");
157 verifySort("import {sym1, sym2} from 'b';\n", "import {\n"
164 TEST_F(SortImportsTestJS, GroupImports) {
165 verifySort("import {a} from 'absolute';\n"
167 "import {b} from '../parent';\n"
168 "import {b} from '../parent/nested';\n"
170 "import {b} from './relative/path';\n"
171 "import {b} from './relative/path/nested';\n"
174 "import {b} from './relative/path/nested';\n"
175 "import {b} from './relative/path';\n"
176 "import {b} from '../parent/nested';\n"
177 "import {b} from '../parent';\n"
178 "import {a} from 'absolute';\n"
182 TEST_F(SortImportsTestJS, Exports) {
183 verifySort("import {S} from 'bpath';\n"
185 "import {T} from './cpath';\n"
187 "export {A, B} from 'apath';\n"
188 "export {P} from '../parent';\n"
189 "export {R} from './relative';\n"
194 "export {R} from './relative';\n"
195 "import {T} from './cpath';\n"
197 "export {A, B} from 'apath';\n"
198 "import {S} from 'bpath';\n"
199 "export {P} from '../parent';\n"
202 verifySort("import {S} from 'bpath';\n"
204 "export {T} from 'epath';\n",
205 "export {T} from 'epath';\n"
206 "import {S} from 'bpath';\n");
209 TEST_F(SortImportsTestJS, SideEffectImports) {
210 verifySort("import 'ZZside-effect';\n"
211 "import 'AAside-effect';\n"
213 "import {A} from 'absolute';\n"
215 "import {R} from './relative';\n",
216 "import {R} from './relative';\n"
217 "import 'ZZside-effect';\n"
218 "import {A} from 'absolute';\n"
219 "import 'AAside-effect';\n");
222 TEST_F(SortImportsTestJS, AffectedRange) {
223 // Affected range inside of import statements.
224 verifySort("import {sym} from 'a';\n"
225 "import {sym} from 'b';\n"
226 "import {sym} from 'c';\n"
229 "import {sym} from 'c';\n"
230 "import {sym} from 'b';\n"
231 "import {sym} from 'a';\n"
234 // Affected range outside of import statements.
235 verifySort("import {sym} from 'c';\n"
236 "import {sym} from 'b';\n"
237 "import {sym} from 'a';\n"
240 "import {sym} from 'c';\n"
241 "import {sym} from 'b';\n"
242 "import {sym} from 'a';\n"
248 TEST_F(SortImportsTestJS, SortingCanShrink) {
249 // Sort excluding a suffix.
250 verifySort("import {B} from 'a';\n"
251 "import {A} from 'b';\n"
254 "import {A} from 'b';\n"
256 "import {B} from 'a';\n"
261 TEST_F(SortImportsTestJS, TrailingComma) {
262 verifySort("import {A, B,} from 'aa';\n", "import {B, A,} from 'aa';\n");
265 TEST_F(SortImportsTestJS, SortCaseInsensitive) {
266 verifySort("import {A} from 'aa';\n"
267 "import {A} from 'Ab';\n"
268 "import {A} from 'b';\n"
269 "import {A} from 'Bc';\n"
272 "import {A} from 'b';\n"
273 "import {A} from 'Bc';\n"
274 "import {A} from 'Ab';\n"
275 "import {A} from 'aa';\n"
278 verifySort("import {aa, Ab, b, Bc} from 'x';\n"
281 "import {b, Bc, Ab, aa} from 'x';\n"
286 TEST_F(SortImportsTestJS, SortMultiLine) {
287 // Reproduces issue where multi-line import was not parsed correctly.
288 verifySort("import {A} from 'a';\n"
289 "import {A} from 'b';\n"
298 "import {A} from 'a';\n"
304 } // end namespace format
305 } // end namespace clang