UNPKG

stew-select

Version:

CSS selectors that allow regular expressions. Stew is a meatier soup.

1,010 lines (998 loc) 47.2 kB
// Generated by CoffeeScript 1.6.3 (function() { var HOMEDIR, HTMLPARSER_OPTIONS, LIB_DIR, Stew, TEST_HTML, fs, htmlparser, path, should; should = require('should'); fs = require('fs'); path = require('path'); HOMEDIR = path.join(__dirname, '..'); LIB_DIR = fs.existsSync(path.join(HOMEDIR, 'lib-cov')) ? path.join(HOMEDIR, 'lib-cov') : path.join(HOMEDIR, 'lib'); htmlparser = require('htmlparser'); Stew = require(path.join(LIB_DIR, 'stew')).Stew; HTMLPARSER_OPTIONS = { ignoreWhitespace: false, caseSensitiveTags: false, caseSensitiveAttr: false }; TEST_HTML = "<html>\n <body>\n <div class=\"outer odd\" id=\"outer-1\">\n <div class=\"inner odd\" id=\"inner-1-1\" lang=\"en-gb\"><span width=17>A</span></div>\n <div class=\"inner even\" id=\"inner-1-2\" lang=\"en\"><b foo=\"bar\">B</b></div>\n </div>\n <div class=\"outer even\" id=\"outer-2\">\n <div class=\"inner odd\" id=\"inner-2-1\" lang=\"en-us\"><b fact=\"white space is ok here\"><i>C</i></b></div>\n <div class=\"inner even\" id=\"inner-2-2\"><em extra=\"contains spaces, commas and symbols like + and /\">D</em></div>\n </div>\n <section>\n <span id=\"escaped-quote-test\" label='this label includes \"quote\" marks'></span>\n </section>\n </body>\n</html>"; describe("Stew", function() { var _this = this; beforeEach(function(done) { var handler, parser, _this = this; this.stew = new Stew(); handler = new htmlparser.DefaultHandler(function(err, dom) { _this.DOM = dom; return done(); }); parser = new htmlparser.Parser(handler, HTMLPARSER_OPTIONS); return parser.parseComplete(TEST_HTML); }); afterEach(function(done) { _this.stew = null; _this.DOM = null; return done(); }); describe("(fixed bugs)", function() { return it("handles colon (:) in unquoted attribute values", function(done) { var html; html = '<html><head><meta property="og:title" content="Stew"/><meta property="og:type" content="githubog:gitrepository"/></head></html>'; return this.stew.select(html, 'meta[property=og:type]', function(err, nodeset) { should.not.exist(err); nodeset.length.should.equal(1); nodeset[0].attribs.content.should.equal("githubog:gitrepository"); return done(); }); }); }); it('can parse a selector string into a list of predictes ', function(done) { var selector; selector = this.stew._parse_selectors('tag .foo #bar [/x/i] [y=/z/]'); (typeof selector).should.equal('function'); return done(); }); describe("select_first()", function() { it('supports the any-tag selector (`*`)', function(done) { var node; node = this.stew.select_first(this.DOM, 'div *'); node.type.should.equal('tag'); node.name.should.equal('div'); node.attribs.id.should.equal('inner-1-1'); return done(); }); it('supports the type selector (`E`)', function(done) { var node; node = this.stew.select_first(this.DOM, 'em'); node.type.should.equal('tag'); node.name.should.equal('em'); node = this.stew.select_first(this.DOM, 'div'); node.type.should.equal('tag'); node.name.should.equal('div'); node.attribs.id.should.equal('outer-1'); return done(); }); it('invokes a callback, if provided', function(done) { return this.stew.select_first(this.DOM, 'em', function(err, node) { node.type.should.equal('tag'); node.name.should.equal('em'); return done(); }); }); it('can also parse a string into a DOM automatically, if given a callback', function(done) { return this.stew.select_first(TEST_HTML, 'em', function(err, node) { node.type.should.equal('tag'); node.name.should.equal('em'); return done(); }); }); return it('throws an exception when given an HTML string but no callback', function(done) { var _this = this; (function() { return _this.stew.select_first(TEST_HTML, 'em'); }).should["throw"](/callback/); return done(); }); }); return describe("select()", function() { it('can also parse a string into a DOM automatically, if given a callback', function(done) { return this.stew.select(TEST_HTML, 'em', function(err, nodeset) { nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('em'); return done(); }); }); it('invokes a callback, when provided', function(done) { return this.stew.select(this.DOM, 'em', function(err, nodeset) { nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('em'); return done(); }); }); it('throws an exception when given an HTML string but no callback', function(done) { var _this = this; (function() { return _this.stew.select(TEST_HTML, 'em'); }).should["throw"](/callback/); return done(); }); it('supports the any-tag selector (`*`)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div *'); nodeset.length.should.equal(9); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('span'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-1-2'); nodeset[3].type.should.equal('tag'); nodeset[3].name.should.equal('b'); nodeset[4].type.should.equal('tag'); nodeset[4].name.should.equal('div'); nodeset[4].attribs.id.should.equal('inner-2-1'); nodeset[5].type.should.equal('tag'); nodeset[5].name.should.equal('b'); nodeset[6].type.should.equal('tag'); nodeset[6].name.should.equal('i'); nodeset[7].type.should.equal('tag'); nodeset[7].name.should.equal('div'); nodeset[7].attribs.id.should.equal('inner-2-2'); nodeset[8].type.should.equal('tag'); nodeset[8].name.should.equal('em'); return done(); }); it('supports the type selector (`E`) (string case)', function(done) { var node, nodeset, _i, _len; nodeset = this.stew.select(this.DOM, 'em'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('em'); nodeset = this.stew.select(this.DOM, 'div'); nodeset.length.should.equal(6); for (_i = 0, _len = nodeset.length; _i < _len; _i++) { node = nodeset[_i]; node.type.should.equal('tag'); node.name.should.equal('div'); } return done(); }); it('supports the type selector (`E`) (regexp case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, '/E*x?M/i'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('html'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('em'); return done(); }); it('supports the class selector (`.warning`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div.outer'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); nodeset = this.stew.select(this.DOM, '.outer'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); nodeset = this.stew.select(this.DOM, 'div.outer.odd'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset = this.stew.select(this.DOM, '.outer.odd'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset = this.stew.select(this.DOM, '.odd.outer'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset = this.stew.select(this.DOM, '.inner.even'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-2'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-2-2'); nodeset = this.stew.select(this.DOM, '*.odd *.even'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-2'); return done(); }); it('supports the class selector (`.warning`) (regex case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div./[ou]+ter/'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); nodeset = this.stew.select(this.DOM, './[ou]+ter/'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); nodeset = this.stew.select(this.DOM, 'div./er$/'); nodeset.length.should.equal(6); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-1-1'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-1-2'); nodeset[3].type.should.equal('tag'); nodeset[3].name.should.equal('div'); nodeset[3].attribs.id.should.equal('outer-2'); nodeset[4].type.should.equal('tag'); nodeset[4].name.should.equal('div'); nodeset[4].attribs.id.should.equal('inner-2-1'); nodeset[5].type.should.equal('tag'); nodeset[5].name.should.equal('div'); nodeset[5].attribs.id.should.equal('inner-2-2'); nodeset = this.stew.select(this.DOM, 'div./er$/.odd'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-1-1'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-1'); nodeset[2].type.should.equal('tag'); return done(); }); it('supports the id selector (`E#myid`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div#outer-2'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-2'); nodeset = this.stew.select(this.DOM, '#outer-2'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-2'); nodeset = this.stew.select(this.DOM, 'div#outer-2.even'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-2'); nodeset = this.stew.select(this.DOM, 'div#outer-2.odd'); nodeset.length.should.equal(0); return done(); }); it('supports the id selector (`E#myid`) (regex case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div#/outer-[0-9]/'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); nodeset = this.stew.select(this.DOM, '#/outer-[0-9]/'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); nodeset = this.stew.select(this.DOM, '#/outer-[0-9]/ b'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); nodeset[0].attribs.foo.should.equal('bar'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('b'); nodeset[1].attribs.fact.should.equal('white space is ok here'); return done(); }); it('supports the descendant selector (`E F`) (string case)', function(done) { var node, nodeset, _i, _j, _len, _len1; nodeset = this.stew.select(this.DOM, 'div span'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset = this.stew.select(this.DOM, 'html span'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset = this.stew.select(this.DOM, 'html body div span'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset = this.stew.select(this.DOM, 'div div'); nodeset.length.should.equal(4); for (_i = 0, _len = nodeset.length; _i < _len; _i++) { node = nodeset[_i]; node.type.should.equal('tag'); node.name.should.equal('div'); } nodeset = this.stew.select(this.DOM, 'body div'); nodeset.length.should.equal(6); for (_j = 0, _len1 = nodeset.length; _j < _len1; _j++) { node = nodeset[_j]; node.type.should.equal('tag'); node.name.should.equal('div'); } return done(); }); it('supports the descendant selector (`E F`) (regexp case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div /s[tp][aeiou]+n/'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); return done(); }); it('supports the child selector (`E > F`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'body div'); nodeset.length.should.equal(6); nodeset = this.stew.select(this.DOM, 'body > div'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); return done(); }); it('supports the child selector without whitespace (`E>F`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'body>div'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); return done(); }); it('supports the child selector (`E > F`) (regexp case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'body /d[aeiou]ve?/'); nodeset.length.should.equal(6); nodeset = this.stew.select(this.DOM, 'body > /d[aeiou]ve?/'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); return done(); }); it('supports the attribute selector (`E[foo]`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'b[foo]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); nodeset = this.stew.select(this.DOM, 'div b[foo]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); return done(); }); it('supports the attribute selector (`E[foo]`) (regexp case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'b[/fo+/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); return done(); }); it('supports the attribute-value selector (`E[foo="bar"]`) (unquoted string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, '[width=17]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset = this.stew.select(this.DOM, 'b[foo=bar]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); nodeset = this.stew.select(this.DOM, 'div [foo=bar]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); nodeset = this.stew.select(this.DOM, 'div b[foo=foo]'); nodeset.length.should.equal(0); nodeset = this.stew.select(this.DOM, 'div[id=inner-1-1]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); return done(); }); it('supports the attribute-value selector (`E[foo="bar"]`) (quoted string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'b[foo="bar"]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); nodeset = this.stew.select(this.DOM, 'div[id="inner-1-1"]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); return done(); }); it('supports the attribute-value selector (`E[foo="bar"]`) (quoted string containing whitespace case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'b[fact="white space is ok here"]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); nodeset[0].attribs.fact.should.equal('white space is ok here'); return done(); }); it('supports the attribute-value selector (`E[foo="bar"]`) (regexp containing whitespace case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'b[fact=/white space is ok here/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); nodeset[0].attribs.fact.should.equal('white space is ok here'); nodeset = this.stew.select(this.DOM, 'b[fact=/white space/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); nodeset[0].attribs.fact.should.equal('white space is ok here'); nodeset = this.stew.select(this.DOM, 'b[fact=/^white space.*ok here$/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); nodeset[0].attribs.fact.should.equal('white space is ok here'); nodeset = this.stew.select(this.DOM, 'b[fact=/"?white\\s*space"? is ok\\s+here/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); nodeset[0].attribs.fact.should.equal('white space is ok here'); return done(); }); it('supports the attribute-value selector (`E[foo="bar"]`) (regexp case)', function(done) { var node, nodeset, _i, _len; nodeset = this.stew.select(this.DOM, 'b[/fo+/=/ba?r/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('b'); nodeset = this.stew.select(this.DOM, 'div[id=/inner-1/]'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset = this.stew.select(this.DOM, 'div[class=inner]'); nodeset.length.should.equal(0); nodeset = this.stew.select(this.DOM, 'div[class=/inner/]'); nodeset.length.should.equal(4); for (_i = 0, _len = nodeset.length; _i < _len; _i++) { node = nodeset[_i]; node.type.should.equal('tag'); node.name.should.equal('div'); } return done(); }); it('supports the attribute-value selector (`E[foo="bar"]`) (extra symbols case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, '[extra="contains spaces, commas and symbols like + and /"]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('em'); nodeset[0].attribs.extra.should.equal('contains spaces, commas and symbols like + and /'); nodeset = this.stew.select(this.DOM, '[extra=/contains spaces, commas and symbols like \\+/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('em'); nodeset[0].attribs.extra.should.equal('contains spaces, commas and symbols like + and /'); nodeset = this.stew.select(this.DOM, '[extra=/^contains spaces, commas and symbols like \\+ and .$/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('em'); nodeset[0].attribs.extra.should.equal('contains spaces, commas and symbols like + and /'); return done(); }); it('supports the ~= operator in the attribute-value selector (`E[foo~="bar"]`) (string case)', function(done) { var node, nodeset, _i, _j, _k, _l, _len, _len1, _len2, _len3; nodeset = this.stew.select(this.DOM, 'div[class~=inner]'); nodeset.length.should.equal(4); for (_i = 0, _len = nodeset.length; _i < _len; _i++) { node = nodeset[_i]; node.type.should.equal('tag'); node.name.should.equal('div'); } nodeset = this.stew.select(this.DOM, 'div[class~=odd]'); nodeset.length.should.equal(3); for (_j = 0, _len1 = nodeset.length; _j < _len1; _j++) { node = nodeset[_j]; node.type.should.equal('tag'); node.name.should.equal('div'); } nodeset = this.stew.select(this.DOM, '[fact~=space]'); nodeset.length.should.equal(1); for (_k = 0, _len2 = nodeset.length; _k < _len2; _k++) { node = nodeset[_k]; node.type.should.equal('tag'); node.name.should.equal('b'); } nodeset = this.stew.select(this.DOM, '[foo~=bar]'); nodeset.length.should.equal(1); for (_l = 0, _len3 = nodeset.length; _l < _len3; _l++) { node = nodeset[_l]; node.type.should.equal('tag'); node.name.should.equal('b'); } nodeset = this.stew.select(this.DOM, '[zzz~=in]'); nodeset.length.should.equal(0); return done(); }); it('supports the |= operator in the attribute-value selector (`E[lang|="en"]`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div[lang|="en"]'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-1-2'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'div[lang|="en-us"]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-2-1'); return done(); }); it('supports the |= operator in the attribute-value selector (`E[lang|="en"]`) (regexp case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div[lang|=/EN/i]'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-1-2'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'div[lang|=/en?/]'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-1-2'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'div[lang|=/^en/]'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-1-2'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'div[lang|=/[aeiou]n-[aeioug][sb]/]'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-2-1'); return done(); }); it('supports the :first-child pseudo class (`E:first-child`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div:first-child'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-1-1'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'section:first-child'); nodeset.length.should.equal(0); nodeset = this.stew.select(this.DOM, 'body section span:first-child'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.id.should.equal('escaped-quote-test'); return done(); }); it('supports the adjacent selector (`E + F`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div div'); nodeset.length.should.equal(4); nodeset = this.stew.select(this.DOM, 'div + div'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-2'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-2'); return done(); }); it('supports the adjacent selector without whitespace (`E+F`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div+div'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-2'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-2'); return done(); }); it('supports the adjacent selector (`E + F`) (regexp case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, '/(div)|(dove)/ /(div)|(dave)/'); nodeset.length.should.equal(4); nodeset = this.stew.select(this.DOM, '/(div)|(dove)/ + /(div)|(dave)/'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-2'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-2'); return done(); }); it('supports the comma (or) operator (`E , F`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'b , span'); nodeset.length.should.equal(4); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('b'); nodeset[1].attribs.foo.should.equal('bar'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('b'); nodeset[2].attribs.fact.should.equal('white space is ok here'); nodeset[3].type.should.equal('tag'); nodeset[3].name.should.equal('span'); nodeset[3].attribs.id.should.equal('escaped-quote-test'); return done(); }); it('supports the comma (or) operator without spaces (`E,F`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'b,span'); nodeset.length.should.equal(4); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('b'); nodeset[1].attribs.foo.should.equal('bar'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('b'); nodeset[2].attribs.fact.should.equal('white space is ok here'); nodeset[3].type.should.equal('tag'); nodeset[3].name.should.equal('span'); nodeset[3].attribs.id.should.equal('escaped-quote-test'); return done(); }); it('supports escaped quotation marks within quoted strings', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, '[label="this label includes \\"quote\\" marks"]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.id.should.equal('escaped-quote-test'); nodeset = this.stew.select(this.DOM, '[label=/^this label includes "quote" marks$/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.id.should.equal('escaped-quote-test'); return done(); }); it('supports multiple attribute-based selectors in series (`E[a=b][c=d]`)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, '[class~="outer"][class~="odd"]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset = this.stew.select(this.DOM, '[class=/outer/][class=/odd/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); return done(); }); it('supports the preceding sibling selector (`E ~ F`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, '.odd section'); nodeset.length.should.equal(0); nodeset = this.stew.select(this.DOM, '.odd + section'); nodeset.length.should.equal(0); nodeset = this.stew.select(this.DOM, '.odd ~ section'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('section'); nodeset = this.stew.select(this.DOM, '.odd ~ section span'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.id.should.equal('escaped-quote-test'); return done(); }); it('supports the preceding adjacent selector (`E ~ F`) (regexp case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, '.odd /section/'); nodeset.length.should.equal(0); nodeset = this.stew.select(this.DOM, '.odd + /s[aeiou]ction/'); nodeset.length.should.equal(0); nodeset = this.stew.select(this.DOM, '.odd ~ /s[aeiou]ction/'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('section'); nodeset = this.stew.select(this.DOM, '.odd ~ /s[aeiou]ction/ span'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.id.should.equal('escaped-quote-test'); return done(); }); it('supports the ^= (starts-with) operator in the attribute-value selector (`E[foo^="bar"]`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div[lang^="en-"]'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'span[width^=1]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); return done(); }); it('supports the ^= (starts-with) operator in the attribute-value selector (`E[foo^="bar"]`) (regexp case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div[lang=/n/]'); nodeset.length.should.equal(3); nodeset = this.stew.select(this.DOM, 'div[lang^=/n/]'); nodeset.length.should.equal(0); nodeset = this.stew.select(this.DOM, 'div[lang^=/en-/]'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'div[lang^=/^en-/]'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'span[width^=/1/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); nodeset = this.stew.select(this.DOM, 'span[width^=/17$/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); return done(); }); it('supports the $= (ends-with) operator in the attribute-value selector (`E[foo$="bar"]`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div[id$="-2"]'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-2'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('outer-2'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-2'); nodeset = this.stew.select(this.DOM, 'span[width$=7]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); nodeset = this.stew.select(this.DOM, 'span[width$=17]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); nodeset = this.stew.select(this.DOM, 'span[width$=1]'); nodeset.length.should.equal(0); return done(); }); it('supports the $= (ends-with) operator in the attribute-value selector (`E[foo$="bar"]`) (regexp case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div[lang=/n/]'); nodeset.length.should.equal(3); nodeset = this.stew.select(this.DOM, 'div[lang$=/n/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-2'); nodeset = this.stew.select(this.DOM, 'div[lang$=/-((gb)|(us))/]'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'div[lang$=/-(g|u)./]'); nodeset.length.should.equal(2); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('inner-1-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'span[width$=/[0-9]7/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); nodeset = this.stew.select(this.DOM, 'span[width$=/7/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); nodeset = this.stew.select(this.DOM, 'span[width$=/^17/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); nodeset = this.stew.select(this.DOM, 'span[width$=/17$/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); nodeset = this.stew.select(this.DOM, 'span[width$=/^17$/]'); nodeset.length.should.equal(1); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('span'); nodeset[0].attribs.width.should.equal('17'); return done(); }); it('supports the *= (contains) operator in the attribute-value selector (`E[foo*="bar"]`) (string case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div[class*="er odd"]'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-1-1'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'div[class*="er"]'); nodeset.length.should.equal(6); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-1-1'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-1-2'); nodeset[3].type.should.equal('tag'); nodeset[3].name.should.equal('div'); nodeset[3].attribs.id.should.equal('outer-2'); nodeset[4].type.should.equal('tag'); nodeset[4].name.should.equal('div'); nodeset[4].attribs.id.should.equal('inner-2-1'); nodeset[5].type.should.equal('tag'); nodeset[5].name.should.equal('div'); nodeset[5].attribs.id.should.equal('inner-2-2'); return done(); }); return it('supports the *= (contains) operator in the attribute-value selector (`E[foo*="bar"]`) (regexp case)', function(done) { var nodeset; nodeset = this.stew.select(this.DOM, 'div[class*=/er odd/]'); nodeset.length.should.equal(3); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-1-1'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-2-1'); nodeset = this.stew.select(this.DOM, 'div[class*=/er/]'); nodeset.length.should.equal(6); nodeset[0].type.should.equal('tag'); nodeset[0].name.should.equal('div'); nodeset[0].attribs.id.should.equal('outer-1'); nodeset[1].type.should.equal('tag'); nodeset[1].name.should.equal('div'); nodeset[1].attribs.id.should.equal('inner-1-1'); nodeset[2].type.should.equal('tag'); nodeset[2].name.should.equal('div'); nodeset[2].attribs.id.should.equal('inner-1-2'); nodeset[3].type.should.equal('tag'); nodeset[3].name.should.equal('div'); nodeset[3].attribs.id.should.equal('outer-2'); nodeset[4].type.should.equal('tag'); nodeset[4].name.should.equal('div'); nodeset[4].attribs.id.should.equal('inner-2-1'); nodeset[5].type.should.equal('tag'); nodeset[5].name.should.equal('div'); nodeset[5].attribs.id.should.equal('inner-2-2'); return done(); }); }); }); }).call(this);