Skip to content
This repository has been archived by the owner on Apr 11, 2018. It is now read-only.

Commit

Permalink
allow asyncronous compileFile and renderFile operations. Fixes gh-283
Browse files Browse the repository at this point in the history
  • Loading branch information
paularmstrong committed Aug 18, 2013
1 parent ba23716 commit 7f6b37e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 48 deletions.
43 changes: 26 additions & 17 deletions lib/swig.js
Expand Up @@ -473,25 +473,23 @@ exports.Swig = function (opts) {
*
* @param {string} pathName File location.
* @param {object} [locals={}] Template variable context.
* @param {Function} [fn] Optional callback function.
* @param {Function} [cb] Asyncronous callback function. If not provided, <var>compileFile</var> will run syncronously.
* @return {string} Rendered output.
*/
this.renderFile = function (pathName, locals, fn) {
this.renderFile = function (pathName, locals, cb) {
var out;
try {
out = exports.compileFile(pathName)(locals);
if (fn) {
fn(null, out);
return;
}
} catch (e) {
if (fn) {
fn(e);
return;
}
throw e;
if (cb) {
exports.compileFile(pathName, {}, function (err, fn) {
if (err) {
cb(err);
return;
}
cb(null, fn(locals));
});
return;
}
return out;

return exports.compileFile(pathName)(locals);
};

/**
Expand Down Expand Up @@ -561,9 +559,10 @@ exports.Swig = function (opts) {
*
* @param {string} pathname File location.
* @param {SwigOpts} [options={}] Swig options object.
* @param {Function} [cb] Asyncronous callback function. If not provided, <var>compileFile</var> will run syncronously.
* @return {function} Renderable function with keys for parent, blocks, and tokens.
*/
this.compileFile = function (pathname, options) {
this.compileFile = function (pathname, options, cb) {
var src, cached;

if (!options) {
Expand All @@ -580,8 +579,18 @@ exports.Swig = function (opts) {
return cached;
}

src = fs.readFileSync(pathname, 'utf8');
if (cb) {
fs.readFile(pathname, 'utf8', function (err, src) {
if (err) {
cb(err);
return;
}
cb(err, self.compile(src, options));
});
return;
}

src = fs.readFileSync(pathname, 'utf8');
return self.compile(src, options);
};

Expand Down
48 changes: 47 additions & 1 deletion tests/basic.test.js
@@ -1,5 +1,6 @@
var swig = require('../lib/swig'),
expect = require('expect.js'),
fs = require('fs'),
_ = require('lodash'),
Swig = swig.Swig;

Expand All @@ -12,7 +13,6 @@ function resetOptions() {
}

describe('options', function () {
var oDefaults;
beforeEach(resetOptions);
afterEach(resetOptions);

Expand Down Expand Up @@ -155,3 +155,49 @@ describe('separate instances', function () {
expect(b.options.varControls[0]).to.equal('{{');
});
});

describe('swig.compileFile', function () {
var test = __dirname + '/cases/extends_1.test.html';

beforeEach(resetOptions);
afterEach(resetOptions);

it('can run syncronously', function () {
expect(swig.compileFile(test)())
.to.be.ok();
});

it('can run asynchronously', function (done) {
expect(swig.compileFile(test, {}, function (err, fn) {
expect(fn).to.be.a(Function);
done();
}));
});
});

describe('swig.renderFile', function () {
var test = __dirname + '/cases/extends_1.test.html',
expectation = fs.readFileSync(test.replace('test.html', 'expectation.html'), 'utf8');

beforeEach(resetOptions);
afterEach(resetOptions);

it('can run syncronously', function () {
expect(swig.renderFile(test))
.to.equal(expectation);
});

it('can run asynchronously', function (done) {
expect(swig.renderFile(test, {}, function (err, fn) {
expect(fn).to.equal(expectation);
done();
}));
});

it('can use callbacks with errors', function (done) {
swig.renderFile(__dirname + '/cases/not-existing', {}, function (err, out) {
expect(err.errno).to.equal(34);
done();
});
});
});
30 changes: 0 additions & 30 deletions tests/templates.test.js
Expand Up @@ -51,34 +51,4 @@ describe('Templates', function () {
swig.compileFile(__dirname + '/cases-error/circular.test.html')();
}).to.throwError(/Illegal circular extends of "[\w\/\._\-]+"\./);
});

describe('renderFile', function () {
var extends_expectation = fs.readFileSync(__dirname + '/cases/extends_1.expectation.html', 'utf8'),
include_expectation = fs.readFileSync(__dirname + '/cases/include.expectation.html', 'utf8'),
opts = { locals: locals };

it('renders files immediately', function () {
expect(swig.renderFile(__dirname + '/cases/extends_1.test.html', opts)).to.equal(extends_expectation);
});

it('throws immediately with no callback', function () {
expect(function () {
swig.renderFile('foobar');
}).to.throwError();
});

it('can use callbacks', function (done) {
swig.renderFile(__dirname + '/cases/include.test.html', locals, function (err, out) {
expect(out).to.equal(include_expectation);
done();
});
});

it('can use callbacks with errors', function (done) {
swig.renderFile(__dirname + '/cases/not-existing', opts, function (err, out) {
expect(err.errno).to.equal(34);
done();
});
});
});
});

0 comments on commit 7f6b37e

Please sign in to comment.