5 ], function($, chai, wlxml) {
10 /* global it, describe, beforeEach */
12 var expect = chai.expect;
14 var nodeFromXML = function(xml) {
15 return wlxml.WLXMLElementNodeFromXML(xml);
18 var getDocumentFromXML = function(xml, options) {
19 return wlxml.WLXMLDocumentFromXML(xml, options || {});
23 describe('WLXMLDocument', function() {
25 describe('Basic wlxml element node properties', function() {
26 it('returns its class', function() {
27 var node = nodeFromXML('<header class="class.subclass"></header>');
28 expect(node.getClass()).to.equal('class.subclass');
31 it('returns unregistered attributes', function() {
34 attrs: {'attr1': {type: 'string'}}
37 doc = getDocumentFromXML('<span class="testClass" attr="val" attr1="val1"></span>', {wlxmlClasses: testClasses});
38 expect(doc.root.getOtherAttributes()).to.eql({attr: {value:'val'}});
42 describe('WLXML node meta attributes', function() {
44 it('inherits keys from super classes', function() {
47 attrs: {'common': {type: 'string'}}
50 attrs: {'a_attr': {type: 'string'}}
53 attrs: {'a_b_attr': {type: 'string'}}
56 attrs: {'a_b_c_attr': {type: 'string'}}
59 doc = getDocumentFromXML('<section></section>', {wlxmlClasses: testClasses}),
62 expect(section.getMetaAttributes().keys()).to.eql(['common']);
64 section.setClass('a');
65 expect(section.getMetaAttributes().keys().sort()).to.eql(['common', 'a_attr'].sort());
67 section.setClass('a.b');
68 expect(section.getMetaAttributes().keys().sort()).to.eql(['common', 'a_attr', 'a_b_attr'].sort());
70 section.setClass('a.b.c');
71 expect(section.getMetaAttributes().keys().sort()).to.eql(['common', 'a_attr', 'a_b_attr', 'a_b_c_attr'].sort());
74 describe('api', function() {
75 it('returns meta attributes as a dict', function() {
79 attr1: {type: 'string'},
84 node = getDocumentFromXML(
85 '<span class="test" attr1="val1" attr2="2014-01-01"></span>',
86 {wlxmlClasses: testClasses}
88 attrs = node.getMetaAttributes();
90 expect(attrs.keys().sort()).to.eql(['attr1', 'attr2'].sort());
91 expect(attrs.attr1.value).to.equal('val1');
92 expect(attrs.attr1.type).to.equal('string');
93 expect(attrs.attr2.value).to.equal('2014-01-01');
94 expect(attrs.attr2.type).to.equal('date');
96 it('returns undefined value if attribute is missing', function() {
100 attr1: {type: 'string'},
104 node = getDocumentFromXML('<span class="test"></span>', {wlxmlClasses: testClasses}).root,
105 attrs = node.getMetaAttributes();
106 expect(attrs.attr1.value).to.be.undefined;
111 describe('White space handling', function() {
114 it('ignores white space surrounding block elements', function() {
115 var node = nodeFromXML('<section> <div></div> </section>'),
116 contents = node.contents();
117 expect(contents).to.have.length(1);
118 expect(contents[0].nodeType).to.equal(Node.ELEMENT_NODE);
120 it('ignores white space between block elements', function() {
121 var node = nodeFromXML('<section><div></div> <div></div></section>'),
122 contents = node.contents();
123 expect(contents).to.have.length(2);
124 [0,1].forEach(function(idx) {
125 expect(contents[idx].nodeType).to.equal(Node.ELEMENT_NODE);
128 it('trims white space from the beginning and the end of the block elements', function() {
129 var node = nodeFromXML('<section> Alice <span>has</span> a cat </section>');
130 expect(node.contents()[0].getText()).to.equal('Alice ');
131 expect(node.contents()[2].getText()).to.equal(' a cat');
133 it('normalizes string of white characters to one space at the inline element boundries', function() {
134 var node = nodeFromXML('<span> Alice has a cat </span>');
135 expect(node.contents()[0].getText()).to.equal(' Alice has a cat ');
137 it('normalizes string of white characters to one space before inline element', function() {
138 var node = nodeFromXML('<div>Alice has <span>a cat</span></div>');
139 expect(node.contents()[0].getText()).to.equal('Alice has ');
141 it('normalizes string of white characters to one space after inline element', function() {
142 var node = nodeFromXML('<div>Alice has <span>a</span> cat</div>');
143 expect(node.contents()[2].getText()).to.equal(' cat');
147 describe('formatting output xml', function() {
149 /*jshint multistr: true */
151 it('keeps white space between XML nodes', function() {
152 var xmlIn = '<section>\n\n\n<div></div>\n\n\n<div></div>\n\n\n</section>',
153 doc = getDocumentFromXML(xmlIn),
154 xmlOut = doc.toXML();
156 var partsIn = xmlIn.split('\n\n\n'),
157 partsOut = xmlOut.split('\n\n\n');
159 expect(partsIn).to.deep.equal(partsOut);
162 it('keeps white space between XML nodes - inline case', function() {
163 var xmlIn = '<section>\n\n\n<span></span>\n\n\n<span></span>\n\n\n</section>',
164 doc = getDocumentFromXML(xmlIn),
165 xmlOut = doc.toXML();
167 var partsIn = xmlIn.split('\n\n\n'),
168 partsOut = xmlOut.split('\n\n\n');
169 expect(partsIn).to.deep.equal(partsOut);
172 it('keeps white space at the beginning of text', function() {
173 var xmlIn = '<section> abc<div>some div</div> abc</section>',
174 doc = getDocumentFromXML(xmlIn),
175 xmlOut = doc.toXML();
177 expect(xmlOut).to.equal(xmlIn);
180 // it('nests new children block elements', function() {
181 // var doc = getDocumentFromXML('<section></section>');
183 // doc.root.append({tag: 'header'});
185 // var xmlOut = doc.toXML();
186 // expect(xmlOut.split('\n ')[0]).to.equal('<section>', 'nesting start ok');
187 // expect(xmlOut.split('\n').slice(-1)[0]).to.equal('</section>', 'nesting end ok');
191 // it('doesn\'t nest new children inline elements', function() {
192 // var doc = getDocumentFromXML('<section></section>');
194 // doc.root.append({tag: 'span'});
196 // var xmlOut = doc.toXML();
197 // expect(xmlOut).to.equal('<section><span></span></section>');
200 it('keeps original white space at the end of text', function() {
202 var xmlIn = '<header> Some text ended with white space \
204 <span class="uri">Some text</span> some text\
207 doc = getDocumentFromXML(xmlIn),
208 xmlOut = doc.toXML();
210 expect(xmlOut).to.equal(xmlIn);
213 it('keeps white space around text node', function() {
214 var xmlIn = '<section>\
215 <header>header1</header>\
216 Some text surrounded by white space\
217 <header>header2</header>\
219 doc = getDocumentFromXML(xmlIn),
220 xmlOut = doc.toXML();
221 expect(xmlOut).to.equal(xmlIn);
224 it('keeps white space around text node - last node case', function() {
225 var xmlIn = '<section>\
226 <header>header</header>\
228 Some text surrounded by white space\
231 doc = getDocumentFromXML(xmlIn),
232 xmlOut = doc.toXML();
234 expect(xmlOut).to.equal(xmlIn);
237 it('keeps white space after detaching text element', function() {
238 var xmlIn = '<section><header>header</header>\n\
243 expectedXmlOut = '<section><header>header</header>\n\
248 doc = getDocumentFromXML(xmlIn),
249 contents = doc.root.contents(),
250 text = contents[contents.length-1];
252 expect(text.getText()).to.equal('text1');
256 var xmlOut = doc.toXML();
257 expect(xmlOut).to.equal(expectedXmlOut);
262 describe('Extension', function() {
263 var doc, extension, elementNode, textNode, testClassNode;
265 beforeEach(function() {
266 doc = getDocumentFromXML('<section>Alice<div class="test_class"></div></section>');
267 elementNode = doc.root;
268 textNode = doc.root.contents()[0];
269 testClassNode = doc.root.contents('.test_class');
272 expect(testClassNode.object).to.be.undefined;
276 it('allows adding method to an ElementNode of specific class', function() {
277 extension = {wlxmlClass: {test_class: {methods: {
278 testMethod: function() { return this; }
280 doc.registerExtension(extension);
281 testClassNode = doc.root.contents()[1];
282 expect(testClassNode.object.testMethod().sameNode(testClassNode)).to.equal(true, '1');
285 it('allows adding transformation to an ElementNode of specific class', function() {
286 extension = {wlxmlClass: {test_class: {transformations: {
287 testTransformation: function() { return this; },
288 testTransformation2: {impl: function() { return this; }}
290 doc.registerExtension(extension);
291 testClassNode = doc.root.contents()[1];
292 expect(testClassNode.object.testTransformation().sameNode(testClassNode)).to.equal(true, '1');
293 expect(testClassNode.object.testTransformation2().sameNode(testClassNode)).to.equal(true, '1');
297 describe.only('Metadata API', function() {
298 it('allows to set metadata on an element node', function() {
299 var doc = getDocumentFromXML('<section></section>');
300 expect(doc.root.getMetadata()).to.deep.equal([]);
301 doc.root.addMetadataRow({key: 'key', value: 'value'});
302 expect(doc.root.getMetadata()).to.deep.equal([{key: 'key', value: 'value'}]);
305 it('reads node\'s metadata from its metadata child node', function() {
306 var doc = getDocumentFromXML('<section><metadata><dc:key>value</dc:key></metadata></section>');
307 expect(doc.root.getMetadata()).to.deep.equal([{key: 'key', value: 'value'}]);
310 it('serializes node\'s metadata to its metadata child node', function() {
311 var doc = getDocumentFromXML('<section></section>');
313 doc.root.addMetadataRow({key: 'key', value: 'value'});
315 var metadataNodes = $(doc.toXML()).children('metadata'),
316 keyNodes = metadataNodes.children();
318 expect(metadataNodes).to.have.length(1);
319 expect(keyNodes).to.have.length(1);
320 expect(keyNodes[0].tagName.toLowerCase()).to.equal('dc:key');
321 expect($(keyNodes[0]).text()).to.equal('value');
323 it('doesnt show metadata node on nodes contents', function() {
324 var doc = getDocumentFromXML('<section><metadata><dc:key>value</dc:key></metadata></section>');
325 expect(doc.root.contents()).to.have.length(0);