mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-22 18:31:57 +03:00
f08a55c21f
refs: https://github.com/TryGhost/Team/issues/856 refs: https://github.com/TryGhost/Team/issues/756 - The .test.js extension is better than _spec.js as it's more obvious that it's an extension - It also meaans we can use the --extension parameter in mocha, which should result in a better default behaviour for `yarn test` - It also highlights that some of our tests were named incorrectly and were not (and still will not be) run (see https://github.com/TryGhost/Team/issues/856) - Note: even with this change, `yarn test` is throwing errors, I believe because of this issue https://github.com/TryGhost/Team/issues/756
616 lines
28 KiB
JavaScript
616 lines
28 KiB
JavaScript
const should = require('should');
|
|
const sinon = require('sinon');
|
|
const _ = require('lodash');
|
|
const helpers = require('../../../core/frontend/helpers');
|
|
const handlebars = require('../../../core/frontend/services/theme-engine/engine').handlebars;
|
|
|
|
describe('{{#foreach}} helper', function () {
|
|
let options;
|
|
let context;
|
|
let _this;
|
|
let resultData;
|
|
|
|
afterEach(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
describe('(function call)', function () {
|
|
beforeEach(function () {
|
|
context = [];
|
|
_this = {};
|
|
resultData = [];
|
|
|
|
function fn(input, data) {
|
|
resultData.push(_.cloneDeep(data));
|
|
}
|
|
|
|
options = {
|
|
fn: sinon.spy(fn),
|
|
inverse: sinon.spy(),
|
|
data: {}
|
|
};
|
|
});
|
|
|
|
function runTest(self, _context, _options) {
|
|
helpers.foreach.call(self, _context, _options);
|
|
}
|
|
|
|
it('should not populate data if no private data is supplied (array)', function () {
|
|
delete options.data;
|
|
options.hash = {
|
|
columns: 0
|
|
};
|
|
|
|
// test with context as an array
|
|
context = 'hello world this is ghost'.split(' ');
|
|
|
|
runTest(_this, context, options);
|
|
|
|
options.fn.called.should.be.true();
|
|
options.fn.getCalls().length.should.eql(_.size(context));
|
|
|
|
_.each(context, function (value, index) {
|
|
options.fn.getCall(index).args[0].should.eql(value);
|
|
should(options.fn.getCall(index).args[1].data).be.undefined();
|
|
});
|
|
});
|
|
|
|
it('should not populate data if no private data is supplied (object)', function () {
|
|
delete options.data;
|
|
options.hash = {
|
|
columns: 0
|
|
};
|
|
|
|
context = {
|
|
one: 'hello',
|
|
two: 'world',
|
|
three: 'this',
|
|
four: 'is',
|
|
five: 'ghost'
|
|
};
|
|
|
|
runTest(_this, context, options);
|
|
|
|
options.fn.called.should.be.true();
|
|
options.fn.getCalls().length.should.eql(_.size(context));
|
|
|
|
_.each(_.keys(context), function (value, index) {
|
|
options.fn.getCall(index).args[0].should.eql(context[value]);
|
|
should(options.fn.getCall(index).args[1].data).be.undefined();
|
|
});
|
|
});
|
|
|
|
it('should populate data when private data is supplied (array)', function () {
|
|
const expected = [
|
|
{first: true, last: false, even: false, odd: true, rowStart: false, rowEnd: false},
|
|
{first: false, last: false, even: true, odd: false, rowStart: false, rowEnd: false},
|
|
{first: false, last: false, even: false, odd: true, rowStart: false, rowEnd: false},
|
|
{first: false, last: false, even: true, odd: false, rowStart: false, rowEnd: false},
|
|
{first: false, last: true, even: false, odd: true, rowStart: false, rowEnd: false}
|
|
];
|
|
|
|
options.hash = {
|
|
columns: 0
|
|
};
|
|
|
|
context = 'hello world this is ghost'.split(' ');
|
|
|
|
runTest(_this, context, options);
|
|
|
|
options.fn.called.should.be.true();
|
|
options.fn.getCalls().length.should.eql(_.size(context));
|
|
|
|
_.each(context, function (value, index) {
|
|
options.fn.getCall(index).args[0].should.eql(value);
|
|
should(options.fn.getCall(index).args[1].data).not.be.undefined();
|
|
|
|
// Expected properties
|
|
resultData[index].data.should.containEql(expected[index]);
|
|
|
|
// Incrementing properties
|
|
resultData[index].data.should.have.property('key', index);
|
|
resultData[index].data.should.have.property('index', index);
|
|
resultData[index].data.should.have.property('number', index + 1);
|
|
});
|
|
|
|
resultData[_.size(context) - 1].data.should.eql(options.fn.lastCall.args[1].data);
|
|
});
|
|
|
|
it('should populate data when private data is supplied (object)', function () {
|
|
const expected = [
|
|
{first: true, last: false, even: false, odd: true, rowStart: false, rowEnd: false},
|
|
{first: false, last: false, even: true, odd: false, rowStart: false, rowEnd: false},
|
|
{first: false, last: false, even: false, odd: true, rowStart: false, rowEnd: false},
|
|
{first: false, last: false, even: true, odd: false, rowStart: false, rowEnd: false},
|
|
{first: false, last: true, even: false, odd: true, rowStart: false, rowEnd: false}
|
|
];
|
|
|
|
options.hash = {
|
|
columns: 0
|
|
};
|
|
|
|
context = {
|
|
one: 'hello',
|
|
two: 'world',
|
|
three: 'this',
|
|
four: 'is',
|
|
five: 'ghost'
|
|
};
|
|
|
|
runTest(_this, context, options);
|
|
|
|
options.fn.called.should.be.true();
|
|
options.fn.getCalls().length.should.eql(_.size(context));
|
|
|
|
_.each(_.keys(context), function (value, index) {
|
|
options.fn.getCall(index).args[0].should.eql(context[value]);
|
|
should(options.fn.getCall(index).args[1].data).not.be.undefined();
|
|
|
|
// Expected properties
|
|
resultData[index].data.should.containEql(expected[index]);
|
|
|
|
// Incrementing properties
|
|
resultData[index].data.should.have.property('key', value);
|
|
resultData[index].data.should.have.property('index', index);
|
|
resultData[index].data.should.have.property('number', index + 1);
|
|
});
|
|
|
|
resultData[_.size(context) - 1].data.should.eql(options.fn.lastCall.args[1].data);
|
|
});
|
|
|
|
it('should handle rowStart and rowEnd for multiple columns (array)', function () {
|
|
const expected = [
|
|
{first: true, last: false, even: false, odd: true, rowStart: true, rowEnd: false},
|
|
{first: false, last: false, even: true, odd: false, rowStart: false, rowEnd: true},
|
|
{first: false, last: false, even: false, odd: true, rowStart: true, rowEnd: false},
|
|
{first: false, last: false, even: true, odd: false, rowStart: false, rowEnd: true},
|
|
{first: false, last: true, even: false, odd: true, rowStart: true, rowEnd: false}
|
|
];
|
|
options.hash = {
|
|
columns: 2
|
|
};
|
|
|
|
// test with context as an array
|
|
context = 'hello world this is ghost'.split(' ');
|
|
runTest(_this, context, options);
|
|
|
|
options.fn.called.should.be.true();
|
|
options.fn.getCalls().length.should.eql(_.size(context));
|
|
|
|
_.each(context, function (value, index) {
|
|
options.fn.getCall(index).args[0].should.eql(value);
|
|
should(options.fn.getCall(index).args[1].data).not.be.undefined();
|
|
|
|
// Expected properties
|
|
resultData[index].data.should.containEql(expected[index]);
|
|
|
|
// Incrementing properties
|
|
resultData[index].data.should.have.property('key', index);
|
|
resultData[index].data.should.have.property('index', index);
|
|
resultData[index].data.should.have.property('number', index + 1);
|
|
});
|
|
|
|
resultData[_.size(context) - 1].data.should.eql(options.fn.lastCall.args[1].data);
|
|
});
|
|
|
|
it('should handle rowStart and rowEnd for multiple columns (array)', function () {
|
|
const expected = [
|
|
{first: true, last: false, even: false, odd: true, rowStart: true, rowEnd: false},
|
|
{first: false, last: false, even: true, odd: false, rowStart: false, rowEnd: true},
|
|
{first: false, last: false, even: false, odd: true, rowStart: true, rowEnd: false},
|
|
{first: false, last: false, even: true, odd: false, rowStart: false, rowEnd: true},
|
|
{first: false, last: true, even: false, odd: true, rowStart: true, rowEnd: false}
|
|
];
|
|
options.hash = {
|
|
columns: 2
|
|
};
|
|
|
|
// test with context as an object
|
|
context = {
|
|
one: 'hello',
|
|
two: 'world',
|
|
three: 'this',
|
|
four: 'is',
|
|
five: 'ghost'
|
|
};
|
|
|
|
runTest(_this, context, options);
|
|
|
|
options.fn.called.should.be.true();
|
|
options.fn.getCalls().length.should.eql(_.size(context));
|
|
|
|
_.each(_.keys(context), function (value, index) {
|
|
options.fn.getCall(index).args[0].should.eql(context[value]);
|
|
should(options.fn.getCall(index).args[1].data).not.be.undefined();
|
|
|
|
// Expected properties
|
|
resultData[index].data.should.containEql(expected[index]);
|
|
|
|
// Incrementing properties
|
|
resultData[index].data.should.have.property('key', value);
|
|
resultData[index].data.should.have.property('index', index);
|
|
resultData[index].data.should.have.property('number', index + 1);
|
|
});
|
|
|
|
resultData[_.size(context) - 1].data.should.eql(options.fn.lastCall.args[1].data);
|
|
});
|
|
|
|
it('should return the correct inverse result if no context is provided', function () {
|
|
_this = 'the inverse data';
|
|
options.hash = {
|
|
columns: 0
|
|
};
|
|
|
|
runTest(_this, context, options);
|
|
|
|
options.fn.called.should.be.false();
|
|
options.inverse.called.should.be.true();
|
|
options.inverse.calledOnce.should.be.true();
|
|
});
|
|
});
|
|
|
|
describe('(compile)', function () {
|
|
const objectHash = {
|
|
posts: {
|
|
first: {title: 'first'},
|
|
second: {title: 'second'},
|
|
third: {title: 'third'},
|
|
fourth: {title: 'fourth'},
|
|
fifth: {title: 'fifth'}
|
|
}
|
|
};
|
|
|
|
const objectHashWithVis = {
|
|
posts: {
|
|
first: {title: 'first', visibility: 'members', slug: 'first', html: ''},
|
|
second: {title: 'second'},
|
|
third: {title: 'third'},
|
|
fourth: {title: 'fourth'},
|
|
fifth: {title: 'fifth'}
|
|
}
|
|
};
|
|
|
|
const arrayHash = {
|
|
posts: [
|
|
{title: 'first'}, {title: 'second'}, {title: 'third'}, {title: 'fourth'}, {title: 'fifth'}
|
|
]
|
|
};
|
|
|
|
const arrayHashWithVis = {
|
|
posts: [
|
|
{title: 'first', visibility: 'members', slug: 'first', html: ''}, {title: 'second'}, {title: 'third'}, {title: 'fourth'}, {title: 'fifth'}
|
|
]
|
|
};
|
|
|
|
const arrayHash2 = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
|
|
|
|
const objectHash2 = {
|
|
goodbyes: {foo: {text: 'goodbye'}, bar: {text: 'Goodbye'}, baz: {text: 'GOODBYE'}},
|
|
world: 'world'
|
|
};
|
|
|
|
function shouldCompileToExpected(templateString, hash, expected) {
|
|
const template = handlebars.compile(templateString);
|
|
const result = template(hash);
|
|
|
|
result.should.eql(expected);
|
|
}
|
|
|
|
before(function () {
|
|
handlebars.registerHelper('foreach', helpers.foreach);
|
|
});
|
|
|
|
/** Many of these are copied direct from the handlebars spec */
|
|
it('object and @key', function () {
|
|
const templateString = '<ul>{{#foreach posts}}<li>{{@key}} {{title}}</li>{{/foreach}}</ul>';
|
|
const expected = '<ul><li>first first</li><li>second second</li><li>third third</li><li>fourth fourth</li><li>fifth fifth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('@index', function () {
|
|
const templateString = '<ul>{{#foreach posts}}<li>{{@index}} {{title}}</li>{{/foreach}}</ul>';
|
|
const expected = '<ul><li>0 first</li><li>1 second</li><li>2 third</li><li>3 fourth</li><li>4 fifth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('@number', function () {
|
|
const templateString = '<ul>{{#foreach posts}}<li>{{@number}} {{title}}</li>{{/foreach}}</ul>';
|
|
const expected = '<ul><li>1 first</li><li>2 second</li><li>3 third</li><li>4 fourth</li><li>5 fifth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('nested @index', function () {
|
|
const templateString = '{{#foreach goodbyes}}{{@index}}. {{text}}! {{#foreach ../goodbyes}}{{@index}} {{/foreach}}After {{@index}} {{/foreach}}{{@index}}cruel {{world}}!';
|
|
const expected = '0. goodbye! 0 1 2 After 0 1. Goodbye! 0 1 2 After 1 2. GOODBYE! 0 1 2 After 2 cruel world!';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash2, expected);
|
|
shouldCompileToExpected(templateString, objectHash2, expected);
|
|
});
|
|
|
|
it('array block params', function () {
|
|
const templateString = '{{#foreach goodbyes as |value index|}}{{index}}. {{value.text}}! {{#foreach ../goodbyes as |childValue childIndex|}} {{index}} {{childIndex}}{{/foreach}} After {{index}} {{/foreach}}{{index}}cruel {{world}}!';
|
|
const expected = '0. goodbye! 0 0 0 1 0 2 After 0 1. Goodbye! 1 0 1 1 1 2 After 1 2. GOODBYE! 2 0 2 1 2 2 After 2 cruel world!';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash2, expected);
|
|
});
|
|
|
|
it('object block params', function () {
|
|
const templateString = '{{#foreach goodbyes as |value index|}}{{index}}. {{value.text}}! {{#foreach ../goodbyes as |childValue childIndex|}} {{index}} {{childIndex}}{{/foreach}} After {{index}} {{/foreach}}{{index}}cruel {{world}}!';
|
|
const expected = 'foo. goodbye! foo foo foo bar foo baz After foo bar. Goodbye! bar foo bar bar bar baz After bar baz. GOODBYE! baz foo baz bar baz baz After baz cruel world!';
|
|
|
|
shouldCompileToExpected(templateString, objectHash2, expected);
|
|
});
|
|
|
|
it('@first', function () {
|
|
const templateString = '{{#foreach goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/foreach}}cruel {{world}}!';
|
|
const expected = 'goodbye! cruel world!';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash2, expected);
|
|
shouldCompileToExpected(templateString, objectHash2, expected);
|
|
});
|
|
|
|
it('nested @first', function () {
|
|
const templateString = '{{#foreach goodbyes}}({{#if @first}}{{text}}! {{/if}}{{#foreach ../goodbyes}}{{#if @first}}{{text}}!{{/if}}{{/foreach}}{{#if @first}} {{text}}!{{/if}}) {{/foreach}}cruel {{world}}!';
|
|
const expected = '(goodbye! goodbye! goodbye!) (goodbye!) (goodbye!) cruel world!';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash2, expected);
|
|
shouldCompileToExpected(templateString, objectHash2, expected);
|
|
});
|
|
|
|
it('@last', function () {
|
|
const templateString = '{{#foreach goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/foreach}}cruel {{world}}!';
|
|
const expected = 'GOODBYE! cruel world!';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash2, expected);
|
|
shouldCompileToExpected(templateString, objectHash2, expected);
|
|
});
|
|
|
|
it('nested @last', function () {
|
|
const templateString = '{{#foreach goodbyes}}({{#if @last}}{{text}}! {{/if}}{{#foreach ../goodbyes}}{{#if @last}}{{text}}!{{/if}}{{/foreach}}{{#if @last}} {{text}}!{{/if}}) {{/foreach}}cruel {{world}}!';
|
|
const expected = '(GOODBYE!) (GOODBYE!) (GOODBYE! GOODBYE! GOODBYE!) cruel world!';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash2, expected);
|
|
shouldCompileToExpected(templateString, objectHash2, expected);
|
|
});
|
|
|
|
it('@last in foreach with limit', function () {
|
|
const templateString = '{{#foreach goodbyes limit="2"}}{{#if @last}}{{text}}! {{/if}}{{/foreach}}cruel {{world}}!';
|
|
const expected = 'Goodbye! cruel world!';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash2, expected);
|
|
shouldCompileToExpected(templateString, objectHash2, expected);
|
|
});
|
|
|
|
it('foreach with limit 1', function () {
|
|
const templateString = '<ul>{{#foreach posts limit="1"}}<li>{{title}}</li>{{else}}not this{{/foreach}}</ul>';
|
|
const expected = '<ul><li>first</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('foreach with limit 3', function () {
|
|
const templateString = '<ul>{{#foreach posts limit="3"}}<li>{{title}}</li>{{else}}not this{{/foreach}}</ul>';
|
|
const expected = '<ul><li>first</li><li>second</li><li>third</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('foreach with limit 3 and post with members visibility', function () {
|
|
const templateString = '<ul>{{#foreach posts limit="3"}}<li>{{title}}</li>{{else}}not this{{/foreach}}</ul>';
|
|
const expected = '<ul><li>first</li><li>second</li><li>third</li></ul>';
|
|
shouldCompileToExpected(templateString, arrayHashWithVis, expected);
|
|
shouldCompileToExpected(templateString, objectHashWithVis, expected);
|
|
});
|
|
|
|
it('foreach with from 2', function () {
|
|
const templateString = '<ul>{{#foreach posts from="2"}}<li>{{title}}</li>{{else}}not this{{/foreach}}</ul>';
|
|
const expected = '<ul><li>second</li><li>third</li><li>fourth</li><li>fifth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('foreach with to 4', function () {
|
|
const templateString = '<ul>{{#foreach posts to="4"}}<li>{{title}}</li>{{else}}not this{{/foreach}}</ul>';
|
|
const expected = '<ul><li>first</li><li>second</li><li>third</li><li>fourth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('foreach with from 2 and to 3', function () {
|
|
const templateString = '<ul>{{#foreach posts from="2" to="3"}}<li>{{title}}</li>{{else}}not this{{/foreach}}</ul>';
|
|
const expected = '<ul><li>second</li><li>third</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('foreach with from 3 and limit 2', function () {
|
|
const templateString = '<ul>{{#foreach posts from="3" limit="2"}}<li>{{title}}</li>{{else}}not this{{/foreach}}</ul>';
|
|
const expected = '<ul><li>third</li><li>fourth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('foreach with from 2, to 5 and limit 3', function () {
|
|
const templateString = '<ul>{{#foreach posts from="2" to="5" limit="3"}}<li>{{title}}</li>{{else}}not this{{/foreach}}</ul>';
|
|
const expected = '<ul><li>second</li><li>third</li><li>fourth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('@first in foreach with from 2 and to 4', function () {
|
|
const templateString = '<ul>{{#foreach posts from="2" to="4"}}{{#if @first}}<li>{{title}}</li>{{/if}}{{/foreach}}</ul>';
|
|
const expected = '<ul><li>second</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
it('@last in foreach with from 2 and to 4', function () {
|
|
const templateString = '<ul>{{#foreach posts from="2" to="4"}}{{#if @last}}<li>{{title}}</li>{{/if}}{{/foreach}}</ul>';
|
|
const expected = '<ul><li>fourth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('@last in foreach with from 4', function () {
|
|
const templateString = '<ul>{{#foreach posts from="4"}}{{#if @last}}<li>{{title}}</li>{{/if}}{{/foreach}}</ul>';
|
|
const expected = '<ul><li>fifth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('@first in foreach with from 4', function () {
|
|
const templateString = '<ul>{{#foreach posts from="4"}}{{#if @first}}<li>{{title}}</li>{{/if}}{{/foreach}}</ul>';
|
|
const expected = '<ul><li>fourth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('@last in foreach with to 4', function () {
|
|
const templateString = '<ul>{{#foreach posts to="4"}}{{#if @last}}<li>{{title}}</li>{{/if}}{{/foreach}}</ul>';
|
|
const expected = '<ul><li>fourth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('@first in foreach with to 4', function () {
|
|
const templateString = '<ul>{{#foreach posts to="4"}}{{#if @first}}<li>{{title}}</li>{{/if}}{{/foreach}}</ul>';
|
|
const expected = '<ul><li>first</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('@last in foreach with from 4 and limit 3', function () {
|
|
const templateString = '<ul>{{#foreach posts from="4" limit="3"}}{{#if @last}}<li>{{title}}</li>{{/if}}{{/foreach}}</ul>';
|
|
const expected = '<ul><li>fifth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('@first in foreach with from 4 and limit 3', function () {
|
|
const templateString = '<ul>{{#foreach posts from="4" limit="3"}}{{#if @first}}<li>{{title}}</li>{{/if}}{{/foreach}}</ul>';
|
|
const expected = '<ul><li>fourth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('@last in foreach with to 4 and limit 3', function () {
|
|
const templateString = '<ul>{{#foreach posts to="4" limit="3"}}{{#if @last}}<li>{{title}}</li>{{/if}}{{/foreach}}</ul>';
|
|
const expected = '<ul><li>third</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
it('@first in foreach with to 4 and limit 3', function () {
|
|
const templateString = '<ul>{{#foreach posts to="4" limit="3"}}{{#if @first}}<li>{{title}}</li>{{/if}}{{/foreach}}</ul>';
|
|
const expected = '<ul><li>first</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, arrayHash, expected);
|
|
shouldCompileToExpected(templateString, objectHash, expected);
|
|
});
|
|
|
|
describe('Internal Tags', function () {
|
|
const tagArrayHash = {
|
|
tags: [
|
|
{name: 'first', visibility: 'public'},
|
|
{name: 'second', visibility: 'public'},
|
|
{name: 'third', visibility: 'internal'},
|
|
{name: 'fourth', visibility: 'public'},
|
|
{name: 'fifth', visibility: 'public'}
|
|
]
|
|
};
|
|
|
|
const tagObjectHash = {
|
|
tags: {
|
|
first: {name: 'first', visibility: 'public'},
|
|
second: {name: 'second', visibility: 'public'},
|
|
third: {name: 'third', visibility: 'internal'},
|
|
fourth: {name: 'fourth', visibility: 'public'},
|
|
fifth: {name: 'fifth', visibility: 'public'}
|
|
}
|
|
};
|
|
|
|
it('will not output internal tags', function () {
|
|
const templateString = '<ul>{{#foreach tags}}<li>{{@index}} {{name}}</li>{{/foreach}}</ul>';
|
|
const expected = '<ul><li>0 first</li><li>1 second</li><li>2 fourth</li><li>3 fifth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, tagObjectHash, expected);
|
|
shouldCompileToExpected(templateString, tagArrayHash, expected);
|
|
});
|
|
|
|
it('should still correctly apply from & limit tags', function () {
|
|
const templateString = '<ul>{{#foreach tags from="2" limit="2"}}<li>{{@index}} {{name}}</li>{{/foreach}}</ul>';
|
|
const expected = '<ul><li>1 second</li><li>2 fourth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, tagObjectHash, expected);
|
|
shouldCompileToExpected(templateString, tagArrayHash, expected);
|
|
});
|
|
|
|
it('should output all tags with visibility="all"', function () {
|
|
const templateString = '<ul>{{#foreach tags visibility="all"}}<li>{{@index}} {{name}}</li>{{/foreach}}</ul>';
|
|
const expected = '<ul><li>0 first</li><li>1 second</li><li>2 third</li><li>3 fourth</li><li>4 fifth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, tagObjectHash, expected);
|
|
shouldCompileToExpected(templateString, tagArrayHash, expected);
|
|
});
|
|
|
|
it('should output all tags with visibility property set with visibility="public,internal"', function () {
|
|
const templateString = '<ul>{{#foreach tags visibility="public,internal"}}<li>{{@index}} {{name}}</li>{{/foreach}}</ul>';
|
|
const expected = '<ul><li>0 first</li><li>1 second</li><li>2 third</li><li>3 fourth</li><li>4 fifth</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, tagObjectHash, expected);
|
|
shouldCompileToExpected(templateString, tagArrayHash, expected);
|
|
});
|
|
|
|
it('should output all tags with visibility="internal"', function () {
|
|
const templateString = '<ul>{{#foreach tags visibility="internal"}}<li>{{@index}} {{name}}</li>{{/foreach}}</ul>';
|
|
const expected = '<ul><li>0 third</li></ul>';
|
|
|
|
shouldCompileToExpected(templateString, tagObjectHash, expected);
|
|
shouldCompileToExpected(templateString, tagArrayHash, expected);
|
|
});
|
|
|
|
it('should output nothing if all tags are internal', function () {
|
|
const internalTagArrayHash = {
|
|
tags: [
|
|
{name: 'first', visibility: 'internal'},
|
|
{name: 'second', visibility: 'internal'}
|
|
]
|
|
};
|
|
|
|
const internalTagObjectHash = {
|
|
tags: {
|
|
first: {name: 'first', visibility: 'internal'},
|
|
second: {name: 'second', visibility: 'internal'}
|
|
}
|
|
};
|
|
|
|
const templateString = '<ul>{{#foreach tags}}<li>{{@index}} {{name}}</li>{{/foreach}}</ul>';
|
|
const expected = '<ul></ul>';
|
|
|
|
shouldCompileToExpected(templateString, internalTagObjectHash, expected);
|
|
shouldCompileToExpected(templateString, internalTagArrayHash, expected);
|
|
});
|
|
});
|
|
});
|
|
});
|