1 //===- unittest/Format/SortImportsTestJS.cpp - JS import sort unit tests --===// 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 10 #include "FormatTestUtils.h" 11 #include "clang/Format/Format.h" 12 #include "llvm/Support/Debug.h" 13 #include "gtest/gtest.h" 14 15 #define DEBUG_TYPE "format-test" 16 17 namespace clang { 18 namespace format { 19 namespace { 20 21 class SortImportsTestJS : public ::testing::Test { 22 protected: 23 std::string sort(StringRef Code, unsigned Offset = 0, unsigned Length = 0) { 24 StringRef FileName = "input.js"; 25 if (Length == 0U) 26 Length = Code.size() - Offset; 27 std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length)); 28 std::string Sorted = 29 applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName)); 30 return applyAllReplacements(Sorted, 31 reformat(Style, Sorted, Ranges, FileName)); 32 } 33 34 void verifySort(llvm::StringRef Expected, llvm::StringRef Code, 35 unsigned Offset = 0, unsigned Length = 0) { 36 std::string Result = sort(Code, Offset, Length); 37 EXPECT_EQ(Expected.str(), Result) << "Expected:\n" 38 << Expected << "\nActual:\n" 39 << Result; 40 } 41 42 FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript); 43 }; 44 45 TEST_F(SortImportsTestJS, AlreadySorted) { 46 verifySort("import {sym} from 'a';\n" 47 "import {sym} from 'b';\n" 48 "import {sym} from 'c';\n" 49 "\n" 50 "let x = 1;", 51 "import {sym} from 'a';\n" 52 "import {sym} from 'b';\n" 53 "import {sym} from 'c';\n" 54 "\n" 55 "let x = 1;"); 56 } 57 58 TEST_F(SortImportsTestJS, BasicSorting) { 59 verifySort("import {sym} from 'a';\n" 60 "import {sym} from 'b';\n" 61 "import {sym} from 'c';\n" 62 "\n" 63 "let x = 1;", 64 "import {sym} from 'a';\n" 65 "import {sym} from 'c';\n" 66 "import {sym} from 'b';\n" 67 "let x = 1;"); 68 } 69 70 TEST_F(SortImportsTestJS, WrappedImportStatements) { 71 verifySort("import {sym1, sym2} from 'a';\n" 72 "import {sym} from 'b';\n" 73 "\n" 74 "1;", 75 "import\n" 76 " {sym}\n" 77 " from 'b';\n" 78 "import {\n" 79 " sym1,\n" 80 " sym2\n" 81 "} from 'a';\n" 82 "1;"); 83 } 84 85 TEST_F(SortImportsTestJS, SeparateMainCodeBody) { 86 verifySort("import {sym} from 'a';" 87 "\n" 88 "let x = 1;\n", 89 "import {sym} from 'a'; let x = 1;\n"); 90 } 91 92 TEST_F(SortImportsTestJS, Comments) { 93 verifySort("/** @fileoverview This is a great file. */\n" 94 "// A very important import follows.\n" 95 "import {sym} from 'a'; /* more comments */\n" 96 "import {sym} from 'b'; // from //foo:bar\n", 97 "/** @fileoverview This is a great file. */\n" 98 "import {sym} from 'b'; // from //foo:bar\n" 99 "// A very important import follows.\n" 100 "import {sym} from 'a'; /* more comments */\n"); 101 } 102 103 TEST_F(SortImportsTestJS, SortStar) { 104 verifySort("import * as foo from 'a';\n" 105 "import {sym} from 'a';\n" 106 "import * as bar from 'b';\n", 107 "import {sym} from 'a';\n" 108 "import * as foo from 'a';\n" 109 "import * as bar from 'b';\n"); 110 } 111 112 TEST_F(SortImportsTestJS, AliasesSymbols) { 113 verifySort("import {sym1 as alias1} from 'b';\n" 114 "import {sym2 as alias2, sym3 as alias3} from 'c';\n", 115 "import {sym2 as alias2, sym3 as alias3} from 'c';\n" 116 "import {sym1 as alias1} from 'b';\n"); 117 } 118 119 TEST_F(SortImportsTestJS, SortSymbols) { 120 verifySort("import {sym1, sym2 as a, sym3} from 'b';\n", 121 "import {sym2 as a, sym1, sym3} from 'b';\n"); 122 verifySort("import {sym1 /* important! */, /*!*/ sym2 as a} from 'b';\n", 123 "import {/*!*/ sym2 as a, sym1 /* important! */} from 'b';\n"); 124 verifySort("import {sym1, sym2} from 'b';\n", "import {\n" 125 " sym2 \n" 126 ",\n" 127 " sym1 \n" 128 "} from 'b';\n"); 129 } 130 131 TEST_F(SortImportsTestJS, GroupImports) { 132 verifySort("import {a} from 'absolute';\n" 133 "\n" 134 "import {b} from '../parent';\n" 135 "import {b} from '../parent/nested';\n" 136 "\n" 137 "import {b} from './relative/path';\n" 138 "import {b} from './relative/path/nested';\n" 139 "\n" 140 "let x = 1;\n", 141 "import {b} from './relative/path/nested';\n" 142 "import {b} from './relative/path';\n" 143 "import {b} from '../parent/nested';\n" 144 "import {b} from '../parent';\n" 145 "import {a} from 'absolute';\n" 146 "let x = 1;\n"); 147 } 148 149 TEST_F(SortImportsTestJS, Exports) { 150 verifySort("import {S} from 'bpath';\n" 151 "\n" 152 "import {T} from './cpath';\n" 153 "\n" 154 "export {A, B} from 'apath';\n" 155 "export {P} from '../parent';\n" 156 "export {R} from './relative';\n" 157 "export {S};\n" 158 "\n" 159 "let x = 1;\n" 160 "export y = 1;\n", 161 "export {R} from './relative';\n" 162 "import {T} from './cpath';\n" 163 "export {S};\n" 164 "export {A, B} from 'apath';\n" 165 "import {S} from 'bpath';\n" 166 "export {P} from '../parent';\n" 167 "let x = 1;\n" 168 "export y = 1;\n"); 169 verifySort("import {S} from 'bpath';\n" 170 "\n" 171 "export {T} from 'epath';\n", 172 "export {T} from 'epath';\n" 173 "import {S} from 'bpath';\n"); 174 } 175 176 TEST_F(SortImportsTestJS, SideEffectImports) { 177 verifySort("import 'ZZside-effect';\n" 178 "import 'AAside-effect';\n" 179 "\n" 180 "import {A} from 'absolute';\n" 181 "\n" 182 "import {R} from './relative';\n", 183 "import {R} from './relative';\n" 184 "import 'ZZside-effect';\n" 185 "import {A} from 'absolute';\n" 186 "import 'AAside-effect';\n"); 187 } 188 189 TEST_F(SortImportsTestJS, AffectedRange) { 190 // Sort excluding a suffix. 191 verifySort("import {sym} from 'b';\n" 192 "import {sym} from 'c';\n" 193 "import {sym} from 'a';\n" 194 "let x = 1;", 195 "import {sym} from 'c';\n" 196 "import {sym} from 'b';\n" 197 "import {sym} from 'a';\n" 198 "let x = 1;", 199 0, 30); 200 // Sort excluding a prefix. 201 verifySort("import {sym} from 'c';\n" 202 "import {sym} from 'a';\n" 203 "import {sym} from 'b';\n" 204 "\n" 205 "let x = 1;", 206 "import {sym} from 'c';\n" 207 "import {sym} from 'b';\n" 208 "import {sym} from 'a';\n" 209 "\n" 210 "let x = 1;", 211 30, 0); 212 // Sort a range within imports. 213 verifySort("import {sym} from 'c';\n" 214 "import {sym} from 'a';\n" 215 "import {sym} from 'b';\n" 216 "import {sym} from 'c';\n" 217 "let x = 1;", 218 "import {sym} from 'c';\n" 219 "import {sym} from 'b';\n" 220 "import {sym} from 'a';\n" 221 "import {sym} from 'c';\n" 222 "let x = 1;", 223 24, 30); 224 } 225 226 } // end namespace 227 } // end namespace format 228 } // end namespace clang 229