summaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/env/browser.js7
-rw-r--r--spec/env/runner.js24
-rw-r--r--spec/env/runtime.js7
-rw-r--r--spec/regressions.js21
-rw-r--r--spec/runtime.js37
-rw-r--r--spec/string-params.js176
-rw-r--r--spec/subexpressions.js44
-rw-r--r--spec/track-ids.js237
8 files changed, 53 insertions, 500 deletions
diff --git a/spec/env/browser.js b/spec/env/browser.js
index 8049dda..60a5d35 100644
--- a/spec/env/browser.js
+++ b/spec/env/browser.js
@@ -4,7 +4,12 @@ var fs = require('fs'),
vm = require('vm');
global.Handlebars = 'no-conflict';
-vm.runInThisContext(fs.readFileSync(__dirname + '/../../dist/handlebars.js'), 'dist/handlebars.js');
+
+var filename = 'dist/handlebars.js';
+if (global.minimizedTest) {
+ filename = 'dist/handlebars.min.js';
+}
+vm.runInThisContext(fs.readFileSync(__dirname + '/../../' + filename), filename);
global.CompilerContext = {
browser: true,
diff --git a/spec/env/runner.js b/spec/env/runner.js
index 4ff1e7e..f4b23d8 100644
--- a/spec/env/runner.js
+++ b/spec/env/runner.js
@@ -7,19 +7,35 @@ var errors = 0,
testDir = path.dirname(__dirname),
grep = process.argv[2];
+// Lazy hack, but whatever
+if (grep === '--min') {
+ global.minimizedTest = true;
+ grep = undefined;
+}
+
var files = fs.readdirSync(testDir)
.filter(function(name) { return (/.*\.js$/).test(name); })
.map(function(name) { return testDir + '/' + name; });
-run('./runtime', function() {
- run('./browser', function() {
- run('./node', function() {
+if (global.minimizedTest) {
+ run('./runtime', function() {
+ run('./browser', function() {
/* eslint-disable no-process-exit */
process.exit(errors);
/* eslint-enable no-process-exit */
});
});
-});
+} else {
+ run('./runtime', function() {
+ run('./browser', function() {
+ run('./node', function() {
+ /* eslint-disable no-process-exit */
+ process.exit(errors);
+ /* eslint-enable no-process-exit */
+ });
+ });
+ });
+}
function run(env, callback) {
diff --git a/spec/env/runtime.js b/spec/env/runtime.js
index 9d1c049..642acd3 100644
--- a/spec/env/runtime.js
+++ b/spec/env/runtime.js
@@ -4,7 +4,12 @@ var fs = require('fs'),
vm = require('vm');
global.Handlebars = 'no-conflict';
-vm.runInThisContext(fs.readFileSync(__dirname + '/../../dist/handlebars.runtime.js'), 'dist/handlebars.runtime.js');
+
+var filename = 'dist/handlebars.runtime.js';
+if (global.minimizedTest) {
+ filename = 'dist/handlebars.runtime.min.js';
+}
+vm.runInThisContext(fs.readFileSync(__dirname + '/../../' + filename), filename);
var parse = require('../../dist/cjs/handlebars/compiler/base').parse;
var compiler = require('../../dist/cjs/handlebars/compiler/compiler');
diff --git a/spec/regressions.js b/spec/regressions.js
index 83765a2..a1eec2f 100644
--- a/spec/regressions.js
+++ b/spec/regressions.js
@@ -247,4 +247,25 @@ describe('Regressions', function() {
};
shouldCompileToWithPartials(string, [{}, {}, partials], true, 'Outer');
});
+
+ it('GH-1135 : Context handling within each iteration', function() {
+ var obj = {array: [1], name: 'John'};
+ var helpers = {
+ myif: function(conditional, options) {
+ if (conditional) {
+ return options.fn(this);
+ } else {
+ return options.inverse(this);
+ }
+ }
+ };
+
+ shouldCompileTo(
+ '{{#each array}}\n'
+ + ' 1. IF: {{#if true}}{{../name}}-{{../../name}}-{{../../../name}}{{/if}}\n'
+ + ' 2. MYIF: {{#myif true}}{{../name}}={{../../name}}={{../../../name}}{{/myif}}\n'
+ + '{{/each}}', [obj, helpers],
+ ' 1. IF: John--\n'
+ + ' 2. MYIF: John==\n');
+ });
});
diff --git a/spec/runtime.js b/spec/runtime.js
index a4830ad..2a85899 100644
--- a/spec/runtime.js
+++ b/spec/runtime.js
@@ -32,43 +32,6 @@ describe('runtime', function() {
});
});
- describe('#child', function() {
- if (!Handlebars.compile) {
- return;
- }
-
- it('should throw for depthed methods without depths', function() {
- shouldThrow(function() {
- var template = Handlebars.compile('{{#foo}}{{../bar}}{{/foo}}');
- // Calling twice to hit the non-compiled case.
- template._setup({});
- template._setup({});
- template._child(1);
- }, Error, 'must pass parent depths');
- });
-
- it('should throw for block param methods without params', function() {
- shouldThrow(function() {
- var template = Handlebars.compile('{{#foo as |foo|}}{{foo}}{{/foo}}');
- // Calling twice to hit the non-compiled case.
- template._setup({});
- template._setup({});
- template._child(1);
- }, Error, 'must pass block params');
- });
- it('should expose child template', function() {
- var template = Handlebars.compile('{{#foo}}bar{{/foo}}');
- // Calling twice to hit the non-compiled case.
- equal(template._child(1)(), 'bar');
- equal(template._child(1)(), 'bar');
- });
- it('should render depthed content', function() {
- var template = Handlebars.compile('{{#foo}}{{../bar}}{{/foo}}');
- // Calling twice to hit the non-compiled case.
- equal(template._child(1, undefined, [], [{bar: 'baz'}])(), 'baz');
- });
- });
-
describe('#noConflict', function() {
if (!CompilerContext.browser) {
return;
diff --git a/spec/string-params.js b/spec/string-params.js
deleted file mode 100644
index b76f291..0000000
--- a/spec/string-params.js
+++ /dev/null
@@ -1,176 +0,0 @@
-describe('string params mode', function() {
- it('arguments to helpers can be retrieved from options hash in string form', function() {
- var template = CompilerContext.compile('{{wycats is.a slave.driver}}', {stringParams: true});
-
- var helpers = {
- wycats: function(passiveVoice, noun) {
- return 'HELP ME MY BOSS ' + passiveVoice + ' ' + noun;
- }
- };
-
- var result = template({}, {helpers: helpers});
-
- equals(result, 'HELP ME MY BOSS is.a slave.driver', 'String parameters output');
- });
-
- it('when using block form, arguments to helpers can be retrieved from options hash in string form', function() {
- var template = CompilerContext.compile('{{#wycats is.a slave.driver}}help :({{/wycats}}', {stringParams: true});
-
- var helpers = {
- wycats: function(passiveVoice, noun, options) {
- return 'HELP ME MY BOSS ' + passiveVoice + ' ' +
- noun + ': ' + options.fn(this);
- }
- };
-
- var result = template({}, {helpers: helpers});
-
- equals(result, 'HELP ME MY BOSS is.a slave.driver: help :(', 'String parameters output');
- });
-
- it('when inside a block in String mode, .. passes the appropriate context in the options hash', function() {
- var template = CompilerContext.compile('{{#with dale}}{{tomdale ../need dad.joke}}{{/with}}', {stringParams: true});
-
- var helpers = {
- tomdale: function(desire, noun, options) {
- return 'STOP ME FROM READING HACKER NEWS I ' +
- options.contexts[0][desire] + ' ' + noun;
- },
-
- 'with': function(context, options) {
- return options.fn(options.contexts[0][context]);
- }
- };
-
- var result = template({
- dale: {},
-
- need: 'need-a'
- }, {helpers: helpers});
-
- equals(result, 'STOP ME FROM READING HACKER NEWS I need-a dad.joke', 'Proper context variable output');
- });
-
- it('information about the types is passed along', function() {
- var template = CompilerContext.compile("{{tomdale 'need' dad.joke true false}}", { stringParams: true });
-
- var helpers = {
- tomdale: function(desire, noun, trueBool, falseBool, options) {
- equal(options.types[0], 'StringLiteral', 'the string type is passed');
- equal(options.types[1], 'PathExpression', 'the expression type is passed');
- equal(options.types[2], 'BooleanLiteral', 'the expression type is passed');
- equal(desire, 'need', 'the string form is passed for strings');
- equal(noun, 'dad.joke', 'the string form is passed for expressions');
- equal(trueBool, true, 'raw booleans are passed through');
- equal(falseBool, false, 'raw booleans are passed through');
- return 'Helper called';
- }
- };
-
- var result = template({}, { helpers: helpers });
- equal(result, 'Helper called');
- });
-
- it('hash parameters get type information', function() {
- var template = CompilerContext.compile("{{tomdale he.says desire='need' noun=dad.joke bool=true}}", { stringParams: true });
-
- var helpers = {
- tomdale: function(exclamation, options) {
- equal(exclamation, 'he.says');
- equal(options.types[0], 'PathExpression');
-
- equal(options.hashTypes.desire, 'StringLiteral');
- equal(options.hashTypes.noun, 'PathExpression');
- equal(options.hashTypes.bool, 'BooleanLiteral');
- equal(options.hash.desire, 'need');
- equal(options.hash.noun, 'dad.joke');
- equal(options.hash.bool, true);
- return 'Helper called';
- }
- };
-
- var result = template({}, { helpers: helpers });
- equal(result, 'Helper called');
- });
-
- it('hash parameters get context information', function() {
- var template = CompilerContext.compile("{{#with dale}}{{tomdale he.says desire='need' noun=../dad/joke bool=true}}{{/with}}", { stringParams: true });
-
- var context = {dale: {}};
-
- var helpers = {
- tomdale: function(exclamation, options) {
- equal(exclamation, 'he.says');
- equal(options.types[0], 'PathExpression');
-
- equal(options.contexts.length, 1);
- equal(options.hashContexts.noun, context);
- equal(options.hash.desire, 'need');
- equal(options.hash.noun, 'dad.joke');
- equal(options.hash.bool, true);
- return 'Helper called';
- },
- 'with': function(withContext, options) {
- return options.fn(options.contexts[0][withContext]);
- }
- };
-
- var result = template(context, { helpers: helpers });
- equal(result, 'Helper called');
- });
-
- it('when inside a block in String mode, .. passes the appropriate context in the options hash to a block helper', function() {
- var template = CompilerContext.compile('{{#with dale}}{{#tomdale ../need dad.joke}}wot{{/tomdale}}{{/with}}', {stringParams: true});
-
- var helpers = {
- tomdale: function(desire, noun, options) {
- return 'STOP ME FROM READING HACKER NEWS I ' +
- options.contexts[0][desire] + ' ' + noun + ' ' +
- options.fn(this);
- },
-
- 'with': function(context, options) {
- return options.fn(options.contexts[0][context]);
- }
- };
-
- var result = template({
- dale: {},
-
- need: 'need-a'
- }, {helpers: helpers});
-
- equals(result, 'STOP ME FROM READING HACKER NEWS I need-a dad.joke wot', 'Proper context variable output');
- });
-
- it('with nested block ambiguous', function() {
- var template = CompilerContext.compile('{{#with content}}{{#view}}{{firstName}} {{lastName}}{{/view}}{{/with}}', {stringParams: true});
-
- var helpers = {
- 'with': function() {
- return 'WITH';
- },
- view: function() {
- return 'VIEW';
- }
- };
-
- var result = template({}, {helpers: helpers});
- equals(result, 'WITH');
- });
-
- it('should handle DATA', function() {
- var template = CompilerContext.compile('{{foo @bar}}', { stringParams: true });
-
- var helpers = {
- foo: function(bar, options) {
- equal(bar, '@bar');
- equal(options.types[0], 'PathExpression');
- return 'Foo!';
- }
- };
-
- var result = template({}, { helpers: helpers });
- equal(result, 'Foo!');
- });
-});
diff --git a/spec/subexpressions.js b/spec/subexpressions.js
index dad741e..3810eb8 100644
--- a/spec/subexpressions.js
+++ b/spec/subexpressions.js
@@ -162,50 +162,6 @@ describe('subexpressions', function() {
shouldCompileTo(string, [context, helpers], '<input aria-label="Name" placeholder="Example User" />');
});
- it('in string params mode,', function() {
- var template = CompilerContext.compile('{{snog (blorg foo x=y) yeah a=b}}', {stringParams: true});
-
- var helpers = {
- snog: function(a, b, options) {
- equals(a, 'foo');
- equals(options.types.length, 2, 'string params for outer helper processed correctly');
- equals(options.types[0], 'SubExpression', 'string params for outer helper processed correctly');
- equals(options.types[1], 'PathExpression', 'string params for outer helper processed correctly');
- return a + b;
- },
-
- blorg: function(a, options) {
- equals(options.types.length, 1, 'string params for inner helper processed correctly');
- equals(options.types[0], 'PathExpression', 'string params for inner helper processed correctly');
- return a;
- }
- };
-
- var result = template({
- foo: {},
- yeah: {}
- }, {helpers: helpers});
-
- equals(result, 'fooyeah');
- });
-
- it('as hashes in string params mode', function() {
- var template = CompilerContext.compile('{{blog fun=(bork)}}', {stringParams: true});
-
- var helpers = {
- blog: function(options) {
- equals(options.hashTypes.fun, 'SubExpression');
- return 'val is ' + options.hash.fun;
- },
- bork: function() {
- return 'BORK';
- }
- };
-
- var result = template({}, {helpers: helpers});
- equals(result, 'val is BORK');
- });
-
it('subexpression functions on the context', function() {
var string = '{{foo (bar)}}!';
var context = {
diff --git a/spec/track-ids.js b/spec/track-ids.js
deleted file mode 100644
index 30a4661..0000000
--- a/spec/track-ids.js
+++ /dev/null
@@ -1,237 +0,0 @@
-describe('track ids', function() {
- var context;
- beforeEach(function() {
- context = {is: {a: 'foo'}, slave: {driver: 'bar'}};
- });
-
- it('should not include anything without the flag', function() {
- var template = CompilerContext.compile('{{wycats is.a slave.driver}}');
-
- var helpers = {
- wycats: function(passiveVoice, noun, options) {
- equal(options.ids, undefined);
- equal(options.hashIds, undefined);
-
- return 'success';
- }
- };
-
- equals(template({}, {helpers: helpers}), 'success');
- });
- it('should include argument ids', function() {
- var template = CompilerContext.compile('{{wycats is.a slave.driver}}', {trackIds: true});
-
- var helpers = {
- wycats: function(passiveVoice, noun, options) {
- equal(options.ids[0], 'is.a');
- equal(options.ids[1], 'slave.driver');
-
- return 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun;
- }
- };
-
- equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS is.a:foo slave.driver:bar');
- });
- it('should include hash ids', function() {
- var template = CompilerContext.compile('{{wycats bat=is.a baz=slave.driver}}', {trackIds: true});
-
- var helpers = {
- wycats: function(options) {
- equal(options.hashIds.bat, 'is.a');
- equal(options.hashIds.baz, 'slave.driver');
-
- return 'HELP ME MY BOSS ' + options.hashIds.bat + ':' + options.hash.bat + ' ' + options.hashIds.baz + ':' + options.hash.baz;
- }
- };
-
- equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS is.a:foo slave.driver:bar');
- });
- it('should note ../ and ./ references', function() {
- var template = CompilerContext.compile('{{wycats ./is.a ../slave.driver this.is.a this}}', {trackIds: true});
-
- var helpers = {
- wycats: function(passiveVoice, noun, thiz, thiz2, options) {
- equal(options.ids[0], 'is.a');
- equal(options.ids[1], '../slave.driver');
- equal(options.ids[2], 'is.a');
- equal(options.ids[3], '');
-
- return 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun;
- }
- };
-
- equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS is.a:foo ../slave.driver:undefined');
- });
- it('should note @data references', function() {
- var template = CompilerContext.compile('{{wycats @is.a @slave.driver}}', {trackIds: true});
-
- var helpers = {
- wycats: function(passiveVoice, noun, options) {
- equal(options.ids[0], '@is.a');
- equal(options.ids[1], '@slave.driver');
-
- return 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun;
- }
- };
-
- equals(template({}, {helpers: helpers, data: context}), 'HELP ME MY BOSS @is.a:foo @slave.driver:bar');
- });
-
- it('should return null for constants', function() {
- var template = CompilerContext.compile('{{wycats 1 "foo" key=false}}', {trackIds: true});
-
- var helpers = {
- wycats: function(passiveVoice, noun, options) {
- equal(options.ids[0], null);
- equal(options.ids[1], null);
- equal(options.hashIds.key, null);
-
- return 'HELP ME MY BOSS ' + passiveVoice + ' ' + noun + ' ' + options.hash.key;
- }
- };
-
- equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS 1 foo false');
- });
- it('should return true for subexpressions', function() {
- var template = CompilerContext.compile('{{wycats (sub)}}', {trackIds: true});
-
- var helpers = {
- sub: function() { return 1; },
- wycats: function(passiveVoice, options) {
- equal(options.ids[0], true);
-
- return 'HELP ME MY BOSS ' + passiveVoice;
- }
- };
-
- equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS 1');
- });
-
- it('should use block param paths', function() {
- var template = CompilerContext.compile('{{#doIt as |is|}}{{wycats is.a slave.driver is}}{{/doIt}}', {trackIds: true});
-
- var helpers = {
- doIt: function(options) {
- var blockParams = [this.is];
- blockParams.path = ['zomg'];
- return options.fn(this, {blockParams: blockParams});
- },
- wycats: function(passiveVoice, noun, blah, options) {
- equal(options.ids[0], 'zomg.a');
- equal(options.ids[1], 'slave.driver');
- equal(options.ids[2], 'zomg');
-
- return 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun;
- }
- };
-
- equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS zomg.a:foo slave.driver:bar');
- });
-
- describe('builtin helpers', function() {
- var helpers = {
- blockParams: function(name, options) {
- return name + ':' + options.ids[0] + '\n';
- },
- wycats: function(name, options) {
- return name + ':' + options.data.contextPath + '\n';
- }
- };
-
- describe('#each', function() {
- it('should track contextPath for arrays', function() {
- var template = CompilerContext.compile('{{#each array}}{{wycats name}}{{/each}}', {trackIds: true});
-
- equals(template({array: [{name: 'foo'}, {name: 'bar'}]}, {helpers: helpers}), 'foo:array.0\nbar:array.1\n');
- });
- it('should track contextPath for keys', function() {
- var template = CompilerContext.compile('{{#each object}}{{wycats name}}{{/each}}', {trackIds: true});
-
- equals(template({object: {foo: {name: 'foo'}, bar: {name: 'bar'}}}, {helpers: helpers}), 'foo:object.foo\nbar:object.bar\n');
- });
- it('should handle nesting', function() {
- var template = CompilerContext.compile('{{#each .}}{{#each .}}{{wycats name}}{{/each}}{{/each}}', {trackIds: true});
-
- equals(template({array: [{name: 'foo'}, {name: 'bar'}]}, {helpers: helpers}), 'foo:.array..0\nbar:.array..1\n');
- });
- it('should handle block params', function() {
- var template = CompilerContext.compile('{{#each array as |value|}}{{blockParams value.name}}{{/each}}', {trackIds: true});
-
- equals(template({array: [{name: 'foo'}, {name: 'bar'}]}, {helpers: helpers}), 'foo:array.0.name\nbar:array.1.name\n');
- });
- });
- describe('#with', function() {
- it('should track contextPath', function() {
- var template = CompilerContext.compile('{{#with field}}{{wycats name}}{{/with}}', {trackIds: true});
-
- equals(template({field: {name: 'foo'}}, {helpers: helpers}), 'foo:field\n');
- });
- it('should handle nesting', function() {
- var template = CompilerContext.compile('{{#with bat}}{{#with field}}{{wycats name}}{{/with}}{{/with}}', {trackIds: true});
-
- equals(template({bat: {field: {name: 'foo'}}}, {helpers: helpers}), 'foo:bat.field\n');
- });
- });
- describe('#blockHelperMissing', function() {
- it('should track contextPath for arrays', function() {
- var template = CompilerContext.compile('{{#field}}{{wycats name}}{{/field}}', {trackIds: true});
-
- equals(template({field: [{name: 'foo'}]}, {helpers: helpers}), 'foo:field.0\n');
- });
- it('should track contextPath for keys', function() {
- var template = CompilerContext.compile('{{#field}}{{wycats name}}{{/field}}', {trackIds: true});
-
- equals(template({field: {name: 'foo'}}, {helpers: helpers}), 'foo:field\n');
- });
- it('should handle nesting', function() {
- var template = CompilerContext.compile('{{#bat}}{{#field}}{{wycats name}}{{/field}}{{/bat}}', {trackIds: true});
-
- equals(template({bat: {field: {name: 'foo'}}}, {helpers: helpers}), 'foo:bat.field\n');
- });
- });
- });
-
- describe('partials', function() {
- var helpers = {
- blockParams: function(name, options) {
- return name + ':' + options.ids[0] + '\n';
- },
- wycats: function(name, options) {
- return name + ':' + options.data.contextPath + '\n';
- }
- };
-
- it('should pass track id for basic partial', function() {
- var template = CompilerContext.compile('Dudes: {{#dudes}}{{> dude}}{{/dudes}}', {trackIds: true}),
- hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-
- var partials = {
- dude: CompilerContext.compile('{{wycats name}}', {trackIds: true})
- };
-
- equals(template(hash, {helpers: helpers, partials: partials}), 'Dudes: Yehuda:dudes.0\nAlan:dudes.1\n');
- });
-
- it('should pass track id for context partial', function() {
- var template = CompilerContext.compile('Dudes: {{> dude dudes}}', {trackIds: true}),
- hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-
- var partials = {
- dude: CompilerContext.compile('{{#each this}}{{wycats name}}{{/each}}', {trackIds: true})
- };
-
- equals(template(hash, {helpers: helpers, partials: partials}), 'Dudes: Yehuda:dudes..0\nAlan:dudes..1\n');
- });
-
- it('should invalidate context for partials with parameters', function() {
- var template = CompilerContext.compile('Dudes: {{#dudes}}{{> dude . bar="foo"}}{{/dudes}}', {trackIds: true}),
- hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-
- var partials = {
- dude: CompilerContext.compile('{{wycats name}}', {trackIds: true})
- };
-
- equals(template(hash, {helpers: helpers, partials: partials}), 'Dudes: Yehuda:true\nAlan:true\n');
- });
- });
-});