diff --git a/bin/perf-diff.sh b/bin/perf-diff.sh index eae3fd28d..6b33da814 100755 --- a/bin/perf-diff.sh +++ b/bin/perf-diff.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash VERSION_LATEST=$(cat package.json | grep '"version":' | awk -F'"' '{print $4}') FILE_LOCAL=dist/liquid.node.cjs.js diff --git a/src/render/render.ts b/src/render/render.ts index 97ac60b92..64366369a 100644 --- a/src/render/render.ts +++ b/src/render/render.ts @@ -10,7 +10,7 @@ import { KeepingTypeEmitter } from '../emitters/keeping-type-emitter' export class Render { public renderTemplatesToNodeStream (templates: Template[], ctx: Context): NodeJS.ReadableStream { const emitter = new StreamedEmitter() - toThenable(this.renderTemplates(templates, ctx, emitter)) + Promise.resolve().then(() => toThenable(this.renderTemplates(templates, ctx, emitter))) .then(() => emitter.end(), err => emitter.error(err)) return emitter.stream } diff --git a/test/e2e/render-to-node-stream.ts b/test/e2e/render-to-node-stream.ts index c16626477..3e0de791d 100644 --- a/test/e2e/render-to-node-stream.ts +++ b/test/e2e/render-to-node-stream.ts @@ -1,6 +1,7 @@ import { expect, use } from 'chai' import { resolve } from 'path' import * as chaiAsPromised from 'chai-as-promised' +import { drainStream } from '../stub/stream' use(chaiAsPromised) @@ -30,27 +31,12 @@ describe('.renderToNodeStream()', function () { }) describe('.renderFileToNodeStream()', function () { - it('should render to stream in Node.js', async done => { + it('should render to stream in Node.js', async () => { const cjs = require('../../dist/liquid.node.cjs') const engine = new cjs.Liquid({ root: resolve(__dirname, '../stub/root/') }) const stream = await engine.renderFileToNodeStream('foo.html') - let html = '' - stream.on('data', (data: string) => { html += data }) - stream.on('end', () => { - try { - expect(html).to.equal('foo') - done() - } catch (err) { - done(err) - } - }) - }) - it('should throw in browser', async function () { - const cjs = require('../../dist/liquid.browser.umd') - const engine = new cjs.Liquid() - const render = () => engine.renderFileToNodeStream('foo') - return expect(render).to.throw('streaming not supported in browser') + expect(drainStream(stream)).to.eventually.equal('foo') }) }) diff --git a/test/integration/liquid/liquid.ts b/test/integration/liquid/liquid.ts index eb25dcfc7..e01a2aac8 100644 --- a/test/integration/liquid/liquid.ts +++ b/test/integration/liquid/liquid.ts @@ -2,6 +2,7 @@ import { Liquid, Context, isFalsy } from '../../../src/liquid' import * as chai from 'chai' import { mock, restore } from '../../stub/mockfs' import * as chaiAsPromised from 'chai-as-promised' +import { drainStream } from '../../stub/stream' const expect = chai.expect chai.use(chaiAsPromised) @@ -132,40 +133,33 @@ describe('Liquid', function () { }) describe('#enderToNodeStream', function () { const engine = new Liquid() - it('should render a simple value', function (done) { - const stream = engine.renderToNodeStream(engine.parse('{{"foo"}}')) - let html = '' - stream.on('data', data => { html += data }) - stream.on('end', () => { - try { - expect(html).to.equal('foo') - done() - } catch (err) { - done(err) - } - }) + it('should render a simple value', async () => { + const stream = await engine.renderToNodeStream(engine.parse('{{"foo"}}')) + expect(drainStream(stream)).to.eventually.equal('foo') }) }) describe('#enderFileToNodeStream', function () { + let engine: Liquid before(function () { mock({ - '/root/foo.html': 'foo' + '/root/foo.html': 'foo', + '/root/error.html': 'A{%throwingTag%}B' + }) + engine = new Liquid({ root: ['/root/'] }) + engine.registerTag('throwingTag', { + render: function () { + throw new Error('intended render error') + } }) }) after(restore) - it('should render a simple value', (done) => { - const engine = new Liquid({ root: ['/root/'] }) - engine.renderFileToNodeStream('foo.html').then(stream => { - let html = '' - stream.on('data', data => { html += data }) - stream.on('end', () => { - try { - expect(html).to.equal('foo'); done() - } catch (err) { - done(err) - } - }) - }) + it('should render a simple value', async () => { + const stream = await engine.renderFileToNodeStream('foo.html') + expect(drainStream(stream)).to.be.eventually.equal('foo') + }) + it('should throw RenderError when tag throws', async () => { + const stream = engine.renderFileToNodeStream('error.html') + expect(drainStream(stream)).to.be.rejectedWith(/intended render error/) }) }) }) diff --git a/test/stub/stream.ts b/test/stub/stream.ts new file mode 100644 index 000000000..23dec23bf --- /dev/null +++ b/test/stub/stream.ts @@ -0,0 +1,8 @@ +export function drainStream (stream: NodeJS.ReadableStream) { + return new Promise((resolve, reject) => { + let html = '' + stream.on('data', data => { html += data }) + stream.on('end', () => resolve(html)) + stream.on('error', (err: Error) => reject(err)) + }) +}