Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STENCIL-3845 Unless helper #126

Merged
merged 1 commit into from
Sep 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions helpers/if.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,38 @@
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;
}

// 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)) {
result = false;
}
// Everything else
else {
result = lvalue;
result = !!lvalue;
}
} else {

Expand Down Expand Up @@ -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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is changing the behavior for if when fn is not passed. Instead of returning the value, we return true. Is that what we want?

Copy link
Contributor Author

@mcampa mcampa Sep 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No is not, there are tests in place for these cases. This code was added in the wrong way a few moths ago a12cdbd

I had to change it because it was breaking when if is called from unless helper because the unless helper relies in fn() and inverse()

Copy link
Contributor Author

@mcampa mcampa Sep 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return values is always a boolean when called from a non-block

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to pass fn but not inverse? Should this be

options.fn = typeof options.fn === 'function' ? options.fn : () => true;
options.inverse = typeof options.inverse === 'function' ? options.inverse : () => false;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both need to exist. If one of them is missing, is probably a bug

options.fn = () => true;
options.inverse = () => false;
}

if (result) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
}
Expand Down
77 changes: 67 additions & 10 deletions test/helpers/if.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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');
Expand Down Expand Up @@ -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('');
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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},
Expand Down Expand Up @@ -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');

Expand All @@ -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();
});
})