Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: pkg/analyzer_experimental/test/services/formatter_test.dart

Issue 18346013: Formatter re-think/updates. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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'; 5 import 'package:unittest/unittest.dart';
6 6
7 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'; 8 import 'package:analyzer_experimental/src/generated/scanner.dart';
9 import 'package:analyzer_experimental/src/services/formatter.dart'; 9 import 'package:analyzer_experimental/src/services/formatter.dart';
10 import 'package:analyzer_experimental/src/services/formatter_impl.dart'; 10 import 'package:analyzer_experimental/src/services/formatter_impl.dart';
11 import 'package:analyzer_experimental/src/services/writer.dart';
11 12
12 main() { 13 main() {
13 14
14 /// Edit recorder tests
15 group('edit recorder', () {
16
17 test('countWhitespace', (){
18 expect(newRecorder(' ').countWhitespace(), equals(3));
19 expect(newRecorder('').countWhitespace(), equals(0));
20 expect(newRecorder(' foo').countWhitespace(), equals(2));
21 });
22
23 test('isNewlineAt', (){
24 expect(newRecorder('012\n').isNewlineAt(3), isTrue);
25 expect(newRecorder('012\n3456').isNewlineAt(3), isTrue);
26 expect(newRecorder('\n').isNewlineAt(0), isTrue);
27 });
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
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));
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
135 });
136
137
138 /// Formatter tests 15 /// Formatter tests
139 group('formatter', () { 16 group('formatter', () {
140 17
141 test('failed parse', () { 18 test('failed parse', () {
142 var formatter = new CodeFormatter(); 19 var formatter = new CodeFormatter();
143 expect(() => formatter.format(CodeKind.COMPILATION_UNIT, '~'), 20 expect(() => formatter.format(CodeKind.COMPILATION_UNIT, '~'),
144 throwsA(new isInstanceOf<FormatterException>())); 21 throwsA(new isInstanceOf<FormatterException>()));
145 }); 22 });
146 23
147 test('CU (1)', () { 24 test('CU (1)', () {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 'class A {\n' 62 'class A {\n'
186 'void x(){\n' 63 'void x(){\n'
187 '}\n' 64 '}\n'
188 '}', 65 '}',
189 'class A {\n' 66 'class A {\n'
190 ' void x() {\n' 67 ' void x() {\n'
191 ' }\n' 68 ' }\n'
192 '}' 69 '}'
193 ); 70 );
194 }); 71 });
195 72 //
196 test('CU (method indent - 2)', () { 73 // test('CU (method indent - 2)', () {
197 expectCUFormatsTo( 74 // expectCUFormatsTo(
198 'class A {\n' 75 // 'class A {\n'
199 ' static void x(){}\n' 76 // ' static bool x(){ return true; }\n'
200 ' }', 77 // ' }',
201 'class A {\n' 78 // 'class A {\n'
202 ' static void x() {\n' 79 // ' static bool x() {\n'
203 ' }\n' 80 // ' return true;\n'
204 '}' 81 // ' }\n'
205 ); 82 // '}'
206 }); 83 // );
207 84 // });
85 //
86 // test('CU (method indent - 3)', () {
87 // expectCUFormatsTo(
88 // 'class A {\n'
89 // ' int x() => 42 + 3 ; \n'
90 // ' }',
91 // 'class A {\n'
92 // ' int x() => 42 + 3;\n'
93 // '}'
94 // );
95 // });
96 //
97 // test('CU (method indent - 4)', () {
98 // expectCUFormatsTo(
99 // 'class A {\n'
100 // ' int x() { \n'
101 // 'if (true) {return 42;\n'
102 // '} else { return false; }\n'
103 // ' }'
104 // '}',
105 // 'class A {\n'
106 // ' int x() {\n'
107 // ' if (true) {\n'
108 // ' return 42;\n'
109 // ' } else {\n'
110 // ' return false;\n'
111 // ' }\n'
112 // '}'
113 // );
114 // });
208 115
209 116
210 // test('initialIndent', () { 117 // test('initialIndent', () {
211 // var formatter = new CodeFormatter( 118 // var formatter = new CodeFormatter(
212 // new FormatterOptions(initialIndentationLevel:2)); 119 // new FormatterOptions(initialIndentationLevel: 2));
213 // var formattedSource = formatter.format(CodeKind.STATEMENT, 'var x;'); 120 // var formattedSource = formatter.format(CodeKind.STATEMENT, 'var x;');
214 // expect(formattedSource, startsWith(' ')); 121 // expect(formattedSource, startsWith(' '));
215 // }); 122 // });
216 123
217 }); 124 });
218 125
126
127 /// Line tests
128 group('line', () {
129
130 test('space', () {
131 var line = new Line(indent: 0);
132 line.addSpaces(2);
133 expect(line.toString(), equals(' '));
134 });
135
136 test('initial indent', () {
137 var line = new Line(indent: 2);
138 expect(line.toString(), equals(' '));
139 });
140
141 test('initial indent (tabbed)', () {
142 var line = new Line(indent:1, useTabs: true);
143 expect(line.toString(), equals('\t'));
144 });
145
146 test('addToken', () {
147 var line = new Line();
148 line.addToken(new LineToken('foo'));
149 expect(line.toString(), equals('foo'));
150 });
151
152 test('addToken (2)', () {
153 var line = new Line(indent: 1);
154 line.addToken(new LineToken('foo'));
155 expect(line.toString(), equals(' foo'));
156 });
157
158 });
159
160
161 /// Writer tests
162 group('writer', () {
163
164 test('basic print', () {
165 var writer = new SourceWriter();
166 writer.print('foo');
167 writer.print(' ');
168 writer.print('bar');
169 expect(writer.toString(), equals('foo bar'));
170 });
171
172 test('newline', () {
173 var writer = new SourceWriter();
174 writer.print('foo');
175 writer.newline();
176 expect(writer.toString(), equals('foo\n'));
177 });
178
179 test('basic print (with indents)', () {
180 var writer = new SourceWriter();
181 writer.print('foo');
182 writer.indent();
183 writer.newline();
184 writer.print('bar');
185 writer.unindent();
186 writer.newline();
187 writer.print('baz');
188 expect(writer.toString(), equals('foo\n bar\nbaz'));
189 });
190
191 });
192
193
194 /// Helper method tests
195 group('helpers', () {
196
197 test('indentString', () {
198 expect(getIndentString(0), '');
199 expect(getIndentString(1), ' ');
200 expect(getIndentString(4), ' ');
201 });
202
203 test('indentString (tabbed)', () {
204 expect(getIndentString(0, useTabs: true), '');
205 expect(getIndentString(1, useTabs: true), '\t');
206 expect(getIndentString(3, useTabs: true), '\t\t\t');
207 });
208
209 test('repeat', () {
210 expect(repeat('x', 0), '');
211 expect(repeat('x', 1), 'x');
212 expect(repeat('x', 4), 'xxxx');
213 });
214
215 });
216
219 } 217 }
220 218
221 Token classKeyword(int offset) => 219 Token classKeyword(int offset) =>
222 new KeywordToken(Keyword.CLASS, offset); 220 new KeywordToken(Keyword.CLASS, offset);
223 221
224 Token identifier(String value, int offset) => 222 Token identifier(String value, int offset) =>
225 new StringToken(TokenType.IDENTIFIER, value, offset); 223 new StringToken(TokenType.IDENTIFIER, value, offset);
226 224
227 Token openParen(int offset) => 225 Token openParen(int offset) =>
228 new StringToken(TokenType.OPEN_PAREN, '{', offset); 226 new StringToken(TokenType.OPEN_PAREN, '{', offset);
229 227
230 Token closeParen(int offset) => 228 Token closeParen(int offset) =>
231 new StringToken(TokenType.CLOSE_PAREN, '}', offset); 229 new StringToken(TokenType.CLOSE_PAREN, '}', offset);
232 230
233 Token chain(List<Token> tokens) { 231 Token chain(List<Token> tokens) {
234 for (var i = 0; i < tokens.length - 1; ++i) { 232 for (var i = 0; i < tokens.length - 1; ++i) {
235 tokens[i].setNext(tokens[i + 1]); 233 tokens[i].setNext(tokens[i + 1]);
236 } 234 }
237 return tokens[0]; 235 return tokens[0];
238 } 236 }
239 237
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()}) => 238 String formatCU(src, {options: const FormatterOptions()}) =>
247 new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src); 239 new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src);
248 240
249 expectCUFormatsTo(src, expected) => expect(formatCU(src), equals(expected)); 241 expectCUFormatsTo(src, expected) => expect(formatCU(src), equals(expected));
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698