| // Copyright (c) 2012, 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 compiler_test; |
| |
| import 'dart:convert'; |
| |
| import 'package:csslib/parser.dart'; |
| import 'package:csslib/visitor.dart'; |
| import 'package:test/test.dart'; |
| |
| import 'testing.dart'; |
| |
| void testClass() { |
| var errors = <Message>[]; |
| var input = '.foobar {}'; |
| var stylesheet = parseCss(input, errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| |
| var ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| var selectorSeqs = |
| ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| expect(selectorSeqs.length, 1); |
| final simpSelector = selectorSeqs[0].simpleSelector; |
| expect(simpSelector is ClassSelector, true); |
| expect(selectorSeqs[0].isCombinatorNone, true); |
| expect(simpSelector.name, 'foobar'); |
| } |
| |
| void testClass2() { |
| var errors = <Message>[]; |
| var input = '.foobar .bar .no-story {}'; |
| var stylesheet = parseCss(input, errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| var ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| expect(simpleSeqs.length, 3); |
| |
| var simpSelector0 = simpleSeqs[0].simpleSelector; |
| expect(simpSelector0 is ClassSelector, true); |
| expect(simpleSeqs[0].isCombinatorNone, true); |
| expect(simpSelector0.name, 'foobar'); |
| |
| var simpSelector1 = simpleSeqs[1].simpleSelector; |
| expect(simpSelector1 is ClassSelector, true); |
| expect(simpleSeqs[1].isCombinatorDescendant, true); |
| expect(simpSelector1.name, 'bar'); |
| |
| var simpSelector2 = simpleSeqs[2].simpleSelector; |
| expect(simpSelector2 is ClassSelector, true); |
| expect(simpleSeqs[2].isCombinatorDescendant, true); |
| expect(simpSelector2.name, 'no-story'); |
| } |
| |
| void testId() { |
| var errors = <Message>[]; |
| var input = '#elemId {}'; |
| var stylesheet = parseCss(input, errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| var ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| |
| expect(simpleSeqs.length, 1); |
| var simpSelector = simpleSeqs[0].simpleSelector; |
| expect(simpSelector is IdSelector, true); |
| expect(simpleSeqs[0].isCombinatorNone, true); |
| expect(simpSelector.name, 'elemId'); |
| } |
| |
| void testElement() { |
| var errors = <Message>[]; |
| var input = 'div {}'; |
| var stylesheet = parseCss(input, errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| var ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| |
| expect(simpleSeqs.length, 1); |
| |
| final simpSelector = simpleSeqs[0].simpleSelector; |
| expect(simpSelector is ElementSelector, true); |
| expect(simpleSeqs[0].isCombinatorNone, true); |
| expect(simpSelector.name, 'div'); |
| |
| input = 'div div span {}'; |
| stylesheet = parseCss(input, errors: errors..clear()); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| |
| expect(simpleSeqs.length, 3); |
| |
| var simpSelector0 = simpleSeqs[0].simpleSelector; |
| expect(simpSelector0 is ElementSelector, true); |
| expect(simpleSeqs[0].isCombinatorNone, true); |
| expect(simpSelector0.name, 'div'); |
| |
| var simpSelector1 = simpleSeqs[1].simpleSelector; |
| expect(simpSelector1 is ElementSelector, true); |
| expect(simpleSeqs[1].isCombinatorDescendant, true); |
| expect(simpSelector1.name, 'div'); |
| |
| var simpSelector2 = simpleSeqs[2].simpleSelector; |
| expect(simpSelector2 is ElementSelector, true); |
| expect(simpleSeqs[2].isCombinatorDescendant, true); |
| expect(simpSelector2.name, 'span'); |
| } |
| |
| void testNamespace() { |
| var errors = <Message>[]; |
| var input = 'ns1|div {}'; |
| var stylesheet = parseCss(input, errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| var ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| |
| expect(simpleSeqs.length, 1); |
| expect(simpleSeqs[0].simpleSelector is NamespaceSelector, true); |
| var simpSelector = simpleSeqs[0].simpleSelector as NamespaceSelector; |
| expect(simpleSeqs[0].isCombinatorNone, true); |
| expect(simpSelector.isNamespaceWildcard, false); |
| expect(simpSelector.namespace, 'ns1'); |
| var elementSelector = simpSelector.nameAsSimpleSelector; |
| expect(elementSelector is ElementSelector, true); |
| expect(elementSelector!.isWildcard, false); |
| expect(elementSelector.name, 'div'); |
| } |
| |
| void testNamespace2() { |
| var errors = <Message>[]; |
| var input = 'ns1|div div ns2|span .foobar {}'; |
| var stylesheet = parseCss(input, errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| var ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| |
| expect(simpleSeqs.length, 4); |
| |
| expect(simpleSeqs[0].simpleSelector is NamespaceSelector, true); |
| var simpSelector0 = simpleSeqs[0].simpleSelector as NamespaceSelector; |
| expect(simpleSeqs[0].isCombinatorNone, true); |
| expect(simpSelector0.namespace, 'ns1'); |
| var elementSelector0 = simpSelector0.nameAsSimpleSelector; |
| expect(elementSelector0 is ElementSelector, true); |
| expect(elementSelector0!.isWildcard, false); |
| expect(elementSelector0.name, 'div'); |
| |
| var simpSelector1 = simpleSeqs[1].simpleSelector; |
| expect(simpSelector1 is ElementSelector, true); |
| expect(simpleSeqs[1].isCombinatorDescendant, true); |
| expect(simpSelector1.name, 'div'); |
| |
| expect(simpleSeqs[2].simpleSelector is NamespaceSelector, true); |
| var simpSelector2 = simpleSeqs[2].simpleSelector as NamespaceSelector; |
| expect(simpleSeqs[2].isCombinatorDescendant, true); |
| expect(simpSelector2.namespace, 'ns2'); |
| var elementSelector2 = simpSelector2.nameAsSimpleSelector; |
| expect(elementSelector2 is ElementSelector, true); |
| expect(elementSelector2!.isWildcard, false); |
| expect(elementSelector2.name, 'span'); |
| |
| var simpSelector3 = simpleSeqs[3].simpleSelector; |
| expect(simpSelector3 is ClassSelector, true); |
| expect(simpleSeqs[3].isCombinatorDescendant, true); |
| expect(simpSelector3.name, 'foobar'); |
| } |
| |
| void testSelectorGroups() { |
| var errors = <Message>[]; |
| var input = |
| 'div, .foobar ,#elemId, .xyzzy .test, ns1|div div #elemId .foobar {}'; |
| var stylesheet = parseCss(input, errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| var ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 5); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| var groupSelector0 = ruleset.selectorGroup!.selectors[0]; |
| expect(groupSelector0.simpleSelectorSequences.length, 1); |
| var selector0 = groupSelector0.simpleSelectorSequences[0]; |
| var simpleSelector0 = selector0.simpleSelector; |
| expect(simpleSelector0 is ElementSelector, true); |
| expect(selector0.isCombinatorNone, true); |
| expect(simpleSelector0.name, 'div'); |
| |
| var groupSelector1 = ruleset.selectorGroup!.selectors[1]; |
| expect(groupSelector1.simpleSelectorSequences.length, 1); |
| var selector1 = groupSelector1.simpleSelectorSequences[0]; |
| var simpleSelector1 = selector1.simpleSelector; |
| expect(simpleSelector1 is ClassSelector, true); |
| expect(selector1.isCombinatorNone, true); |
| expect(simpleSelector1.name, 'foobar'); |
| |
| var groupSelector2 = ruleset.selectorGroup!.selectors[2]; |
| expect(groupSelector2.simpleSelectorSequences.length, 1); |
| var selector2 = groupSelector2.simpleSelectorSequences[0]; |
| var simpleSelector2 = selector2.simpleSelector; |
| expect(simpleSelector2 is IdSelector, true); |
| expect(selector2.isCombinatorNone, true); |
| expect(simpleSelector2.name, 'elemId'); |
| |
| var groupSelector3 = ruleset.selectorGroup!.selectors[3]; |
| expect(groupSelector3.simpleSelectorSequences.length, 2); |
| |
| var selector30 = groupSelector3.simpleSelectorSequences[0]; |
| var simpleSelector30 = selector30.simpleSelector; |
| expect(simpleSelector30 is ClassSelector, true); |
| expect(selector30.isCombinatorNone, true); |
| expect(simpleSelector30.name, 'xyzzy'); |
| |
| var selector31 = groupSelector3.simpleSelectorSequences[1]; |
| var simpleSelector31 = selector31.simpleSelector; |
| expect(simpleSelector31 is ClassSelector, true); |
| expect(selector31.isCombinatorDescendant, true); |
| expect(simpleSelector31.name, 'test'); |
| |
| var groupSelector4 = ruleset.selectorGroup!.selectors[4]; |
| expect(groupSelector4.simpleSelectorSequences.length, 4); |
| |
| var selector40 = groupSelector4.simpleSelectorSequences[0]; |
| expect(selector40.simpleSelector is NamespaceSelector, true); |
| var simpleSelector40 = selector40.simpleSelector as NamespaceSelector; |
| expect(selector40.isCombinatorNone, true); |
| expect(simpleSelector40.namespace, 'ns1'); |
| var elementSelector = simpleSelector40.nameAsSimpleSelector; |
| expect(elementSelector is ElementSelector, true); |
| expect(elementSelector!.isWildcard, false); |
| expect(elementSelector.name, 'div'); |
| |
| var selector41 = groupSelector4.simpleSelectorSequences[1]; |
| var simpleSelector41 = selector41.simpleSelector; |
| expect(simpleSelector41 is ElementSelector, true); |
| expect(selector41.isCombinatorDescendant, true); |
| expect(simpleSelector41.name, 'div'); |
| |
| var selector42 = groupSelector4.simpleSelectorSequences[2]; |
| var simpleSelector42 = selector42.simpleSelector; |
| expect(simpleSelector42 is IdSelector, true); |
| expect(selector42.isCombinatorDescendant, true); |
| expect(simpleSelector42.name, 'elemId'); |
| |
| var selector43 = groupSelector4.simpleSelectorSequences[3]; |
| var simpleSelector43 = selector43.simpleSelector; |
| expect(selector43.isCombinatorDescendant, true); |
| expect(simpleSelector43.name, 'foobar'); |
| } |
| |
| void testCombinator() { |
| var errors = <Message>[]; |
| var input = '.foobar > .bar + .no-story ~ myNs|div #elemId {}'; |
| var stylesheet = parseCss(input, errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| var ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| |
| expect(simpleSeqs.length, 5); |
| |
| var selector0 = simpleSeqs[0]; |
| var simpleSelector0 = selector0.simpleSelector; |
| expect(simpleSelector0 is ClassSelector, true); |
| expect(selector0.isCombinatorNone, true); |
| expect(simpleSelector0.name, 'foobar'); |
| |
| var selector1 = simpleSeqs[1]; |
| var simpleSelector1 = selector1.simpleSelector; |
| expect(simpleSelector1 is ClassSelector, true); |
| expect(selector1.isCombinatorGreater, true); |
| expect(simpleSelector1.name, 'bar'); |
| |
| var selector2 = simpleSeqs[2]; |
| var simpleSelector2 = selector2.simpleSelector; |
| expect(simpleSelector2 is ClassSelector, true); |
| expect(selector2.isCombinatorPlus, true); |
| expect(simpleSelector2.name, 'no-story'); |
| |
| var selector3 = simpleSeqs[3]; |
| expect(selector3.simpleSelector is NamespaceSelector, true); |
| var simpleSelector3 = selector3.simpleSelector as NamespaceSelector; |
| expect(selector3.isCombinatorTilde, true); |
| expect(simpleSelector3.namespace, 'myNs'); |
| var elementSelector = simpleSelector3.nameAsSimpleSelector; |
| expect(elementSelector is ElementSelector, true); |
| expect(elementSelector!.isWildcard, false); |
| expect(elementSelector.name, 'div'); |
| |
| var selector4 = simpleSeqs[4]; |
| var simpleSelector4 = selector4.simpleSelector; |
| expect(simpleSelector4 is IdSelector, true); |
| expect(selector4.isCombinatorDescendant, true); |
| expect(simpleSelector4.name, 'elemId'); |
| } |
| |
| void testWildcard() { |
| var errors = <Message>[]; |
| var input = '* {}'; |
| var stylesheet = parseCss(input, errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| var ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| |
| expect(simpleSeqs.length, 1); |
| var simpSelector = simpleSeqs[0].simpleSelector; |
| expect(simpSelector is ElementSelector, true); |
| expect(simpleSeqs[0].isCombinatorNone, true); |
| expect(simpSelector.isWildcard, true); |
| expect(simpSelector.name, '*'); |
| |
| input = '*.foobar {}'; |
| stylesheet = parseCss(input, errors: errors..clear()); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| |
| expect(simpleSeqs.length, 2); |
| |
| { |
| var selector0 = simpleSeqs[0]; |
| var simpleSelector0 = selector0.simpleSelector; |
| expect(simpleSelector0 is ElementSelector, true); |
| expect(selector0.isCombinatorNone, true); |
| expect(simpleSelector0.isWildcard, true); |
| expect(simpleSelector0.name, '*'); |
| } |
| |
| var selector1 = simpleSeqs[1]; |
| var simpleSelector1 = selector1.simpleSelector; |
| expect(simpleSelector1 is ClassSelector, true); |
| expect(selector1.isCombinatorNone, true); |
| expect(simpleSelector1.name, 'foobar'); |
| |
| input = 'myNs|*.foobar {}'; |
| stylesheet = parseCss(input, errors: errors..clear()); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels.length, 1); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| |
| expect(simpleSeqs.length, 2); |
| |
| { |
| var selector0 = simpleSeqs[0]; |
| expect(selector0.simpleSelector is NamespaceSelector, true); |
| var simpleSelector0 = selector0.simpleSelector as NamespaceSelector; |
| expect(selector0.isCombinatorNone, true); |
| expect(simpleSelector0.isNamespaceWildcard, false); |
| var elementSelector = simpleSelector0.nameAsSimpleSelector; |
| expect('myNs', simpleSelector0.namespace); |
| expect(elementSelector!.isWildcard, true); |
| expect('*', elementSelector.name); |
| } |
| |
| selector1 = simpleSeqs[1]; |
| simpleSelector1 = selector1.simpleSelector; |
| expect(simpleSelector1 is ClassSelector, true); |
| expect(selector1.isCombinatorNone, true); |
| expect('foobar', simpleSelector1.name); |
| |
| input = '*|*.foobar {}'; |
| stylesheet = parseCss(input, errors: errors..clear()); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(stylesheet.topLevels[0] is RuleSet, true); |
| ruleset = stylesheet.topLevels[0] as RuleSet; |
| expect(ruleset.selectorGroup!.selectors.length, 1); |
| expect(ruleset.declarationGroup.declarations.length, 0); |
| |
| simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences; |
| |
| expect(simpleSeqs.length, 2); |
| |
| { |
| var selector0 = simpleSeqs[0]; |
| expect(selector0.simpleSelector is NamespaceSelector, true); |
| var simpleSelector0 = selector0.simpleSelector as NamespaceSelector; |
| expect(selector0.isCombinatorNone, true); |
| expect(simpleSelector0.isNamespaceWildcard, true); |
| expect('*', simpleSelector0.namespace); |
| var elementSelector = simpleSelector0.nameAsSimpleSelector; |
| expect(elementSelector!.isWildcard, true); |
| expect('*', elementSelector.name); |
| } |
| |
| selector1 = simpleSeqs[1]; |
| simpleSelector1 = selector1.simpleSelector; |
| expect(simpleSelector1 is ClassSelector, true); |
| expect(selector1.isCombinatorNone, true); |
| expect('foobar', simpleSelector1.name); |
| } |
| |
| /// Test List<int> as input to parser. |
| void testArrayOfChars() { |
| var errors = <Message>[]; |
| var input = '<![CDATA[.foo { ' |
| 'color: red; left: 20px; top: 20px; width: 100px; height:200px' |
| '}' |
| '#div {' |
| 'color : #00F578; border-color: #878787;' |
| '}]]>'; |
| |
| var stylesheet = parse(utf8.encode(input), errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| expect(prettyPrint(stylesheet), r''' |
| .foo { |
| color: #f00; |
| left: 20px; |
| top: 20px; |
| width: 100px; |
| height: 200px; |
| } |
| #div { |
| color: #00F578; |
| border-color: #878787; |
| }'''); |
| } |
| |
| void testPseudo() { |
| var errors = <Message>[]; |
| |
| final input = r''' |
| html:lang(fr-ca) { quotes: '" ' ' "' } |
| zoom: { } |
| |
| a:link { color: red } |
| :link { color: blue } |
| |
| a:focus { background: yellow } |
| a:focus:hover { background: white } |
| |
| p.special:first-letter {color: #ffd800} |
| |
| p:not(#example){ |
| background-color: yellow; |
| } |
| |
| input:not([DISABLED]){ |
| background-color: yellow; |
| } |
| |
| html|*:not(:link):not(:visited) { |
| border: 1px solid black; |
| } |
| |
| *:not(FOO) { |
| height: 20px; |
| } |
| |
| *|*:not(*) { |
| color: orange; |
| } |
| |
| *|*:not(:hover) { |
| color: magenta; |
| } |
| |
| p:nth-child(3n-3) { } |
| |
| div:nth-child(2n) { color : red; } |
| '''; |
| |
| var stylesheet = parseCss(input, errors: errors, opts: simpleOptions); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), r''' |
| html:lang(fr-ca) { |
| quotes: '" ' ' "'; |
| } |
| zoom { |
| } |
| a:link { |
| color: #f00; |
| } |
| :link { |
| color: #00f; |
| } |
| a:focus { |
| background: #ff0; |
| } |
| a:focus:hover { |
| background: #fff; |
| } |
| p.special:first-letter { |
| color: #ffd800; |
| } |
| p:not(#example) { |
| background-color: #ff0; |
| } |
| input:not([DISABLED]) { |
| background-color: #ff0; |
| } |
| html|*:not(:link):not(:visited) { |
| border: 1px solid #000; |
| } |
| *:not(FOO) { |
| height: 20px; |
| } |
| *|*:not(*) { |
| color: #ffa500; |
| } |
| *|*:not(:hover) { |
| color: #f0f; |
| } |
| p:nth-child(3n-3) { |
| } |
| div:nth-child(2n) { |
| color: #f00; |
| }'''); |
| } |
| |
| void testAttribute() { |
| // TODO(terry): Implement |
| } |
| |
| void testNegation() { |
| // TODO(terry): Implement |
| } |
| |
| void testHost() { |
| var errors = <Message>[]; |
| var input = '@host { ' |
| ':scope {' |
| 'white-space: nowrap;' |
| 'overflow-style: marquee-line;' |
| 'overflow-x: marquee;' |
| '}' |
| '* { color: red; }' |
| '*:hover { font-weight: bold; }' |
| ':nth-child(odd) { color: blue; }' |
| '}'; |
| var stylesheet = parseCss(input, errors: errors, opts: simpleOptions); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), r''' |
| @host { |
| :scope { |
| white-space: nowrap; |
| overflow-style: marquee-line; |
| overflow-x: marquee; |
| } |
| * { |
| color: #f00; |
| } |
| *:hover { |
| font-weight: bold; |
| } |
| :nth-child(odd) { |
| color: #00f; |
| } |
| }'''); |
| } |
| |
| void testStringEscape() { |
| var errors = <Message>[]; |
| var input = r'''a { foo: '{"text" : "a\\\""}' }'''; |
| var stylesheet = parseCss(input, errors: errors, opts: simpleOptions); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| expect(prettyPrint(stylesheet), r''' |
| a { |
| foo: '{"text" : "a\\\""}'; |
| }'''); |
| } |
| |
| // TODO(terry): Move to emitter_test.dart when real emitter exist. |
| void testEmitter() { |
| var errors = <Message>[]; |
| var input = '.foo { ' |
| 'color: red; left: 20px; top: 20px; width: 100px; height:200px' |
| '}' |
| '#div {' |
| 'color : #00F578; border-color: #878787;' |
| '}'; |
| var stylesheet = parseCss(input, errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(prettyPrint(stylesheet), r''' |
| .foo { |
| color: #f00; |
| left: 20px; |
| top: 20px; |
| width: 100px; |
| height: 200px; |
| } |
| #div { |
| color: #00F578; |
| border-color: #878787; |
| }'''); |
| } |
| |
| void testExpressionParsing() { |
| var errors = <Message>[]; |
| var input = r''' |
| .foobar { |
| border-radius: calc(0 - 1px); |
| border-width: calc(0 + 1px); |
| }'''; |
| var stylesheet = parseCss(input, errors: errors); |
| |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| |
| walkTree(stylesheet); |
| |
| expect(prettyPrint(stylesheet), r''' |
| .foobar { |
| border-radius: calc(0 - 1px); |
| border-width: calc(0 + 1px); |
| }'''); |
| } |
| |
| void main() { |
| test('Classes', testClass); |
| test('Classes 2', testClass2); |
| test('Ids', testId); |
| test('Elements', testElement); |
| test('Namespace', testNamespace); |
| test('Namespace 2', testNamespace2); |
| test('Selector Groups', testSelectorGroups); |
| test('Combinator', testCombinator); |
| test('Wildcards', testWildcard); |
| test('Pseudo', testPseudo); |
| test('Attributes', testAttribute); |
| test('Negation', testNegation); |
| test('@host', testHost); |
| test('stringEscape', testStringEscape); |
| test('Parse List<int> as input', testArrayOfChars); |
| test('Simple Emitter', testEmitter); |
| test('Expression parsing', testExpressionParsing); |
| } |