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, SeparateMainCodeBody) { 71 verifySort("import {sym} from 'a';" 72 "\n" 73 "let x = 1;\n", 74 "import {sym} from 'a'; let x = 1;\n"); 75 } 76 77 TEST_F(SortImportsTestJS, Comments) { 78 verifySort("/** @fileoverview This is a great file. */\n" 79 "// A very important import follows.\n" 80 "import {sym} from 'a'; /* more comments */\n" 81 "import {sym} from 'b'; // from //foo:bar\n", 82 "/** @fileoverview This is a great file. */\n" 83 "import {sym} from 'b'; // from //foo:bar\n" 84 "// A very important import follows.\n" 85 "import {sym} from 'a'; /* more comments */\n"); 86 } 87 88 TEST_F(SortImportsTestJS, SortStar) { 89 verifySort("import * as foo from 'a';\n" 90 "import {sym} from 'a';\n" 91 "import * as bar from 'b';\n", 92 "import {sym} from 'a';\n" 93 "import * as foo from 'a';\n" 94 "import * as bar from 'b';\n"); 95 } 96 97 TEST_F(SortImportsTestJS, AliasesSymbols) { 98 verifySort("import {sym1 as alias1} from 'b';\n" 99 "import {sym2 as alias2, sym3 as alias3} from 'c';\n", 100 "import {sym2 as alias2, sym3 as alias3} from 'c';\n" 101 "import {sym1 as alias1} from 'b';\n"); 102 } 103 104 TEST_F(SortImportsTestJS, GroupImports) { 105 verifySort("import {a} from 'absolute';\n" 106 "\n" 107 "import {b} from '../parent';\n" 108 "import {b} from '../parent/nested';\n" 109 "\n" 110 "import {b} from './relative/path';\n" 111 "import {b} from './relative/path/nested';\n" 112 "\n" 113 "let x = 1;\n", 114 "import {b} from './relative/path/nested';\n" 115 "import {b} from './relative/path';\n" 116 "import {b} from '../parent/nested';\n" 117 "import {b} from '../parent';\n" 118 "import {a} from 'absolute';\n" 119 "let x = 1;\n"); 120 } 121 122 TEST_F(SortImportsTestJS, Exports) { 123 verifySort("import {S} from 'bpath';\n" 124 "\n" 125 "import {T} from './cpath';\n" 126 "\n" 127 "export {A, B} from 'apath';\n" 128 "export {P} from '../parent';\n" 129 "export {R} from './relative';\n" 130 "export {S};\n" 131 "\n" 132 "let x = 1;\n" 133 "export y = 1;\n", 134 "export {R} from './relative';\n" 135 "import {T} from './cpath';\n" 136 "export {S};\n" 137 "export {A, B} from 'apath';\n" 138 "import {S} from 'bpath';\n" 139 "export {P} from '../parent';\n" 140 "let x = 1;\n" 141 "export y = 1;\n"); 142 verifySort("import {S} from 'bpath';\n" 143 "\n" 144 "export {T} from 'epath';\n", 145 "export {T} from 'epath';\n" 146 "import {S} from 'bpath';\n"); 147 } 148 149 TEST_F(SortImportsTestJS, SideEffectImports) { 150 verifySort("import 'ZZside-effect';\n" 151 "import 'AAside-effect';\n" 152 "\n" 153 "import {A} from 'absolute';\n" 154 "\n" 155 "import {R} from './relative';\n", 156 "import {R} from './relative';\n" 157 "import 'ZZside-effect';\n" 158 "import {A} from 'absolute';\n" 159 "import 'AAside-effect';\n"); 160 } 161 162 TEST_F(SortImportsTestJS, AffectedRange) { 163 // Sort excluding a suffix. 164 verifySort("import {sym} from 'b';\n" 165 "import {sym} from 'c';\n" 166 "import {sym} from 'a';\n" 167 "let x = 1;", 168 "import {sym} from 'c';\n" 169 "import {sym} from 'b';\n" 170 "import {sym} from 'a';\n" 171 "let x = 1;", 172 0, 30); 173 // Sort excluding a prefix. 174 verifySort("import {sym} from 'c';\n" 175 "import {sym} from 'a';\n" 176 "import {sym} from 'b';\n" 177 "\n" 178 "let x = 1;", 179 "import {sym} from 'c';\n" 180 "import {sym} from 'b';\n" 181 "import {sym} from 'a';\n" 182 "\n" 183 "let x = 1;", 184 30, 0); 185 // Sort a range within imports. 186 verifySort("import {sym} from 'c';\n" 187 "import {sym} from 'a';\n" 188 "import {sym} from 'b';\n" 189 "import {sym} from 'c';\n" 190 "let x = 1;", 191 "import {sym} from 'c';\n" 192 "import {sym} from 'b';\n" 193 "import {sym} from 'a';\n" 194 "import {sym} from 'c';\n" 195 "let x = 1;", 196 24, 30); 197 } 198 199 } // end namespace 200 } // end namespace format 201 } // end namespace clang 202