diff --git a/helpers/if.js b/helpers/if.js index 446a8172..dc4b9bde 100644 --- a/helpers/if.js +++ b/helpers/if.js @@ -3,9 +3,20 @@ var _ = require('lodash'); function helper(paper) { + paper.handlebars.registerHelper('unless', function () { + const options = arguments[arguments.length - 1]; + arguments[arguments.length - 1] = Object.assign({}, options, { + fn: options.inverse || (() => false), + inverse: options.fn || (() => true), + hash: options.hash + }); + + return paper.handlebars.helpers['if'].apply(this, arguments); + }); + paper.handlebars.registerHelper('if', function (lvalue, operator, rvalue) { const options = arguments[arguments.length - 1]; - var result; + let result; function isOptions(obj) { return _.isObject(obj) && obj.fn; @@ -13,10 +24,9 @@ function helper(paper) { // Only parameter if (isOptions(operator)) { - // If an array is passed as the only parameter if (_.isArray(lvalue)) { - result = lvalue.length; + result = !!lvalue.length; } // If an empty object is passed, treat as false else if (_.isEmpty(lvalue) && _.isObject(lvalue)) { @@ -24,7 +34,7 @@ function helper(paper) { } // Everything else else { - result = lvalue; + result = !!lvalue; } } else { @@ -77,14 +87,15 @@ function helper(paper) { } } - if (options.fn) { // block helper - if (result) { - return options.fn(this); - } else { - return options.inverse(this); - } - } else { // non-block helper - return result; + if (!options.fn || !options.inverse) { + options.fn = () => true; + options.inverse = () => false; + } + + if (result) { + return options.fn(this); + } else { + return options.inverse(this); } }); } diff --git a/test/helpers/if.js b/test/helpers/if.js index dde08025..98cc039c 100644 --- a/test/helpers/if.js +++ b/test/helpers/if.js @@ -10,17 +10,18 @@ function c(template, context) { return new Paper().loadTemplatesSync({template: template}).render('template', context); } -describe('if helper', function() { +describe('if helper', () => { var context = { num1: 1, num2: 2, product: {a: 1, b: 2}, string: 'yolo', alwaysTrue: true, + alwaysFalse: true, big: 'big' }; - it('should have the same behavior as the original if helper', function(done) { + it('should have the same behavior as the original if helper', done => { expect(c('{{#if 1}}{{big}}{{/if}}', context)) .to.be.equal('big'); @@ -54,7 +55,7 @@ describe('if helper', function() { done(); }); - it('should render "big" if all conditions match', function(done) { + it('should render "big" if all conditions match', done => { expect(c('{{#if "1" "==" num1}}big{{/if}}', context)) .to.be.equal('big'); @@ -89,7 +90,7 @@ describe('if helper', function() { done(); }); - it('should render empty for all cases', function(done) { + it('should render empty for all cases', done => { expect(c('{{#if "2" "==" num1}}big{{/if}}', context)) .to.be.equal(''); @@ -125,7 +126,7 @@ describe('if helper', function() { }); - it('should render "big" if all ifs match', function(done) { + it('should render "big" if all ifs match', done => { var context = { num1: 1, @@ -167,9 +168,8 @@ describe('if helper', function() { done(); }); - it('should render empty for all cases', function(done) { - - var context = { + it('should render empty for all cases', done => { + const context = { num1: 1, num2: 2, product: {a: 1, b: 2}, @@ -220,7 +220,7 @@ describe('if helper', function() { done(); }); - it('should work as a non-block helper when used as a subexpression', function(done) { + it('should work as a non-block helper when used as a subexpression', done => { expect(c('{{#if (if num1 "!==" num2)}}{{big}}{{/if}}', context)) .to.be.equal('big'); @@ -229,5 +229,62 @@ describe('if helper', function() { done(); }); - }); + +describe('unless helper', () => { + const context = { + num1: 1, + num2: 2, + product: {a: 1, b: 2}, + alwaysTrue: true, + alwaysFalse: false, + notEmptyArray: [ 1, 2 , 3 ], + emptyArray: [], + }; + + it('should print hello', done => { + expect(c('{{#unless num1 "===" num2}}hello{{/unless}}', context)) + .to.be.equal('hello'); + + expect(c('{{#unless alwaysFalse}}hello{{/unless}}', context)) + .to.be.equal('hello'); + + expect(c('{{#unless does_not_exist}}hello{{/unless}}', context)) + .to.be.equal('hello'); + + done(); + }); + + it('should print empty', done => { + expect(c('{{#unless num1 "===" num1}}hello{{/unless}}', context)) + .to.be.equal(''); + + expect(c('{{#unless alwaysTrue}}hello{{/unless}}', context)) + .to.be.equal(''); + + expect(c('{{#unless product}}hello{{/unless}}', context)) + .to.be.equal(''); + + done(); + }); + + it('should work with arrays', done => { + expect(c('{{#unless emptyArray}}foo{{else}}bar{{/unless}}', context)) + .to.be.equal('foo'); + + expect(c('{{#unless notEmptyArray}}foo{{else}}bar{{/unless}}', context)) + .to.be.equal('bar'); + + done(); + }); + + it('should work as a non-block helper when used as a subexpression', done => { + expect(c('{{#if (unless num1 "===" num2)}}big{{/if}}', context)) + .to.be.equal('big'); + + expect(c('{{#all (unless num1 "===" num2) "1" true}}big{{/all}}', context)) + .to.be.equal('big'); + + done(); + }); +})