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

Side by Side Diff: pkg/polymer/test/validator_test.dart

Issue 23452010: Add a polymer validator: a linter/analysis that will replace the old (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library polymer.test.validator_test;
6
7 import 'package:source_maps/span.dart';
8 import 'package:polymer/src/validator.dart';
9 import 'package:unittest/compact_vm_config.dart';
10 import 'package:unittest/unittest.dart';
11
12 import 'transform/common.dart';
13
14 void main() {
15 useCompactVMConfiguration();
16 _testValidator('nothing to report', {
17 'a|web/test.html': '<!DOCTYPE html><html></html>',
18 }, {
19 'a|web/test.html.messages': '',
20 });
21
22 group('doctype warning', () {
23 _testValidator('in web', {
24 'a|web/test.html': '<html></html>',
25 }, {
26 'a|web/test.html.messages':
27 'warning: Unexpected start tag (html). Expected DOCTYPE. '
28 '(web/test.html 0 0)',
29 });
30
31 _testValidator('in lib', {
32 'a|lib/test.html': '<html></html>',
33 }, {
34 'a|lib/test.html.messages': '',
35 });
36 });
37
38 group('duplicate polymer-elements,', () {
39 _testValidator('same file', {
40 'a|lib/test.html': '''<html>
41 <polymer-element name="a"></polymer-element>
42 <polymer-element name="a"></polymer-element>
43 </html>'''.replaceAll(' ', ''),
44 }, {
45 'a|lib/test.html.messages':
46 'warning: duplicate definition for custom tag "a". '
47 '(lib/test.html 1 0)\n'
48 'warning: duplicate definition for custom tag "a" '
49 '(second definition). (lib/test.html 2 0)'
50 });
51
52 _testValidator('other file', {
53 'a|lib/b.html': '''<html>
54 <polymer-element name="a"></polymer-element>
55 </html>'''.replaceAll(' ', ''),
56 'a|lib/test.html': '''<html>
57 <link rel="import" href="b.html">
58 <polymer-element name="a"></polymer-element>
59 </html>'''.replaceAll(' ', ''),
60 }, {
61 'a|lib/test.html.messages':
62 'warning: duplicate definition for custom tag "a". '
63 '(lib/b.html 1 0)\n'
64 'warning: duplicate definition for custom tag "a" '
65 '(second definition). (lib/test.html 2 0)'
66 });
67
68 _testValidator('other package', {
69 'b|lib/b.html': '''<html>
70 <polymer-element name="a"></polymer-element>
71 </html>'''.replaceAll(' ', ''),
72 'a|lib/test.html': '''<html>
73 <link rel="import" href="packages/b/b.html">
74 <polymer-element name="a"></polymer-element>
75 </html>'''.replaceAll(' ', ''),
76 }, {
77 'a|lib/test.html.messages':
78 'warning: duplicate definition for custom tag "a". '
79 '(package:b/b.html 1 0)\n'
80 'warning: duplicate definition for custom tag "a" '
81 '(second definition). (lib/test.html 2 0)'
82 });
83 });
84
85 _testValidator('bad link-rel tag (href missing)', {
86 'a|lib/test.html': '''<html>
87 <link rel="import">
88 <link rel="stylesheet">
89 <link rel="foo">
90 <link rel="import" href="">
91 </html>'''.replaceAll(' ', ''),
92 }, {
93 'a|lib/test.html.messages':
94 'warning: link rel="import" missing href. (lib/test.html 1 0)\n'
95 'warning: link rel="stylesheet" missing href. (lib/test.html 2 0)\n'
96 'warning: link rel="import" missing href. (lib/test.html 4 0)'
97 });
98
99 _testValidator('<element> is not supported', {
100 'a|lib/test.html': '''<html>
101 <element name="a"></element>
102 </html>'''.replaceAll(' ', ''),
103 }, {
104 'a|lib/test.html.messages':
105 'warning: <element> elements are not supported, use <polymer-element>'
106 ' instead (lib/test.html 1 0)'
107 });
108
109 _testValidator('do not nest <polymer-element>', {
110 'a|lib/test.html': '''<html>
111 <polymer-element name="a">
112 <template><div>
113 <polymer-element name="b"></polymer-element>
114 </div></template>
115 </polymer-element>
116 </html>'''.replaceAll(' ', ''),
117 }, {
118 'a|lib/test.html.messages':
119 'error: Nested polymer element definitions are not allowed.'
120 ' (lib/test.html 3 4)'
121 });
122
123 _testValidator('need a name for <polymer-element>', {
124 'a|lib/test.html': '''<html>
125 <polymer-element></polymer-element>
126 </html>'''.replaceAll(' ', ''),
127 }, {
128 'a|lib/test.html.messages':
129 'error: Missing tag name of the custom element. Please include an '
130 'attribute like \'name="your-tag-name"\'. (lib/test.html 1 0)'
131 });
132
133 _testValidator('extend is a valid element or existing tag', {
134 'a|lib/test.html': '''<html>
135 <polymer-element name="x-a" extends="li"></polymer-element>
136 </html>'''.replaceAll(' ', ''),
137 }, {
138 'a|lib/test.html.messages': ''
139 });
140
141 _testValidator('extend is a valid element or existing tag', {
142 'a|lib/test.html': '''<html>
143 <polymer-element name="x-a" extends="x-b"></polymer-element>
144 </html>'''.replaceAll(' ', ''),
145 }, {
146 'a|lib/test.html.messages': ''
147 'warning: custom element with name "x-b" not found. '
148 '(lib/test.html 1 0)'
149 });
150
151
152 group('script type matches code', () {
153 _testValidator('top-level, .dart url', {
154 'a|lib/test.html': '''<html>
155 <script src="foo.dart"></script>
156 </html>'''.replaceAll(' ', ''),
157 }, {
158 'a|lib/test.html.messages':
159 'warning: script tag with .dart source file but no type will be '
160 'treated as JavaScript. Did you forget type="application/dart"?'
161 ' (lib/test.html 1 0)'
162 });
163
164 _testValidator('in polymer-element, .dart url', {
165 'a|lib/test.html': '''<html>
166 <polymer-element name="a">
167 <script src="foo.dart"></script>
168 </polymer-element>
169 </html>'''.replaceAll(' ', ''),
170 }, {
171 'a|lib/test.html.messages':
172 'warning: script tag with .dart source file but no type will be '
173 'treated as JavaScript. Did you forget type="application/dart"?'
174 ' (lib/test.html 2 0)'
175 });
176
177 _testValidator('in polymer-element, .js url', {
178 'a|lib/test.html': '''<html>
179 <polymer-element name="a">
180 <script src="foo.js"></script>
181 </polymer-element>
182 </html>'''.replaceAll(' ', ''),
183 }, {
184 'a|lib/test.html.messages': ''
185 });
186
187 _testValidator('in polymer-element, inlined', {
188 'a|lib/test.html': '''<html>
189 <polymer-element name="a">
190 <script>foo...</script>
191 </polymer-element>
192 </html>'''.replaceAll(' ', ''),
193 }, {
194 'a|lib/test.html.messages':
195 'warning: script tag in polymer element with no type will '
196 'be treated as JavaScript. Did you forget type="application/dart"?'
197 ' (lib/test.html 2 0)'
198 });
199
200 _testValidator('top-level, dart type & .dart url', {
201 'a|lib/test.html': '''<html>
202 <script type="applicatino/dart" src="foo.dart"></script>
203 </html>'''.replaceAll(' ', ''),
204 }, {
205 'a|lib/test.html.messages': ''
206 });
207
208 _testValidator('top-level, dart type & .js url', {
209 'a|lib/test.html': '''<html>
210 <script type="application/dart" src="foo.js"></script>
211 </html>'''.replaceAll(' ', ''),
212 }, {
213 'a|lib/test.html.messages':
214 'warning: "application/dart" scripts should use the .dart file '
215 'extension. (lib/test.html 1 0)'
216 });
217 });
218
219 _testValidator('script tags should have only src url or inline code', {
220 'a|lib/test.html': '''<html>
221 <script type="application/dart" src="foo.dart">more</script>
222 </html>'''.replaceAll(' ', ''),
223 }, {
224 'a|lib/test.html.messages':
225 'warning: script tag has "src" attribute and also has script text. '
226 '(lib/test.html 1 0)'
227 });
228
229 group('event handlers', () {
230 _testValidator('onfoo is not polymer', {
231 'a|lib/test.html': '''<html><body>
232 <div onfoo="something"></div>
233 '''.replaceAll(' ', ''),
234 }, {
235 'a|lib/test.html.messages':
236 'warning: Event handler "onfoo" will be interpreted as an inline '
237 'JavaScript event handler. Use the form '
238 'on-event-name="handlerName" if you want a Dart handler '
239 'that will automatically update the UI based on model changes. '
240 '(lib/test.html 1 0)'
241 });
242
243 _testValidator('on-foo is only supported in polymer elements', {
244 'a|lib/test.html': '''<html><body>
245 <div on-foo="something"></div>
246 '''.replaceAll(' ', ''),
247 }, {
248 'a|lib/test.html.messages':
249 'warning: Inline event handlers are only supported inside '
250 'declarations of <polymer-element>. '
251 '(lib/test.html 1 0)'
252 });
253
254 _testValidator('on-foo is not an expression', {
255 'a|lib/test.html': '''<html><body>
256 <polymer-element name="a"><div on-foo="bar()"></div>
257 </polymer-element>
258 '''.replaceAll(' ', ''),
259 }, {
260 'a|lib/test.html.messages':
261 'warning: Invalid event handler body "bar()". Declare a method '
262 'in your custom element "void handlerName(event, detail, target)" '
263 'and use the form on-foo="handlerName". '
264 '(lib/test.html 1 26)'
265 });
266 });
267
268 group('using custom tags', () {
269 _testValidator('tag exists (x-tag)', {
270 'a|lib/test.html': '<x-foo></x-foo>',
271 }, {
272 'a|lib/test.html.messages':
273 'warning: definition for custom element with tag name "x-foo" not '
274 'found. (lib/test.html 0 0)'
275 });
276
277 _testValidator('tag exists (type extension)', {
278 'a|lib/test.html': '<div is="x-foo"></div>',
279 }, {
280 'a|lib/test.html.messages':
281 'warning: definition for custom element with tag name "x-foo" not '
282 'found. (lib/test.html 0 0)'
283 });
284
285 _testValidator('used correctly (no base tag)', {
286 'a|lib/test.html': '''
287 <polymer-element name="x-a"></polymer-element>
288 <x-a></x-a>
289 '''.replaceAll(' ', ''),
290 }, {
291 'a|lib/test.html.messages': ''
292 });
293
294 _testValidator('used incorrectly (no base tag)', {
295 'a|lib/test.html': '''
296 <polymer-element name="x-a"></polymer-element>
297 <div is="x-a"></div>
298 '''.replaceAll(' ', ''),
299 }, {
300 'a|lib/test.html.messages':
301 'warning: custom element "x-a" doesn\'t declare any type '
302 'extensions. To fix this, either rewrite this tag as '
303 '<x-a> or add \'extends="div"\' to '
304 'the custom element declaration. (lib/test.html 1 0)'
305 });
306
307 _testValidator('used incorrectly, imported def (no base tag)', {
308 'a|lib/b.html': '<polymer-element name="x-a"></polymer-element>',
309 'a|lib/test.html': '''
310 <link rel="import" href="b.html">
311 <div is="x-a"></div>
312 '''.replaceAll(' ', ''),
313 }, {
314 'a|lib/test.html.messages':
315 'warning: custom element "x-a" doesn\'t declare any type '
316 'extensions. To fix this, either rewrite this tag as '
317 '<x-a> or add \'extends="div"\' to '
318 'the custom element declaration. (lib/test.html 1 0)'
319 });
320
321 _testValidator('used correctly (base tag)', {
322 'a|lib/b.html': '''
323 <polymer-element name="x-a" extends="div">
324 </polymer-element>
325 '''.replaceAll(' ', ''),
326 'a|lib/test.html': '''
327 <link rel="import" href="b.html">
328 <div is="x-a"></div>
329 '''.replaceAll(' ', ''),
330 }, {
331 'a|lib/test.html.messages': ''
332 });
333
334 _testValidator('used incorrectly (missing base tag)', {
335 'a|lib/b.html': '''
336 <polymer-element name="x-a" extends="div">
337 </polymer-element>
338 '''.replaceAll(' ', ''),
339 'a|lib/test.html': '''
340 <link rel="import" href="b.html">
341 <x-a></x-a>
342 '''.replaceAll(' ', ''),
343 }, {
344 'a|lib/test.html.messages': ''
345 'warning: custom element "x-a" extends from "div", but this tag '
346 'will not include the default properties of "div". To fix this, '
347 'either write this tag as <div is="x-a"> or remove the "extends" '
348 'attribute from the custom element declaration. (lib/test.html 1 0)'
349 });
350
351 _testValidator('used incorrectly (wrong base tag)', {
352 'a|lib/b.html': '''
353 <polymer-element name="x-a" extends="div">
354 </polymer-element>
355 '''.replaceAll(' ', ''),
356 'a|lib/test.html': '''
357 <link rel="import" href="b.html">
358 <span is="x-a"></span>
359 '''.replaceAll(' ', ''),
360 }, {
361 'a|lib/test.html.messages': ''
362 'warning: custom element "x-a" extends from "div". Did you mean '
363 'to write <div is="x-a">? (lib/test.html 1 0)'
364 });
365
366 _testValidator('used incorrectly (wrong base tag, transitive)', {
367 'a|lib/c.html': '''
368 <polymer-element name="x-c" extends="li">
369 </polymer-element>
370 <polymer-element name="x-b" extends="x-c">
371 </polymer-element>
372 '''.replaceAll(' ', ''),
373 'a|lib/b.html': '''
374 <link rel="import" href="c.html">
375 <polymer-element name="x-a" extends="x-b">
376 </polymer-element>
377 '''.replaceAll(' ', ''),
378 'a|lib/test.html': '''
379 <link rel="import" href="b.html">
380 <span is="x-a"></span>
381 '''.replaceAll(' ', ''),
382 }, {
383 'a|lib/test.html.messages': ''
384 'warning: custom element "x-a" extends from "li". Did you mean '
385 'to write <li is="x-a">? (lib/test.html 1 0)'
386 });
387 });
388 }
389
390 _testValidator(String name, Map inputFiles, Map outputMessages) {
391 var validator = new Validator(_testFormatter);
392 var outputFiles = {};
393 inputFiles.forEach((k, v) => outputFiles[k] = v);
394 outputMessages.forEach((k, v) => outputFiles[k] = v);
395 var keys = inputFiles.keys.toSet();
396 keys.retainAll(outputMessages.keys);
397 expect(keys, isEmpty);
398 testPhases(name, [[validator]], inputFiles, outputFiles);
399 }
400
401
402 _testFormatter(String kind, String message, Span span) {
403 var formattedMessage = '$kind: $message';
404 if (span != null) {
405 formattedMessage = '$formattedMessage '
406 '(${span.sourceUrl} ${span.start.line} ${span.start.column})';
407 }
408 return formattedMessage;
409 }
OLDNEW
« pkg/polymer/lib/src/validator.dart ('K') | « pkg/polymer/test/run_all.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698