Index: packages/csslib/test/nested_test.dart |
diff --git a/packages/csslib/test/nested_test.dart b/packages/csslib/test/nested_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1848ef13b3764c361ef5e7e5dab58e0b0fd18680 |
--- /dev/null |
+++ b/packages/csslib/test/nested_test.dart |
@@ -0,0 +1,631 @@ |
+// 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 nested_test; |
+ |
+import 'package:test/test.dart'; |
+ |
+import 'testing.dart'; |
+ |
+compileAndValidate(String input, String generated) { |
+ var errors = []; |
+ var stylesheet = compileCss(input, errors: errors, opts: simpleOptions); |
+ expect(stylesheet != null, true); |
+ expect(errors.isEmpty, true, reason: errors.toString()); |
+ expect(prettyPrint(stylesheet), generated); |
+} |
+ |
+selectorVariations() { |
+ final input1 = r'''html { color: red; }'''; |
+ final generated1 = r'''html { |
+ color: #f00; |
+}'''; |
+ compileAndValidate(input1, generated1); |
+ |
+ final input2 = r'''button { span { height: 200 } }'''; |
+ final generated2 = r'''button { |
+} |
+button span { |
+ height: 200; |
+}'''; |
+ compileAndValidate(input2, generated2); |
+ |
+ final input3 = r'''div { color: red; } button { span { height: 200 } }'''; |
+ final generated3 = r'''div { |
+ color: #f00; |
+} |
+button { |
+} |
+button span { |
+ height: 200; |
+}'''; |
+ compileAndValidate(input3, generated3); |
+ |
+ final input4 = r'''#header { color: red; h1 { font-size: 26px; } }'''; |
+ final generated4 = r'''#header { |
+ color: #f00; |
+} |
+#header h1 { |
+ font-size: 26px; |
+}'''; |
+ compileAndValidate(input4, generated4); |
+ |
+ final input5 = r''' |
+#header { |
+ color: red; |
+ h1 { font-size: 26px; } |
+ background-color: blue; |
+}'''; |
+ final generated5 = r'''#header { |
+ color: #f00; |
+ background-color: #00f; |
+} |
+#header h1 { |
+ font-size: 26px; |
+}'''; |
+ compileAndValidate(input5, generated5); |
+ |
+ final input6 = r'''html { body {color: red; }}'''; |
+ final generated6 = r'''html { |
+} |
+html body { |
+ color: #f00; |
+}'''; |
+ compileAndValidate(input6, generated6); |
+ |
+ final input7 = r'''html body {color: red; }'''; |
+ final generated7 = r'''html body { |
+ color: #f00; |
+}'''; |
+ compileAndValidate(input7, generated7); |
+ |
+ final input8 = r''' |
+html, body { color: red; } |
+button { height: 200 } |
+body { width: 300px; }'''; |
+ final generated8 = r'''html, body { |
+ color: #f00; |
+} |
+button { |
+ height: 200; |
+} |
+body { |
+ width: 300px; |
+}'''; |
+ compileAndValidate(input8, generated8); |
+ |
+ final input9 = ''' |
+html, body { |
+ color: red; |
+ button { height: 200 } |
+ div { width: 300px; } |
+}'''; |
+ final generated9 = r'''html, body { |
+ color: #f00; |
+} |
+html button, body button { |
+ height: 200; |
+} |
+html div, body div { |
+ width: 300px; |
+}'''; |
+ compileAndValidate(input9, generated9); |
+ |
+ final input10 = ''' |
+html { |
+ color: red; |
+ button, div { height: 200 } |
+ body { width: 300px; } |
+}'''; |
+ final generated10 = r'''html { |
+ color: #f00; |
+} |
+html button, html div { |
+ height: 200; |
+} |
+html body { |
+ width: 300px; |
+}'''; |
+ compileAndValidate(input10, generated10); |
+ |
+ final input11 = ''' |
+html, body { |
+ color: red; |
+ button, div { height: 200 } |
+ table { width: 300px; } |
+}'''; |
+ final generated11 = r'''html, body { |
+ color: #f00; |
+} |
+html button, body button, html div, body div { |
+ height: 200; |
+} |
+html table, body table { |
+ width: 300px; |
+}'''; |
+ compileAndValidate(input11, generated11); |
+ |
+ final input12 = ''' |
+html, body { |
+ color: red; |
+ button, div { |
+ span, a, ul { height: 200 } |
+ } |
+ table { width: 300px; } |
+}'''; |
+ final generated12 = r'''html, body { |
+ color: #f00; |
+} |
+''' |
+ 'html button span, body button span, html div span, body div span, ' |
+ 'html button a, body button a, html div a, body div a, html button ul, ' |
+ r'''body button ul, html div ul, body div ul { |
+ height: 200; |
+} |
+html table, body table { |
+ width: 300px; |
+}'''; |
+ compileAndValidate(input12, generated12); |
+ |
+ final input13 = r''' |
+#header { |
+ div { |
+ width: 100px; |
+ a { height: 200px; } |
+ } |
+ color: blue; |
+} |
+span { color: #1f1f1f; } |
+'''; |
+ final generated13 = r'''#header { |
+ color: #00f; |
+} |
+#header div { |
+ width: 100px; |
+} |
+#header div a { |
+ height: 200px; |
+} |
+span { |
+ color: #1f1f1f; |
+}'''; |
+ compileAndValidate(input13, generated13); |
+} |
+ |
+void simpleNest() { |
+ final input = ''' |
+div span { color: green; } |
+#header { |
+ color: red; |
+ h1 { |
+ font-size: 26px; |
+ font-weight: bold; |
+ } |
+ p { |
+ font-size: 12px; |
+ a { |
+ text-decoration: none; |
+ } |
+ } |
+ background-color: blue; |
+} |
+div > span[attr="foo"] { color: yellow; } |
+'''; |
+ |
+ final generated = r'''div span { |
+ color: #008000; |
+} |
+#header { |
+ color: #f00; |
+ background-color: #00f; |
+} |
+#header h1 { |
+ font-size: 26px; |
+ font-weight: bold; |
+} |
+#header p { |
+ font-size: 12px; |
+} |
+#header p a { |
+ text-decoration: none; |
+} |
+div > span[attr="foo"] { |
+ color: #ff0; |
+}'''; |
+ compileAndValidate(input, generated); |
+} |
+ |
+void complexNest() { |
+ final input = ''' |
+@font-face { font-family: arial; } |
+div { color: #f0f0f0; } |
+#header + div { |
+ color: url(abc.png); |
+ *[attr="bar"] { |
+ font-size: 26px; |
+ font-weight: bold; |
+ } |
+ p~ul { |
+ font-size: 12px; |
+ :not(p) { |
+ text-decoration: none; |
+ div > span[attr="foo"] { color: yellow; } |
+ } |
+ } |
+ background-color: blue; |
+ span { |
+ color: red; |
+ .one { color: blue; } |
+ .two { color: green; } |
+ .three { color: yellow; } |
+ .four { |
+ .four-1 { background-color: #00000f; } |
+ .four-2 { background-color: #0000ff; } |
+ .four-3 { background-color: #000fff; } |
+ .four-4 { |
+ height: 44px; |
+ .four-4-1 { height: 10px; } |
+ .four-4-2 { height: 20px; } |
+ .four-4-3 { height: 30px; } |
+ width: 44px; |
+ } |
+ } |
+ } |
+} |
+span { color: #1f1f2f; } |
+'''; |
+ |
+ final generated = r'''@font-face { |
+ font-family: arial; |
+} |
+div { |
+ color: #f0f0f0; |
+} |
+#header + div { |
+ color: url("abc.png"); |
+ background-color: #00f; |
+} |
+#header + div *[attr="bar"] { |
+ font-size: 26px; |
+ font-weight: bold; |
+} |
+#header + div p ~ ul { |
+ font-size: 12px; |
+} |
+#header + div p ~ ul :not(p) { |
+ text-decoration: none; |
+} |
+#header + div p ~ ul :not(p) div > span[attr="foo"] { |
+ color: #ff0; |
+} |
+#header + div span { |
+ color: #f00; |
+} |
+#header + div span .one { |
+ color: #00f; |
+} |
+#header + div span .two { |
+ color: #008000; |
+} |
+#header + div span .three { |
+ color: #ff0; |
+} |
+#header + div span .four .four-1 { |
+ background-color: #00000f; |
+} |
+#header + div span .four .four-2 { |
+ background-color: #00f; |
+} |
+#header + div span .four .four-3 { |
+ background-color: #000fff; |
+} |
+#header + div span .four .four-4 { |
+ height: 44px; |
+ width: 44px; |
+} |
+#header + div span .four .four-4 .four-4-1 { |
+ height: 10px; |
+} |
+#header + div span .four .four-4 .four-4-2 { |
+ height: 20px; |
+} |
+#header + div span .four .four-4 .four-4-3 { |
+ height: 30px; |
+} |
+span { |
+ color: #1f1f2f; |
+}'''; |
+ |
+ compileAndValidate(input, generated); |
+} |
+ |
+void mediaNesting() { |
+ final input = r''' |
+@media screen and (-webkit-min-device-pixel-ratio:0) { |
+ #toggle-all { |
+ image: url(test.jpb); |
+ div, table { |
+ background: none; |
+ a { width: 100px; } |
+ } |
+ color: red; |
+ } |
+} |
+'''; |
+ final generated = r'''@media screen AND (-webkit-min-device-pixel-ratio:0) { |
+#toggle-all { |
+ image: url("test.jpb"); |
+ color: #f00; |
+} |
+#toggle-all div, #toggle-all table { |
+ background: none; |
+} |
+#toggle-all div a, #toggle-all table a { |
+ width: 100px; |
+} |
+}'''; |
+ |
+ compileAndValidate(input, generated); |
+} |
+ |
+void simpleThis() { |
+ final input = '''#header { |
+ h1 { |
+ font-size: 26px; |
+ font-weight: bold; |
+ } |
+ p { font-size: 12px; |
+ a { text-decoration: none; |
+ &:hover { border-width: 1px } |
+ } |
+ } |
+} |
+'''; |
+ |
+ final generated = r'''#header { |
+} |
+#header h1 { |
+ font-size: 26px; |
+ font-weight: bold; |
+} |
+#header p { |
+ font-size: 12px; |
+} |
+#header p a { |
+ text-decoration: none; |
+} |
+#header p a:hover { |
+ border-width: 1px; |
+}'''; |
+ |
+ compileAndValidate(input, generated); |
+} |
+ |
+void complexThis() { |
+ final input1 = r''' |
+.light { |
+ .leftCol { |
+ .textLink { |
+ color: fooL1; |
+ &:hover { color: barL1;} |
+ } |
+ .picLink { |
+ background-image: url(/fooL1.jpg); |
+ &:hover { background-image: url(/barL1.jpg);} |
+ } |
+ .textWithIconLink { |
+ color: fooL2; |
+ background-image: url(/fooL2.jpg); |
+ &:hover { color: barL2; background-image: url(/barL2.jpg);} |
+ } |
+ } |
+}'''; |
+ |
+ final generated1 = r'''.light { |
+} |
+.light .leftCol .textLink { |
+ color: fooL1; |
+} |
+.light .leftCol .textLink:hover { |
+ color: barL1; |
+} |
+.light .leftCol .picLink { |
+ background-image: url("/fooL1.jpg"); |
+} |
+.light .leftCol .picLink:hover { |
+ background-image: url("/barL1.jpg"); |
+} |
+.light .leftCol .textWithIconLink { |
+ color: fooL2; |
+ background-image: url("/fooL2.jpg"); |
+} |
+.light .leftCol .textWithIconLink:hover { |
+ color: barL2; |
+ background-image: url("/barL2.jpg"); |
+}'''; |
+ |
+ compileAndValidate(input1, generated1); |
+ |
+ final input2 = r''' |
+.textLink { |
+ .light .leftCol & { |
+ color: fooL1; |
+ &:hover { color: barL1; } |
+ } |
+ .light .rightCol & { |
+ color: fooL3; |
+ &:hover { color: barL3; } |
+ } |
+}'''; |
+ |
+ final generated2 = r''' |
+.textLink { |
+} |
+.light .leftCol .textLink { |
+ color: fooL1; |
+} |
+.light .leftCol .textLink:hover { |
+ color: barL1; |
+} |
+.light .rightCol .textLink { |
+ color: fooL3; |
+} |
+.light .rightCol .textLink:hover { |
+ color: barL3; |
+}'''; |
+ |
+ compileAndValidate(input2, generated2); |
+} |
+ |
+variationsThis() { |
+ final input1 = r''' |
+.textLink { |
+ a { |
+ light .leftCol & { |
+ color: red; |
+ } |
+ } |
+}'''; |
+ final generated1 = r'''.textLink { |
+} |
+light .leftCol .textLink a { |
+ color: #f00; |
+}'''; |
+ |
+ compileAndValidate(input1, generated1); |
+ |
+ final input2 = r'''.textLink { |
+ a { |
+ & light .leftCol & { |
+ color: red; |
+ } |
+ } |
+}'''; |
+ final generated2 = r'''.textLink { |
+} |
+.textLink a light .leftCol .textLink a { |
+ color: #f00; |
+}'''; |
+ compileAndValidate(input2, generated2); |
+ |
+ final input3 = r''' |
+.textLink { |
+ a { |
+ & light .leftCol { color: red; } |
+ } |
+}'''; |
+ final generated3 = r'''.textLink { |
+} |
+.textLink a light .leftCol { |
+ color: #f00; |
+}'''; |
+ compileAndValidate(input3, generated3); |
+ |
+ final input4 = r''' |
+.textLink { |
+ a { |
+ & light .leftCol { color: red; } |
+ &:hover { width: 100px; } |
+ } |
+}'''; |
+ final generated4 = r'''.textLink { |
+} |
+.textLink a light .leftCol { |
+ color: #f00; |
+} |
+.textLink a:hover { |
+ width: 100px; |
+}'''; |
+ compileAndValidate(input4, generated4); |
+ |
+ final input5 = r'''.textLink { a { &:hover { color: red; } } }'''; |
+ final generated5 = r'''.textLink { |
+} |
+.textLink a:hover { |
+ color: #f00; |
+}'''; |
+ |
+ compileAndValidate(input5, generated5); |
+ |
+ final input6 = r'''.textLink { &:hover { color: red; } }'''; |
+ final generated6 = r'''.textLink { |
+} |
+.textLink:hover { |
+ color: #f00; |
+}'''; |
+ compileAndValidate(input6, generated6); |
+ |
+ final input7 = r'''.textLink { a { & + & { color: red; } } }'''; |
+ final generated7 = r'''.textLink { |
+} |
+.textLink a + .textLink a { |
+ color: #f00; |
+}'''; |
+ compileAndValidate(input7, generated7); |
+ |
+ final input8 = r'''.textLink { a { & { color: red; } } }'''; |
+ final generated8 = r'''.textLink { |
+} |
+.textLink a { |
+ color: #f00; |
+}'''; |
+ compileAndValidate(input8, generated8); |
+ |
+ final input9 = r'''.textLink { a { & ~ & { color: red; } } }'''; |
+ final generated9 = r'''.textLink { |
+} |
+.textLink a ~ .textLink a { |
+ color: #f00; |
+}'''; |
+ compileAndValidate(input9, generated9); |
+ |
+ final input10 = r'''.textLink { a { & & { color: red; } } }'''; |
+ final generated10 = r'''.textLink { |
+} |
+.textLink a .textLink a { |
+ color: #f00; |
+}'''; |
+ compileAndValidate(input10, generated10); |
+} |
+ |
+thisCombinator() { |
+ var input = r''' |
+.btn { |
+ color: red; |
+} |
+.btn + .btn { |
+ margin-left: 5px; |
+} |
+input.second { |
+ & + label { |
+ color: blue; |
+ } |
+} |
+'''; |
+ |
+ var generated = r'''.btn { |
+ color: #f00; |
+} |
+.btn + .btn { |
+ margin-left: 5px; |
+} |
+input.second { |
+} |
+input.second + label { |
+ color: #00f; |
+}'''; |
+ |
+ compileAndValidate(input, generated); |
+} |
+ |
+main() { |
+ test('Selector and Nested Variations', selectorVariations); |
+ test('Simple nesting', simpleNest); |
+ test('Complex nesting', complexNest); |
+ test('@media nesting', mediaNesting); |
+ test('Simple &', simpleThis); |
+ test("Variations &", variationsThis); |
+ test('Complex &', complexThis); |
+ test('& with + selector', thisCombinator); |
+} |