| // 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. | |
| 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); | |
| } |