AsyncWriter now emits "finish" (not "end") to conform to Writable stream spec. If given callback then we now listen for "finish" and not "end".

This commit is contained in:
Phil Gates-Idem 2014-10-10 21:09:32 -04:00
parent 7c7bb2d1db
commit 7630333de5
5 changed files with 70 additions and 57 deletions

View File

@ -62,23 +62,30 @@ Template.prototype = {
// callback is last argument if provided // callback is last argument if provided
callback = arguments[arguments.length - 1]; callback = arguments[arguments.length - 1];
var shouldEnd = true;
var shouldEnd = false;
if (typeof callback === 'function') { if (typeof callback === 'function') {
if (arguments.length === 2) { // data, out, callback if (arguments.length === 2) {
callback = out; // render called with data and callback,
out = new AsyncWriter(); // we need to create the "out"
out = null;
} }
out.on('end', function() {
callback(null, out.getOutput()); if (!out || !out.isAsyncWriter) {
})
.on('error', callback);
} else {
if (out.isAsyncWriter) {
shouldEnd = false;
} else {
// Assume the "out" is really a stream
out = new AsyncWriter(out); out = new AsyncWriter(out);
shouldEnd = true;
} }
out.on('finish', function() {
callback(null, out.getOutput());
});
out.on('error', callback);
} else if (!out || !out.isAsyncWriter) {
// Assume the "out" is really a stream
out = new AsyncWriter(out);
shouldEnd = true;
} }
var $global = data.$global; var $global = data.$global;
@ -87,8 +94,17 @@ Template.prototype = {
} }
renderFunc(data, out); renderFunc(data, out);
// Automatically end output stream (the writer) if we
// had to create an async writer (which might happen
// if the caller did not provide a writer/out or the
// writer/out was not an AsyncWriter).
//
// If out parameter was originally an AsyncWriter then
// we assume that we are writing to output that was
// created in the context of another rendering job.
if (shouldEnd) { if (shouldEnd) {
out.end(); // End the async writer and the underlying stream out.end();
} }
return out; return out;

View File

@ -34,11 +34,11 @@ describe('marko/api' , function() {
}); });
}); });
it('should allow a template to be rendered to a context wrapping a string builder', function(done) { it('should allow a template to be rendered to a writer wrapping a string builder', function(done) {
var context = marko.createWriter(); var out = marko.createWriter();
context out
.on('end', function() { .on('finish', function() {
expect(context.getOutput()).to.equal('Hello John!'); expect(out.getOutput()).to.equal('Hello John!');
done(); done();
}) })
.on('error', function(e) { .on('error', function(e) {
@ -50,21 +50,21 @@ describe('marko/api' , function() {
{ {
name: 'John' name: 'John'
}, },
context); out);
context.end(); out.end();
}); });
it('should allow a template to be rendered to a context wrapping a stream', function(done) { it('should allow a template to be rendered to a writer wrapping a stream', function(done) {
var output = ''; var output = '';
var stream = through(function write(data) { var stream = through(function write(data) {
output += data; output += data;
}); });
var context = marko.createWriter(stream); var out = marko.createWriter(stream);
context out
.on('end', function() { .on('finish', function() {
expect(output).to.equal('Hello John!'); expect(output).to.equal('Hello John!');
done(); done();
}) })
@ -77,9 +77,7 @@ describe('marko/api' , function() {
{ {
name: 'John' name: 'John'
}, },
context); out).end();
context.end();
}); });
it('should allow a template to be rendered to a stream', function(done) { it('should allow a template to be rendered to a stream', function(done) {
@ -87,8 +85,13 @@ describe('marko/api' , function() {
var output = ''; var output = '';
var outStream = through(function write(data) { var outStream = through(function write(data) {
output += data; output += data;
}); });
outStream.on('end', function() {
expect(output).to.equal('Hello John!');
done();
});
marko.stream( marko.stream(
@ -97,10 +100,6 @@ describe('marko/api' , function() {
name: 'John' name: 'John'
}) })
.pipe(outStream) .pipe(outStream)
.on('end', function() {
expect(output).to.equal('Hello John!');
done();
})
.on('error', function(e) { .on('error', function(e) {
done(e); done(e);
}); });
@ -124,11 +123,11 @@ describe('marko/api' , function() {
}); });
}); });
it('should allow a template to be loaded and rendered to a context wrapping a string builder', function(done) { it('should allow a template to be loaded and rendered to a writer wrapping a string builder', function(done) {
var context = marko.createWriter(); var out = marko.createWriter();
context out
.on('end', function() { .on('finish', function() {
expect(context.getOutput()).to.equal('Hello John!'); expect(out.getOutput()).to.equal('Hello John!');
done(); done();
}) })
.on('error', function(e) { .on('error', function(e) {
@ -139,12 +138,12 @@ describe('marko/api' , function() {
template.render({ template.render({
name: 'John' name: 'John'
}, },
context); out);
context.end(); out.end();
}); });
it('should allow a template to be loaded and rendered to a context wrapping a stream', function(done) { it('should allow a template to be loaded and rendered to a writer wrapping a stream', function(done) {
var output = ''; var output = '';
@ -152,9 +151,8 @@ describe('marko/api' , function() {
output += data; output += data;
}); });
var context = marko.createWriter(stream); var out = marko.createWriter(stream)
context .on('finish', function() {
.on('end', function() {
expect(output).to.equal('Hello John!'); expect(output).to.equal('Hello John!');
done(); done();
}) })
@ -166,9 +164,7 @@ describe('marko/api' , function() {
template.render({ template.render({
name: 'John' name: 'John'
}, },
context); out).end();
context.end();
}); });
it('should allow a template to be loaded and rendered to a stream', function(done) { it('should allow a template to be loaded and rendered to a stream', function(done) {
@ -176,18 +172,19 @@ describe('marko/api' , function() {
var output = ''; var output = '';
var outStream = through(function write(data) { var outStream = through(function write(data) {
output += data; output += data;
}); });
outStream.on('end', function() {
expect(output).to.equal('Hello John!');
done();
});
template.stream({ template.stream({
name: 'John' name: 'John'
}) })
.pipe(outStream) .pipe(outStream)
.on('end', function() {
expect(output).to.equal('Hello John!');
done();
})
.on('error', function(e) { .on('error', function(e) {
done(e); done(e);
}); });

View File

@ -42,7 +42,7 @@ function testRender(path, data, done, options) {
require('../compiler').defaultOptions.checkUpToDate = false; require('../compiler').defaultOptions.checkUpToDate = false;
marko.render(inputPath, data, out) marko.render(inputPath, data, out)
.on('end', function() { .on('finish', function() {
var output = out.getOutput(); var output = out.getOutput();
fs.writeFileSync(actualPath, output, {encoding: 'utf8'}); fs.writeFileSync(actualPath, output, {encoding: 'utf8'});

View File

@ -34,7 +34,7 @@ function testRender(path, data, done, options) {
var out = options.out || new AsyncWriter(new StringBuilder()); var out = options.out || new AsyncWriter(new StringBuilder());
marko.render(inputPath, data, out) marko.render(inputPath, data, out)
.on('end', function() { .on('finish', function() {
var output = out.getOutput(); var output = out.getOutput();
fs.writeFileSync(actualPath, output, {encoding: 'utf8'}); fs.writeFileSync(actualPath, output, {encoding: 'utf8'});

View File

@ -31,7 +31,7 @@ function testRender(path, data, done, options) {
var out = options.out || new AsyncWriter(new StringBuilder()); var out = options.out || new AsyncWriter(new StringBuilder());
marko.render(inputPath, data, out) marko.render(inputPath, data, out)
.on('end', function() { .on('finish', function() {
var output = out.getOutput(); var output = out.getOutput();
fs.writeFileSync(actualPath, output, {encoding: 'utf8'}); fs.writeFileSync(actualPath, output, {encoding: 'utf8'});