Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 import 'package:unittest/unittest.dart'; | |
| 6 | |
| 5 import 'package:analyzer_experimental/src/generated/ast.dart'; | 7 import 'package:analyzer_experimental/src/generated/ast.dart'; |
| 8 import 'package:analyzer_experimental/src/generated/scanner.dart'; | |
| 6 import 'package:analyzer_experimental/src/services/formatter.dart'; | 9 import 'package:analyzer_experimental/src/services/formatter.dart'; |
| 7 import 'package:analyzer_experimental/src/services/formatter_impl.dart'; | 10 import 'package:analyzer_experimental/src/services/formatter_impl.dart'; |
| 8 import 'package:unittest/unittest.dart'; | |
| 9 | 11 |
| 10 main() { | 12 main() { |
| 11 | 13 |
| 12 /// Edit recorder tests | 14 /// Edit recorder tests |
| 13 group('edit recorder', () { | 15 group('edit recorder', () { |
| 14 | 16 |
| 15 test('countWhitespace', (){ | 17 test('countWhitespace', (){ |
| 16 expect(newRecorder(' ').countWhitespace(), equals(3)); | 18 expect(newRecorder(' ').countWhitespace(), equals(3)); |
| 17 expect(newRecorder('').countWhitespace(), equals(0)); | 19 expect(newRecorder('').countWhitespace(), equals(0)); |
| 18 expect(newRecorder(' foo').countWhitespace(), equals(2)); | 20 expect(newRecorder(' foo').countWhitespace(), equals(2)); |
| 19 }); | 21 }); |
| 20 | 22 |
| 21 test('indent', (){ | |
| 22 var recorder = newRecorder(''); | |
| 23 expect(recorder.indentationLevel, equals(0)); | |
| 24 expect(recorder.options.indentPerLevel, equals(2)); | |
| 25 recorder.indent(); | |
| 26 expect(recorder.indentationLevel, equals(2)); | |
| 27 expect(recorder.numberOfIndentations, equals(1)); | |
| 28 }); | |
| 29 | |
| 30 test('isNewlineAt', (){ | 23 test('isNewlineAt', (){ |
| 31 expect(newRecorder('012\n').isNewlineAt(3), isTrue); | 24 expect(newRecorder('012\n').isNewlineAt(3), isTrue); |
| 32 expect(newRecorder('012\n3456').isNewlineAt(3), isTrue); | 25 expect(newRecorder('012\n3456').isNewlineAt(3), isTrue); |
| 33 expect(newRecorder('\n').isNewlineAt(0), isTrue); | 26 expect(newRecorder('\n').isNewlineAt(0), isTrue); |
| 34 }); | 27 }); |
| 35 | 28 |
| 29 test('space advances 1', (){ | |
| 30 var recorder = newRecorder(' foo'); | |
| 31 var startColumn = recorder.column; | |
| 32 recorder.space(); | |
| 33 expect(recorder.column, equals(startColumn + 1)); | |
| 34 }); | |
| 35 | |
| 36 test('space eats WS (1)', (){ | |
| 37 var recorder = newRecorder(' class') | |
| 38 ..currentToken = new KeywordToken(Keyword.CLASS, 3) | |
| 39 ..space() | |
| 40 ..advanceToken('class'); | |
| 41 expect(doFormat(recorder), equals(' class')); | |
| 42 }); | |
| 43 | |
| 44 test('space eats WS (2)', (){ | |
| 45 var src = 'class A'; | |
| 46 var recorder = newRecorder(src); | |
| 47 recorder..currentToken = (classKeyword(0)..setNext(identifier('A', 7))) | |
| 48 ..advanceToken('class') | |
| 49 ..space() | |
| 50 ..advanceToken('A'); | |
| 51 | |
|
scheglov
2013/06/19 22:12:05
There was no empty line in the same code in test b
pquitslund
2013/06/20 22:34:52
Maybe not. Consolidating tests.
Thanks!
| |
| 52 expect(doFormat(recorder), equals('class A')); | |
| 53 }); | |
| 54 | |
| 55 test('advance string token', (){ | |
| 56 var recorder = newRecorder('class A')..currentToken = classKeyword(0); | |
| 57 expect(recorder.column, equals(0)); | |
| 58 recorder.advanceToken('class'); | |
| 59 expect(recorder.column, equals(5)); | |
| 60 }); | |
| 61 | |
| 62 test('advance string token (failure)', (){ | |
| 63 var recorder = newRecorder('class A')..currentToken = classKeyword(0); | |
| 64 expect(() => recorder.advanceToken('static'), | |
| 65 throwsA(new isInstanceOf<FormatterException>())); | |
| 66 }); | |
| 67 | |
| 68 test('advance indent', (){ | |
| 69 var recorder = newRecorder(' class A')..currentToken = classKeyword(0); | |
| 70 recorder.advanceIndent(); | |
| 71 expect(doFormat(recorder), equals('class A')); | |
| 72 }); | |
| 73 | |
| 74 test('indent string', (){ | |
| 75 var recorder = newRecorder(''); | |
| 76 expect(recorder.getIndentString(0).length, equals(0)); | |
| 77 expect(recorder.getIndentString(5).length, equals(5)); | |
| 78 expect(recorder.getIndentString(50).length, equals(50)); | |
| 79 }); | |
| 80 | |
| 81 | |
| 82 test('newline', (){ | |
| 83 var recorder = newRecorder('class A { }'); | |
| 84 recorder..currentToken = chain([classKeyword(0), | |
| 85 identifier('A', 6), | |
| 86 openParen(8), | |
| 87 closeParen(10)]) | |
| 88 ..advanceToken('class') | |
| 89 ..space() | |
| 90 ..advanceToken('A') | |
| 91 ..space() | |
| 92 ..advanceToken('{') | |
| 93 ..newline(); | |
| 94 | |
| 95 expect(doFormat(recorder)[9], equals(NEW_LINE)); | |
| 96 }); | |
| 97 | |
| 98 test('newline eats trailing WS', (){ | |
| 99 var src = 'class A {'; | |
| 100 var recorder = newRecorder(src + ' '); | |
| 101 recorder..currentToken = chain([classKeyword(0), | |
| 102 identifier('A', 6), | |
| 103 openParen(8)]) | |
| 104 ..advanceToken('class') | |
| 105 ..space() | |
| 106 ..advanceToken('A') | |
| 107 ..space() | |
| 108 ..advanceToken('{') | |
| 109 ..newline(); | |
| 110 | |
| 111 expect(doFormat(recorder).length, equals((src+ NEW_LINE).length)); | |
|
scheglov
2013/06/19 22:12:05
Space before '+'.
pquitslund
2013/06/20 22:34:52
Done.
| |
| 112 }); | |
| 113 | |
| 114 | |
| 115 }); | |
| 116 | |
| 117 | |
| 118 /// Edit operations | |
| 119 group('edit operations', () { | |
| 120 | |
| 121 test('replace same length', () { | |
| 122 var edits = [new Edit(1, 2, 'oo'), | |
| 123 new Edit(4, 5, 'bar')]; | |
| 124 expect(new EditOperation().apply(edits, 'fun house'), equals('foo bar')); | |
| 125 }); | |
| 126 | |
| 127 test('replace shorten', () { | |
| 128 var edits = [new Edit(0, 2, 'a'), | |
| 129 new Edit(2, 2, 'b'), | |
| 130 new Edit(4, 2, 'c')]; | |
| 131 expect(new EditOperation().apply(edits, 'AaBbCc'), equals('abc')); | |
| 132 }); | |
| 133 | |
| 134 | |
| 36 }); | 135 }); |
| 37 | 136 |
| 38 | 137 |
| 39 /// Formatter tests | 138 /// Formatter tests |
| 40 group('formatter', () { | 139 group('formatter', () { |
| 41 | 140 |
| 42 test('failedParse', () { | 141 test('failed parse', () { |
| 43 var formatter = new CodeFormatter(); | 142 var formatter = new CodeFormatter(); |
| 44 expect(() => formatter.format(CodeKind.COMPILATION_UNIT, "~"), | 143 expect(() => formatter.format(CodeKind.COMPILATION_UNIT, '~'), |
| 45 throwsA(new isInstanceOf<FormatterException>('FE'))); | 144 throwsA(new isInstanceOf<FormatterException>())); |
| 46 }); | 145 }); |
| 47 | 146 |
| 147 test('CU (1)', () { | |
| 148 expectCUFormatsTo( | |
| 149 'class A {\n' | |
| 150 '}', | |
| 151 'class A {\n' | |
| 152 '}' | |
| 153 ); | |
| 154 }); | |
| 155 | |
| 156 test('CU (2)', () { | |
| 157 expectCUFormatsTo( | |
| 158 'class A { \n' | |
| 159 '}', | |
| 160 'class A {\n' | |
| 161 '}' | |
| 162 ); | |
| 163 }); | |
| 164 | |
| 165 test('CU (3)', () { | |
| 166 expectCUFormatsTo( | |
| 167 'class A {\n' | |
| 168 ' }', | |
| 169 'class A {\n' | |
| 170 '}' | |
| 171 ); | |
| 172 }); | |
| 173 | |
| 174 test('CU (4)', () { | |
| 175 expectCUFormatsTo( | |
| 176 ' class A {\n' | |
| 177 '}', | |
| 178 'class A {\n' | |
| 179 '}' | |
| 180 ); | |
| 181 }); | |
| 182 | |
| 183 test('CU (method indent)', () { | |
| 184 expectCUFormatsTo( | |
| 185 'class A {\n' | |
| 186 'void x(){\n' | |
| 187 '}\n' | |
| 188 '}', | |
| 189 'class A {\n' | |
| 190 ' void x() {\n' | |
| 191 ' }\n' | |
| 192 '}' | |
| 193 ); | |
| 194 }); | |
| 195 | |
| 196 test('CU (method indent - 2)', () { | |
| 197 expectCUFormatsTo( | |
| 198 'class A {\n' | |
| 199 ' static void x(){}\n' | |
| 200 ' }', | |
| 201 'class A {\n' | |
| 202 ' static void x() {\n' | |
| 203 ' }\n' | |
| 204 '}' | |
| 205 ); | |
| 206 }); | |
| 207 | |
| 208 | |
| 209 | |
| 48 // test('initialIndent', () { | 210 // test('initialIndent', () { |
| 49 // var formatter = new CodeFormatter(new Options(initialIndentationLevel:2) ); | 211 // var formatter = new CodeFormatter( |
| 212 // new FormatterOptions(initialIndentationLevel:2)); | |
| 50 // var formattedSource = formatter.format(CodeKind.STATEMENT, 'var x;'); | 213 // var formattedSource = formatter.format(CodeKind.STATEMENT, 'var x;'); |
| 51 // expect(formattedSource, startsWith(' ')); | 214 // expect(formattedSource, startsWith(' ')); |
| 52 // }); | 215 // }); |
| 53 | 216 |
| 54 }); | 217 }); |
| 55 | 218 |
| 56 } | 219 } |
| 57 | 220 |
| 58 EditRecorder newRecorder(String source) { | 221 Token classKeyword(int offset) => |
| 59 var recorder = new EditRecorder(new FormatterOptions()); | 222 new KeywordToken(Keyword.CLASS, offset); |
| 60 recorder.source = source; | 223 |
| 61 return recorder; | 224 Token identifier(String value, int offset) => |
| 225 new StringToken(TokenType.IDENTIFIER, value, offset); | |
| 226 | |
| 227 Token openParen(int offset) => | |
| 228 new StringToken(TokenType.OPEN_PAREN, '{', offset); | |
| 229 | |
| 230 Token closeParen(int offset) => | |
| 231 new StringToken(TokenType.CLOSE_PAREN, '}', offset); | |
| 232 | |
| 233 Token chain(List<Token> tokens) { | |
| 234 for (var i = 0; i < tokens.length - 1; ++i) { | |
| 235 tokens[i].setNext(tokens[i+1]); | |
| 236 } | |
| 237 return tokens[0]; | |
| 62 } | 238 } |
| 239 | |
| 240 EditRecorder newRecorder(source) => | |
| 241 new EditRecorder(new FormatterOptions())..source = source; | |
| 242 | |
| 243 String doFormat(recorder) => | |
| 244 new EditOperation().apply(recorder.editStore.edits, recorder.source); | |
| 245 | |
| 246 String formatCU(src, {options: const FormatterOptions()}) => | |
| 247 new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src); | |
| 248 | |
| 249 expectCUFormatsTo(src, expected) => expect(formatCU(src), equals(expected)); | |
| OLD | NEW |