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("descendantsNamed", function (t) {
var xmlString =
' ';
var navigation = new XmlDocument(xmlString);
var items = navigation.descendantsNamed("item");
t.equal(items.length, 6);
t.equal(items[0].attr.id, "1");
t.equal(items[1].attr.id, "2");
t.equal(items[2].attr.id, "2.1");
t.equal(items[3].attr.id, "2.2");
t.equal(items[4].attr.id, "2.2.1");
t.equal(items[5].attr.id, "3");
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();
});