4 ], function(chai, wlxml) {
 
   9 /* global it, describe, beforeEach */
 
  11 var expect = chai.expect;
 
  13 var nodeFromXML = function(xml) {
 
  14     return wlxml.WLXMLElementNodeFromXML(xml);
 
  17 var getDocumentFromXML = function(xml, options) {
 
  18     return wlxml.WLXMLDocumentFromXML(xml, options || {});
 
  22 describe('WLXMLDocument', function() {
 
  24     describe('Basic wlxml element node properties', function() {
 
  25         it('returns its class', function() {
 
  26             var node = nodeFromXML('<header class="class.subclass"></header>');
 
  27             expect(node.getClass()).to.equal('class.subclass');
 
  30         it('returns its class hierarchy', function() {
 
  31             var node = nodeFromXML('<div class="a.b.c"></div>');
 
  32             expect(node.getClassHierarchy()).to.eql(['', 'a', 'a.b', 'a.b.c']);
 
  36     describe('White space handling', function() {
 
  39         it('ignores white space surrounding block elements', function() {
 
  40             var node = nodeFromXML('<section> <div></div> </section>'),
 
  41                 contents = node.contents();
 
  42             expect(contents).to.have.length(1);
 
  43             expect(contents[0].nodeType).to.equal(Node.ELEMENT_NODE);
 
  45         it('ignores white space between block elements', function() {
 
  46             var node = nodeFromXML('<section><div></div> <div></div></section>'),
 
  47             contents = node.contents();
 
  48             expect(contents).to.have.length(2);
 
  49             [0,1].forEach(function(idx) {
 
  50                 expect(contents[idx].nodeType).to.equal(Node.ELEMENT_NODE);
 
  53         it('trims white space from the beginning and the end of the block elements', function() {
 
  54             var node = nodeFromXML('<section> Alice <span>has</span> a cat </section>');
 
  55             expect(node.contents()[0].getText()).to.equal('Alice ');
 
  56             expect(node.contents()[2].getText()).to.equal(' a cat');
 
  58         it('normalizes string of white characters to one space at the inline element boundries', function() {
 
  59             var node = nodeFromXML('<span>   Alice has a cat   </span>');
 
  60             expect(node.contents()[0].getText()).to.equal(' Alice has a cat ');
 
  62         it('normalizes string of white characters to one space before inline element', function() {
 
  63             var node = nodeFromXML('<div>Alice has  <span>a cat</span></div>');
 
  64             expect(node.contents()[0].getText()).to.equal('Alice has ');
 
  66         it('normalizes string of white characters to one space after inline element', function() {
 
  67             var node = nodeFromXML('<div>Alice has <span>a</span>  cat</div>');
 
  68             expect(node.contents()[2].getText()).to.equal(' cat');
 
  72     describe('formatting output xml', function() {
 
  74         /*jshint multistr: true */
 
  76         it('keeps white space between XML nodes', function() {
 
  77             var xmlIn = '<section>\n\n\n<div></div>\n\n\n<div></div>\n\n\n</section>',
 
  78             doc = getDocumentFromXML(xmlIn),
 
  81             var partsIn = xmlIn.split('\n\n\n'),
 
  82                 partsOut = xmlOut.split('\n\n\n');
 
  84             expect(partsIn).to.deep.equal(partsOut);
 
  87         it('keeps white space between XML nodes - inline case', function() {
 
  88             var xmlIn = '<section>\n\n\n<span></span>\n\n\n<span></span>\n\n\n</section>',
 
  89                 doc = getDocumentFromXML(xmlIn),
 
  92             var partsIn = xmlIn.split('\n\n\n'),
 
  93                 partsOut = xmlOut.split('\n\n\n');
 
  94             expect(partsIn).to.deep.equal(partsOut);
 
  97         it('keeps white space at the beginning of text', function() {
 
  98             var xmlIn = '<section>    abc<div>some div</div>    abc</section>',
 
  99                 doc = getDocumentFromXML(xmlIn),
 
 100                 xmlOut = doc.toXML();
 
 102             expect(xmlOut).to.equal(xmlIn);
 
 105         // it('nests new children block elements', function() {
 
 106         //     var doc = getDocumentFromXML('<section></section>');
 
 108         //     doc.root.append({tag: 'header'});
 
 110         //     var xmlOut = doc.toXML();
 
 111         //     expect(xmlOut.split('\n  ')[0]).to.equal('<section>', 'nesting start ok');
 
 112         //     expect(xmlOut.split('\n').slice(-1)[0]).to.equal('</section>', 'nesting end ok');
 
 116         // it('doesn\'t nest new children inline elements', function() {
 
 117         //     var doc = getDocumentFromXML('<section></section>');
 
 119         //     doc.root.append({tag: 'span'});
 
 121         //     var xmlOut = doc.toXML();
 
 122         //     expect(xmlOut).to.equal('<section><span></span></section>');
 
 125         it('keeps original white space at the end of text', function() {
 
 127             var xmlIn = '<header>    Some text ended with white space \
 
 129             <span class="uri">Some text</span> some text\
 
 132                 doc = getDocumentFromXML(xmlIn),
 
 133                 xmlOut = doc.toXML();
 
 135             expect(xmlOut).to.equal(xmlIn);
 
 138         it('keeps white space around text node', function() {
 
 139             var xmlIn = '<section>\
 
 140             <header>header1</header>\
 
 141             Some text surrounded by white space\
 
 142             <header>header2</header>\
 
 144                 doc = getDocumentFromXML(xmlIn),
 
 145                 xmlOut = doc.toXML();
 
 146             expect(xmlOut).to.equal(xmlIn);
 
 149         it('keeps white space around text node - last node case', function() {
 
 150             var xmlIn = '<section>\
 
 151             <header>header</header>\
 
 153             Some text surrounded by white space\
 
 156                 doc = getDocumentFromXML(xmlIn),
 
 157                 xmlOut = doc.toXML();
 
 159             expect(xmlOut).to.equal(xmlIn);
 
 162         it('keeps white space after detaching text element', function() {
 
 163             var xmlIn = '<section><header>header</header>\n\
 
 168                 expectedXmlOut = '<section><header>header</header>\n\
 
 173                 doc = getDocumentFromXML(xmlIn),
 
 174                 contents = doc.root.contents(),
 
 175                 text = contents[contents.length-1];
 
 177             expect(text.getText()).to.equal('text1');
 
 181             var xmlOut = doc.toXML();
 
 182             expect(xmlOut).to.equal(expectedXmlOut);
 
 187     describe('Extension', function() {
 
 188         var doc, extension, elementNode, textNode, testClassNode;
 
 190         beforeEach(function() {
 
 191             doc = getDocumentFromXML('<section>Alice<div class="test_class"></div><div class="test_class.a"></div></section>');
 
 192             elementNode = doc.root;
 
 193             textNode = doc.root.contents()[0];
 
 194             testClassNode = doc.root.contents('.test_class');
 
 197             expect(testClassNode.object).to.be.undefined;
 
 201         it('allows adding method to an ElementNode of specific class', function() {
 
 202             extension = {wlxmlClass: {test_class: {methods: {
 
 203                 testMethod: function() { return this; }
 
 205             doc.registerExtension(extension);
 
 206             testClassNode = doc.root.contents()[1];
 
 207             expect(testClassNode.object.testMethod().sameNode(testClassNode)).to.equal(true, '1');
 
 210         it('allows adding non-function properties to an ElementNode of specific class', function() {
 
 211             extension = {wlxmlClass: {test_class: {methods: {
 
 214             doc.registerExtension(extension);
 
 215             testClassNode = doc.root.contents()[1];
 
 216             expect(testClassNode.object.testProp).to.equal(123);
 
 219         it('allows adding transformation to an ElementNode of specific class', function() {
 
 220             extension = {wlxmlClass: {test_class: {transformations: {
 
 221                 testTransformation: function() { return this; },
 
 222                 testTransformation2: {impl: function() { return this; }}
 
 224             doc.registerExtension(extension);
 
 225             testClassNode = doc.root.contents()[1];
 
 226             expect(testClassNode.object.testTransformation().sameNode(testClassNode)).to.equal(true, '1');
 
 227             expect(testClassNode.object.testTransformation2().sameNode(testClassNode)).to.equal(true, '1');
 
 230         it('added methods are inherited by nodes with subclasses', function() {
 
 231             extension = {wlxmlClass: {test_class: {methods: {
 
 232                 testMethod: function() { return this; }
 
 234             doc.registerExtension(extension);
 
 235             testClassNode = doc.root.contents()[2];
 
 236             expect(testClassNode.object.testMethod().sameNode(testClassNode)).to.equal(true);
 
 238         it('added transformations are inherited by nodes with subclasses', function() {
 
 239             extension = {wlxmlClass: {test_class: {transformations: {
 
 240                 testTransformation: function() { return this; },
 
 241                 testTransformation2: {impl: function() { return this; }}
 
 243             doc.registerExtension(extension);
 
 244             testClassNode = doc.root.contents()[2];
 
 245             expect(testClassNode.object.testTransformation().sameNode(testClassNode)).to.equal(true, '1');
 
 246             expect(testClassNode.object.testTransformation2().sameNode(testClassNode)).to.equal(true, '2');