| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- var vows = require('vows'),
- assert = require('assert'),
- selectorGrammar = require(__dirname + '/grammarInvoker');
- var shouldParse = function() {
- var selector,
- context = {
- topic: function() {
- selector = this.context.name;
- selectorGrammar.parse(selector, this.callback);
- }
- };
- context['should parse selector'] = function(err, parsedSelector) {
- if(err) {
- assert.fail(err.inner.toString());
- } else {
- assert.equal(parsedSelector, selector);
- }
- };
- return context;
- };
- var shouldParseTo = function(expectedSelector) {
- var context = {
- topic: function() {
- var selector = this.context.name;
- selectorGrammar.parse(selector, this.callback);
- }
- };
- context['should parse selector'] = function(err, parsedSelector) {
- if(err) {
- assert.fail(err.inner.toString());
- } else {
- assert.equal(parsedSelector, expectedSelector);
- }
- };
- return context;
- };
- vows.describe('Summarized Selectors').addBatch({
- // Taken from http://www.w3.org/TR/css3-selectors/#selectors
- '*': shouldParse(),
- 'E': shouldParse(),
- 'E[foo]': shouldParse(),
- 'E[foo="bar"]': shouldParse(),
- 'E[foo~="bar"]': shouldParse(),
- 'E[foo^="bar"]': shouldParse(),
- 'E[foo$="bar"]': shouldParse(),
- 'E[foo*="bar"]': shouldParse(),
- 'E[foo|="en"]': shouldParse(),
- 'E:root': shouldParse(),
- 'E:nth-child(n)': shouldParse(),
- 'E:nth-last-child(n)': shouldParse(),
- 'E:nth-of-type(n)': shouldParse(),
- 'E:nth-last-of-type(n)': shouldParse(),
- 'E:first-child': shouldParse(),
- 'E:last-child': shouldParse(),
- 'E:first-of-type': shouldParse(),
- 'E:last-of-type': shouldParse(),
- 'E:only-child': shouldParse(),
- 'E:only-of-type': shouldParse(),
- 'E:empty': shouldParse(),
- 'E:link': shouldParse(),
- 'E:visited': shouldParse(),
- 'E:active': shouldParse(),
- 'E:hover': shouldParse(),
- 'E:focus': shouldParse(),
- 'E:target': shouldParse(),
- 'E:lang(fr)': shouldParse(),
- 'E:enabled': shouldParse(),
- 'E:disabled': shouldParse(),
- 'E:checked': shouldParse(),
- 'E::first-line': shouldParse(),
- 'E::first-letter': shouldParse(),
- 'E::before': shouldParse(),
- 'E::after': shouldParse(),
- 'E.warning': shouldParse(),
- 'E#myid': shouldParse(),
- 'E:not(s)': shouldParse(),
- 'E F': shouldParse(),
- 'E > F': shouldParse(),
- 'E + F': shouldParse(),
- 'E ~ F': shouldParse()
- }).run();
- vows.describe('Lonely Selectors').addBatch({
- // Taken from http://www.w3.org/TR/css3-selectors/#selectors,
- // but without the element names
- '[foo]': shouldParse(),
- '[foo="bar"]': shouldParse(),
- '[foo~="bar"]': shouldParse(),
- '[foo^="bar"]': shouldParse(),
- '[foo$="bar"]': shouldParse(),
- '[foo*="bar"]': shouldParse(),
- '[foo|="en"]': shouldParse(),
- ':root': shouldParse(),
- ':nth-child(n)': shouldParse(),
- ':nth-last-child(n)': shouldParse(),
- ':nth-of-type(n)': shouldParse(),
- ':nth-last-of-type(n)': shouldParse(),
- ':first-child': shouldParse(),
- ':last-child': shouldParse(),
- ':first-of-type': shouldParse(),
- ':last-of-type': shouldParse(),
- ':only-child': shouldParse(),
- ':only-of-type': shouldParse(),
- ':empty': shouldParse(),
- ':link': shouldParse(),
- ':visited': shouldParse(),
- ':active': shouldParse(),
- ':hover': shouldParse(),
- ':focus': shouldParse(),
- ':target': shouldParse(),
- ':lang(fr)': shouldParse(),
- ':enabled': shouldParse(),
- ':disabled': shouldParse(),
- ':checked': shouldParse(),
- '::first-line': shouldParse(),
- '::first-letter': shouldParse(),
- '::before': shouldParse(),
- '::after': shouldParse(),
- '.warning': shouldParse(),
- '#myid': shouldParse(),
- ':not(s)': shouldParse()
- }).run();
- vows.describe('Attribute Selectors with Identifiers').addBatch({
- '[foo~=bar]': shouldParse(),
- '[foo^=bar]': shouldParse(),
- '[foo$=bar]': shouldParse(),
- '[foo*=bar]': shouldParse(),
- '[foo|=en]': shouldParse()
- }).run();
- vows.describe('Nth Selectors').addBatch({
- ':nth-child(-n)': shouldParse(),
- ':nth-child(+n)': shouldParse(),
- ':nth-child(even)': shouldParse(),
- ':nth-child(odd)': shouldParse(),
- ':nth-child(50)': shouldParse(),
- ':nth-child(-50)': shouldParse(),
- ':nth-child(+50)': shouldParse(),
- ':nth-child(2n+3)': shouldParse(),
- ':nth-child(2n-3)': shouldParse(),
- ':nth-child(+2n-3)': shouldParse(),
- ':nth-child(-2n+3)': shouldParse(),
- ':nth-child(-2n+ 3)': shouldParse(),
- ':nth-child(-2n+ 3)': shouldParse(),
- ':nth-child(-2n+ 3)': shouldParse(),
- ':nth-child( 2n + 3 )': shouldParseTo(':nth-child(2n + 3)')
- }).run();
- vows.describe('Negation Selectors').addBatch({
- ':not(foo|bar)': shouldParse(),
- ':not(*|bar)': shouldParse(),
- ':not(foo|*)': shouldParse(),
- ':not(*|*)': shouldParse(),
- ':not(#blah)': shouldParse(),
- ':not(.blah)': shouldParse(),
- ':not([foo])': shouldParse(),
- ':not([foo^="bar"])': shouldParse(),
- ':not([baz|foo~="bar"])': shouldParse(),
- ':not(:hover)': shouldParse(),
- ':not(:nth-child(2n + 3))': shouldParse(),
- // Not technically allowed, but what the heck
- ':not(:not(#foo))': shouldParse(),
- ':not(a#foo.bar)': shouldParse(),
- ':not(#foo .bar > baz)': shouldParse(),
- ':not(h1, h2, h3)': shouldParse()
- }).run();
- vows.describe('moz-any Selector').addBatch({
- ':-moz-any(h1, h2, h3)': shouldParse(),
- ':-moz-any(.foo)': shouldParse(),
- ':-moz-any(foo bar, .baz > .bang)': shouldParse()
- }).run();
- vows.describe('Namespaced Selectors').addBatch({
- 'foo|E': shouldParse(),
- '*|E': shouldParse(),
- 'foo|*': shouldParse(),
- '*|*': shouldParse()
- }).run();
- vows.describe('Namespaced Attribute Selectors').addBatch({
- '[foo|bar=baz]': shouldParse(),
- '[*|bar=baz]': shouldParse(),
- '[foo|bar|=baz]': shouldParse()
- }).run();
- vows.describe('Comma Selectors').addBatch({
- 'E, F': shouldParse(),
- 'E F, G H': shouldParse(),
- 'E > F, G > H': shouldParse()
- }).run();
- vows.describe('Selectors with Newlines').addBatch({
- "E,\nF": shouldParse(),
- "E\nF": shouldParse(),
- "E, F\nG, H": shouldParse()
- }).run();
- vows.describe('Expression Fallback Selectors').addBatch({
- '0%': shouldParse(),
- '60%': shouldParse(),
- '100%': shouldParse(),
- '12px': shouldParse(),
- '"foo"': shouldParse()
- }).run();
- vows.describe('Functional Pseudo Selectors').addBatch({
- ':foo("bar")': shouldParse(),
- ':foo(bar)': shouldParse(),
- ':foo(12px)': shouldParse(),
- ':foo(+)': shouldParse(),
- ':foo(-)': shouldParse(),
- ':foo(+"bar")': shouldParse(),
- ':foo(-++--baz-"bar"12px)': shouldParse()
- }).run();
- vows.describe('Selector Hacks').addBatch({
- '> E': shouldParse(),
- '+ E': shouldParse(),
- '~ E': shouldParse(),
- '> > E': shouldParse(),
- '>> E': shouldParseTo('> > E'),
- 'E*': shouldParse(),
- 'E*.foo': shouldParse(),
- 'E*:hover': shouldParse()
- }).run();
|