From 868dab173d8b4b7d7a256fb1e21b5b3557152b43 Mon Sep 17 00:00:00 2001 From: George Thomas Date: Wed, 14 May 2014 17:07:22 +0100 Subject: [PATCH 1/2] Router accepts a stream response from ViewEngine --- server/router.js | 10 +++++-- test/server/router.test.js | 56 ++++++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/server/router.js b/server/router.js index 157dd2d8..14d760a4 100644 --- a/server/router.js +++ b/server/router.js @@ -1,7 +1,8 @@ var _ = require('underscore'), BaseRouter = require('../shared/base/router'), ExpressRouter = require('express').Router, - sanitizer = require('sanitizer'); + sanitizer = require('sanitizer'), + ReadableStream = require('stream').Readable; module.exports = ServerRouter; @@ -97,7 +98,12 @@ ServerRouter.prototype.getHandler = function(action, pattern, route) { res.render(viewPath, viewData, function(err, html) { if (err) return next(err); res.set(router.getHeadersForRoute(route)); - res.type('html').end(html); + + if (html instanceof ReadableStream) { + html.pipe(res); + } else { + res.type('html').end(html); + } }); }); }; diff --git a/test/server/router.test.js b/test/server/router.test.js index b138e472..59aefc83 100644 --- a/test/server/router.test.js +++ b/test/server/router.test.js @@ -5,7 +5,8 @@ var chai = require('chai'), Router = require('../../server/router'), express = require('express'), _ = require('underscore'), - sinon = require('sinon'); + sinon = require('sinon'), + ReadableStream = require('stream').Readable; chai.use(require('sinon-chai')); @@ -483,7 +484,7 @@ describe("server/router", function() { next = sinon.stub(); action = sinon.stub().yields(); middleware = this.router.getHandler(action, this.pattern, {}); - res = { set: sinon.spy(), type: sinon.stub(), end: sinon.spy(), render: sinon.stub() }; + res = { set: sinon.spy(), type: sinon.stub(), end: sinon.spy(), render: sinon.stub(), pipe: sinon.stub() }; res.render.yields(); res.type.returns(res); getHeadersForRoute = sinon.stub(this.router, 'getHeadersForRoute').returns({ 'Content-Type': 'image/jpeg' }); @@ -496,21 +497,6 @@ describe("server/router", function() { res.set.should.have.been.calledWithExactly({ 'Content-Type': 'image/jpeg' }); }); - it('should set the type to html', function () { - middleware(this.req, res); - - res.type.should.have.been.calledOnce; - res.type.should.have.been.calledWithExactly('html'); - }); - - it('should call end with the html output', function () { - res.render.yields(null, 'foo'); - middleware(this.req, res); - - res.end.should.have.been.calledOnce; - res.end.should.have.been.calledWithExactly('foo'); - }); - it('should pass through an error', function () { var error = new Error(); res.render.yields(error); @@ -519,6 +505,42 @@ describe("server/router", function() { next.should.have.been.calledOnce; next.should.have.been.calledWithExactly(error); }); + + describe('a streaming response', function(){ + var stream; + + beforeEach(function(){ + stream = ReadableStream(); + stream.pipe = sinon.stub(); + }); + + it('should pipe the stream through the res object', function(){ + res.render.yields(null, stream); + middleware(this.req, res); + + stream.pipe.should.have.been.calledOnce; + stream.pipe.should.have.been.calledWithExactly(res); + }) + }); + + describe('a non-streaming response', function(){ + + it('should set the type to html', function () { + middleware(this.req, res); + + res.type.should.have.been.calledOnce; + res.type.should.have.been.calledWithExactly('html'); + }); + + it('should call end with the html output', function () { + res.render.yields(null, 'foo'); + middleware(this.req, res); + + res.end.should.have.been.calledOnce; + res.end.should.have.been.calledWithExactly('foo'); + }); + }) + }); }); From 27a8e07fef7523c1dff1866814725edb189da68f Mon Sep 17 00:00:00 2001 From: George Thomas Date: Wed, 14 May 2014 17:38:33 +0100 Subject: [PATCH 2/2] Update streaming response test to only expect to pass when Streams2 are available --- server/router.js | 2 +- test/server/router.test.js | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/server/router.js b/server/router.js index 14d760a4..951d1f9d 100644 --- a/server/router.js +++ b/server/router.js @@ -99,7 +99,7 @@ ServerRouter.prototype.getHandler = function(action, pattern, route) { if (err) return next(err); res.set(router.getHeadersForRoute(route)); - if (html instanceof ReadableStream) { + if (ReadableStream && html instanceof ReadableStream) { html.pipe(res); } else { res.type('html').end(html); diff --git a/test/server/router.test.js b/test/server/router.test.js index 59aefc83..478e4fd4 100644 --- a/test/server/router.test.js +++ b/test/server/router.test.js @@ -507,20 +507,21 @@ describe("server/router", function() { }); describe('a streaming response', function(){ - var stream; + it('should pipe the stream through the res object if streams2 available', function(){ - beforeEach(function(){ - stream = ReadableStream(); + if (!ReadableStream) { return; } + + var stream = ReadableStream(); stream.pipe = sinon.stub(); - }); - it('should pipe the stream through the res object', function(){ res.render.yields(null, stream); middleware(this.req, res); stream.pipe.should.have.been.calledOnce; stream.pipe.should.have.been.calledWithExactly(res); - }) + }); + + }); describe('a non-streaming response', function(){