Index: packages/csslib/test/extend_test.dart |
diff --git a/packages/csslib/test/extend_test.dart b/packages/csslib/test/extend_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..49c8a9c46169c0bea8ace01e8ed020006bcc723f |
--- /dev/null |
+++ b/packages/csslib/test/extend_test.dart |
@@ -0,0 +1,234 @@ |
+// 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 extend_test; |
+ |
+import 'package:test/test.dart'; |
+ |
+import 'testing.dart'; |
+ |
+compileAndValidate(String input, String generated) { |
+ var errors = []; |
+ var stylesheet = compileCss(input, errors: errors, opts: options); |
+ expect(stylesheet != null, true); |
+ expect(errors.isEmpty, true, reason: errors.toString()); |
+ expect(prettyPrint(stylesheet), generated); |
+} |
+ |
+void simpleExtend() { |
+ compileAndValidate(r''' |
+.error { |
+ border: 1px red; |
+ background-color: #fdd; |
+} |
+.seriousError { |
+ @extend .error; |
+ border-width: 3px; |
+} |
+''', r'''.error, .seriousError { |
+ border: 1px #f00; |
+ background-color: #fdd; |
+} |
+.seriousError { |
+ border-width: 3px; |
+}'''); |
+} |
+ |
+void complexSelectors() { |
+ compileAndValidate(r''' |
+.error { |
+ border: 1px #f00; |
+ background-color: #fdd; |
+} |
+.error.intrusion { |
+ background-image: url("/image/hacked.png"); |
+} |
+.seriousError { |
+ @extend .error; |
+ border-width: 3px; |
+} |
+''', r'''.error, .seriousError { |
+ border: 1px #f00; |
+ background-color: #fdd; |
+} |
+.error.intrusion, .seriousError.intrusion { |
+ background-image: url("/image/hacked.png"); |
+} |
+.seriousError { |
+ border-width: 3px; |
+}'''); |
+ |
+ compileAndValidate(r''' |
+a:hover { |
+ text-decoration: underline; |
+} |
+.hoverlink { |
+ @extend a:hover; |
+} |
+''', r'''a:hover, .hoverlink { |
+ text-decoration: underline; |
+} |
+.hoverlink { |
+}'''); |
+} |
+ |
+void multipleExtends() { |
+ compileAndValidate(r''' |
+.error { |
+ border: 1px #f00; |
+ background-color: #fdd; |
+} |
+.attention { |
+ font-size: 3em; |
+ background-color: #ff0; |
+} |
+.seriousError { |
+ @extend .error; |
+ @extend .attention; |
+ border-width: 3px; |
+} |
+''', r'''.error, .seriousError { |
+ border: 1px #f00; |
+ background-color: #fdd; |
+} |
+.attention, .seriousError { |
+ font-size: 3em; |
+ background-color: #ff0; |
+} |
+.seriousError { |
+ border-width: 3px; |
+}'''); |
+} |
+ |
+void chaining() { |
+ compileAndValidate(r''' |
+.error { |
+ border: 1px #f00; |
+ background-color: #fdd; |
+} |
+.seriousError { |
+ @extend .error; |
+ border-width: 3px; |
+} |
+.criticalError { |
+ @extend .seriousError; |
+ position: fixed; |
+ top: 10%; |
+ bottom: 10%; |
+ left: 10%; |
+ right: 10%; |
+} |
+''', r'''.error, .seriousError, .criticalError { |
+ border: 1px #f00; |
+ background-color: #fdd; |
+} |
+.seriousError, .criticalError { |
+ border-width: 3px; |
+} |
+.criticalError { |
+ position: fixed; |
+ top: 10%; |
+ bottom: 10%; |
+ left: 10%; |
+ right: 10%; |
+}'''); |
+} |
+ |
+void nestedSelectors() { |
+ compileAndValidate(r''' |
+a { |
+ color: blue; |
+ &:hover { |
+ text-decoration: underline; |
+ } |
+} |
+ |
+#fake-links .link { |
+ @extend a; |
+} |
+''', r'''a, #fake-links .link { |
+ color: #00f; |
+} |
+a:hover, #fake-links .link:hover { |
+ text-decoration: underline; |
+} |
+#fake-links .link { |
+}'''); |
+} |
+ |
+void nestedMulty() { |
+ compileAndValidate(r''' |
+.btn { |
+ display: inline-block; |
+} |
+ |
+input[type="checkbox"].toggle-button { |
+ color: red; |
+ |
+ + label { |
+ @extend .btn; |
+ } |
+} |
+''', r'''.btn, input[type="checkbox"].toggle-button label { |
+ display: inline-block; |
+} |
+input[type="checkbox"].toggle-button { |
+ color: #f00; |
+} |
+input[type="checkbox"].toggle-button label { |
+}'''); |
+} |
+ |
+void nWayExtends() { |
+ compileAndValidate(r''' |
+.btn > .btn { |
+ margin-left: 5px; |
+} |
+input.second + label { |
+ @extend .btn; |
+} |
+''', '.btn > .btn, ' |
+ 'input.second + label > .btn, ' |
+ '.btn > input.second + label, ' |
+ 'input.second + label > input.second + label, ' |
+ 'input.second + label > input.second + label {\n' |
+ ' margin-left: 5px;\n}\n' |
+ 'input.second + label {\n' |
+ '}'); |
+ |
+ // TODO(terry): Optimize merge selectors would be: |
+ // |
+ // .btn + .btn, input.second + label + .btn, input.second.btn + label { |
+ // margin-left: 5px; |
+ // } |
+ // input.second + label { |
+ // color: blue; |
+ // } |
+ compileAndValidate(r''' |
+.btn + .btn { |
+ margin-left: 5px; |
+} |
+input.second + label { |
+ @extend .btn; |
+ color: blue; |
+} |
+''', '.btn + .btn, ' |
+ 'input.second + label + .btn, ' |
+ '.btn + input.second + label, ' |
+ 'input.second + label + input.second + label, ' |
+ 'input.second + label + input.second + label {\n' |
+ ' margin-left: 5px;\n}\n' |
+ 'input.second + label {\n' |
+ ' color: #00f;\n}'); |
+} |
+ |
+main() { |
+ test("Simple Extend", simpleExtend); |
+ test("complex", complexSelectors); |
+ test("multiple", multipleExtends); |
+ test("chaining", chaining); |
+ test("nested selectors", nestedSelectors); |
+ test("nested many selector sequences", nestedMulty); |
+ test("N-way extends", nWayExtends); |
+} |