UNPKG

stew-select

Version:

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

216 lines (193 loc) 9.53 kB
should = require 'should' fs = require 'fs' path = require 'path' HOMEDIR = path.join(__dirname,'..') LIB_DIR = if fs.existsSync(path.join(HOMEDIR,'lib-cov')) then path.join(HOMEDIR,'lib-cov') else path.join(HOMEDIR,'lib') #------------------------------------------------------------------------------- DOMUtil = require(path.join(LIB_DIR,'dom-util')).DOMUtil #------------------------------------------------------------------------------- HTMLPARSER_OPTIONS = ignoreWhitespace: false caseSensitiveTags: false caseSensitiveAttr: false describe "DOMUtil",=> beforeEach (done)=> @dom_util = new DOMUtil() done() afterEach (done)=> @dom_util = null done() describe "parse_html",=> it "produces a DOM tree for the given HTML string",(done)=> @dom_util.parse_html '<html><div>This is an example HTML document</div></html>', (err, dom)=> should.not.exist err should.exist dom dom.type.should.equal 'tag' dom.name.should.equal 'html' done() it "produces an array of DOM trees when the given HTML string has more than one root",(done)=> @dom_util.parse_html '<div>First div.</div><span>Second span.</span>', (err, dom)=> should.not.exist err should.exist dom dom.length.should.equal 2 dom[0].type.should.equal 'tag' dom[0].name.should.equal 'div' dom[1].type.should.equal 'tag' dom[1].name.should.equal 'span' done() it "allows a map of options to be passed",(done)=> @dom_util.parse_html '<html><DIV>This is an example HTML document</div></HTML>', HTMLPARSER_OPTIONS, (err, dom)=> should.not.exist err should.exist dom dom.type.should.equal 'tag' dom.name.should.equal 'html' done() it "as_node converts a nodeset to a single node",(done)=> should.not.exist @dom_util.as_node(null) should.not.exist @dom_util.as_node([]) should.not.exist @dom_util.as_node([null]) nodes = [ { type:'tag', name:'html' } { type:'tag', name:'body' } { type:'tag', name:'div' } { type:'tag', name:'span' } ] @dom_util.as_node(nodes).name.should.equal 'html' @dom_util.as_node([{ type:'tag', name:'html' }]).name.should.equal 'html' @dom_util.as_node({ type:'tag', name:'html' }).name.should.equal 'html' done() it "as_nodeset converts a node to a nodeset",(done)=> @dom_util.as_nodeset(null).length.should.equal 0 @dom_util.as_nodeset([]).length.should.equal 0 @dom_util.as_nodeset([null]).length.should.equal 1 nodes = [ { type:'tag', name:'html' } { type:'tag', name:'body' } { type:'tag', name:'div' } { type:'tag', name:'span' } ] @dom_util.as_nodeset(nodes).length.should.equal 4 @dom_util.as_nodeset(nodes[0]).length.should.equal 1 done() describe "to_text",=> it "returns the value of all text descendants",(done)=> html = '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> text = @dom_util.to_text dom text.should.equal 'alphabeta' done() it "handles whitespace between nodes",(done)=> html = '<html><div id="A"> <span>alpha</span></div> <div id="B"><b><i>beta</i> </b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> text = @dom_util.to_text dom text.should.equal ' alpha beta ' done() it "supports a `filter` function for excluding nodes",(done)=> html = '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> text = @dom_util.to_text dom, (node)=>node.attribs?.id isnt 'A' text.should.equal 'beta' done() it "supports a `decode` function for converting HTML to text nodes",(done)=> dom_util = new DOMUtil(decode:(str)->str.toUpperCase()) html = '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> text = dom_util.to_text dom text.should.equal 'ALPHABETA' done() it "is also known as `inner_text`",(done)=> html = '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> text = @dom_util.inner_text dom text.should.equal 'alphabeta' done() describe "inner_html",=> it "returns an HTML representation of the children of the given node",(done)=> html = '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> text = @dom_util.inner_html dom text.should.equal '<div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div>' done() it "handles whitespace between nodes",(done)=> html = '<html><div id="A"> <span>alpha</span></div> <div id="B"><b><i>beta</i> </b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> text = @dom_util.inner_html dom text.should.equal '<div id="A"> <span>alpha</span></div> <div id="B"><b><i>beta</i> </b></div>' done() describe "to_html",=> it "returns an HTML representation of the given node",(done)=> html = '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> text = @dom_util.to_html dom text.should.equal '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' done() it "handles whitespace between nodes",(done)=> html = '<html><div id="A"> <span>alpha</span></div> <div id="B"><b><i>beta</i> </b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> text = @dom_util.to_html dom text.should.equal '<html><div id="A"> <span>alpha</span></div> <div id="B"><b><i>beta</i> </b></div></html>' done() describe "walk_dom",=> it "performs a depth-first walk of the dom tree",(done)=> html = '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> expected = [ 'html', 'div', 'span', 'div', 'b', 'i' ] @dom_util.walk_dom dom, (node)=> if node.type is 'tag' expected_name = expected.shift() node.name.should.equal expected_name return true expected.length.should.equal 0 done() it "passes parent node to visit function",(done)=> html = '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> expected = [ null, 'html', 'div', 'html', 'div', 'b' ] @dom_util.walk_dom dom, (node,node_metadata)=> if node.type is 'tag' expected_name = expected.shift() if expected_name? node_metadata.parent.should.exist node_metadata.parent.name.should.equal expected_name else should.not.exist node_metadata.parent return true expected.length.should.equal 0 done() it "passes path to node to visit function",(done)=> html = '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> expected = [ [], ['html'], ['html','div'], ['html','div','span'], ['html'], ['html','div'], ['html','div','b'], ['html','div','b','i'] ] @dom_util.walk_dom dom, (node,node_metadata)=> if node.type is 'tag' or node.type is 'text' expected_path = expected.shift() expected_path.length.should.equal node_metadata.path.length for elt,i in expected_path node_metadata.path[i].name.should.equal elt return true expected.length.should.equal 0 done() it "passes siblings to visit function",(done)=> html = '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> expected = [ ['html'], ['div','div'], ['span'], ['div','div'],['b'],['i'] ] @dom_util.walk_dom dom, (node,node_metadata)=> if node.type is 'tag' expected_sibs = expected.shift() expected_sibs.length.should.equal node_metadata.siblings.length for elt,i in expected_sibs node_metadata.siblings[i].name.should.equal elt return true expected.length.should.equal 0 done() it "passes sibling index to visit function",(done)=> html = '<html><div id="A"><span>alpha</span></div><div id="B"><b><i>beta</i></b></div></html>' @dom_util.parse_html html, HTMLPARSER_OPTIONS, (err, dom)=> expected = [ 0, 0, 0, 1, 0, 0 ] @dom_util.walk_dom dom, (node,node_metadata)=> if node.type is 'tag' expected_index = expected.shift() node_metadata.sib_index.should.equal expected_index return true expected.length.should.equal 0 done()