diff --git a/lib/index.js b/lib/index.js index db7f9ef..8e82007 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1 +1,2 @@ module.exports.SaXPath = require('./saxpath'); +module.exports.Stream = require('./stream'); diff --git a/lib/stream.js b/lib/stream.js new file mode 100644 index 0000000..d52cc7d --- /dev/null +++ b/lib/stream.js @@ -0,0 +1,22 @@ +var stream = require('stream'); +var duplexify = require('duplexify'); +var SaXPath = require('./saxpath'); + +function createReadable(streamer, args) { + var readable = new stream.Readable(args); + streamer.on('match', function(chunk) { + readable.push(chunk); + }); + streamer.on('end', function() { + readable.push(null); + }); + readable._read = function(n) { + }; + return readable; +} + +module.exports = function SaXPathStream(saxParser, xpath, recorder, streamArgs) { + var streamer = new SaXPath(saxParser, xpath, recorder); + var readable = createReadable(streamer, streamArgs); + return duplexify(saxParser, readable, streamArgs); +}; diff --git a/package.json b/package.json index d753686..5f97e0f 100644 --- a/package.json +++ b/package.json @@ -10,14 +10,15 @@ "url": "https://raw.github.com/StevenLooman/saxpath/master/LICENSE" } ], - "dependencies": { + "duplexify": "~3.2.0" }, "devDependencies": { "sax": "0.5.4", "pegjs": "0.7.0", "mocha": "1.12.0", "jscover": "0.2.4", + "mocha": "~2.1.0", "mocha-lcov-reporter": "0.0.1" }, "directories": { diff --git a/test/stream.js b/test/stream.js new file mode 100644 index 0000000..421157a --- /dev/null +++ b/test/stream.js @@ -0,0 +1,67 @@ +var util = require('util'); +var assert = require('assert'); +var XMLrecorder = require('../lib/xml_recorder.js'); + +var fs = require('fs'); +var sax = require('sax'); +var saxpath = process.env.JS_COV ? require('../lib-cov') : require('../lib'); + + +describe('Stream', function() { + + it('should be a duplex stream emitting XML chunks', function(done) { + var fileStream = fs.createReadStream('test/bookstore.xml'); + var saxParser = sax.createStream(true); + var streamer = new saxpath.Stream(saxParser, '//book'); + + var list = []; + fileStream.pipe(streamer) + .on('data', function(data) { + assert.ok(Buffer.isBuffer(data)); + list.push(data.toString()); + }) + .on('end', function() { + assert.equal(list.length, 4); + assert.notEqual(list[0].indexOf('COOKING'), -1); + assert.notEqual(list[1].indexOf('Harry Potter'), -1); + assert.notEqual(list[2].indexOf('Kurt Cagle'), -1); + assert.notEqual(list[3].indexOf('39.95'), -1); + done(); + }); + }); + + it('can emit objects if the recorder is setup that way', function(done) { + var fileStream = fs.createReadStream('test/bookstore.xml'); + var saxParser = sax.createStream(true); + var recorder = new IndexRecorder(); + var streamer = new saxpath.Stream(saxParser, '//book', recorder, {objectMode: true}); + + fileStream + .pipe(streamer) + .on('data', function(data) { + assert.equal(typeof data, 'object'); + assert.ok(data.index >= 0); + assert.ok(data.index < 4); + }) + .on('end', function() { + assert.equal(recorder.index, 3); + done(); + }); + }); + +}); + +var IndexRecorder = function () { + XMLrecorder.call(this); + this.index = -1; +}; + +util.inherits(IndexRecorder, XMLrecorder); + +IndexRecorder.prototype.start = function() { + ++this.index; +}; + +IndexRecorder.prototype.stop = function() { + return { index: this.index }; +};