Skip to content

Commit

Permalink
DSL for mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
pgte committed Sep 16, 2012
1 parent dc1a1f5 commit dacad89
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 16 deletions.
62 changes: 46 additions & 16 deletions lib/map.js
@@ -1,4 +1,5 @@
var Stream = require('stream').Stream;
var BufferedStream = require('bufferedstream');

var actions = ['remove', 'replace', 'update'];

Expand All @@ -11,12 +12,39 @@ function actionFromVal(val) {
try {
throw new Error('Ambiguous action, don\'t know what to do with' + JSON.stringify(val));
} catch (e) {
throw new Error('Ambiguous action, don\'t know what to do with it');
throw new Error('Ambiguous action, don\'t know what to do with it:' + val.toString());
}
}
return remainingActions[0];
}

function handleStream(selector, action, stream) {
var buffer = [], ended = false;
stream.on('data', function(d) { buffer.push(d); });
stream.on('end', function() { ended = true; });

this.select(selector, function(node) {
node[action](function(html) {
var index = 0;
var bs = new BufferedStream();

(function flush() {
if (buffer.length > index) {
bs.write(buffer[index]);
index ++;
}
if (buffer.length > index || ! ended) {
process.nextTick(flush);
} else {
bs.end();
}
}());

return bs;
});
});
}

function map(mapping) {
var self = this;

Expand All @@ -27,34 +55,36 @@ function map(mapping) {
Object.keys(mapping).forEach(function(selector) {
var val = mapping[selector];

// console.log('val:', val);

switch (typeof val) {

case 'string':
case 'function':

console.log('A');

console.log('.update(%j, %s)', selector, val);

self.update(selector, val);

break;

case 'object':

console.log('B');

var action = actionFromVal(val);
if (! action) {
throw new Error('Value for selector `' + selector + '` should contain action field, either rmeove, replace or update');
if (val instanceof Stream) {

handleStream.call(self, selector, 'update', val);

} else {

var action = actionFromVal(val);
if (! action) {
throw new Error('Value for selector `' + selector +
'` should contain action field, either remove, replace or update');
}
var replaceBy = val[action];
if (replaceBy instanceof Stream) {
handleStream.call(self, selector, action, replaceBy);
} else {
self[action](selector, replaceBy);
}
}

console.log('.%s(%j, %j)', action, selector, val[action]);

self[action](selector, val[action]);

break;

default:
Expand Down
8 changes: 8 additions & 0 deletions lib/select.js
Expand Up @@ -142,6 +142,14 @@ module.exports = function (parser, opts) {
if (done) { done(); }
});
};

stream.pause = function() {
parser.pause();
};

stream.resume = function() {
parser.resume();
};

return stream;
};
Expand Down
45 changes: 45 additions & 0 deletions test/dsl_compose_streaming.js
@@ -0,0 +1,45 @@
var test = require('tap').test;
var trumpet = require('../');
var fs = require('fs');
var BufferedStream = require('bufferedstream');

test('compose with streams', function (t) {
t.plan(1);
var html = fs.readFileSync(__dirname + '/compose_target.html', 'utf8');

var tr = trumpet();
fs.createReadStream(__dirname + '/compose.html').pipe(tr);

var tr2 = trumpet();
fs.createReadStream(__dirname + '/partial.html').pipe(tr2);

var tr3 = trumpet();
fs.createReadStream(__dirname + '/partial.html').pipe(tr3);
tr3.select('.b span', function(node) {
node.update(function(html) {
return html.toUpperCase();
});
});

var stream = new BufferedStream();
stream.end('<b>NOTHING TO SEE HERE</b>');

var stream2 = new BufferedStream();
stream2.end('<blink>TERRIBLE</blink>');

tr.map({
'.b span': tr2,
'.c': tr3,
'.d': { remove: true },
'.e': { remove: true },
'.f': { replace: stream },
'.g': { replace: stream2}
});

var data = '';
tr.on('data', function (buf) { data += buf });

tr.on('end', function () {
t.equal(data, html);
});
});

0 comments on commit dacad89

Please sign in to comment.