2020-04-29 18:44:27 +03:00
|
|
|
const should = require('should');
|
|
|
|
const sinon = require('sinon');
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2020-04-29 18:44:27 +03:00
|
|
|
// Stuff we are testing
|
2021-10-06 12:52:46 +03:00
|
|
|
const has = require('../../../../core/frontend/helpers/has');
|
2014-10-10 18:54:07 +04:00
|
|
|
|
|
|
|
describe('{{#has}} helper', function () {
|
2020-04-29 18:44:27 +03:00
|
|
|
let fn;
|
|
|
|
let inverse;
|
|
|
|
let thisCtx;
|
|
|
|
let handlebarsOptions;
|
2017-08-15 18:00:17 +03:00
|
|
|
|
2017-03-21 11:24:11 +03:00
|
|
|
afterEach(function () {
|
2019-01-21 19:53:44 +03:00
|
|
|
sinon.restore();
|
2017-03-21 11:24:11 +03:00
|
|
|
});
|
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
beforeEach(function () {
|
2019-01-21 19:53:44 +03:00
|
|
|
fn = sinon.spy();
|
|
|
|
inverse = sinon.spy();
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
thisCtx = {};
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
// This object mocks out the object that handlebars helpers get passed
|
|
|
|
handlebarsOptions = {
|
|
|
|
hash: {},
|
|
|
|
data: {},
|
|
|
|
fn: fn,
|
|
|
|
inverse: inverse
|
|
|
|
};
|
2014-10-10 18:54:07 +04:00
|
|
|
});
|
|
|
|
|
2020-10-19 07:45:26 +03:00
|
|
|
function callHasHelper(context, hash) {
|
2017-08-15 18:00:17 +03:00
|
|
|
// Hash is the options passed in
|
|
|
|
handlebarsOptions.hash = hash;
|
2021-10-04 18:30:54 +03:00
|
|
|
return has.call(context, handlebarsOptions);
|
2017-08-15 18:00:17 +03:00
|
|
|
}
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
describe('tag match', function () {
|
|
|
|
it('should handle tag list that validates true', function () {
|
|
|
|
thisCtx = {tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
// {{#has tag="invalid, bar, wat"}}
|
|
|
|
callHasHelper(thisCtx, {tag: 'invalid, bar, wat'});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
2015-01-10 00:52:23 +03:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
it('should handle tags with case-insensitivity', function () {
|
|
|
|
thisCtx = {tags: [{name: 'ghost'}]};
|
2015-01-10 00:52:23 +03:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
// {{#has tag="GhoSt"}}
|
|
|
|
callHasHelper(thisCtx, {tag: 'GhoSt'});
|
2015-01-10 00:52:23 +03:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
2015-01-10 00:52:23 +03:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
it('should match exact tags, not superstrings', function () {
|
|
|
|
thisCtx = {tags: [{name: 'magical'}]};
|
2015-01-10 00:52:23 +03:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
callHasHelper(thisCtx, {tag: 'magic'});
|
2015-01-10 00:52:23 +03:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
it('should match exact tags, not substrings', function () {
|
|
|
|
thisCtx = {tags: [{name: 'magic'}]};
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
callHasHelper(thisCtx, {tag: 'magical'});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
it('should handle tag list that validates false', function () {
|
|
|
|
thisCtx = {tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
callHasHelper(thisCtx, {tag: 'much, such, wow'});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
it('should not do anything if there are no attributes', function () {
|
|
|
|
thisCtx = {tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
callHasHelper(thisCtx);
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
it('should not do anything when an invalid attribute is given', function () {
|
|
|
|
thisCtx = {tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
callHasHelper(thisCtx, {invalid: 'nonsense'});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
2018-03-27 17:16:15 +03:00
|
|
|
|
|
|
|
it('count:0', function () {
|
|
|
|
thisCtx = {tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {tag: 'count:0'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:3', function () {
|
|
|
|
thisCtx = {tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {tag: 'count:3'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:11', function () {
|
|
|
|
thisCtx = {tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {tag: 'count:11'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:>3', function () {
|
|
|
|
thisCtx = {tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {tag: 'count:>3'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:>2', function () {
|
|
|
|
thisCtx = {tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {tag: 'count:>2'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:<1', function () {
|
|
|
|
thisCtx = {tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {tag: 'count:<1'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:<3', function () {
|
|
|
|
thisCtx = {tags: [{name: 'foo'}, {name: 'bar'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {tag: 'count:<3'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
});
|
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
describe('author match', function () {
|
|
|
|
it('should handle author list that evaluates to true', function () {
|
2018-03-27 17:16:15 +03:00
|
|
|
thisCtx = {authors: [{name: 'sam'}]};
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
callHasHelper(thisCtx, {author: 'joe, sam, pat'});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
it('should handle author list that evaluates to false', function () {
|
2018-03-27 17:16:15 +03:00
|
|
|
thisCtx = {authors: [{name: 'jamie'}]};
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
callHasHelper(thisCtx, {author: 'joe, sam, pat'});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle authors with case-insensitivity', function () {
|
2018-03-27 17:16:15 +03:00
|
|
|
thisCtx = {authors: [{name: 'Sam'}]};
|
2017-08-15 18:00:17 +03:00
|
|
|
|
|
|
|
callHasHelper(thisCtx, {author: 'joe, sAm, pat'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle tags and authors like an OR query (pass)', function () {
|
2018-03-27 17:16:15 +03:00
|
|
|
thisCtx = {authors: [{name: 'sam'}], tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
2017-08-15 18:00:17 +03:00
|
|
|
|
|
|
|
callHasHelper(thisCtx, {author: 'joe, sam, pat', tag: 'much, such, wow'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
it('should handle tags and authors like an OR query (pass)', function () {
|
2018-03-27 17:16:15 +03:00
|
|
|
thisCtx = {authors: [{name: 'sam'}], tags: [{name: 'much'}, {name: 'bar'}, {name: 'baz'}]};
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
callHasHelper(thisCtx, {author: 'joe, sam, pat', tag: 'much, such, wow'});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle tags and authors like an OR query (fail)', function () {
|
2018-03-27 17:16:15 +03:00
|
|
|
thisCtx = {authors: [{name: 'fred'}], tags: [{name: 'foo'}, {name: 'bar'}, {name: 'baz'}]};
|
2017-08-15 18:00:17 +03:00
|
|
|
|
|
|
|
callHasHelper(thisCtx, {author: 'joe, sam, pat', tag: 'much, such, wow'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
2018-03-27 17:16:15 +03:00
|
|
|
|
|
|
|
it('count:0', function () {
|
|
|
|
thisCtx = {authors: [{name: 'fred'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {author: 'count:0'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:1', function () {
|
|
|
|
thisCtx = {authors: [{name: 'fred'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {author: 'count:1'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:>1', function () {
|
|
|
|
thisCtx = {authors: [{name: 'fred'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {author: 'count:>1'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:>1', function () {
|
|
|
|
thisCtx = {authors: [{name: 'fred'}, {name: 'sam'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {author: 'count:>1'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:>2', function () {
|
|
|
|
thisCtx = {authors: [{name: 'fred'}, {name: 'sam'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {author: 'count:>2'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:<1', function () {
|
|
|
|
thisCtx = {authors: [{name: 'fred'}, {name: 'sam'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {author: 'count:<1'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('count:<3', function () {
|
|
|
|
thisCtx = {authors: [{name: 'fred'}, {name: 'sam'}]};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {author: 'count:<3'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
});
|
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
describe('number match (1-based index)', function () {
|
|
|
|
it('will match on an exact number (pass)', function () {
|
|
|
|
handlebarsOptions.data = {number: 6};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {number: '6'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on an exact number (fail)', function () {
|
|
|
|
handlebarsOptions.data = {number: 5};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {number: '6'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on an exact number (loop)', function () {
|
2020-04-29 18:44:27 +03:00
|
|
|
for (let number = 1; number < 9; number += 1) {
|
2017-08-15 18:00:17 +03:00
|
|
|
handlebarsOptions.data = {number: number};
|
|
|
|
// Will match 6
|
|
|
|
callHasHelper(thisCtx, {number: '6'});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn.calledOnce.should.be.true();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
inverse.callCount.should.eql(7);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on a number list (pass)', function () {
|
|
|
|
handlebarsOptions.data = {number: 6};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {number: '1, 3, 6,12'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on a number list (fail)', function () {
|
|
|
|
handlebarsOptions.data = {number: 5};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {number: '1, 3, 6,12'});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
it('will match on a number list (loop)', function () {
|
2020-04-29 18:44:27 +03:00
|
|
|
for (let number = 1; number < 9; number += 1) {
|
2017-08-15 18:00:17 +03:00
|
|
|
handlebarsOptions.data = {number: number};
|
|
|
|
// Will match 1, 3, 6
|
|
|
|
callHasHelper(thisCtx, {number: '1, 3, 6,12'});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
fn.callCount.should.eql(3);
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
inverse.callCount.should.eql(5);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on a nth pattern (pass)', function () {
|
|
|
|
handlebarsOptions.data = {number: 6};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {number: 'nth:3'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on a nth pattern (fail)', function () {
|
|
|
|
handlebarsOptions.data = {number: 5};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {number: 'nth:3'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on a nth pattern (loop)', function () {
|
2020-04-29 18:44:27 +03:00
|
|
|
for (let number = 1; number < 9; number += 1) {
|
2017-08-15 18:00:17 +03:00
|
|
|
handlebarsOptions.data = {number: number};
|
|
|
|
// Will match 3 & 6
|
|
|
|
callHasHelper(thisCtx, {number: 'nth:3'});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
fn.callCount.should.eql(2);
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
inverse.callCount.should.eql(6);
|
|
|
|
});
|
2017-08-17 14:22:29 +03:00
|
|
|
|
|
|
|
it('fails gracefully if there is no number property', function () {
|
|
|
|
handlebarsOptions.data = {};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {number: 'nth:3'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('fails gracefully if there is no data property', function () {
|
|
|
|
handlebarsOptions.data = null;
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {number: 'nth:3'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
});
|
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
describe('index match (0-based index)', function () {
|
|
|
|
it('will match on an exact index (pass)', function () {
|
|
|
|
handlebarsOptions.data = {index: 6};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {index: '6'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on an exact index (fail)', function () {
|
|
|
|
handlebarsOptions.data = {index: 5};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {index: '6'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on an exact index (loop)', function () {
|
2020-04-29 18:44:27 +03:00
|
|
|
for (let index = 0; index < 8; index += 1) {
|
2017-08-15 18:00:17 +03:00
|
|
|
handlebarsOptions.data = {index: index};
|
|
|
|
// Will match 6
|
|
|
|
callHasHelper(thisCtx, {index: '6'});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn.calledOnce.should.be.true();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
inverse.callCount.should.eql(7);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on an index list (pass)', function () {
|
|
|
|
handlebarsOptions.data = {index: 6};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {index: '1, 3, 6,12'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on an index list (fail)', function () {
|
|
|
|
handlebarsOptions.data = {index: 5};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {index: '1, 3, 6,12'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on an index list (loop)', function () {
|
2020-04-29 18:44:27 +03:00
|
|
|
for (let index = 0; index < 8; index += 1) {
|
2017-08-15 18:00:17 +03:00
|
|
|
handlebarsOptions.data = {index: index};
|
|
|
|
// Will match 1, 3, 6
|
|
|
|
callHasHelper(thisCtx, {index: '1, 3, 6,12'});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
fn.callCount.should.eql(3);
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
inverse.callCount.should.eql(5);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on a nth pattern (pass)', function () {
|
|
|
|
handlebarsOptions.data = {index: 6};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {index: 'nth:3'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('will match on a nth pattern (fail)', function () {
|
|
|
|
handlebarsOptions.data = {index: 5};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {index: 'nth:3'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
it('will match on a nth pattern (loop)', function () {
|
2020-04-29 18:44:27 +03:00
|
|
|
for (let index = 0; index < 8; index += 1) {
|
2017-08-15 18:00:17 +03:00
|
|
|
handlebarsOptions.data = {index: index};
|
|
|
|
// Will match 0, 3, 6
|
|
|
|
callHasHelper(thisCtx, {index: 'nth:3'});
|
|
|
|
}
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2017-08-15 18:00:17 +03:00
|
|
|
fn.called.should.be.true();
|
|
|
|
fn.callCount.should.eql(3);
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
inverse.callCount.should.eql(5);
|
|
|
|
});
|
2017-08-17 14:22:29 +03:00
|
|
|
|
|
|
|
it('fails gracefully if there is no index property', function () {
|
|
|
|
handlebarsOptions.data = {};
|
|
|
|
|
|
|
|
callHasHelper(thisCtx, {index: 'nth:3'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
});
|
2017-08-15 18:25:06 +03:00
|
|
|
|
|
|
|
describe('slug match', function () {
|
|
|
|
it('matches on an exact slug (pass)', function () {
|
|
|
|
thisCtx = {slug: 'welcome'};
|
|
|
|
|
|
|
|
// {{#has slug="welcome"}}
|
|
|
|
callHasHelper(thisCtx, {slug: 'welcome'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on an exact slug (fail)', function () {
|
|
|
|
thisCtx = {slug: 'welcome'};
|
|
|
|
|
|
|
|
// {{#has slug="welcome-to-ghost"}}
|
|
|
|
callHasHelper(thisCtx, {slug: 'welcome-to-ghost'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('fails gracefully if there is no slug (fail)', function () {
|
|
|
|
thisCtx = {};
|
|
|
|
|
|
|
|
// {{#has slug="welcome-to-ghost"}}
|
|
|
|
callHasHelper(thisCtx, {slug: 'welcome-to-ghost'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2020-02-14 12:28:26 +03:00
|
|
|
describe('visibility match', function () {
|
|
|
|
it('matches on an exact visibility (pass)', function () {
|
|
|
|
thisCtx = {visibility: 'paid'};
|
|
|
|
|
|
|
|
// {{#has visibility="paid"}}
|
|
|
|
callHasHelper(thisCtx, {visibility: 'paid'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on an exact visibility (fail)', function () {
|
|
|
|
thisCtx = {visibility: 'paid'};
|
|
|
|
|
|
|
|
// {{#has visibility="members"}}
|
|
|
|
callHasHelper(thisCtx, {visibility: 'members'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('fails gracefully if there is no visibility (fail)', function () {
|
|
|
|
thisCtx = {};
|
|
|
|
|
|
|
|
// {{#has visibility="welcome-to-ghost"}}
|
|
|
|
callHasHelper(thisCtx, {visibility: 'paid'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-08-15 18:25:06 +03:00
|
|
|
describe('id match', function () {
|
|
|
|
it('matches on an exact id (pass)', function () {
|
|
|
|
thisCtx = {id: '5981fbed98141579627e9a5a'};
|
|
|
|
|
|
|
|
// {{#has id="5981fbed98141579627e9a5a"}}
|
|
|
|
callHasHelper(thisCtx, {id: '5981fbed98141579627e9a5a'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on an exact id (fail)', function () {
|
|
|
|
thisCtx = {id: '5981fbed98141579627e9a5a'};
|
|
|
|
|
|
|
|
// {{#has id="5981fbed98141579627e9a5a"}}
|
|
|
|
callHasHelper(thisCtx, {id: '5981fbed98141579627e9abc'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('fails gracefully if there is no id (fail)', function () {
|
|
|
|
thisCtx = {};
|
|
|
|
|
|
|
|
// {{#has id="5981fbed98141579627e9a5a"}}
|
|
|
|
callHasHelper(thisCtx, {id: '5981fbed98141579627e9abc'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
});
|
2017-08-17 14:22:29 +03:00
|
|
|
|
|
|
|
describe('any match', function () {
|
|
|
|
it('matches on a single property (pass)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: '',
|
|
|
|
website: null
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has any="twitter"}}
|
|
|
|
callHasHelper(thisCtx, {any: 'twitter'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on a single property (fail)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: '',
|
|
|
|
website: null
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has any="facebook"}}
|
|
|
|
callHasHelper(thisCtx, {any: 'facebook'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on multiple properties (pass)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: '',
|
|
|
|
website: null
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has any="twitter, facebook,website"}}
|
|
|
|
callHasHelper(thisCtx, {any: 'twitter, facebook,website'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on multiple properties (fail)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: '',
|
|
|
|
website: null
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has any="facebook,website, foo"}}
|
|
|
|
callHasHelper(thisCtx, {any: 'facebook,website, foo'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on global properties (pass)', function () {
|
|
|
|
thisCtx = {};
|
|
|
|
handlebarsOptions.data = {
|
2019-09-10 12:37:04 +03:00
|
|
|
site: {
|
2017-08-17 14:22:29 +03:00
|
|
|
twitter: 'foo',
|
|
|
|
facebook: '',
|
|
|
|
website: null
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-09-10 12:37:04 +03:00
|
|
|
// {{#has any="@site.twitter, @site.facebook,@site.website"}}
|
|
|
|
callHasHelper(thisCtx, {any: '@site.twitter, @site.facebook,@site.website'});
|
2017-08-17 14:22:29 +03:00
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on global properties (fail)', function () {
|
|
|
|
thisCtx = {};
|
|
|
|
handlebarsOptions.data = {
|
2019-09-10 12:37:04 +03:00
|
|
|
site: {
|
2017-08-17 14:22:29 +03:00
|
|
|
twitter: 'foo',
|
|
|
|
facebook: '',
|
|
|
|
website: null
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-09-10 12:37:04 +03:00
|
|
|
// {{#has any="@site.facebook,@site.website, @site.foo"}}
|
|
|
|
callHasHelper(thisCtx, {any: '@site.facebook,@site.website, @not.foo'});
|
2017-08-17 14:22:29 +03:00
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on path expressions (pass)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
author: {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: '',
|
|
|
|
website: null
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has any="author.twitter, author.facebook,author.website"}}
|
|
|
|
callHasHelper(thisCtx, {any: 'author.twitter, author.facebook,author.website'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on path expressions (fail)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
author: {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: '',
|
|
|
|
website: null
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has any="author.facebook,author.website, author.foo"}}
|
|
|
|
callHasHelper(thisCtx, {any: 'author.facebook,author.website, fred.foo'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('all match', function () {
|
|
|
|
it('matches on a single property (pass)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: 'bar',
|
|
|
|
website: null
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has all="twitter"}}
|
|
|
|
callHasHelper(thisCtx, {all: 'twitter'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on a single property (fail)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: 'bar',
|
|
|
|
website: null
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has all="website"}}
|
|
|
|
callHasHelper(thisCtx, {all: 'website'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on multiple properties (pass)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: 'bar',
|
|
|
|
website: null
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has all="twitter, facebook"}}
|
|
|
|
callHasHelper(thisCtx, {all: 'twitter, facebook'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on multiple properties (fail)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: 'bar',
|
|
|
|
website: null
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has all="facebook,website, foo"}}
|
|
|
|
callHasHelper(thisCtx, {all: 'facebook,website, foo'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on global properties (pass)', function () {
|
|
|
|
thisCtx = {};
|
|
|
|
handlebarsOptions.data = {
|
2019-09-10 12:37:04 +03:00
|
|
|
site: {
|
2017-08-17 14:22:29 +03:00
|
|
|
twitter: 'foo',
|
|
|
|
facebook: 'bar',
|
|
|
|
website: null
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-09-10 12:37:04 +03:00
|
|
|
// {{#has all="@site.twitter, @site.facebook"}}
|
|
|
|
callHasHelper(thisCtx, {all: '@site.twitter, @site.facebook'});
|
2017-08-17 14:22:29 +03:00
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on global properties (fail)', function () {
|
|
|
|
thisCtx = {};
|
|
|
|
handlebarsOptions.data = {
|
2019-09-10 12:37:04 +03:00
|
|
|
site: {
|
2017-08-17 14:22:29 +03:00
|
|
|
twitter: 'foo',
|
|
|
|
facebook: 'bar',
|
|
|
|
website: null
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-09-10 12:37:04 +03:00
|
|
|
// {{#has all="@site.facebook,@site.website, @site.foo"}}
|
|
|
|
callHasHelper(thisCtx, {all: '@site.facebook,@site.website, @not.foo'});
|
2017-08-17 14:22:29 +03:00
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on path expressions (pass)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
author: {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: 'bar',
|
|
|
|
website: null
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has all="author.twitter, author.facebook"}}
|
|
|
|
callHasHelper(thisCtx, {all: 'author.twitter, author.facebook'});
|
|
|
|
|
|
|
|
fn.called.should.be.true();
|
|
|
|
inverse.called.should.be.false();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('matches on path expressions (fail)', function () {
|
|
|
|
thisCtx = {
|
|
|
|
author: {
|
|
|
|
twitter: 'foo',
|
|
|
|
facebook: 'bar',
|
|
|
|
website: null
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// {{#has all="author.facebook,author.website, author.foo"}}
|
|
|
|
callHasHelper(thisCtx, {all: 'author.facebook,author.website, fred.foo'});
|
|
|
|
|
|
|
|
fn.called.should.be.false();
|
|
|
|
inverse.called.should.be.true();
|
|
|
|
});
|
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
});
|