Files
xml-streamer/test/test.js
2016-11-08 18:15:51 +05:30

759 lines
23 KiB
JavaScript

var should = require('should')
var fs = require('fs')
var zlib = require('zlib')
var ParserFactory = require('../parser')
describe('Tests', function () {
describe('Basic behaviour', function () {
it('should properly parse a simple file.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/item.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var expectedData = [
{ '$': { id: '1', test: 'hello' },
subitem:
[ { '$': { sub: 'TESTING SUB' }, _: 'one' },
{ '$': { sub: '2' }, _: 'two' } ] },
{ '$': { id: '2' },
subitem: [ { _: 'three' }, { _: 'four' }, { _: 'five' } ] } ]
var actualData = []
var dataEventCount = 0
parser.on('data', function (data) {
actualData.push(data)
dataEventCount++
})
parser.on('error', function (err) {
should(err).not.be.ok()
done(err)
})
parser.on('end', function () {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
actualData.should.deepEqual(expectedData)
dataEventCount.should.equal(2)
done()
})
xmlStream.pipe(parser)
})
it('should properly parse a medium size file.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/medium.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var dataEventCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(10)
done()
})
xmlStream.pipe(parser)
})
it('should properly parse a file containing many nodes.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/manyItems.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var dataEventCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(296)
done()
})
xmlStream.pipe(parser)
})
it('should properly parse a xml simple file in which nodes contain text values randomly.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/randomText.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var 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' } ] }
]
var actualData = []
var dataEventCount = 0
parser.on('data', function (data) {
actualData.push(data)
dataEventCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('actualData=', JSON.stringify(actualData, null, 1))
// console.log('dataEventCount=', dataEventCount)
actualData.should.deepEqual(expectedData)
dataEventCount.should.equal(2)
done()
})
xmlStream.pipe(parser)
})
it('should properly parse a file containing many nodes.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/manyItems.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
// console.log(parser)
var dataEventCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(296)
done()
})
xmlStream.pipe(parser)
})
it('should properly parse a huge file.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/hugeFile.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
// console.log(parser)
var dataEventCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(2072)
done()
})
xmlStream.pipe(parser)
})
})
describe('pause and resume', function () {
it('should properly parse a simple file.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/item.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var expectedData = [
{ '$': { id: '1', test: 'hello' },
subitem:
[ { '$': { sub: 'TESTING SUB' }, _: 'one' },
{ '$': { sub: '2' }, _: 'two' } ] },
{ '$': { id: '2' },
subitem: [ { _: 'three' }, { _: 'four' }, { _: 'five' } ] } ]
var actualData = []
var dataEventCount = 0
var isSetTimeoutHappened = true
this.timeout(4000)
parser.on('data', function (data) {
actualData.push(data)
parser.pause()
isSetTimeoutHappened.should.equal(true)
setTimeout(function () {
parser.resume()
isSetTimeoutHappened = true
}, 3000)
dataEventCount++
isSetTimeoutHappened = false
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
actualData.should.deepEqual(expectedData)
dataEventCount.should.equal(2)
done()
})
xmlStream.pipe(parser)
})
it('should emit data events with 1sec interval between each using pause and resume.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/medium.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var dataEventCount = 0
var isSetTimeoutHappened = true
this.timeout(20000)
parser.on('data', function (data) {
parser.pause()
isSetTimeoutHappened.should.equal(true)
setTimeout(function () {
parser.resume()
isSetTimeoutHappened = true
}, 2000)
dataEventCount++
isSetTimeoutHappened = false
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(10)
done()
})
xmlStream.pipe(parser)
})
})
describe('should respect the options passed', function () {
it('should properly generate objects with $ as key for attrs and _ as key for text value of node.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/item.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var expectedData = [
{ '$': { id: '1', test: 'hello' },
subitem:
[ { '$': { sub: 'TESTING SUB' }, _: 'one' },
{ '$': { sub: '2' }, _: 'two' } ] },
{ '$': { id: '2' },
subitem: [ { _: 'three' }, { _: 'four' }, { _: 'five' } ] } ]
var actualData = []
var dataEventCount = 0
parser.on('data', function (data) {
actualData.push(data)
dataEventCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
actualData.should.deepEqual(expectedData)
dataEventCount.should.equal(2)
done()
})
xmlStream.pipe(parser)
})
it('should properly generate objects with passed attrs and text keys in the options.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/item.xml')
var parser = new ParserFactory({resourcePath: '/items/item', attrsKey: 'attrs', textKey: 'text'})
var 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' } ] } ]
var actualData = []
var dataEventCount = 0
parser.on('data', function (data) {
actualData.push(data)
dataEventCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('actualData=', JSON.stringify(actualData, null, 1))
// console.log('dataEventCount=', dataEventCount)
actualData.should.deepEqual(expectedData)
dataEventCount.should.equal(2)
done()
})
xmlStream.pipe(parser)
})
it('should properly generate objects when special symbols are passed as attrs and text keys in the options.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/item.xml')
var parser = new ParserFactory({resourcePath: '/items/item', attrsKey: '!', textKey: '%'})
var expectedData = [
{ '!': { id: '1', test: 'hello' },
subitem:
[ { '!': { sub: 'TESTING SUB' }, '%': 'one' },
{ '!': { sub: '2' }, '%': 'two' } ] },
{ '!': { id: '2' },
subitem: [ { '%': 'three' }, { '%': 'four' }, { '%': 'five' } ] } ]
var actualData = []
var dataEventCount = 0
parser.on('data', function (data) {
actualData.push(data)
dataEventCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('actualData=', JSON.stringify(actualData, null, 1))
// console.log('dataEventCount=', dataEventCount)
actualData.should.deepEqual(expectedData)
dataEventCount.should.equal(2)
done()
})
xmlStream.pipe(parser)
})
})
describe('should properly handle uncompressed files', function () {
it('should properly parse a uncompressed xml file.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/medium.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var gzip = zlib.createGzip()
var gunzip = zlib.createGunzip()
var dataEventCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.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) {
var xmlStream = fs.createReadStream('./test/TestFiles/medium.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var gzip = zlib.createGzip()
var gunzip = zlib.createGunzip()
var dataEventCount = 0
var isSetTimeoutHappened = true
this.timeout(20000)
parser.on('data', function (data) {
parser.pause()
isSetTimeoutHappened.should.equal(true)
setTimeout(function () {
parser.resume()
isSetTimeoutHappened = true
}, 2000)
dataEventCount++
isSetTimeoutHappened = false
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(10)
done()
})
xmlStream.pipe(gzip).pipe(gunzip).pipe(parser)
})
})
describe('read method', function () {
it('should properly parse a simple file.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/item.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var expectedData = [
{ '$': { id: '1', test: 'hello' },
subitem:
[ { '$': { sub: 'TESTING SUB' }, _: 'one' },
{ '$': { sub: '2' }, _: 'two' } ] },
{ '$': { id: '2' },
subitem: [ { _: 'three' }, { _: 'four' }, { _: 'five' } ] } ]
var actualData = []
var obj
var Timeout
parser.on('readable', function () {
Timeout = setInterval(function () {
if ((obj = parser.read())) actualData.push(obj)
obj = null
}, 50)
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
clearInterval(Timeout)
actualData.should.deepEqual(expectedData)
done()
})
xmlStream.pipe(parser)
})
it('should properly parse a file containing many nodes.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/manyItems.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var objCount = 0
var endEventOcurred = false
parser.on('readable', function () {
read()
})
function read () {
while (parser.read()) objCount++
if (!endEventOcurred) setTimeout(read, 50)
}
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log(objCount)
objCount.should.deepEqual(296)
done()
})
xmlStream.pipe(parser)
})
it('should properly parse a huge.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/hugeFile.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var objCount = 0
var endEventOcurred = false
parser.on('readable', function () {
read()
})
function read () {
while (parser.read()) objCount++
if (!endEventOcurred) setTimeout(read, 50)
}
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log(objCount)
objCount.should.deepEqual(2072)
done()
})
xmlStream.pipe(parser)
})
})
describe('Error Handling', function () {
it('should properly return error if the xml file is corrupted.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/corrupted.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var dataEventCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('error', function (err) {
// console.log(err)
err.message.should.equal('mismatched tag at line no: 11')
done()
})
xmlStream.pipe(parser)
})
it('should properly return error if the large xml file is corrupted.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/largeCorruptedFile.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var dataEventCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('error', function (err) {
// console.log(err)
err.message.should.equal('mismatched tag at line no: 8346')
done()
})
xmlStream.pipe(parser)
})
})
describe('CData and comments in xml', function () {
it('should properly parse a simple file.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/CData-comments.xml')
var parser = new ParserFactory({resourcePath: '/items/item'})
var dataEventCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(296)
done()
})
xmlStream.pipe(parser)
})
})
describe('emitOnNodeName', function () {
it('should properly emit events on node names.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/item.xml')
var parser = new ParserFactory({resourcePath: '/items/item', emitOnNodeName: true})
var expectedData = [
{ '$': { id: '1', test: 'hello' },
subitem:
[ { '$': { sub: 'TESTING SUB' }, _: 'one' },
{ '$': { sub: '2' }, _: 'two' } ] },
{ '$': { id: '2' },
subitem: [ { _: 'three' }, { _: 'four' }, { _: 'five' } ] } ]
var actualData = []
var itemData = []
var dataEventCount = 0
var itemCount = 0
parser.on('data', function (data) {
actualData.push(data)
dataEventCount++
})
parser.on('item', function (item) {
itemData.push(item)
itemCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
actualData.should.deepEqual(expectedData)
dataEventCount.should.equal(2)
itemData.should.deepEqual(expectedData)
itemCount.should.equal(2)
done()
})
xmlStream.pipe(parser)
})
it('should properly emit events on node names while parsing a medium size file.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/medium.xml')
var parser = new ParserFactory({resourcePath: '/items/item', emitOnNodeName: true})
var dataEventCount = 0
var itemCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('item', function (data) {
itemCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(10)
itemCount.should.equal(10)
done()
})
xmlStream.pipe(parser)
})
it('should properly parse a file containing many nodes.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/manyItems.xml')
var parser = new ParserFactory({resourcePath: '/items/item', emitOnNodeName: true})
var dataEventCount = 0
var itemCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('item', function (data) {
itemCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(296)
itemCount.should.equal(296)
done()
})
xmlStream.pipe(parser)
})
it('should properly parse a huge file.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/hugeFile.xml')
var parser = new ParserFactory({resourcePath: '/items/item', emitOnNodeName: true})
var dataEventCount = 0
var itemCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('item', function (item) {
itemCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(2072)
itemCount.should.equal(2072)
done()
})
xmlStream.pipe(parser)
})
})
describe('wrong resourcePath', function () {
it('should be able to detect the wrong resourcePath at root level.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/item.xml')
var parser = new ParserFactory({resourcePath: '/wrong/noNodes', emitOnNodeName: true})
var actualData = []
var itemData = []
var dataEventCount = 0
var itemCount = 0
parser.on('data', function (data) {
actualData.push(data)
dataEventCount++
})
parser.on('item', function (item) {
itemData.push(item)
itemCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('actualData=', actualData)
// console.log('dataEventCount=', dataEventCount)
actualData.length.should.equal(0)
dataEventCount.should.equal(0)
itemData.length.should.equal(0)
itemCount.should.equal(0)
done()
})
xmlStream.pipe(parser)
})
it('should be able to detect wrong resourcePath while parsing xml', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/manyItems.xml')
var parser = new ParserFactory({resourcePath: '/wrong/noNodes', emitOnNodeName: true})
var dataEventCount = 0
var itemCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('item', function (data) {
itemCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(0)
itemCount.should.equal(0)
done()
})
xmlStream.pipe(parser)
})
it('should properly parse a huge file.', function (done) {
var xmlStream = fs.createReadStream('./test/TestFiles/hugeFile.xml')
var parser = new ParserFactory({resourcePath: '/wrong/path', emitOnNodeName: true})
var dataEventCount = 0
var itemCount = 0
parser.on('data', function (data) {
dataEventCount++
})
parser.on('item', function (item) {
itemCount++
})
parser.on('error', function (err) {
done(err)
})
parser.on('end', function () {
// console.log('dataEventCount=', dataEventCount)
dataEventCount.should.equal(0)
itemCount.should.equal(0)
done()
})
xmlStream.pipe(parser)
})
})
})