Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

453 строки
12 KiB

  1. var XmlDocument = require("../").XmlDocument;
  2. var t = require("tap");
  3. t.test("verify sax global in browser", function (t) {
  4. // "un-require" the xmldoc module that we loaded up top
  5. delete require.cache[require.resolve("../")];
  6. // also un-require the actual xmldoc module pulled in by index.js ('../')
  7. delete require.cache[require.resolve("../lib/xmldoc.js")];
  8. // this signal will be picked up on by xmldoc.js
  9. global.xmldocAssumeBrowser = true;
  10. t.throws(function () {
  11. require("../");
  12. });
  13. // try again, but this time satisfy the sax check
  14. delete require.cache[require.resolve("../")];
  15. delete require.cache[require.resolve("../lib/xmldoc.js")];
  16. global.sax = {};
  17. require("../");
  18. t.ok(global.XmlDocument);
  19. t.end();
  20. });
  21. t.test("extend util", function (t) {
  22. delete require.cache[require.resolve("../")];
  23. delete require.cache[require.resolve("../lib/xmldoc.js")];
  24. Object.prototype.cruftyExtension = "blah";
  25. try {
  26. require("../");
  27. } finally {
  28. delete Object.prototype.cruftyExtension;
  29. }
  30. t.end();
  31. });
  32. t.test("parse xml", function (t) {
  33. var xmlString = "<hello>world</hello>";
  34. var parsed = new XmlDocument(xmlString);
  35. t.ok(parsed);
  36. t.throws(function () {
  37. new XmlDocument();
  38. });
  39. t.throws(function () {
  40. new XmlDocument(" ");
  41. });
  42. t.end();
  43. });
  44. t.test("cdata handling", function (t) {
  45. var xmlString = "<hello><![CDATA[<world>]]></hello>";
  46. var parsed = new XmlDocument(xmlString);
  47. t.equal(parsed.val, "<world>");
  48. t.end();
  49. });
  50. t.test("cdata and text handling", function (t) {
  51. var xmlString = "<hello>(<![CDATA[<world>]]>)</hello>";
  52. var parsed = new XmlDocument(xmlString);
  53. t.equal(parsed.val, "(<world>)");
  54. t.end();
  55. });
  56. t.test("doctype handling", function (t) {
  57. var docWithType = new XmlDocument(
  58. "<!DOCTYPE HelloWorld><hello>world</hello>",
  59. );
  60. t.equal(docWithType.doctype, " HelloWorld");
  61. var docWithoutType = new XmlDocument("<hello>world</hello>");
  62. t.equal(docWithoutType.doctype, "");
  63. t.throws(function () {
  64. new XmlDocument("<hello><!DOCTYPE HelloWorld>world</hello>");
  65. });
  66. t.end();
  67. });
  68. t.test("comment handling", function (t) {
  69. var xmlString = "<hello><!-- World --></hello>";
  70. var parsed = new XmlDocument(xmlString);
  71. t.equal(parsed.val, "");
  72. t.end();
  73. });
  74. t.test("comment and text handling", function (t) {
  75. var xmlString = "<hello>(<!-- World -->)</hello>";
  76. var parsed = new XmlDocument(xmlString);
  77. t.equal(parsed.val, "()");
  78. t.end();
  79. });
  80. t.test("text, cdata, and comment handling", function (t) {
  81. var xmlString = "<hello>Hello<!-- , --> <![CDATA[<world>]]>!</hello>";
  82. var parsed = new XmlDocument(xmlString);
  83. t.equal(parsed.val, "Hello <world>!");
  84. t.end();
  85. });
  86. t.test("text with elements handling", function (t) {
  87. var xmlString = "<hello>hello, <world/>!</hello>";
  88. var parsed = new XmlDocument(xmlString);
  89. t.equal(parsed.val, "hello, !");
  90. t.end();
  91. });
  92. t.test("text before root node", function (t) {
  93. var xmlString = "\n\n<hello>*</hello>";
  94. var xml = new XmlDocument(xmlString);
  95. t.equal(xml.val, "*");
  96. t.equal(xml.children.length, 1);
  97. t.end();
  98. });
  99. t.test("text after root node", function (t) {
  100. var xmlString = "<hello>*</hello>\n\n";
  101. var xml = new XmlDocument(xmlString);
  102. t.equal(xml.val, "*");
  103. t.equal(xml.children.length, 1);
  104. t.end();
  105. });
  106. t.test("text before root node with version", function (t) {
  107. var xmlString = '<?xml version="1.0"?>\n\n<hello>*</hello>';
  108. var xml = new XmlDocument(xmlString);
  109. t.equal(xml.val, "*");
  110. t.equal(xml.children.length, 1);
  111. t.end();
  112. });
  113. t.test("text after root node with version", function (t) {
  114. var xmlString = '<?xml version="1.0"?><hello>*</hello>\n\n';
  115. var xml = new XmlDocument(xmlString);
  116. t.equal(xml.val, "*");
  117. t.equal(xml.children.length, 1);
  118. t.end();
  119. });
  120. t.test("comment before root node", function (t) {
  121. var xmlString = "<!-- hello --><world>*</world>";
  122. var xml = new XmlDocument(xmlString);
  123. t.equal(xml.val, "*");
  124. t.equal(xml.children.length, 1);
  125. t.end();
  126. });
  127. t.test("comment after root node", function (t) {
  128. var xmlString = "<hello>*</hello><!-- world -->";
  129. var xml = new XmlDocument(xmlString);
  130. t.equal(xml.val, "*");
  131. t.equal(xml.children.length, 1);
  132. t.end();
  133. });
  134. t.test("error handling", function (t) {
  135. var xmlString = "<hello><unclosed-tag></hello>";
  136. t.throws(function () {
  137. var parsed = new XmlDocument(xmlString);
  138. });
  139. t.end();
  140. });
  141. t.test("tag locations", function (t) {
  142. var xmlString = '<books><book title="Twilight"/></books>';
  143. var books = new XmlDocument(xmlString);
  144. var book = books.children[0];
  145. t.equal(book.attr.title, "Twilight");
  146. t.equal(book.startTagPosition, 8);
  147. t.equal(book.line, 0);
  148. t.equal(book.column, 31);
  149. t.equal(book.position, 31);
  150. t.end();
  151. });
  152. t.test("eachChild", function (t) {
  153. var xmlString =
  154. '<books><book title="Twilight"/><book title="Twister"/></books>';
  155. var books = new XmlDocument(xmlString);
  156. expectedTitles = ["Twilight", "Twister"];
  157. books.eachChild(function (book, i, books) {
  158. t.equal(book.attr.title, expectedTitles[i]);
  159. });
  160. called = 0;
  161. books.eachChild(function (book, i, books) {
  162. called++;
  163. return false; // test that returning false short-circuits the loop
  164. });
  165. t.equal(called, 1);
  166. t.end();
  167. });
  168. t.test("eachChild with text and comments", function (t) {
  169. var xmlString =
  170. '<books><book title="Twilight"/>text!<book title="Twister"/><!--comment!--></books>';
  171. var books = new XmlDocument(xmlString);
  172. expectedTitles = ["Twilight", "Twister"];
  173. var elI = 0;
  174. books.eachChild(function (book, i, books) {
  175. t.equal(book.attr.title, expectedTitles[elI++]);
  176. });
  177. called = 0;
  178. books.eachChild(function (book, i, books) {
  179. called++;
  180. return false; // test that returning false short-circuits the loop
  181. });
  182. t.equal(called, 1);
  183. t.end();
  184. });
  185. t.test("childNamed", function (t) {
  186. var xmlString = "<books><book/><good-book/></books>";
  187. var books = new XmlDocument(xmlString);
  188. var goodBook = books.childNamed("good-book");
  189. t.equal(goodBook.name, "good-book");
  190. var badBook = books.childNamed("bad-book");
  191. t.equal(badBook, undefined);
  192. t.end();
  193. });
  194. t.test("childNamed with text", function (t) {
  195. var xmlString = "<books><book/>text<good-book/></books>";
  196. var books = new XmlDocument(xmlString);
  197. var goodBook = books.childNamed("good-book");
  198. t.equal(goodBook.name, "good-book");
  199. var badBook = books.childNamed("bad-book");
  200. t.equal(badBook, undefined);
  201. t.end();
  202. });
  203. t.test("childNamed", function (t) {
  204. var xmlString =
  205. '<fruits><apple sweet="yes"/><orange/><apple sweet="no"/><banana/></fruits>';
  206. var fruits = new XmlDocument(xmlString);
  207. var apples = fruits.childrenNamed("apple");
  208. t.equal(apples.length, 2);
  209. t.equal(apples[0].attr.sweet, "yes");
  210. t.equal(apples[1].attr.sweet, "no");
  211. t.end();
  212. });
  213. t.test("childWithAttribute", function (t) {
  214. var xmlString =
  215. '<fruits><apple pick="no"/><orange rotten="yes"/><apple pick="yes"/><banana/></fruits>';
  216. var fruits = new XmlDocument(xmlString);
  217. var pickedFruit = fruits.childWithAttribute("pick", "yes");
  218. t.equal(pickedFruit.name, "apple");
  219. t.equal(pickedFruit.attr.pick, "yes");
  220. var rottenFruit = fruits.childWithAttribute("rotten");
  221. t.equal(rottenFruit.name, "orange");
  222. var peeled = fruits.childWithAttribute("peeled");
  223. t.equal(peeled, undefined);
  224. t.end();
  225. });
  226. t.test("childWithAttribute with text", function (t) {
  227. var xmlString =
  228. '<fruits><apple pick="no"/><orange rotten="yes"/>text<apple pick="yes"/><banana/></fruits>';
  229. var fruits = new XmlDocument(xmlString);
  230. var pickedFruit = fruits.childWithAttribute("pick", "yes");
  231. t.equal(pickedFruit.name, "apple");
  232. t.equal(pickedFruit.attr.pick, "yes");
  233. var rottenFruit = fruits.childWithAttribute("rotten");
  234. t.equal(rottenFruit.name, "orange");
  235. var peeled = fruits.childWithAttribute("peeled");
  236. t.equal(peeled, undefined);
  237. t.end();
  238. });
  239. t.test("descendantsNamed", function (t) {
  240. var xmlString =
  241. '<navigation><item id="1"/><divider/><item id="2"><item id="2.1"/><item id="2.2"><item id="2.2.1"/></item><divider/><item id="3"/></item></navigation>';
  242. var navigation = new XmlDocument(xmlString);
  243. var items = navigation.descendantsNamed("item");
  244. t.equal(items.length, 6);
  245. t.equal(items[0].attr.id, "1");
  246. t.equal(items[1].attr.id, "2");
  247. t.equal(items[2].attr.id, "2.1");
  248. t.equal(items[3].attr.id, "2.2");
  249. t.equal(items[4].attr.id, "2.2.1");
  250. t.equal(items[5].attr.id, "3");
  251. t.end();
  252. });
  253. t.test("descendantWithPath", function (t) {
  254. var xmlString =
  255. "<book><author><first>George R.R.</first><last>Martin</last></author></book>";
  256. var book = new XmlDocument(xmlString);
  257. var lastNameNode = book.descendantWithPath("author.last");
  258. t.equal(lastNameNode.val, "Martin");
  259. var middleNameNode = book.descendantWithPath("author.middle");
  260. t.equal(middleNameNode, undefined);
  261. var publisherNameNode = book.descendantWithPath("publisher.first");
  262. t.equal(publisherNameNode, undefined);
  263. t.end();
  264. });
  265. t.test("descendantWithPath with text", function (t) {
  266. var xmlString =
  267. "<book><author>text<first>George R.R.</first><last>Martin</last></author></book>";
  268. var book = new XmlDocument(xmlString);
  269. var lastNameNode = book.descendantWithPath("author.last");
  270. t.equal(lastNameNode.val, "Martin");
  271. var middleNameNode = book.descendantWithPath("author.middle");
  272. t.equal(middleNameNode, undefined);
  273. var publisherNameNode = book.descendantWithPath("publisher.first");
  274. t.equal(publisherNameNode, undefined);
  275. t.end();
  276. });
  277. t.test("valueWithPath", function (t) {
  278. var xmlString =
  279. '<book><author><first>George R.R.</first><last hyphenated="no">Martin</last></author></book>';
  280. var book = new XmlDocument(xmlString);
  281. var lastName = book.valueWithPath("author.last");
  282. t.equal(lastName, "Martin");
  283. var lastNameHyphenated = book.valueWithPath("author.last@hyphenated");
  284. t.equal(lastNameHyphenated, "no");
  285. var publisherName = book.valueWithPath("publisher.last@hyphenated");
  286. t.equal(publisherName, undefined);
  287. t.end();
  288. });
  289. t.test("valueWithPath with text", function (t) {
  290. var xmlString =
  291. '<book><author>text<first>George R.R.</first><last hyphenated="no">Martin</last></author></book>';
  292. var book = new XmlDocument(xmlString);
  293. var lastName = book.valueWithPath("author.last");
  294. t.equal(lastName, "Martin");
  295. var lastNameHyphenated = book.valueWithPath("author.last@hyphenated");
  296. t.equal(lastNameHyphenated, "no");
  297. var publisherName = book.valueWithPath("publisher.last@hyphenated");
  298. t.equal(publisherName, undefined);
  299. t.end();
  300. });
  301. t.test("toString", function (t) {
  302. var xmlString = '<books><book title="Twilight"/></books>';
  303. var doc = new XmlDocument(xmlString);
  304. t.equal(doc.toString(), '<books>\n <book title="Twilight"/>\n</books>');
  305. t.equal(
  306. doc.toString({ compressed: true }),
  307. '<books><book title="Twilight"/></books>',
  308. );
  309. xmlString = "<hello> world </hello>";
  310. doc = new XmlDocument(xmlString);
  311. t.equal(doc.toString(), "<hello>world</hello>");
  312. t.equal(doc.toString({ preserveWhitespace: true }), "<hello> world </hello>");
  313. xmlString = "<hello><![CDATA[<world>]]></hello>";
  314. doc = new XmlDocument(xmlString);
  315. t.equal(doc.toString(), "<hello><![CDATA[<world>]]></hello>");
  316. xmlString = "<hello>Hello<!-- , --> <![CDATA[<world>]]>!</hello>";
  317. doc = new XmlDocument(xmlString);
  318. t.equal(
  319. doc.toString({ preserveWhitespace: true }),
  320. "<hello>\n Hello\n <!-- , -->\n \n <![CDATA[<world>]]>\n !\n</hello>",
  321. );
  322. xmlString = "<hello>hello, <world/>!</hello>";
  323. doc = new XmlDocument(xmlString);
  324. t.equal(doc.toString(), "<hello>\n hello,\n <world/>\n !\n</hello>");
  325. xmlString =
  326. "<hello>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam et accumsan nisi.</hello>";
  327. doc = new XmlDocument(xmlString);
  328. t.equal(doc.toString(), xmlString);
  329. t.equal(
  330. doc.toString({ trimmed: true }),
  331. "<hello>Lorem ipsum dolor sit ame…</hello>",
  332. );
  333. try {
  334. // test that adding stuff to the Object prototype doesn't interfere with attribute exporting
  335. Object.prototype.cruftyExtension =
  336. "You don't want this string to be exported!";
  337. var xmlString = '<books><book title="Twilight"/></books>';
  338. var doc = new XmlDocument(xmlString);
  339. t.equal(doc.toString(), '<books>\n <book title="Twilight"/>\n</books>');
  340. } finally {
  341. delete Object.prototype.cruftyExtensionMethod;
  342. }
  343. xmlString = "<hello>world<earth/><moon/></hello>";
  344. doc = new XmlDocument(xmlString);
  345. t.equal(doc.toString({ compressed: true }), xmlString);
  346. t.end();
  347. });