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

Unified 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 side-by-side diff with in-line comments
Download patch
« pkg/polymer/lib/src/transform/common.dart ('K') | « pkg/polymer/test/run_all.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/polymer/test/validator_test.dart
diff --git a/pkg/polymer/test/validator_test.dart b/pkg/polymer/test/validator_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..4333020d6c8a72638d1856816866a00a8c35995a
--- /dev/null
+++ b/pkg/polymer/test/validator_test.dart
@@ -0,0 +1,421 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library polymer.test.validator_test;
+
+import 'package:source_maps/span.dart';
+import 'package:polymer/src/validator.dart';
+import 'package:unittest/compact_vm_config.dart';
+import 'package:unittest/unittest.dart';
+
+import 'transform/common.dart';
+
+void main() {
+ useCompactVMConfiguration();
+ _testValidator('nothing to report', {
+ 'a|web/test.html': '<!DOCTYPE html><html></html>',
+ }, {
+ 'a|web/test.html.messages': '',
+ });
+
+ group('doctype warning', () {
+ _testValidator('in web', {
+ 'a|web/test.html': '<html></html>',
+ }, {
+ 'a|web/test.html.messages':
+ 'warning: Unexpected start tag (html). Expected DOCTYPE. '
+ '(web/test.html 0 0)',
+ });
+
+ _testValidator('in lib', {
+ 'a|lib/test.html': '<html></html>',
+ }, {
+ 'a|lib/test.html.messages': '',
+ });
+ });
+
+ group('duplicate polymer-elements,', () {
+ _testValidator('same file', {
+ 'a|lib/test.html': '''<html>
+ <polymer-element name="x-a"></polymer-element>
+ <polymer-element name="x-a"></polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: duplicate definition for custom tag "x-a". '
+ '(lib/test.html 1 0)\n'
+ 'warning: duplicate definition for custom tag "x-a" '
+ '(second definition). (lib/test.html 2 0)'
+ });
+
+ _testValidator('other file', {
+ 'a|lib/b.html': '''<html>
+ <polymer-element name="x-a"></polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ 'a|lib/test.html': '''<html>
+ <link rel="import" href="b.html">
+ <polymer-element name="x-a"></polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: duplicate definition for custom tag "x-a". '
+ '(lib/b.html 1 0)\n'
+ 'warning: duplicate definition for custom tag "x-a" '
+ '(second definition). (lib/test.html 2 0)'
+ });
+
+ _testValidator('other package', {
+ 'b|lib/b.html': '''<html>
+ <polymer-element name="x-a"></polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ 'a|lib/test.html': '''<html>
+ <link rel="import" href="packages/b/b.html">
+ <polymer-element name="x-a"></polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: duplicate definition for custom tag "x-a". '
+ '(package:b/b.html 1 0)\n'
+ 'warning: duplicate definition for custom tag "x-a" '
+ '(second definition). (lib/test.html 2 0)'
+ });
+ });
+
+ _testValidator('bad link-rel tag (href missing)', {
+ 'a|lib/test.html': '''<html>
+ <link rel="import">
+ <link rel="stylesheet">
+ <link rel="foo">
+ <link rel="import" href="">
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: link rel="import" missing href. (lib/test.html 1 0)\n'
+ 'warning: link rel="stylesheet" missing href. (lib/test.html 2 0)\n'
+ 'warning: link rel="import" missing href. (lib/test.html 4 0)'
+ });
+
+ _testValidator('<element> is not supported', {
+ 'a|lib/test.html': '''<html>
+ <element name="x-a"></element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: <element> elements are not supported, use <polymer-element>'
+ ' instead (lib/test.html 1 0)'
+ });
+
+ _testValidator('do not nest <polymer-element>', {
+ 'a|lib/test.html': '''<html>
+ <polymer-element name="x-a">
+ <template><div>
+ <polymer-element name="b"></polymer-element>
+ </div></template>
+ </polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'error: Nested polymer element definitions are not allowed.'
+ ' (lib/test.html 3 4)'
+ });
+
+ _testValidator('need a name for <polymer-element>', {
+ 'a|lib/test.html': '''<html>
+ <polymer-element></polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'error: Missing tag name of the custom element. Please include an '
+ 'attribute like \'name="your-tag-name"\'. (lib/test.html 1 0)'
+ });
+
+ _testValidator('name for <polymer-element> should have dashes', {
+ 'a|lib/test.html': '''<html>
+ <polymer-element name="a"></polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'error: Invalid name "a". Custom element names must have at least one'
+ ' dash and can\'t be any of the following names: annotation-xml, '
+ 'color-profile, font-face, font-face-src, font-face-uri, '
+ 'font-face-format, font-face-name, missing-glyph. (lib/test.html 1 0)'
+ });
+
+ _testValidator('extend is a valid element or existing tag', {
+ 'a|lib/test.html': '''<html>
+ <polymer-element name="x-a" extends="li"></polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages': ''
+ });
+
+ _testValidator('extend is a valid element or existing tag', {
+ 'a|lib/test.html': '''<html>
+ <polymer-element name="x-a" extends="x-b"></polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages': ''
+ 'warning: custom element with name "x-b" not found. '
+ '(lib/test.html 1 0)'
+ });
+
+
+ group('script type matches code', () {
+ _testValidator('top-level, .dart url', {
+ 'a|lib/test.html': '''<html>
+ <script src="foo.dart"></script>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: script tag with .dart source file but no type will be '
+ 'treated as JavaScript. Did you forget type="application/dart"?'
+ ' (lib/test.html 1 0)'
+ });
+
+ _testValidator('in polymer-element, .dart url', {
+ 'a|lib/test.html': '''<html>
+ <polymer-element name="x-a">
+ <script src="foo.dart"></script>
+ </polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: script tag with .dart source file but no type will be '
+ 'treated as JavaScript. Did you forget type="application/dart"?'
+ ' (lib/test.html 2 0)'
+ });
+
+ _testValidator('in polymer-element, .js url', {
+ 'a|lib/test.html': '''<html>
+ <polymer-element name="x-a">
+ <script src="foo.js"></script>
+ </polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages': ''
+ });
+
+ _testValidator('in polymer-element, inlined', {
+ 'a|lib/test.html': '''<html>
+ <polymer-element name="x-a">
+ <script>foo...</script>
+ </polymer-element>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: script tag in polymer element with no type will '
+ 'be treated as JavaScript. Did you forget type="application/dart"?'
+ ' (lib/test.html 2 0)'
+ });
+
+ _testValidator('top-level, dart type & .dart url', {
+ 'a|lib/test.html': '''<html>
+ <script type="applicatino/dart" src="foo.dart"></script>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages': ''
+ });
+
+ _testValidator('top-level, dart type & .js url', {
+ 'a|lib/test.html': '''<html>
+ <script type="application/dart" src="foo.js"></script>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: "application/dart" scripts should use the .dart file '
+ 'extension. (lib/test.html 1 0)'
+ });
+ });
+
+ _testValidator('script tags should have only src url or inline code', {
+ 'a|lib/test.html': '''<html>
+ <script type="application/dart" src="foo.dart">more</script>
+ </html>'''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: script tag has "src" attribute and also has script text. '
+ '(lib/test.html 1 0)'
+ });
+
+ group('event handlers', () {
+ _testValidator('onfoo is not polymer', {
+ 'a|lib/test.html': '''<html><body>
+ <div onfoo="something"></div>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: Event handler "onfoo" will be interpreted as an inline '
+ 'JavaScript event handler. Use the form '
+ 'on-event-name="handlerName" if you want a Dart handler '
+ 'that will automatically update the UI based on model changes. '
+ '(lib/test.html 1 0)'
+ });
+
+ _testValidator('on-foo is only supported in polymer elements', {
+ 'a|lib/test.html': '''<html><body>
+ <div on-foo="something"></div>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: Inline event handlers are only supported inside '
+ 'declarations of <polymer-element>. '
+ '(lib/test.html 1 0)'
+ });
+
+ _testValidator('on-foo is not an expression', {
+ 'a|lib/test.html': '''<html><body>
+ <polymer-element name="x-a"><div on-foo="bar()"></div>
+ </polymer-element>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: Invalid event handler body "bar()". Declare a method '
+ 'in your custom element "void handlerName(event, detail, target)" '
+ 'and use the form on-foo="handlerName". '
+ '(lib/test.html 1 28)'
+ });
+ });
+
+ group('using custom tags', () {
+ _testValidator('tag exists (x-tag)', {
+ 'a|lib/test.html': '<x-foo></x-foo>',
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: definition for custom element with tag name "x-foo" not '
+ 'found. (lib/test.html 0 0)'
+ });
+
+ _testValidator('tag exists (type extension)', {
+ 'a|lib/test.html': '<div is="x-foo"></div>',
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: definition for custom element with tag name "x-foo" not '
+ 'found. (lib/test.html 0 0)'
+ });
+
+ _testValidator('used correctly (no base tag)', {
+ 'a|lib/test.html': '''
+ <polymer-element name="x-a"></polymer-element>
+ <x-a></x-a>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages': ''
+ });
+
+ _testValidator('used incorrectly (no base tag)', {
+ 'a|lib/test.html': '''
+ <polymer-element name="x-a"></polymer-element>
+ <div is="x-a"></div>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: custom element "x-a" doesn\'t declare any type '
+ 'extensions. To fix this, either rewrite this tag as '
+ '<x-a> or add \'extends="div"\' to '
+ 'the custom element declaration. (lib/test.html 1 0)'
+ });
+
+ _testValidator('used incorrectly, imported def (no base tag)', {
+ 'a|lib/b.html': '<polymer-element name="x-a"></polymer-element>',
+ 'a|lib/test.html': '''
+ <link rel="import" href="b.html">
+ <div is="x-a"></div>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: custom element "x-a" doesn\'t declare any type '
+ 'extensions. To fix this, either rewrite this tag as '
+ '<x-a> or add \'extends="div"\' to '
+ 'the custom element declaration. (lib/test.html 1 0)'
+ });
+
+ _testValidator('used correctly (base tag)', {
+ 'a|lib/b.html': '''
+ <polymer-element name="x-a" extends="div">
+ </polymer-element>
+ '''.replaceAll(' ', ''),
+ 'a|lib/test.html': '''
+ <link rel="import" href="b.html">
+ <div is="x-a"></div>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages': ''
+ });
+
+ _testValidator('used incorrectly (missing base tag)', {
+ 'a|lib/b.html': '''
+ <polymer-element name="x-a" extends="div">
+ </polymer-element>
+ '''.replaceAll(' ', ''),
+ 'a|lib/test.html': '''
+ <link rel="import" href="b.html">
+ <x-a></x-a>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages': ''
+ 'warning: custom element "x-a" extends from "div", but this tag '
+ 'will not include the default properties of "div". To fix this, '
+ 'either write this tag as <div is="x-a"> or remove the "extends" '
+ 'attribute from the custom element declaration. (lib/test.html 1 0)'
+ });
+
+ _testValidator('used incorrectly (wrong base tag)', {
+ 'a|lib/b.html': '''
+ <polymer-element name="x-a" extends="div">
+ </polymer-element>
+ '''.replaceAll(' ', ''),
+ 'a|lib/test.html': '''
+ <link rel="import" href="b.html">
+ <span is="x-a"></span>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages': ''
+ 'warning: custom element "x-a" extends from "div". Did you mean '
+ 'to write <div is="x-a">? (lib/test.html 1 0)'
+ });
+
+ _testValidator('used incorrectly (wrong base tag, transitive)', {
+ 'a|lib/c.html': '''
+ <polymer-element name="x-c" extends="li">
+ </polymer-element>
+ <polymer-element name="x-b" extends="x-c">
+ </polymer-element>
+ '''.replaceAll(' ', ''),
+ 'a|lib/b.html': '''
+ <link rel="import" href="c.html">
+ <polymer-element name="x-a" extends="x-b">
+ </polymer-element>
+ '''.replaceAll(' ', ''),
+ 'a|lib/test.html': '''
+ <link rel="import" href="b.html">
+ <span is="x-a"></span>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages': ''
+ 'warning: custom element "x-a" extends from "li". Did you mean '
+ 'to write <li is="x-a">? (lib/test.html 1 0)'
+ });
+ });
+}
+
+_testValidator(String name, Map inputFiles, Map outputMessages) {
+ var validator = new Validator(_testFormatter);
+ var outputFiles = {};
+ inputFiles.forEach((k, v) => outputFiles[k] = v);
+ outputMessages.forEach((k, v) => outputFiles[k] = v);
+ var keys = inputFiles.keys.toSet();
+ keys.retainAll(outputMessages.keys);
+ expect(keys, isEmpty);
+ testPhases(name, [[validator]], inputFiles, outputFiles);
+}
+
+
+_testFormatter(String kind, String message, Span span) {
+ var formattedMessage = '$kind: $message';
+ if (span != null) {
+ formattedMessage = '$formattedMessage '
+ '(${span.sourceUrl} ${span.start.line} ${span.start.column})';
+ }
+ return formattedMessage;
+}
« pkg/polymer/lib/src/transform/common.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