typescriptify and cleanup

This commit is contained in:
Dror Gluska
2019-05-31 11:27:48 +03:00
parent 28006be580
commit cfebc962f0
28 changed files with 2863 additions and 1845 deletions

146
test/basic.spec.ts Normal file
View File

@@ -0,0 +1,146 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("Basic behavior", () => {
it("should properly parse a simple file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/item.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
const expectedData = [
{
$: { id: "1", test: "hello" },
subitem:
[{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{
$: { id: "2" },
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}];
const actualData: string[] = [];
let dataEventCount = 0;
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("error", (err) => {
should(err).not.be.ok();
done(err);
});
parser.on("end", () => {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
should(actualData).deepEqual(expectedData);
should(dataEventCount).equal(2);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a medium size file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/medium.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
let dataEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(10);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a file containing many nodes.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/manyItems.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
let dataEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(296);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a xml simple file in which nodes contain text values randomly.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/randomText.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
const expectedData = [{
$: { id: "1", test: "hello" }, _: " item one two",
subitem: [{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{
$: { id: "2" }, _: " item one two three four",
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}
];
const actualData: string[] = [];
let dataEventCount = 0;
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('actualData=', JSON.stringify(actualData, null, 1))
// console.log('dataEventCount=', dataEventCount)
should(actualData).deepEqual(expectedData);
should(dataEventCount).equal(2);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a huge file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/hugeFile.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
// console.log(parser)
let dataEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(2072);
done();
});
xmlStream.pipe(parser);
});
});

View File

@@ -0,0 +1,30 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("CData and comments in xml", () => {
it("should properly parse a simple file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/CData-comments.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
let dataEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(296);
done();
});
xmlStream.pipe(parser);
});
});

136
test/emit.spec.ts Normal file
View File

@@ -0,0 +1,136 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("emitOnNodeName", () => {
it("should properly emit events on node names.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/item.xml");
const parser = new XmlParser({ resourcePath: "/items/item", emitOnNodeName: true });
const expectedData = [
{
$: { id: "1", test: "hello" },
subitem:
[{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{
$: { id: "2" },
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}];
const actualData: string[] = [];
const itemData : string[] = [];
let dataEventCount = 0;
let itemCount = 0;
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("item", (item) => {
itemData.push(item);
itemCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
should(actualData).deepEqual(expectedData);
should(dataEventCount).equal(2);
should(itemData).deepEqual(expectedData);
should(itemCount).equal(2);
done();
});
xmlStream.pipe(parser);
});
it("should properly emit events on node names while parsing a medium size file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/medium.xml");
const parser = new XmlParser({ resourcePath: "/items/item", emitOnNodeName: true });
let dataEventCount = 0;
let itemCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("item", (data) => {
itemCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(10);
should(itemCount).equal(10);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a file containing many nodes.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/manyItems.xml");
const parser = new XmlParser({ resourcePath: "/items/item", emitOnNodeName: true });
let dataEventCount = 0;
let itemCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("item", (data) => {
itemCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(296);
should(itemCount).equal(296);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a huge file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/hugeFile.xml");
const parser = new XmlParser({ resourcePath: "/items/item", emitOnNodeName: true });
let dataEventCount = 0;
let itemCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("item", (item) => {
itemCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(2072);
should(itemCount).equal(2072);
done();
});
xmlStream.pipe(parser);
});
});

45
test/error.spec.ts Normal file
View File

@@ -0,0 +1,45 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("Error Handling", () => {
it("should properly return error if the xml file is corrupted.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/corrupted.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
let dataEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
// console.log(err)
should(err.message).equal("mismatched tag at line no: 11");
done();
});
xmlStream.pipe(parser);
});
it("should properly return error if the large xml file is corrupted.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/largeCorruptedFile.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
let dataEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
// console.log(err)
should(err.message).equal("mismatched tag at line no: 8346");
done();
});
xmlStream.pipe(parser);
});
});

250
test/explicit_array.spec.ts Normal file
View File

@@ -0,0 +1,250 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("should respect explicitArray constructor option", () => {
it("should properly parse a simple file with explicitArray set to false.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/item.xml");
const parser = new XmlParser({ resourcePath: "/items/item", explicitArray: false });
const expectedData = [
{
$: { id: "1", test: "hello" },
subitem: { $: { sub: "2" }, _: "two" }
},
{
$: { id: "2" },
subitem: { _: "five" }
}];
parser.parse(xml.toString(), (err, data) => {
if (err) { done(err); }
// console.log('data=', JSON.stringify(data))
should(data).deepEqual(expectedData);
done();
});
});
it("should properly parse a medium size file with explicitArray set to false.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/medium.xml");
const parser = new XmlParser({ resourcePath: "/items/item", explicitArray: false });
const expectedData = [
{
$: {
id: "1",
test: "hello"
},
subitem: {
$: {
sub: "2"
},
_: "two"
}
},
{
$: {
id: "2"
},
subitem: {
_: "five"
}
},
{
$: {
id: "3",
test: "hello"
},
subitem: {
$: {
sub: "2"
},
_: "two"
}
},
{
$: {
id: "4",
test: "hello"
},
subitem: {
$: {
sub: "2"
},
_: "two"
}
},
{
$: {
id: "5",
test: "hello"
},
subitem: {
$: {
sub: "2"
},
_: "two"
}
},
{
$: {
id: "6",
test: "hello"
},
subitem: {
$: {
sub: "2"
},
_: "two"
}
},
{
$: {
id: "7",
test: "hello"
},
subitem: {
$: {
sub: "2"
},
_: "two"
}
},
{
$: {
id: "8",
test: "hello"
},
subitem: {
$: {
sub: "2"
},
_: "two"
}
},
{
$: {
id: "9",
test: "hello"
},
subitem: {
$: {
sub: "2"
},
_: "two"
}
},
{
$: {
id: "10",
test: "hello"
},
subitem: {
$: {
sub: "2"
},
_: "two"
}
}
];
parser.parse(xml, (err, data) => {
if (err) { done(err); }
should(data).deepEqual(expectedData);
should(data.length).equal(10);
done();
});
});
it("should properly parse a file containing many nodes when explicitArray set to false.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/manyItems.xml");
const parser = new XmlParser({ resourcePath: "/items/item", explicitArray: false });
parser.parse(xml, (err, data) => {
if (err) { done(err); }
should(data.length).equal(296);
done();
});
});
it("should properly parse a xml simple file in which nodes contain text values randomly when explicitArray set to false.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/randomText.xml");
const parser = new XmlParser({ resourcePath: "/items/item", explicitArray: false });
const expectedData = [{
$: { id: "1", test: "hello" }, _: " item one two",
subitem: { $: { sub: "2" }, _: "two" }
},
{
$: { id: "2" }, _: " item one two three four",
subitem: { _: "five" }
}
];
parser.parse(xml, (err, data) => {
if (err) { done(err); }
should(data).deepEqual(expectedData);
should(data.length).equal(2);
done();
});
});
it("should properly parse a huge file with explicitArray set to false.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/hugeFile.xml");
const parser = new XmlParser({ resourcePath: "/items/item", explicitArray: false });
// console.log(parser)
parser.parse(xml, (err, data) => {
if (err) { done(err); }
should(data.length).equal(2072);
done();
});
});
it("should properly return error if the xml file is corrupted.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/corrupted.xml");
const parser = new XmlParser({ resourcePath: "/items/item", explicitArray: false });
parser.parse(xml, (err, data) => {
// console.log(err)
should(err.message).equal("mismatched tag at line no: 11");
should(data).not.be.ok();
done();
});
});
it("should properly generate objects when special symbols are passed as attrs and text keys and explicitArray is false in the options.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/item.xml");
const parser = new XmlParser({ resourcePath: "/items/item", attrsKey: "!", textKey: "%", explicitArray: false });
const expectedData = [
{
"!": { id: "1", test: "hello" },
"subitem": { "!": { sub: "2" }, "%": "two" }
},
{
"!": { id: "2" },
"subitem": { "%": "five" }
}];
const actualData : string[] = [];
let dataEventCount = 0;
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('actualData=', JSON.stringify(actualData, null, 1))
// console.log('dataEventCount=', dataEventCount)
should(actualData).deepEqual(expectedData);
should(dataEventCount).equal(2);
done();
});
xmlStream.pipe(parser);
});
});

321
test/interested.spec.ts Normal file
View File

@@ -0,0 +1,321 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("interested Nodes", () => {
it("should properly parse a simple file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/item.xml");
const parser = new XmlParser();
const expectedData =
[
{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" },
{
$: { id: "1", test: "hello" },
subitem: [{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{ _: "three" },
{ _: "four" },
{ _: "five" },
{
$: { id: "2" },
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}
];
const actualData: string[] = [];
let dataEventCount = 0;
const expectedItems = [
{
$: { id: "1", test: "hello" },
subitem:
[{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{
$: { id: "2" },
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}];
const actualItems: string[] = [];
const actualSubitems: string[] = [];
const expectedSubitems = [
{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" },
{ _: "three" },
{ _: "four" },
{ _: "five" }
];
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("error", (err) => {
should(err).not.be.ok();
done(err);
});
parser.on("item", (item) => {
actualItems.push(item);
});
parser.on("subitem", (subitem) => {
actualSubitems.push(subitem);
});
parser.on("end", () => {
// console.log('actualData=', JSON.stringify(actualData, null, 1))
// console.log('dataEventCount=', dataEventCount)
should(actualData).deepEqual(expectedData);
should(actualItems).deepEqual(expectedItems);
should(actualSubitems).deepEqual(expectedSubitems);
should(actualSubitems.length).equal(5);
should(actualItems.length).equal(2);
should(dataEventCount).equal(7);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a medium size file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/medium.xml");
const parser = new XmlParser();
let dataEventCount = 0;
let itemEventCount = 0;
let subitemEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("item", (item) => {
itemEventCount++;
});
parser.on("subitem", (subitem) => {
subitemEventCount++;
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
// console.log('itemEventCount=', itemEventCount)
// console.log('subitemEventCount=', subitemEventCount)
should(dataEventCount).equal(31);
should(itemEventCount).equal(10);
should(subitemEventCount).equal(21);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a file containing many nodes.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/manyItems.xml");
const parser = new XmlParser();
let dataEventCount = 0;
let itemEventCount = 0;
let subitemEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("item", (item) => {
itemEventCount++;
});
parser.on("subitem", (subitem) => {
subitemEventCount++;
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
// console.log('itemEventCount=', itemEventCount)
// console.log('subitemEventCount=', subitemEventCount)
should(itemEventCount).equal(296);
should(subitemEventCount).equal(600);
should(dataEventCount).equal(896);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a xml simple file in which nodes contain text values randomly.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/randomText.xml");
const parser = new XmlParser();
const expectedData =
[
{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" },
{
$: { id: "1", test: "hello" }, _: " item one two",
subitem: [{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{ _: "three" },
{ _: "four" },
{ _: "five" },
{
$: { id: "2" }, _: " item one two three four",
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}
];
const expectedItems = [
{
$: { id: "1", test: "hello" }, _: " item one two",
subitem:
[{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{
$: { id: "2" }, _: " item one two three four",
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}];
const actualItems: string[] = [];
const actualSubitems: string[] = [];
const expectedSubitems = [
{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" },
{ _: "three" },
{ _: "four" },
{ _: "five" }
];
const actualData: string[] = [];
let dataEventCount = 0;
let itemEventCount = 0;
let subitemEventCount = 0;
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("item", (item) => {
itemEventCount++;
actualItems.push(item);
});
parser.on("subitem", (subitem) => {
subitemEventCount++;
actualSubitems.push(subitem);
});
parser.on("end", () => {
// console.log('actualData=', JSON.stringify(actualData, null, 1))
// console.log('dataEventCount=', dataEventCount)
// console.log('itemEventCount=', itemEventCount)
// console.log('subitemEventCount=', subitemEventCount)
should(actualData).deepEqual(expectedData);
should(actualItems).deepEqual(expectedItems);
should(actualSubitems).deepEqual(expectedSubitems);
should(dataEventCount).equal(7);
should(itemEventCount).equal(2);
should(subitemEventCount).equal(5);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a huge file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/hugeFile.xml");
const parser = new XmlParser();
let dataEventCount = 0;
let itemEventCount = 0;
let subitemEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("item", (item) => {
itemEventCount++;
});
parser.on("subitem", (subitem) => {
subitemEventCount++;
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
// console.log('itemEventCount=', itemEventCount)
// console.log('subitemEventCount=', subitemEventCount)
should(dataEventCount).equal(6272);
should(itemEventCount).equal(2072);
should(subitemEventCount).equal(4200);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a simple file and return when root element when listening on it.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/item.xml");
const parser = new XmlParser();
const expectedData =
[{
item: [{
$: { id: "1", test: "hello" },
subitem: [{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{
$: { id: "2" }, subitem: [{ _: "three" }, { _: "four" },
{ _: "five" }]
}]
}];
const actualData: string[] = [];
let dataEventCount = 0;
let itemsEventCount = 0;
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("error", (err) => {
should(err).not.be.ok();
done(err);
});
parser.on("items", (item) => {
itemsEventCount++;
});
parser.on("end", () => {
// console.log('actualData=', JSON.stringify(actualData, null, 1))
// console.log('dataEventCount=', dataEventCount)
// console.log('itemEventCount=', itemsEventCount)
should(actualData).deepEqual(expectedData);
should(itemsEventCount).equal(1);
should(dataEventCount).equal(1);
done();
});
xmlStream.pipe(parser);
});
});

117
test/options.spec.ts Normal file
View File

@@ -0,0 +1,117 @@
import fs from "fs";
import "mocha";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("should respect the options passed", () => {
it("should properly generate objects with $ as key for attrs and _ as key for text value of node.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/item.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
const expectedData = [
{
$: { id: "1", test: "hello" },
subitem:
[{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{
$: { id: "2" },
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}];
const actualData: string[] = [];
let dataEventCount = 0;
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
should(actualData).deepEqual(expectedData);
should(dataEventCount).equal(2);
done();
});
xmlStream.pipe(parser);
});
it("should properly generate objects with passed attrs and text keys in the options.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/item.xml");
const parser = new XmlParser({ resourcePath: "/items/item", attrsKey: "attrs", textKey: "text" });
const expectedData = [
{
attrs: { id: "1", test: "hello" },
subitem:
[{ attrs: { sub: "TESTING SUB" }, text: "one" },
{ attrs: { sub: "2" }, text: "two" }]
},
{
attrs: { id: "2" },
subitem: [{ text: "three" }, { text: "four" }, { text: "five" }]
}];
const actualData: string[] = [];
let dataEventCount = 0;
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('actualData=', JSON.stringify(actualData, null, 1))
// console.log('dataEventCount=', dataEventCount)
should(actualData).deepEqual(expectedData);
should(dataEventCount).equal(2);
done();
});
xmlStream.pipe(parser);
});
it("should properly generate objects when special symbols are passed as attrs and text keys in the options.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/item.xml");
const parser = new XmlParser({ resourcePath: "/items/item", attrsKey: "!", textKey: "%" });
const expectedData = [
{
"!": { id: "1", test: "hello" },
"subitem":
[{ "!": { sub: "TESTING SUB" }, "%": "one" },
{ "!": { sub: "2" }, "%": "two" }]
},
{
"!": { id: "2" },
"subitem": [{ "%": "three" }, { "%": "four" }, { "%": "five" }]
}];
const actualData: string[] = [];
let dataEventCount = 0;
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('actualData=', JSON.stringify(actualData, null, 1))
// console.log('dataEventCount=', dataEventCount)
should(actualData).deepEqual(expectedData);
should(dataEventCount).equal(2);
done();
});
xmlStream.pipe(parser);
});
});

97
test/parse.spec.ts Normal file
View File

@@ -0,0 +1,97 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("Parse function should work properly", () => {
it("should properly parse a simple file.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/item.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
const expectedData = [
{
$: { id: "1", test: "hello" },
subitem:
[{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{
$: { id: "2" },
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}];
parser.parse(xml.toString(), (err, data) => {
if (err) { done(err); }
should(data).deepEqual(expectedData);
done();
});
});
it("should properly parse a medium size file.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/medium.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
parser.parse(xml, (err, data) => {
if (err) { done(err); }
should(data.length).equal(10);
done();
});
});
it("should properly parse a file containing many nodes.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/manyItems.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
parser.parse(xml, (err, data) => {
if (err) { done(err); }
should(data.length).equal(296);
done();
});
});
it("should properly parse a xml simple file in which nodes contain text values randomly.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/randomText.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
const expectedData = [{
$: { id: "1", test: "hello" }, _: " item one two",
subitem: [{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{
$: { id: "2" }, _: " item one two three four",
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}
];
parser.parse(xml, (err, data) => {
if (err) { done(err); }
should(data).deepEqual(expectedData);
should(data.length).equal(2);
done();
});
});
it("should properly parse a huge file.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/hugeFile.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
// console.log(parser)
parser.parse(xml, (err, data) => {
if (err) { done(err); }
should(data.length).equal(2072);
done();
});
});
it("should properly return error if the xml file is corrupted.", (done) => {
const xml = fs.readFileSync("./test/TestFiles/corrupted.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
parser.parse(xml, (err, data) => {
// console.log(err)
should(err.message).equal("mismatched tag at line no: 11");
should(data).not.be.ok();
done();
});
});
});

View File

@@ -0,0 +1,82 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("pause and resume", () => {
it("should properly parse a simple file.", function(done) {
const xmlStream = fs.createReadStream("./test/TestFiles/item.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
const expectedData = [
{
$: { id: "1", test: "hello" },
subitem:
[{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{
$: { id: "2" },
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}];
const actualData: string[] = [];
let dataEventCount = 0;
let isSetTimeoutHappened = true;
this.timeout(4000);
parser.on("data", (data) => {
actualData.push(data);
parser.pause();
should(isSetTimeoutHappened).equal(true);
setTimeout(() => {
parser.resume();
isSetTimeoutHappened = true;
}, 1000);
dataEventCount++;
isSetTimeoutHappened = false;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
should(actualData).deepEqual(expectedData);
should(dataEventCount).equal(2);
done();
});
xmlStream.pipe(parser);
});
it("should emit data events with 1sec interval between each using pause and resume.", function(done) {
const xmlStream = fs.createReadStream("./test/TestFiles/medium.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
let dataEventCount = 0;
let isSetTimeoutHappened = true;
this.timeout(20000);
parser.on("data", (data) => {
parser.pause();
should(isSetTimeoutHappened).equal(true);
setTimeout(() => {
parser.resume();
isSetTimeoutHappened = true;
}, 1000);
dataEventCount++;
isSetTimeoutHappened = false;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(10);
done();
});
xmlStream.pipe(parser);
});
});

103
test/performance.spec.ts Normal file
View File

@@ -0,0 +1,103 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe.skip("performance testing", () => {
it("should properly parse more than 500 MB of file.", function(done) {
const parser = new XmlParser({ resourcePath: "/items/item" });
// var wsStream = fs.createWriteStream('./test/TestFiles/MB_and_GB_size_files/MBFile.xml')
// var rsStream = fs.createReadStream('./test/TestFiles/MB_and_GB_size_files/MBFile.xml')
let dataEventCount = 0;
// var maxRSSMemoryTaken = 0
// var rss
const startTime = Date.now();
const xmlStream = new stream.Readable();
xmlStream._read = function noop() {
// nop
};
let dataChunk;
this.timeout(900000);
const firstChunk = fs.readFileSync("./test/TestFiles/MB_and_GB_size_files/firstChunk.xml");
xmlStream.push(firstChunk);
for (let i = 0; i < 2200; i++) {
dataChunk = fs.readFileSync("./test/TestFiles/MB_and_GB_size_files/repetitiveChunk.xml");
xmlStream.push(dataChunk);
}
const endingChunk = fs.readFileSync("./test/TestFiles/MB_and_GB_size_files/endingChunk.xml");
xmlStream.push(endingChunk);
xmlStream.push(null);
parser.on("data", (data) => {
// rss = process.memoryUsage().rss
// if (rss > maxRSSMemoryTaken) maxRSSMemoryTaken = rss
dataEventCount++;
});
parser.on("error", (err) => {
should(err).not.be.ok();
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
// console.log('RSS memory=', rss)
const TimeTaken = Date.now() - startTime;
// console.log('time taken=', TimeTaken)
should(TimeTaken).be.belowOrEqual(300000);
should(dataEventCount).equal(4558400);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse more than 1 GB of file.", function(done) {
const parser = new XmlParser({ resourcePath: "/items/item" });
// var wsStream = fs.createWriteStream('./test/TestFiles/MB_and_GB_size_files/MBFile.xml')
// var rsStream = fs.createReadStream('./test/TestFiles/MB_and_GB_size_files/MBFile.xml')
let dataEventCount = 0;
// var maxRSSMemoryTaken = 0
// var rss
const startTime = Date.now();
const xmlStream = new stream.Readable();
xmlStream._read = function noop() {
// nop
};
let dataChunk;
this.timeout(900000);
const firstChunk = fs.readFileSync("./test/TestFiles/MB_and_GB_size_files/firstChunk.xml");
xmlStream.push(firstChunk);
for (let i = 0; i < 4400; i++) {
dataChunk = fs.readFileSync("./test/TestFiles/MB_and_GB_size_files/repetitiveChunk.xml");
xmlStream.push(dataChunk);
}
const endingChunk = fs.readFileSync("./test/TestFiles/MB_and_GB_size_files/endingChunk.xml");
xmlStream.push(endingChunk);
xmlStream.push(null);
parser.on("data", (data) => {
// rss = process.memoryUsage().rss
// if (rss > maxRSSMemoryTaken) maxRSSMemoryTaken = rss
dataEventCount++;
});
parser.on("error", (err) => {
should(err).not.be.ok();
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
// console.log('RSS memory=', rss)
const TimeTaken = Date.now() - startTime;
// console.log('time taken=', TimeTaken)
should(TimeTaken).be.belowOrEqual(700000);
should(dataEventCount).equal(9116800);
done();
});
xmlStream.pipe(parser);
});
});

105
test/read.spec.ts Normal file
View File

@@ -0,0 +1,105 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("read method", () => {
it("should properly parse a simple file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/item.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
const expectedData = [
{
$: { id: "1", test: "hello" },
subitem:
[{ $: { sub: "TESTING SUB" }, _: "one" },
{ $: { sub: "2" }, _: "two" }]
},
{
$: { id: "2" },
subitem: [{ _: "three" }, { _: "four" }, { _: "five" }]
}];
const actualData: string[] = [];
let obj;
let Timeout: any;
parser.on("readable", () => {
Timeout = setInterval(() => {
obj = parser.read();
if (obj) {
actualData.push(obj);
}
obj = null;
}, 50);
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
clearInterval(Timeout);
should(actualData).deepEqual(expectedData);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a file containing many nodes.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/manyItems.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
let objCount = 0;
const endEventOcurred = false;
parser.on("readable", () => {
read();
});
function read() {
while (parser.read()) { objCount++; }
if (!endEventOcurred) { setTimeout(read, 50); }
}
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log(objCount)
should(objCount).deepEqual(296);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a huge.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/hugeFile.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
let objCount = 0;
const endEventOcurred = false;
parser.on("readable", () => {
read();
});
function read() {
while (parser.read()) { objCount++; }
if (!endEventOcurred) { setTimeout(read, 50); }
}
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log(objCount)
should(objCount).deepEqual(2072);
done();
});
xmlStream.pipe(parser);
});
});

111
test/same_name.spec.ts Normal file
View File

@@ -0,0 +1,111 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("nodes with same names", () => {
it("should properly parse a simple file containing nodes with same names.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/nodesWithSameNames.xml");
const parser = new XmlParser();
const actualData: string[] = [];
const actualItems: string[] = [];
let dataEventCount = 0;
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("error", (err) => {
should(err).not.be.ok();
done(err);
});
parser.on("item", (item) => {
actualItems.push(item);
});
parser.on("end", () => {
should(actualItems.length).equal(18);
should(dataEventCount).equal(18);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a simple file containing nodes with same names and emit events on multiple nodes.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/nodesWithSameNames.xml");
const parser = new XmlParser();
let dataEventCount = 0;
let itemEventCount = 0;
let subitemEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
should(err).not.be.ok();
done(err);
});
parser.on("item", (item) => {
itemEventCount++;
});
parser.on("subitem", (subitem) => {
subitemEventCount++;
});
parser.on("end", () => {
should(itemEventCount).equal(18);
should(subitemEventCount).equal(13);
should(dataEventCount).equal(31);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a medium size file with same names randomly.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/nodesWithSameNamesRandomly.xml");
const parser = new XmlParser();
let dataEventCount = 0;
let itemEventCount = 0;
let subitemEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("item", (item) => {
itemEventCount++;
});
parser.on("subitem", (subitem) => {
subitemEventCount++;
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
// console.log('itemEventCount=', itemEventCount)
// console.log('subitemEventCount=', subitemEventCount)
should(dataEventCount).equal(32);
should(itemEventCount).equal(19);
should(subitemEventCount).equal(13);
done();
});
xmlStream.pipe(parser);
});
});

File diff suppressed because it is too large Load Diff

64
test/uncompressed.spec.ts Normal file
View File

@@ -0,0 +1,64 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("should properly handle uncompressed files", () => {
it("should properly parse a uncompressed xml file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/medium.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
const gzip = zlib.createGzip();
const gunzip = zlib.createGunzip();
let dataEventCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(10);
done();
});
xmlStream.pipe(gzip).pipe(gunzip).pipe(parser);
});
it("should properly parse uncompressed file and go fine with pause and resume.", function(done) {
const xmlStream = fs.createReadStream("./test/TestFiles/medium.xml");
const parser = new XmlParser({ resourcePath: "/items/item" });
const gzip = zlib.createGzip();
const gunzip = zlib.createGunzip();
let dataEventCount = 0;
let isSetTimeoutHappened = true;
this.timeout(20000);
parser.on("data", (data) => {
parser.pause();
should(isSetTimeoutHappened).equal(true);
setTimeout(() => {
parser.resume();
isSetTimeoutHappened = true;
}, 2000);
dataEventCount++;
isSetTimeoutHappened = false;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(10);
done();
});
xmlStream.pipe(gzip).pipe(gunzip).pipe(parser);
});
});

View File

@@ -0,0 +1,99 @@
import fs from "fs";
import "mocha";
import should from "should";
import stream from "stream";
import zlib from "zlib";
import { XmlParser } from "../src/parser";
describe("wrong resourcePath", () => {
it("should be able to detect the wrong resourcePath at root level.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/item.xml");
const parser = new XmlParser({ resourcePath: "/wrong/noNodes", emitOnNodeName: true });
const actualData : string[] = [];
const itemData : string[] = [];
let dataEventCount = 0;
let itemCount = 0;
parser.on("data", (data) => {
actualData.push(data);
dataEventCount++;
});
parser.on("item", (item) => {
itemData.push(item);
itemCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
should(actualData.length).equal(0);
should(dataEventCount).equal(0);
should(itemData.length).equal(0);
should(itemCount).equal(0);
done();
});
xmlStream.pipe(parser);
});
it("should be able to detect wrong resourcePath while parsing xml", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/manyItems.xml");
const parser = new XmlParser({ resourcePath: "/wrong/noNodes", emitOnNodeName: true });
let dataEventCount = 0;
let itemCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("item", (data) => {
itemCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(0);
should(itemCount).equal(0);
done();
});
xmlStream.pipe(parser);
});
it("should properly parse a huge file.", (done) => {
const xmlStream = fs.createReadStream("./test/TestFiles/hugeFile.xml");
const parser = new XmlParser({ resourcePath: "/wrong/path", emitOnNodeName: true });
let dataEventCount = 0;
let itemCount = 0;
parser.on("data", (data) => {
dataEventCount++;
});
parser.on("item", (item) => {
itemCount++;
});
parser.on("error", (err) => {
done(err);
});
parser.on("end", () => {
// console.log('dataEventCount=', dataEventCount)
should(dataEventCount).equal(0);
should(itemCount).equal(0);
done();
});
xmlStream.pipe(parser);
});
});