OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart_style.test.formatter_test; | 5 library dart_style.test.formatter_test; |
6 | 6 |
7 import 'dart:io'; | 7 import 'dart:io'; |
8 | 8 |
9 import 'package:path/path.dart' as p; | 9 import 'package:path/path.dart' as p; |
10 import 'package:unittest/compact_vm_config.dart'; | 10 import 'package:unittest/compact_vm_config.dart'; |
11 import 'package:unittest/unittest.dart'; | 11 import 'package:unittest/unittest.dart'; |
12 | 12 |
13 import 'package:dart_style/dart_style.dart'; | 13 import 'package:dart_style/dart_style.dart'; |
14 | 14 |
15 void main() { | 15 void main() { |
16 // Tidy up the unittest output. | 16 // Tidy up the unittest output. |
17 filterStacks = true; | 17 filterStacks = true; |
18 formatStacks = true; | 18 formatStacks = true; |
19 useCompactVMConfiguration(); | 19 useCompactVMConfiguration(); |
20 | 20 |
21 testDirectory("comments"); | 21 testDirectory("comments"); |
22 testDirectory("regression"); | 22 testDirectory("regression"); |
| 23 testDirectory("selections"); |
23 testDirectory("splitting"); | 24 testDirectory("splitting"); |
24 testDirectory("whitespace"); | 25 testDirectory("whitespace"); |
25 | 26 |
26 test("throws a FormatterException on failed parse", () { | 27 test("throws a FormatterException on failed parse", () { |
27 var formatter = new DartFormatter(); | 28 var formatter = new DartFormatter(); |
28 expect(() => formatter.format('wat?!'), | 29 expect(() => formatter.format('wat?!'), |
29 throwsA(new isInstanceOf<FormatterException>())); | 30 throwsA(new isInstanceOf<FormatterException>())); |
30 }); | 31 }); |
31 | 32 |
32 test("FormatterException describes parse errors", () { | 33 test("FormatterException describes parse errors", () { |
33 try { | 34 try { |
34 new DartFormatter().format(""" | 35 new DartFormatter().format(""" |
35 | 36 |
36 var a = some error; | 37 var a = some error; |
37 | 38 |
38 var b = another one; | 39 var b = another one; |
39 """, uri: "my_file.dart"); | 40 """, uri: "my_file.dart"); |
40 | 41 |
41 fail("Should throw."); | 42 fail("Should throw."); |
42 } on FormatterException catch (err) { | 43 } on FormatterException catch (err) { |
43 var message = err.message(); | 44 var message = err.message(); |
44 expect(message, contains("my_file.dart")); | 45 expect(message, contains("my_file.dart")); |
45 expect(message, contains("line 2")); | 46 expect(message, contains("line 2")); |
46 expect(message, contains("line 4")); | 47 expect(message, contains("line 4")); |
47 } | 48 } |
48 }); | 49 }); |
49 | 50 |
| 51 group('SourceCode', () { |
| 52 test('throws on negative start', () { |
| 53 expect(() { |
| 54 new SourceCode("12345;", selectionStart: -1, selectionLength: 0); |
| 55 }, throwsArgumentError); |
| 56 }); |
| 57 |
| 58 test('throws on out of bounds start', () { |
| 59 expect(() { |
| 60 new SourceCode("12345;", selectionStart: 7, selectionLength: 0); |
| 61 }, throwsArgumentError); |
| 62 }); |
| 63 |
| 64 test('throws on negative length', () { |
| 65 expect(() { |
| 66 new SourceCode("12345;", selectionStart: 1, selectionLength: -1); |
| 67 }, throwsArgumentError); |
| 68 }); |
| 69 |
| 70 test('throws on out of bounds length', () { |
| 71 expect(() { |
| 72 new SourceCode("12345;", selectionStart: 2, selectionLength: 5); |
| 73 }, throwsArgumentError); |
| 74 }); |
| 75 |
| 76 test('throws is start is null and length is not', () { |
| 77 expect(() { |
| 78 new SourceCode("12345;", selectionStart: 0); |
| 79 }, throwsArgumentError); |
| 80 }); |
| 81 |
| 82 test('throws is length is null and start is not', () { |
| 83 expect(() { |
| 84 new SourceCode("12345;", selectionLength: 1); |
| 85 }, throwsArgumentError); |
| 86 }); |
| 87 }); |
| 88 |
50 test("adds newline to unit", () { | 89 test("adds newline to unit", () { |
51 expect(new DartFormatter().format("var x = 1;"), | 90 expect(new DartFormatter().format("var x = 1;"), |
52 equals("var x = 1;\n")); | 91 equals("var x = 1;\n")); |
53 }); | 92 }); |
54 | 93 |
55 test("adds newline to unit after trailing comment", () { | 94 test("adds newline to unit after trailing comment", () { |
56 expect(new DartFormatter().format("library foo; //zamm"), | 95 expect(new DartFormatter().format("library foo; //zamm"), |
57 equals("library foo; //zamm\n")); | 96 equals("library foo; //zamm\n")); |
58 }); | 97 }); |
59 | 98 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 while (!lines[i].startsWith("<<<")) { | 181 while (!lines[i].startsWith("<<<")) { |
143 input += lines[i++] + "\n"; | 182 input += lines[i++] + "\n"; |
144 } | 183 } |
145 | 184 |
146 var expectedOutput = ""; | 185 var expectedOutput = ""; |
147 while (++i < lines.length && !lines[i].startsWith(">>>")) { | 186 while (++i < lines.length && !lines[i].startsWith(">>>")) { |
148 expectedOutput += lines[i] + "\n"; | 187 expectedOutput += lines[i] + "\n"; |
149 } | 188 } |
150 | 189 |
151 test(description, () { | 190 test(description, () { |
| 191 var isCompilationUnit = p.extension(entry.path) == ".unit"; |
| 192 |
| 193 var inputCode = _extractSelection(input, |
| 194 isCompilationUnit: isCompilationUnit); |
| 195 |
| 196 var expected = _extractSelection(expectedOutput, |
| 197 isCompilationUnit: isCompilationUnit); |
| 198 |
152 var formatter = new DartFormatter( | 199 var formatter = new DartFormatter( |
153 pageWidth: pageWidth, indent: leadingIndent); | 200 pageWidth: pageWidth, indent: leadingIndent); |
154 | 201 |
155 var result; | 202 var actual = formatter.formatSource(inputCode); |
156 if (p.extension(entry.path) == ".stmt") { | |
157 result = formatter.formatStatement(input) + "\n"; | |
158 } else { | |
159 result = formatter.format(input); | |
160 } | |
161 | 203 |
162 expect(result, equals(expectedOutput)); | 204 // The test files always put a newline at the end of the expectation. |
| 205 // Statements from the formatter (correctly) don't have that, so add |
| 206 // one to line up with the expected result. |
| 207 var actualText = actual.text; |
| 208 if (!isCompilationUnit) actualText += "\n"; |
| 209 |
| 210 expect(actualText, equals(expected.text)); |
| 211 expect(actual.selectionStart, equals(expected.selectionStart)); |
| 212 expect(actual.selectionLength, equals(expected.selectionLength)); |
163 }); | 213 }); |
164 } | 214 } |
165 }); | 215 }); |
166 } | 216 } |
167 } | 217 } |
| 218 |
| 219 /// Given a source string that contains ‹ and › to indicate a selection, returns |
| 220 /// a [SourceCode] with the text (with the selection markers removed) and the |
| 221 /// correct selection range. |
| 222 SourceCode _extractSelection(String source, {bool isCompilationUnit: false}) { |
| 223 var start = source.indexOf("‹"); |
| 224 source = source.replaceAll("‹", ""); |
| 225 |
| 226 var end = source.indexOf("›"); |
| 227 source = source.replaceAll("›", ""); |
| 228 |
| 229 // If the selection end is after a trailing newline, there will be an extra |
| 230 // newline *after* the "›", so remove it. |
| 231 if (end != -1 && source.endsWith("\n\n")) { |
| 232 source = source.substring(0, source.length - 1); |
| 233 } |
| 234 |
| 235 return new SourceCode(source, |
| 236 isCompilationUnit: isCompilationUnit, |
| 237 selectionStart: start == -1 ? null : start, |
| 238 selectionLength: end == -1 ? null : end - start); |
| 239 } |
OLD | NEW |