var XmlDocument = require('../').XmlDocument var t = require('tap') t.test('verify sax global in browser', function (t) { // "un-require" the xmldoc module that we loaded up top delete require.cache[require.resolve('../')]; // also un-require the actual xmldoc module pulled in by index.js ('../') delete require.cache[require.resolve('../lib/xmldoc.js')]; // this signal will be picked up on by xmldoc.js global.xmldocAssumeBrowser = true; t.throws(function() { require('../'); }); // try again, but this time satisfy the sax check delete require.cache[require.resolve('../')]; delete require.cache[require.resolve('../lib/xmldoc.js')]; global.sax = {}; require('../'); t.ok(global.XmlDocument); t.end(); }) t.test('extend util', function(t) { delete require.cache[require.resolve('../')]; delete require.cache[require.resolve('../lib/xmldoc.js')]; Object.prototype.cruftyExtension = "blah"; try { require('../'); } finally { delete Object.prototype.cruftyExtension; } t.end(); }) t.test('parse xml', function (t) { var xmlString = 'world'; var parsed = new XmlDocument(xmlString); t.ok(parsed); t.throws(function() { new XmlDocument(); }); t.throws(function() { new XmlDocument(" "); }); t.end(); }) t.test('cdata handling', function (t) { var xmlString = ']]>'; var parsed = new XmlDocument(xmlString); t.equal(parsed.val, ""); t.end(); }) t.test('cdata and text handling', function (t) { var xmlString = '(]]>)'; var parsed = new XmlDocument(xmlString); t.equal(parsed.val, "()"); t.end(); }) t.test('doctype handling', function (t) { var docWithType = new XmlDocument('world'); t.equal(docWithType.doctype, " HelloWorld"); var docWithoutType = new XmlDocument('world'); t.equal(docWithoutType.doctype, ""); t.throws(function() { new XmlDocument('world'); }); t.end(); }) t.test('comment handling', function (t) { var xmlString = ''; var parsed = new XmlDocument(xmlString); t.equal(parsed.val, ""); t.end(); }) t.test('comment and text handling', function (t) { var xmlString = '()'; var parsed = new XmlDocument(xmlString); t.equal(parsed.val, "()"); t.end(); }) t.test('text, cdata, and comment handling', function (t) { var xmlString = 'Hello ]]>!'; var parsed = new XmlDocument(xmlString); t.equal(parsed.val, "Hello !"); t.end(); }) t.test('text with elements handling', function (t) { var xmlString = 'hello, !'; var parsed = new XmlDocument(xmlString); t.equal(parsed.val, "hello, !"); t.end(); }) t.test('text before root node', function (t) { var xmlString = '\n\n*'; var xml = new XmlDocument(xmlString); t.equal(xml.val, '*'); t.equal(xml.children.length, 1); t.end(); }) t.test('text after root node', function (t) { var xmlString = '*\n\n'; var xml = new XmlDocument(xmlString); t.equal(xml.val, '*'); t.equal(xml.children.length, 1); t.end(); }) t.test('text before root node with version', function (t) { var xmlString = '\n\n*'; var xml = new XmlDocument(xmlString); t.equal(xml.val, '*'); t.equal(xml.children.length, 1); t.end(); }) t.test('text after root node with version', function (t) { var xmlString = '*\n\n'; var xml = new XmlDocument(xmlString); t.equal(xml.val, '*'); t.equal(xml.children.length, 1); t.end(); }) t.test('comment before root node', function (t) { var xmlString = '*'; var xml = new XmlDocument(xmlString); t.equal(xml.val, '*'); t.equal(xml.children.length, 1); t.end(); }) t.test('comment after root node', function (t) { var xmlString = '*'; var xml = new XmlDocument(xmlString); t.equal(xml.val, '*'); t.equal(xml.children.length, 1); t.end(); }) t.test('error handling', function (t) { var xmlString = ''; t.throws(function() { var parsed = new XmlDocument(xmlString); }); t.end(); }) t.test('tag locations', function (t) { var xmlString = ''; var books = new XmlDocument(xmlString); var book = books.children[0]; t.equal(book.attr.title, "Twilight"); t.equal(book.startTagPosition, 8); t.equal(book.line, 0); t.equal(book.column, 31); t.equal(book.position, 31); t.end(); }) t.test('eachChild', function (t) { var xmlString = ''; var books = new XmlDocument(xmlString); expectedTitles = ["Twilight", "Twister"]; books.eachChild(function(book, i, books) { t.equal(book.attr.title, expectedTitles[i]); }); called = 0; books.eachChild(function(book, i, books) { called++; return false; // test that returning false short-circuits the loop }); t.equal(called, 1); t.end(); }) t.test('eachChild with text and comments', function (t) { var xmlString = 'text!'; var books = new XmlDocument(xmlString); expectedTitles = ["Twilight", "Twister"]; var elI = 0; books.eachChild(function(book, i, books) { t.equal(book.attr.title, expectedTitles[elI++]); }); called = 0; books.eachChild(function(book, i, books) { called++; return false; // test that returning false short-circuits the loop }); t.equal(called, 1); t.end(); }) t.test('childNamed', function (t) { var xmlString = ''; var books = new XmlDocument(xmlString); var goodBook = books.childNamed('good-book'); t.equal(goodBook.name, 'good-book'); var badBook = books.childNamed('bad-book'); t.equal(badBook, undefined); t.end(); }) t.test('childNamed with text', function (t) { var xmlString = 'text'; var books = new XmlDocument(xmlString); var goodBook = books.childNamed('good-book'); t.equal(goodBook.name, 'good-book'); var badBook = books.childNamed('bad-book'); t.equal(badBook, undefined); t.end(); }) t.test('childNamed', function (t) { var xmlString = ''; var fruits = new XmlDocument(xmlString); var apples = fruits.childrenNamed('apple'); t.equal(apples.length, 2); t.equal(apples[0].attr.sweet, 'yes'); t.equal(apples[1].attr.sweet, 'no'); t.end(); }) t.test('childWithAttribute', function (t) { var xmlString = ''; var fruits = new XmlDocument(xmlString); var pickedFruit = fruits.childWithAttribute('pick', 'yes'); t.equal(pickedFruit.name, 'apple'); t.equal(pickedFruit.attr.pick, 'yes'); var rottenFruit = fruits.childWithAttribute('rotten'); t.equal(rottenFruit.name, 'orange'); var peeled = fruits.childWithAttribute('peeled'); t.equal(peeled, undefined); t.end(); }) t.test('childWithAttribute with text', function (t) { var xmlString = 'text'; var fruits = new XmlDocument(xmlString); var pickedFruit = fruits.childWithAttribute('pick', 'yes'); t.equal(pickedFruit.name, 'apple'); t.equal(pickedFruit.attr.pick, 'yes'); var rottenFruit = fruits.childWithAttribute('rotten'); t.equal(rottenFruit.name, 'orange'); var peeled = fruits.childWithAttribute('peeled'); t.equal(peeled, undefined); t.end(); }) t.test('descendantWithPath', function (t) { var xmlString = 'George R.R.Martin'; var book = new XmlDocument(xmlString); var lastNameNode = book.descendantWithPath('author.last'); t.equal(lastNameNode.val, 'Martin'); var middleNameNode = book.descendantWithPath('author.middle'); t.equal(middleNameNode, undefined); var publisherNameNode = book.descendantWithPath('publisher.first'); t.equal(publisherNameNode, undefined); t.end(); }) t.test('descendantWithPath with text', function (t) { var xmlString = 'textGeorge R.R.Martin'; var book = new XmlDocument(xmlString); var lastNameNode = book.descendantWithPath('author.last'); t.equal(lastNameNode.val, 'Martin'); var middleNameNode = book.descendantWithPath('author.middle'); t.equal(middleNameNode, undefined); var publisherNameNode = book.descendantWithPath('publisher.first'); t.equal(publisherNameNode, undefined); t.end(); }) t.test('valueWithPath', function (t) { var xmlString = 'George R.R.Martin'; var book = new XmlDocument(xmlString); var lastName = book.valueWithPath('author.last'); t.equal(lastName, 'Martin'); var lastNameHyphenated = book.valueWithPath('author.last@hyphenated'); t.equal(lastNameHyphenated, "no"); var publisherName = book.valueWithPath('publisher.last@hyphenated'); t.equal(publisherName, undefined); t.end(); }) t.test('valueWithPath with text', function (t) { var xmlString = 'textGeorge R.R.Martin'; var book = new XmlDocument(xmlString); var lastName = book.valueWithPath('author.last'); t.equal(lastName, 'Martin'); var lastNameHyphenated = book.valueWithPath('author.last@hyphenated'); t.equal(lastNameHyphenated, "no"); var publisherName = book.valueWithPath('publisher.last@hyphenated'); t.equal(publisherName, undefined); t.end(); }) t.test('toString', function (t) { var xmlString = ''; var doc = new XmlDocument(xmlString); t.equal(doc.toString(), '\n \n'); t.equal(doc.toString({compressed:true}), ''); xmlString = ' world '; doc = new XmlDocument(xmlString); t.equal(doc.toString(), 'world'); t.equal(doc.toString({preserveWhitespace:true}), ' world '); xmlString = ']]>'; doc = new XmlDocument(xmlString); t.equal(doc.toString(), ']]>'); xmlString = 'Hello ]]>!'; doc = new XmlDocument(xmlString); t.equal(doc.toString({preserveWhitespace:true}), '\n Hello\n \n \n ]]>\n !\n'); xmlString = 'hello, !'; doc = new XmlDocument(xmlString); t.equal(doc.toString(), '\n hello,\n \n !\n'); xmlString = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam et accumsan nisi.'; doc = new XmlDocument(xmlString); t.equal(doc.toString(), xmlString); t.equal(doc.toString({trimmed:true}), 'Lorem ipsum dolor sit ameā€¦') try { // test that adding stuff to the Object prototype doesn't interfere with attribute exporting Object.prototype.cruftyExtension = "You don't want this string to be exported!"; var xmlString = ''; var doc = new XmlDocument(xmlString); t.equal(doc.toString(), '\n \n'); } finally { delete Object.prototype.cruftyExtensionMethod; } xmlString = 'world'; doc = new XmlDocument(xmlString); t.equal(doc.toString({compressed:true}), xmlString); t.end(); })