Upgrade prettier to v2
Prettier v2 has the following breaking changes: * enforces spaces between `function` and params * enforces trailing commas by default
This commit is contained in:
committed by
Jay Linski
parent
f6ff3bf52b
commit
e534a911f3
+5
-5
@@ -1,14 +1,14 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
extends: ['eslint:recommended', 'plugin:compat/recommended', 'prettier'],
|
extends: ['eslint:recommended', 'plugin:compat/recommended', 'prettier'],
|
||||||
globals: {
|
globals: {
|
||||||
self: false
|
self: false,
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
node: true,
|
node: true,
|
||||||
es2020: true
|
es2020: true,
|
||||||
},
|
},
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
sourceType: 'module'
|
sourceType: 'module',
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
'no-console': 'warn',
|
'no-console': 'warn',
|
||||||
@@ -59,6 +59,6 @@ module.exports = {
|
|||||||
|
|
||||||
// ECMAScript 6 //
|
// ECMAScript 6 //
|
||||||
//--------------//
|
//--------------//
|
||||||
'no-var': 'error'
|
'no-var': 'error',
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
+45
-40
@@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable no-process-env */
|
/* eslint-disable no-process-env */
|
||||||
module.exports = function(grunt) {
|
module.exports = function (grunt) {
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
pkg: grunt.file.readJSON('package.json'),
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ module.exports = function(grunt) {
|
|||||||
copy: {
|
copy: {
|
||||||
dist: {
|
dist: {
|
||||||
options: {
|
options: {
|
||||||
processContent: function(content) {
|
processContent: function (content) {
|
||||||
return (
|
return (
|
||||||
grunt.template.process(
|
grunt.template.process(
|
||||||
'/**!\n\n @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat\n <%= pkg.name %> v<%= pkg.version %>\n\n<%= grunt.file.read("LICENSE") %>\n*/\n'
|
'/**!\n\n @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat\n <%= pkg.name %> v<%= pkg.version %>\n\n<%= grunt.file.read("LICENSE") %>\n*/\n'
|
||||||
@@ -16,9 +16,9 @@ module.exports = function(grunt) {
|
|||||||
content +
|
content +
|
||||||
'\n// @license-end\n'
|
'\n// @license-end\n'
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
files: [{ expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/' }]
|
files: [{ expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/' }],
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
files: [
|
files: [
|
||||||
@@ -26,18 +26,23 @@ module.exports = function(grunt) {
|
|||||||
expand: true,
|
expand: true,
|
||||||
cwd: 'components/',
|
cwd: 'components/',
|
||||||
src: ['**'],
|
src: ['**'],
|
||||||
dest: 'dist/components'
|
dest: 'dist/components',
|
||||||
},
|
},
|
||||||
{ expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/components' }
|
{
|
||||||
]
|
expand: true,
|
||||||
}
|
cwd: 'dist/',
|
||||||
|
src: ['*.js'],
|
||||||
|
dest: 'dist/components',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
babel: {
|
babel: {
|
||||||
options: {
|
options: {
|
||||||
sourceMaps: 'inline',
|
sourceMaps: 'inline',
|
||||||
loose: ['es6.modules'],
|
loose: ['es6.modules'],
|
||||||
auxiliaryCommentBefore: 'istanbul ignore next'
|
auxiliaryCommentBefore: 'istanbul ignore next',
|
||||||
},
|
},
|
||||||
cjs: {
|
cjs: {
|
||||||
files: [
|
files: [
|
||||||
@@ -45,10 +50,10 @@ module.exports = function(grunt) {
|
|||||||
cwd: 'lib/',
|
cwd: 'lib/',
|
||||||
expand: true,
|
expand: true,
|
||||||
src: '**/!(index).js',
|
src: '**/!(index).js',
|
||||||
dest: 'dist/cjs/'
|
dest: 'dist/cjs/',
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
webpack: {
|
webpack: {
|
||||||
options: {
|
options: {
|
||||||
@@ -56,28 +61,28 @@ module.exports = function(grunt) {
|
|||||||
output: {
|
output: {
|
||||||
path: 'dist/',
|
path: 'dist/',
|
||||||
library: 'Handlebars',
|
library: 'Handlebars',
|
||||||
libraryTarget: 'umd'
|
libraryTarget: 'umd',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
handlebars: {
|
handlebars: {
|
||||||
entry: './dist/cjs/handlebars.js',
|
entry: './dist/cjs/handlebars.js',
|
||||||
output: {
|
output: {
|
||||||
filename: 'handlebars.js'
|
filename: 'handlebars.js',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
runtime: {
|
runtime: {
|
||||||
entry: './dist/cjs/handlebars.runtime.js',
|
entry: './dist/cjs/handlebars.runtime.js',
|
||||||
output: {
|
output: {
|
||||||
filename: 'handlebars.runtime.js'
|
filename: 'handlebars.runtime.js',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
uglify: {
|
uglify: {
|
||||||
options: {
|
options: {
|
||||||
mangle: true,
|
mangle: true,
|
||||||
compress: true,
|
compress: true,
|
||||||
preserveComments: /(?:^!|@(?:license|preserve|cc_on))/
|
preserveComments: /(?:^!|@(?:license|preserve|cc_on))/,
|
||||||
},
|
},
|
||||||
dist: {
|
dist: {
|
||||||
files: [
|
files: [
|
||||||
@@ -86,19 +91,19 @@ module.exports = function(grunt) {
|
|||||||
expand: true,
|
expand: true,
|
||||||
src: ['handlebars*.js', '!*.min.js'],
|
src: ['handlebars*.js', '!*.min.js'],
|
||||||
dest: 'dist/',
|
dest: 'dist/',
|
||||||
rename: function(dest, src) {
|
rename: function (dest, src) {
|
||||||
return dest + src.replace(/\.js$/, '.min.js');
|
return dest + src.replace(/\.js$/, '.min.js');
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
concat: {
|
concat: {
|
||||||
tests: {
|
tests: {
|
||||||
src: ['spec/!(require).js'],
|
src: ['spec/!(require).js'],
|
||||||
dest: 'tmp/tests.js'
|
dest: 'tmp/tests.js',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
connect: {
|
connect: {
|
||||||
@@ -106,27 +111,27 @@ module.exports = function(grunt) {
|
|||||||
options: {
|
options: {
|
||||||
base: '.',
|
base: '.',
|
||||||
hostname: '*',
|
hostname: '*',
|
||||||
port: 9999
|
port: 9999,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
shell: {
|
shell: {
|
||||||
integrationTests: {
|
integrationTests: {
|
||||||
command: './tests/integration/run-integration-tests.sh'
|
command: './tests/integration/run-integration-tests.sh',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
scripts: {
|
scripts: {
|
||||||
options: {
|
options: {
|
||||||
atBegin: true
|
atBegin: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
files: ['src/*', 'lib/**/*.js', 'spec/**/*.js'],
|
files: ['src/*', 'lib/**/*.js', 'spec/**/*.js'],
|
||||||
tasks: ['on-file-change']
|
tasks: ['on-file-change'],
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load tasks from npm
|
// Load tasks from npm
|
||||||
@@ -148,7 +153,7 @@ module.exports = function(grunt) {
|
|||||||
'uglify',
|
'uglify',
|
||||||
'test:min',
|
'test:min',
|
||||||
'copy:dist',
|
'copy:dist',
|
||||||
'copy:components'
|
'copy:components',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Requires secret properties from .travis.yaml
|
// Requires secret properties from .travis.yaml
|
||||||
@@ -156,7 +161,7 @@ module.exports = function(grunt) {
|
|||||||
'default',
|
'default',
|
||||||
'shell:integrationTests',
|
'shell:integrationTests',
|
||||||
'metrics',
|
'metrics',
|
||||||
'publish-to-aws'
|
'publish-to-aws',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
grunt.registerTask('on-file-change', ['build', 'concat:tests', 'test']);
|
grunt.registerTask('on-file-change', ['build', 'concat:tests', 'test']);
|
||||||
@@ -174,6 +179,6 @@ module.exports = function(grunt) {
|
|||||||
);
|
);
|
||||||
grunt.registerTask('integration-tests', [
|
grunt.registerTask('integration-tests', [
|
||||||
'default',
|
'default',
|
||||||
'shell:integrationTests'
|
'shell:integrationTests',
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|||||||
+20
-20
@@ -5,103 +5,103 @@ const yargs = require('yargs')
|
|||||||
.option('f', {
|
.option('f', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Output File',
|
description: 'Output File',
|
||||||
alias: 'output'
|
alias: 'output',
|
||||||
})
|
})
|
||||||
.option('map', {
|
.option('map', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Source Map File'
|
description: 'Source Map File',
|
||||||
})
|
})
|
||||||
.option('a', {
|
.option('a', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Exports amd style (require.js)',
|
description: 'Exports amd style (require.js)',
|
||||||
alias: 'amd'
|
alias: 'amd',
|
||||||
})
|
})
|
||||||
.option('c', {
|
.option('c', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Exports CommonJS style, path to Handlebars module',
|
description: 'Exports CommonJS style, path to Handlebars module',
|
||||||
alias: 'commonjs',
|
alias: 'commonjs',
|
||||||
default: null
|
default: null,
|
||||||
})
|
})
|
||||||
.option('h', {
|
.option('h', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Path to handlebar.js (only valid for amd-style)',
|
description: 'Path to handlebar.js (only valid for amd-style)',
|
||||||
alias: 'handlebarPath',
|
alias: 'handlebarPath',
|
||||||
default: ''
|
default: '',
|
||||||
})
|
})
|
||||||
.option('k', {
|
.option('k', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Known helpers',
|
description: 'Known helpers',
|
||||||
alias: 'known'
|
alias: 'known',
|
||||||
})
|
})
|
||||||
.option('o', {
|
.option('o', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Known helpers only',
|
description: 'Known helpers only',
|
||||||
alias: 'knownOnly'
|
alias: 'knownOnly',
|
||||||
})
|
})
|
||||||
.option('m', {
|
.option('m', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Minimize output',
|
description: 'Minimize output',
|
||||||
alias: 'min'
|
alias: 'min',
|
||||||
})
|
})
|
||||||
.option('n', {
|
.option('n', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Template namespace',
|
description: 'Template namespace',
|
||||||
alias: 'namespace',
|
alias: 'namespace',
|
||||||
default: 'Handlebars.templates'
|
default: 'Handlebars.templates',
|
||||||
})
|
})
|
||||||
.option('s', {
|
.option('s', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Output template function only.',
|
description: 'Output template function only.',
|
||||||
alias: 'simple'
|
alias: 'simple',
|
||||||
})
|
})
|
||||||
.option('N', {
|
.option('N', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description:
|
description:
|
||||||
'Name of passed string templates. Optional if running in a simple mode. Required when operating on multiple templates.',
|
'Name of passed string templates. Optional if running in a simple mode. Required when operating on multiple templates.',
|
||||||
alias: 'name'
|
alias: 'name',
|
||||||
})
|
})
|
||||||
.option('i', {
|
.option('i', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description:
|
description:
|
||||||
'Generates a template from the passed CLI argument.\n"-" is treated as a special value and causes stdin to be read for the template value.',
|
'Generates a template from the passed CLI argument.\n"-" is treated as a special value and causes stdin to be read for the template value.',
|
||||||
alias: 'string'
|
alias: 'string',
|
||||||
})
|
})
|
||||||
.option('r', {
|
.option('r', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description:
|
description:
|
||||||
'Template root. Base value that will be stripped from template names.',
|
'Template root. Base value that will be stripped from template names.',
|
||||||
alias: 'root'
|
alias: 'root',
|
||||||
})
|
})
|
||||||
.option('p', {
|
.option('p', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Compiling a partial template',
|
description: 'Compiling a partial template',
|
||||||
alias: 'partial'
|
alias: 'partial',
|
||||||
})
|
})
|
||||||
.option('d', {
|
.option('d', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Include data when compiling',
|
description: 'Include data when compiling',
|
||||||
alias: 'data'
|
alias: 'data',
|
||||||
})
|
})
|
||||||
.option('e', {
|
.option('e', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Template extension.',
|
description: 'Template extension.',
|
||||||
alias: 'extension',
|
alias: 'extension',
|
||||||
default: 'handlebars'
|
default: 'handlebars',
|
||||||
})
|
})
|
||||||
.option('b', {
|
.option('b', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description:
|
description:
|
||||||
'Removes the BOM (Byte Order Mark) from the beginning of the templates.',
|
'Removes the BOM (Byte Order Mark) from the beginning of the templates.',
|
||||||
alias: 'bom'
|
alias: 'bom',
|
||||||
})
|
})
|
||||||
.option('v', {
|
.option('v', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Prints the current compiler version',
|
description: 'Prints the current compiler version',
|
||||||
alias: 'version'
|
alias: 'version',
|
||||||
})
|
})
|
||||||
.option('help', {
|
.option('help', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Outputs this message'
|
description: 'Outputs this message',
|
||||||
})
|
})
|
||||||
.wrap(120);
|
.wrap(120);
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ argv.files = argv._;
|
|||||||
delete argv._;
|
delete argv._;
|
||||||
|
|
||||||
const Precompiler = require('../dist/cjs/precompiler');
|
const Precompiler = require('../dist/cjs/precompiler');
|
||||||
Precompiler.loadTemplates(argv, function(err, opts) {
|
Precompiler.loadTemplates(argv, function (err, opts) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -2,6 +2,6 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
env: {
|
env: {
|
||||||
// Handlebars should run natively in the browser
|
// Handlebars should run natively in the browser
|
||||||
node: false
|
node: false,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
+3
-3
@@ -2,7 +2,7 @@ import {
|
|||||||
parser as Parser,
|
parser as Parser,
|
||||||
parse,
|
parse,
|
||||||
parseWithoutProcessing,
|
parseWithoutProcessing,
|
||||||
Visitor
|
Visitor,
|
||||||
} from '@handlebars/parser';
|
} from '@handlebars/parser';
|
||||||
|
|
||||||
import runtime from './handlebars.runtime';
|
import runtime from './handlebars.runtime';
|
||||||
@@ -18,10 +18,10 @@ let _create = runtime.create;
|
|||||||
function create() {
|
function create() {
|
||||||
let hb = _create();
|
let hb = _create();
|
||||||
|
|
||||||
hb.compile = function(input, options) {
|
hb.compile = function (input, options) {
|
||||||
return compile(input, options, hb);
|
return compile(input, options, hb);
|
||||||
};
|
};
|
||||||
hb.precompile = function(input, options) {
|
hb.precompile = function (input, options) {
|
||||||
return precompile(input, options, hb);
|
return precompile(input, options, hb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ function create() {
|
|||||||
hb.escapeExpression = Utils.escapeExpression;
|
hb.escapeExpression = Utils.escapeExpression;
|
||||||
|
|
||||||
hb.VM = runtime;
|
hb.VM = runtime;
|
||||||
hb.template = function(spec) {
|
hb.template = function (spec) {
|
||||||
return runtime.template(spec, hb);
|
return runtime.template(spec, hb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export const REVISION_CHANGES = {
|
|||||||
5: '== 2.0.0-alpha.x',
|
5: '== 2.0.0-alpha.x',
|
||||||
6: '>= 2.0.0-beta.1',
|
6: '>= 2.0.0-beta.1',
|
||||||
7: '>= 4.0.0 <4.3.0',
|
7: '>= 4.0.0 <4.3.0',
|
||||||
8: '>= 4.3.0'
|
8: '>= 4.3.0',
|
||||||
};
|
};
|
||||||
|
|
||||||
const objectType = '[object Object]';
|
const objectType = '[object Object]';
|
||||||
@@ -37,7 +37,7 @@ HandlebarsEnvironment.prototype = {
|
|||||||
logger: logger,
|
logger: logger,
|
||||||
log: logger.log,
|
log: logger.log,
|
||||||
|
|
||||||
registerHelper: function(name, fn) {
|
registerHelper: function (name, fn) {
|
||||||
if (toString.call(name) === objectType) {
|
if (toString.call(name) === objectType) {
|
||||||
if (fn) {
|
if (fn) {
|
||||||
throw new Exception('Arg not supported with multiple helpers');
|
throw new Exception('Arg not supported with multiple helpers');
|
||||||
@@ -47,11 +47,11 @@ HandlebarsEnvironment.prototype = {
|
|||||||
this.helpers[name] = fn;
|
this.helpers[name] = fn;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
unregisterHelper: function(name) {
|
unregisterHelper: function (name) {
|
||||||
delete this.helpers[name];
|
delete this.helpers[name];
|
||||||
},
|
},
|
||||||
|
|
||||||
registerPartial: function(name, partial) {
|
registerPartial: function (name, partial) {
|
||||||
if (toString.call(name) === objectType) {
|
if (toString.call(name) === objectType) {
|
||||||
extend(this.partials, name);
|
extend(this.partials, name);
|
||||||
} else {
|
} else {
|
||||||
@@ -63,11 +63,11 @@ HandlebarsEnvironment.prototype = {
|
|||||||
this.partials[name] = partial;
|
this.partials[name] = partial;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
unregisterPartial: function(name) {
|
unregisterPartial: function (name) {
|
||||||
delete this.partials[name];
|
delete this.partials[name];
|
||||||
},
|
},
|
||||||
|
|
||||||
registerDecorator: function(name, fn) {
|
registerDecorator: function (name, fn) {
|
||||||
if (toString.call(name) === objectType) {
|
if (toString.call(name) === objectType) {
|
||||||
if (fn) {
|
if (fn) {
|
||||||
throw new Exception('Arg not supported with multiple decorators');
|
throw new Exception('Arg not supported with multiple decorators');
|
||||||
@@ -77,7 +77,7 @@ HandlebarsEnvironment.prototype = {
|
|||||||
this.decorators[name] = fn;
|
this.decorators[name] = fn;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
unregisterDecorator: function(name) {
|
unregisterDecorator: function (name) {
|
||||||
delete this.decorators[name];
|
delete this.decorators[name];
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -86,7 +86,7 @@ HandlebarsEnvironment.prototype = {
|
|||||||
*/
|
*/
|
||||||
resetLoggedPropertyAccesses() {
|
resetLoggedPropertyAccesses() {
|
||||||
resetLoggedProperties();
|
resetLoggedProperties();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export let log = logger.log;
|
export let log = logger.log;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ let AST = {
|
|||||||
// a mustache is definitely a helper if:
|
// a mustache is definitely a helper if:
|
||||||
// * it is an eligible helper, and
|
// * it is an eligible helper, and
|
||||||
// * it has at least one parameter or hash segment
|
// * it has at least one parameter or hash segment
|
||||||
helperExpression: function(node) {
|
helperExpression: function (node) {
|
||||||
return (
|
return (
|
||||||
node.type === 'SubExpression' ||
|
node.type === 'SubExpression' ||
|
||||||
((node.type === 'MustacheStatement' ||
|
((node.type === 'MustacheStatement' ||
|
||||||
@@ -13,18 +13,18 @@ let AST = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
scopedId: function(path) {
|
scopedId: function (path) {
|
||||||
return /^\.|this\b/.test(path.original);
|
return /^\.|this\b/.test(path.original);
|
||||||
},
|
},
|
||||||
|
|
||||||
// an ID is simple if it only has one part, and that part is not
|
// an ID is simple if it only has one part, and that part is not
|
||||||
// `..` or `this`.
|
// `..` or `this`.
|
||||||
simpleId: function(path) {
|
simpleId: function (path) {
|
||||||
return (
|
return (
|
||||||
path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth
|
path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Must be exported as an object rather than the root of the module as the jison lexer
|
// Must be exported as an object rather than the root of the module as the jison lexer
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ try {
|
|||||||
|
|
||||||
/* istanbul ignore if: tested but not covered in istanbul due to dist build */
|
/* istanbul ignore if: tested but not covered in istanbul due to dist build */
|
||||||
if (!SourceNode) {
|
if (!SourceNode) {
|
||||||
SourceNode = function(line, column, srcFile, chunks) {
|
SourceNode = function (line, column, srcFile, chunks) {
|
||||||
this.src = '';
|
this.src = '';
|
||||||
if (chunks) {
|
if (chunks) {
|
||||||
this.add(chunks);
|
this.add(chunks);
|
||||||
@@ -25,24 +25,24 @@ if (!SourceNode) {
|
|||||||
};
|
};
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
SourceNode.prototype = {
|
SourceNode.prototype = {
|
||||||
add: function(chunks) {
|
add: function (chunks) {
|
||||||
if (isArray(chunks)) {
|
if (isArray(chunks)) {
|
||||||
chunks = chunks.join('');
|
chunks = chunks.join('');
|
||||||
}
|
}
|
||||||
this.src += chunks;
|
this.src += chunks;
|
||||||
},
|
},
|
||||||
prepend: function(chunks) {
|
prepend: function (chunks) {
|
||||||
if (isArray(chunks)) {
|
if (isArray(chunks)) {
|
||||||
chunks = chunks.join('');
|
chunks = chunks.join('');
|
||||||
}
|
}
|
||||||
this.src = chunks + this.src;
|
this.src = chunks + this.src;
|
||||||
},
|
},
|
||||||
toStringWithSourceMap: function() {
|
toStringWithSourceMap: function () {
|
||||||
return { code: this.toString() };
|
return { code: this.toString() };
|
||||||
},
|
},
|
||||||
toString: function() {
|
toString: function () {
|
||||||
return this.src;
|
return this.src;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,32 +70,32 @@ CodeGen.prototype = {
|
|||||||
isEmpty() {
|
isEmpty() {
|
||||||
return !this.source.length;
|
return !this.source.length;
|
||||||
},
|
},
|
||||||
prepend: function(source, loc) {
|
prepend: function (source, loc) {
|
||||||
this.source.unshift(this.wrap(source, loc));
|
this.source.unshift(this.wrap(source, loc));
|
||||||
},
|
},
|
||||||
push: function(source, loc) {
|
push: function (source, loc) {
|
||||||
this.source.push(this.wrap(source, loc));
|
this.source.push(this.wrap(source, loc));
|
||||||
},
|
},
|
||||||
|
|
||||||
merge: function() {
|
merge: function () {
|
||||||
let source = this.empty();
|
let source = this.empty();
|
||||||
this.each(function(line) {
|
this.each(function (line) {
|
||||||
source.add([' ', line, '\n']);
|
source.add([' ', line, '\n']);
|
||||||
});
|
});
|
||||||
return source;
|
return source;
|
||||||
},
|
},
|
||||||
|
|
||||||
each: function(iter) {
|
each: function (iter) {
|
||||||
for (let i = 0, len = this.source.length; i < len; i++) {
|
for (let i = 0, len = this.source.length; i < len; i++) {
|
||||||
iter(this.source[i]);
|
iter(this.source[i]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
empty: function() {
|
empty: function () {
|
||||||
let loc = this.currentLocation || { start: {} };
|
let loc = this.currentLocation || { start: {} };
|
||||||
return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
|
return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
|
||||||
},
|
},
|
||||||
wrap: function(chunk, loc = this.currentLocation || { start: {} }) {
|
wrap: function (chunk, loc = this.currentLocation || { start: {} }) {
|
||||||
if (chunk instanceof SourceNode) {
|
if (chunk instanceof SourceNode) {
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
@@ -110,12 +110,12 @@ CodeGen.prototype = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
functionCall: function(fn, type, params) {
|
functionCall: function (fn, type, params) {
|
||||||
params = this.generateList(params);
|
params = this.generateList(params);
|
||||||
return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
|
return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
|
||||||
},
|
},
|
||||||
|
|
||||||
quotedString: function(str) {
|
quotedString: function (str) {
|
||||||
return (
|
return (
|
||||||
'"' +
|
'"' +
|
||||||
(str + '')
|
(str + '')
|
||||||
@@ -129,10 +129,10 @@ CodeGen.prototype = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
objectLiteral: function(obj) {
|
objectLiteral: function (obj) {
|
||||||
let pairs = [];
|
let pairs = [];
|
||||||
|
|
||||||
Object.keys(obj).forEach(key => {
|
Object.keys(obj).forEach((key) => {
|
||||||
let value = castChunk(obj[key], this);
|
let value = castChunk(obj[key], this);
|
||||||
if (value !== 'undefined') {
|
if (value !== 'undefined') {
|
||||||
pairs.push([this.quotedString(key), ':', value]);
|
pairs.push([this.quotedString(key), ':', value]);
|
||||||
@@ -145,7 +145,7 @@ CodeGen.prototype = {
|
|||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
|
||||||
generateList: function(entries) {
|
generateList: function (entries) {
|
||||||
let ret = this.empty();
|
let ret = this.empty();
|
||||||
|
|
||||||
for (let i = 0, len = entries.length; i < len; i++) {
|
for (let i = 0, len = entries.length; i < len; i++) {
|
||||||
@@ -159,13 +159,13 @@ CodeGen.prototype = {
|
|||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
|
||||||
generateArray: function(entries) {
|
generateArray: function (entries) {
|
||||||
let ret = this.generateList(entries);
|
let ret = this.generateList(entries);
|
||||||
ret.prepend('[');
|
ret.prepend('[');
|
||||||
ret.add(']');
|
ret.add(']');
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CodeGen;
|
export default CodeGen;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export function Compiler() {}
|
|||||||
Compiler.prototype = {
|
Compiler.prototype = {
|
||||||
compiler: Compiler,
|
compiler: Compiler,
|
||||||
|
|
||||||
equals: function(other) {
|
equals: function (other) {
|
||||||
let len = this.opcodes.length;
|
let len = this.opcodes.length;
|
||||||
if (other.opcodes.length !== len) {
|
if (other.opcodes.length !== len) {
|
||||||
return false;
|
return false;
|
||||||
@@ -47,7 +47,7 @@ Compiler.prototype = {
|
|||||||
|
|
||||||
guid: 0,
|
guid: 0,
|
||||||
|
|
||||||
compile: function(program, options) {
|
compile: function (program, options) {
|
||||||
this.sourceNode = [];
|
this.sourceNode = [];
|
||||||
this.opcodes = [];
|
this.opcodes = [];
|
||||||
this.children = [];
|
this.children = [];
|
||||||
@@ -65,7 +65,7 @@ Compiler.prototype = {
|
|||||||
unless: true,
|
unless: true,
|
||||||
with: true,
|
with: true,
|
||||||
log: true,
|
log: true,
|
||||||
lookup: true
|
lookup: true,
|
||||||
},
|
},
|
||||||
options.knownHelpers
|
options.knownHelpers
|
||||||
);
|
);
|
||||||
@@ -73,7 +73,7 @@ Compiler.prototype = {
|
|||||||
return this.accept(program);
|
return this.accept(program);
|
||||||
},
|
},
|
||||||
|
|
||||||
compileProgram: function(program) {
|
compileProgram: function (program) {
|
||||||
let childCompiler = new this.compiler(), // eslint-disable-line new-cap
|
let childCompiler = new this.compiler(), // eslint-disable-line new-cap
|
||||||
result = childCompiler.compile(program, this.options),
|
result = childCompiler.compile(program, this.options),
|
||||||
guid = this.guid++;
|
guid = this.guid++;
|
||||||
@@ -86,7 +86,7 @@ Compiler.prototype = {
|
|||||||
return guid;
|
return guid;
|
||||||
},
|
},
|
||||||
|
|
||||||
accept: function(node) {
|
accept: function (node) {
|
||||||
/* istanbul ignore next: Sanity code */
|
/* istanbul ignore next: Sanity code */
|
||||||
if (!this[node.type]) {
|
if (!this[node.type]) {
|
||||||
throw new Exception('Unknown type: ' + node.type, node);
|
throw new Exception('Unknown type: ' + node.type, node);
|
||||||
@@ -98,7 +98,7 @@ Compiler.prototype = {
|
|||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
|
||||||
Program: function(program) {
|
Program: function (program) {
|
||||||
this.options.blockParams.unshift(program.blockParams);
|
this.options.blockParams.unshift(program.blockParams);
|
||||||
|
|
||||||
let body = program.body,
|
let body = program.body,
|
||||||
@@ -115,7 +115,7 @@ Compiler.prototype = {
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
BlockStatement: function(block) {
|
BlockStatement: function (block) {
|
||||||
transformLiteralToPath(block);
|
transformLiteralToPath(block);
|
||||||
|
|
||||||
let program = block.program,
|
let program = block.program,
|
||||||
@@ -160,7 +160,7 @@ Compiler.prototype = {
|
|||||||
this.opcode('registerDecorator', params.length, path.original);
|
this.opcode('registerDecorator', params.length, path.original);
|
||||||
},
|
},
|
||||||
|
|
||||||
PartialStatement: function(partial) {
|
PartialStatement: function (partial) {
|
||||||
this.usePartial = true;
|
this.usePartial = true;
|
||||||
|
|
||||||
let program = partial.program;
|
let program = partial.program;
|
||||||
@@ -199,11 +199,11 @@ Compiler.prototype = {
|
|||||||
this.opcode('invokePartial', isDynamic, partialName, indent);
|
this.opcode('invokePartial', isDynamic, partialName, indent);
|
||||||
this.opcode('append');
|
this.opcode('append');
|
||||||
},
|
},
|
||||||
PartialBlockStatement: function(partialBlock) {
|
PartialBlockStatement: function (partialBlock) {
|
||||||
this.PartialStatement(partialBlock);
|
this.PartialStatement(partialBlock);
|
||||||
},
|
},
|
||||||
|
|
||||||
MustacheStatement: function(mustache) {
|
MustacheStatement: function (mustache) {
|
||||||
this.SubExpression(mustache);
|
this.SubExpression(mustache);
|
||||||
|
|
||||||
if (mustache.escaped && !this.options.noEscape) {
|
if (mustache.escaped && !this.options.noEscape) {
|
||||||
@@ -216,15 +216,15 @@ Compiler.prototype = {
|
|||||||
this.DecoratorBlock(decorator);
|
this.DecoratorBlock(decorator);
|
||||||
},
|
},
|
||||||
|
|
||||||
ContentStatement: function(content) {
|
ContentStatement: function (content) {
|
||||||
if (content.value) {
|
if (content.value) {
|
||||||
this.opcode('appendContent', content.value);
|
this.opcode('appendContent', content.value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
CommentStatement: function() {},
|
CommentStatement: function () {},
|
||||||
|
|
||||||
SubExpression: function(sexpr) {
|
SubExpression: function (sexpr) {
|
||||||
transformLiteralToPath(sexpr);
|
transformLiteralToPath(sexpr);
|
||||||
let type = this.classifySexpr(sexpr);
|
let type = this.classifySexpr(sexpr);
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ Compiler.prototype = {
|
|||||||
this.ambiguousSexpr(sexpr);
|
this.ambiguousSexpr(sexpr);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ambiguousSexpr: function(sexpr, program, inverse) {
|
ambiguousSexpr: function (sexpr, program, inverse) {
|
||||||
let path = sexpr.path,
|
let path = sexpr.path,
|
||||||
name = path.parts[0],
|
name = path.parts[0],
|
||||||
isBlock = program != null || inverse != null;
|
isBlock = program != null || inverse != null;
|
||||||
@@ -252,14 +252,14 @@ Compiler.prototype = {
|
|||||||
this.opcode('invokeAmbiguous', name, isBlock);
|
this.opcode('invokeAmbiguous', name, isBlock);
|
||||||
},
|
},
|
||||||
|
|
||||||
simpleSexpr: function(sexpr) {
|
simpleSexpr: function (sexpr) {
|
||||||
let path = sexpr.path;
|
let path = sexpr.path;
|
||||||
path.strict = true;
|
path.strict = true;
|
||||||
this.accept(path);
|
this.accept(path);
|
||||||
this.opcode('resolvePossibleLambda');
|
this.opcode('resolvePossibleLambda');
|
||||||
},
|
},
|
||||||
|
|
||||||
helperSexpr: function(sexpr, program, inverse) {
|
helperSexpr: function (sexpr, program, inverse) {
|
||||||
let params = this.setupFullMustacheParams(sexpr, program, inverse),
|
let params = this.setupFullMustacheParams(sexpr, program, inverse),
|
||||||
path = sexpr.path,
|
path = sexpr.path,
|
||||||
name = path.parts[0];
|
name = path.parts[0];
|
||||||
@@ -285,7 +285,7 @@ Compiler.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
PathExpression: function(path) {
|
PathExpression: function (path) {
|
||||||
this.addDepth(path.depth);
|
this.addDepth(path.depth);
|
||||||
this.opcode('getContext', path.depth);
|
this.opcode('getContext', path.depth);
|
||||||
|
|
||||||
@@ -312,27 +312,27 @@ Compiler.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
StringLiteral: function(string) {
|
StringLiteral: function (string) {
|
||||||
this.opcode('pushString', string.value);
|
this.opcode('pushString', string.value);
|
||||||
},
|
},
|
||||||
|
|
||||||
NumberLiteral: function(number) {
|
NumberLiteral: function (number) {
|
||||||
this.opcode('pushLiteral', number.value);
|
this.opcode('pushLiteral', number.value);
|
||||||
},
|
},
|
||||||
|
|
||||||
BooleanLiteral: function(bool) {
|
BooleanLiteral: function (bool) {
|
||||||
this.opcode('pushLiteral', bool.value);
|
this.opcode('pushLiteral', bool.value);
|
||||||
},
|
},
|
||||||
|
|
||||||
UndefinedLiteral: function() {
|
UndefinedLiteral: function () {
|
||||||
this.opcode('pushLiteral', 'undefined');
|
this.opcode('pushLiteral', 'undefined');
|
||||||
},
|
},
|
||||||
|
|
||||||
NullLiteral: function() {
|
NullLiteral: function () {
|
||||||
this.opcode('pushLiteral', 'null');
|
this.opcode('pushLiteral', 'null');
|
||||||
},
|
},
|
||||||
|
|
||||||
Hash: function(hash) {
|
Hash: function (hash) {
|
||||||
let pairs = hash.pairs,
|
let pairs = hash.pairs,
|
||||||
i = 0,
|
i = 0,
|
||||||
l = pairs.length;
|
l = pairs.length;
|
||||||
@@ -349,15 +349,15 @@ Compiler.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// HELPERS
|
// HELPERS
|
||||||
opcode: function(name) {
|
opcode: function (name) {
|
||||||
this.opcodes.push({
|
this.opcodes.push({
|
||||||
opcode: name,
|
opcode: name,
|
||||||
args: slice.call(arguments, 1),
|
args: slice.call(arguments, 1),
|
||||||
loc: this.sourceNode[0].loc
|
loc: this.sourceNode[0].loc,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
addDepth: function(depth) {
|
addDepth: function (depth) {
|
||||||
if (!depth) {
|
if (!depth) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -365,7 +365,7 @@ Compiler.prototype = {
|
|||||||
this.useDepths = true;
|
this.useDepths = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
classifySexpr: function(sexpr) {
|
classifySexpr: function (sexpr) {
|
||||||
let isSimple = AST.helpers.simpleId(sexpr.path);
|
let isSimple = AST.helpers.simpleId(sexpr.path);
|
||||||
|
|
||||||
let isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]);
|
let isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]);
|
||||||
@@ -400,17 +400,17 @@ Compiler.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
pushParams: function(params) {
|
pushParams: function (params) {
|
||||||
for (let i = 0, l = params.length; i < l; i++) {
|
for (let i = 0, l = params.length; i < l; i++) {
|
||||||
this.pushParam(params[i]);
|
this.pushParam(params[i]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
pushParam: function(val) {
|
pushParam: function (val) {
|
||||||
this.accept(val);
|
this.accept(val);
|
||||||
},
|
},
|
||||||
|
|
||||||
setupFullMustacheParams: function(sexpr, program, inverse, omitEmpty) {
|
setupFullMustacheParams: function (sexpr, program, inverse, omitEmpty) {
|
||||||
let params = sexpr.params;
|
let params = sexpr.params;
|
||||||
this.pushParams(params);
|
this.pushParams(params);
|
||||||
|
|
||||||
@@ -426,7 +426,7 @@ Compiler.prototype = {
|
|||||||
return params;
|
return params;
|
||||||
},
|
},
|
||||||
|
|
||||||
blockParamIndex: function(name) {
|
blockParamIndex: function (name) {
|
||||||
for (
|
for (
|
||||||
let depth = 0, len = this.options.blockParams.length;
|
let depth = 0, len = this.options.blockParams.length;
|
||||||
depth < len;
|
depth < len;
|
||||||
@@ -438,7 +438,7 @@ Compiler.prototype = {
|
|||||||
return [depth, param];
|
return [depth, param];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function precompile(input, options = {}, env) {
|
export function precompile(input, options = {}, env) {
|
||||||
@@ -467,7 +467,7 @@ export function compile(input, options = {}, env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Template is only compiled on first use and cached after that point.
|
// Template is only compiled on first use and cached after that point.
|
||||||
return function(context, execOptions) {
|
return function (context, execOptions) {
|
||||||
if (!compiled) {
|
if (!compiled) {
|
||||||
compiled = compileInput();
|
compiled = compileInput();
|
||||||
}
|
}
|
||||||
@@ -530,7 +530,7 @@ function transformLiteralToPath(sexpr) {
|
|||||||
depth: 0,
|
depth: 0,
|
||||||
parts: [literal.original + ''],
|
parts: [literal.original + ''],
|
||||||
original: literal.original + '',
|
original: literal.original + '',
|
||||||
loc: literal.loc
|
loc: literal.loc,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,25 +12,25 @@ function JavaScriptCompiler() {}
|
|||||||
JavaScriptCompiler.prototype = {
|
JavaScriptCompiler.prototype = {
|
||||||
// PUBLIC API: You can override these methods in a subclass to provide
|
// PUBLIC API: You can override these methods in a subclass to provide
|
||||||
// alternative compiled forms for name lookup and buffering semantics
|
// alternative compiled forms for name lookup and buffering semantics
|
||||||
nameLookup: function(parent, name /*, type */) {
|
nameLookup: function (parent, name /*, type */) {
|
||||||
return this.internalNameLookup(parent, name);
|
return this.internalNameLookup(parent, name);
|
||||||
},
|
},
|
||||||
depthedLookup: function(name) {
|
depthedLookup: function (name) {
|
||||||
return [
|
return [
|
||||||
this.aliasable('container.lookup'),
|
this.aliasable('container.lookup'),
|
||||||
'(depths, ',
|
'(depths, ',
|
||||||
JSON.stringify(name),
|
JSON.stringify(name),
|
||||||
')'
|
')',
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
compilerInfo: function() {
|
compilerInfo: function () {
|
||||||
const revision = COMPILER_REVISION,
|
const revision = COMPILER_REVISION,
|
||||||
versions = REVISION_CHANGES[revision];
|
versions = REVISION_CHANGES[revision];
|
||||||
return [revision, versions];
|
return [revision, versions];
|
||||||
},
|
},
|
||||||
|
|
||||||
appendToBuffer: function(source, location, explicit) {
|
appendToBuffer: function (source, location, explicit) {
|
||||||
// Force a source as this simplifies the merge logic.
|
// Force a source as this simplifies the merge logic.
|
||||||
if (!isArray(source)) {
|
if (!isArray(source)) {
|
||||||
source = [source];
|
source = [source];
|
||||||
@@ -50,18 +50,18 @@ JavaScriptCompiler.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
initializeBuffer: function() {
|
initializeBuffer: function () {
|
||||||
return this.quotedString('');
|
return this.quotedString('');
|
||||||
},
|
},
|
||||||
// END PUBLIC API
|
// END PUBLIC API
|
||||||
internalNameLookup: function(parent, name) {
|
internalNameLookup: function (parent, name) {
|
||||||
this.lookupPropertyFunctionIsUsed = true;
|
this.lookupPropertyFunctionIsUsed = true;
|
||||||
return ['lookupProperty(', parent, ',', JSON.stringify(name), ')'];
|
return ['lookupProperty(', parent, ',', JSON.stringify(name), ')'];
|
||||||
},
|
},
|
||||||
|
|
||||||
lookupPropertyFunctionIsUsed: false,
|
lookupPropertyFunctionIsUsed: false,
|
||||||
|
|
||||||
compile: function(environment, options, context, asObject) {
|
compile: function (environment, options, context, asObject) {
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.precompile = !asObject;
|
this.precompile = !asObject;
|
||||||
@@ -71,7 +71,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
this.context = context || {
|
this.context = context || {
|
||||||
decorators: [],
|
decorators: [],
|
||||||
programs: [],
|
programs: [],
|
||||||
environments: []
|
environments: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
this.preamble();
|
this.preamble();
|
||||||
@@ -123,7 +123,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
this.decorators.prepend([
|
this.decorators.prepend([
|
||||||
'var decorators = container.decorators, ',
|
'var decorators = container.decorators, ',
|
||||||
this.lookupPropertyFunctionVarDeclaration(),
|
this.lookupPropertyFunctionVarDeclaration(),
|
||||||
';\n'
|
';\n',
|
||||||
]);
|
]);
|
||||||
this.decorators.push('return fn;');
|
this.decorators.push('return fn;');
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
'data',
|
'data',
|
||||||
'blockParams',
|
'blockParams',
|
||||||
'depths',
|
'depths',
|
||||||
this.decorators.merge()
|
this.decorators.merge(),
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
this.decorators.prepend(
|
this.decorators.prepend(
|
||||||
@@ -154,7 +154,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
if (!this.isChild) {
|
if (!this.isChild) {
|
||||||
let ret = {
|
let ret = {
|
||||||
compiler: this.compilerInfo(),
|
compiler: this.compilerInfo(),
|
||||||
main: fn
|
main: fn,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.decorators) {
|
if (this.decorators) {
|
||||||
@@ -211,7 +211,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
preamble: function() {
|
preamble: function () {
|
||||||
// track the last context pushed into place to allow skipping the
|
// track the last context pushed into place to allow skipping the
|
||||||
// getContext opcode when it would be a noop
|
// getContext opcode when it would be a noop
|
||||||
this.lastContext = 0;
|
this.lastContext = 0;
|
||||||
@@ -219,7 +219,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
this.decorators = new CodeGen(this.options.srcName);
|
this.decorators = new CodeGen(this.options.srcName);
|
||||||
},
|
},
|
||||||
|
|
||||||
createFunctionContext: function(asObject) {
|
createFunctionContext: function (asObject) {
|
||||||
let varDeclarations = '';
|
let varDeclarations = '';
|
||||||
|
|
||||||
let locals = this.stackVars.concat(this.registers.list);
|
let locals = this.stackVars.concat(this.registers.list);
|
||||||
@@ -234,7 +234,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// aliases will not be used, but this case is already being run on the client and
|
// aliases will not be used, but this case is already being run on the client and
|
||||||
// we aren't concern about minimizing the template size.
|
// we aren't concern about minimizing the template size.
|
||||||
let aliasCount = 0;
|
let aliasCount = 0;
|
||||||
Object.keys(this.aliases).forEach(alias => {
|
Object.keys(this.aliases).forEach((alias) => {
|
||||||
let node = this.aliases[alias];
|
let node = this.aliases[alias];
|
||||||
if (node.children && node.referenceCount > 1) {
|
if (node.children && node.referenceCount > 1) {
|
||||||
varDeclarations += ', alias' + ++aliasCount + '=' + alias;
|
varDeclarations += ', alias' + ++aliasCount + '=' + alias;
|
||||||
@@ -268,18 +268,18 @@ JavaScriptCompiler.prototype = {
|
|||||||
params.join(','),
|
params.join(','),
|
||||||
') {\n ',
|
') {\n ',
|
||||||
source,
|
source,
|
||||||
'}'
|
'}',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mergeSource: function(varDeclarations) {
|
mergeSource: function (varDeclarations) {
|
||||||
let isSimple = this.environment.isSimple,
|
let isSimple = this.environment.isSimple,
|
||||||
appendOnly = !this.forceBuffer,
|
appendOnly = !this.forceBuffer,
|
||||||
appendFirst,
|
appendFirst,
|
||||||
sourceSeen,
|
sourceSeen,
|
||||||
bufferStart,
|
bufferStart,
|
||||||
bufferEnd;
|
bufferEnd;
|
||||||
this.source.each(line => {
|
this.source.each((line) => {
|
||||||
if (line.appendToBuffer) {
|
if (line.appendToBuffer) {
|
||||||
if (bufferStart) {
|
if (bufferStart) {
|
||||||
line.prepend(' + ');
|
line.prepend(' + ');
|
||||||
@@ -333,7 +333,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
return this.source.merge();
|
return this.source.merge();
|
||||||
},
|
},
|
||||||
|
|
||||||
lookupPropertyFunctionVarDeclaration: function() {
|
lookupPropertyFunctionVarDeclaration: function () {
|
||||||
return `
|
return `
|
||||||
lookupProperty = container.lookupProperty || function(parent, propertyName) {
|
lookupProperty = container.lookupProperty || function(parent, propertyName) {
|
||||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||||
@@ -353,7 +353,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
|
// `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
|
||||||
// replace it on the stack with the result of properly
|
// replace it on the stack with the result of properly
|
||||||
// invoking blockHelperMissing.
|
// invoking blockHelperMissing.
|
||||||
blockValue: function(name) {
|
blockValue: function (name) {
|
||||||
let blockHelperMissing = this.aliasable(
|
let blockHelperMissing = this.aliasable(
|
||||||
'container.hooks.blockHelperMissing'
|
'container.hooks.blockHelperMissing'
|
||||||
),
|
),
|
||||||
@@ -372,7 +372,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// Compiler value, before: lastHelper=value of last found helper, if any
|
// Compiler value, before: lastHelper=value of last found helper, if any
|
||||||
// On stack, after, if no lastHelper: same as [blockValue]
|
// On stack, after, if no lastHelper: same as [blockValue]
|
||||||
// On stack, after, if lastHelper: value
|
// On stack, after, if lastHelper: value
|
||||||
ambiguousBlockValue: function() {
|
ambiguousBlockValue: function () {
|
||||||
// We're being a bit cheeky and reusing the options value from the prior exec
|
// We're being a bit cheeky and reusing the options value from the prior exec
|
||||||
let blockHelperMissing = this.aliasable(
|
let blockHelperMissing = this.aliasable(
|
||||||
'container.hooks.blockHelperMissing'
|
'container.hooks.blockHelperMissing'
|
||||||
@@ -392,7 +392,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
current,
|
current,
|
||||||
' = ',
|
' = ',
|
||||||
this.source.functionCall(blockHelperMissing, 'call', params),
|
this.source.functionCall(blockHelperMissing, 'call', params),
|
||||||
'}'
|
'}',
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -402,7 +402,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// On stack, after: ...
|
// On stack, after: ...
|
||||||
//
|
//
|
||||||
// Appends the string value of `content` to the current buffer
|
// Appends the string value of `content` to the current buffer
|
||||||
appendContent: function(content) {
|
appendContent: function (content) {
|
||||||
if (this.pendingContent) {
|
if (this.pendingContent) {
|
||||||
content = this.pendingContent + content;
|
content = this.pendingContent + content;
|
||||||
} else {
|
} else {
|
||||||
@@ -421,9 +421,9 @@ JavaScriptCompiler.prototype = {
|
|||||||
//
|
//
|
||||||
// If `value` is truthy, or 0, it is coerced into a string and appended
|
// If `value` is truthy, or 0, it is coerced into a string and appended
|
||||||
// Otherwise, the empty string is appended
|
// Otherwise, the empty string is appended
|
||||||
append: function() {
|
append: function () {
|
||||||
if (this.isInline()) {
|
if (this.isInline()) {
|
||||||
this.replaceStack(current => [' != null ? ', current, ' : ""']);
|
this.replaceStack((current) => [' != null ? ', current, ' : ""']);
|
||||||
|
|
||||||
this.pushSource(this.appendToBuffer(this.popStack()));
|
this.pushSource(this.appendToBuffer(this.popStack()));
|
||||||
} else {
|
} else {
|
||||||
@@ -433,13 +433,13 @@ JavaScriptCompiler.prototype = {
|
|||||||
local,
|
local,
|
||||||
' != null) { ',
|
' != null) { ',
|
||||||
this.appendToBuffer(local, undefined, true),
|
this.appendToBuffer(local, undefined, true),
|
||||||
' }'
|
' }',
|
||||||
]);
|
]);
|
||||||
if (this.environment.isSimple) {
|
if (this.environment.isSimple) {
|
||||||
this.pushSource([
|
this.pushSource([
|
||||||
'else { ',
|
'else { ',
|
||||||
this.appendToBuffer("''", undefined, true),
|
this.appendToBuffer("''", undefined, true),
|
||||||
' }'
|
' }',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -451,13 +451,13 @@ JavaScriptCompiler.prototype = {
|
|||||||
// On stack, after: ...
|
// On stack, after: ...
|
||||||
//
|
//
|
||||||
// Escape `value` and append it to the buffer
|
// Escape `value` and append it to the buffer
|
||||||
appendEscaped: function() {
|
appendEscaped: function () {
|
||||||
this.pushSource(
|
this.pushSource(
|
||||||
this.appendToBuffer([
|
this.appendToBuffer([
|
||||||
this.aliasable('container.escapeExpression'),
|
this.aliasable('container.escapeExpression'),
|
||||||
'(',
|
'(',
|
||||||
this.popStack(),
|
this.popStack(),
|
||||||
')'
|
')',
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -469,7 +469,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// Compiler value, after: lastContext=depth
|
// Compiler value, after: lastContext=depth
|
||||||
//
|
//
|
||||||
// Set the value of the `lastContext` compiler value to the depth
|
// Set the value of the `lastContext` compiler value to the depth
|
||||||
getContext: function(depth) {
|
getContext: function (depth) {
|
||||||
this.lastContext = depth;
|
this.lastContext = depth;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -479,7 +479,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// On stack, after: currentContext, ...
|
// On stack, after: currentContext, ...
|
||||||
//
|
//
|
||||||
// Pushes the value of the current context onto the stack.
|
// Pushes the value of the current context onto the stack.
|
||||||
pushContext: function() {
|
pushContext: function () {
|
||||||
this.pushStackLiteral(this.contextName(this.lastContext));
|
this.pushStackLiteral(this.contextName(this.lastContext));
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -490,7 +490,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
//
|
//
|
||||||
// Looks up the value of `name` on the current context and pushes
|
// Looks up the value of `name` on the current context and pushes
|
||||||
// it onto the stack.
|
// it onto the stack.
|
||||||
lookupOnContext: function(parts, falsy, strict, scoped) {
|
lookupOnContext: function (parts, falsy, strict, scoped) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
|
||||||
if (!scoped && this.options.compat && !this.lastContext) {
|
if (!scoped && this.options.compat && !this.lastContext) {
|
||||||
@@ -511,7 +511,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
//
|
//
|
||||||
// Looks up the value of `parts` on the given block param and pushes
|
// Looks up the value of `parts` on the given block param and pushes
|
||||||
// it onto the stack.
|
// it onto the stack.
|
||||||
lookupBlockParam: function(blockParamId, parts) {
|
lookupBlockParam: function (blockParamId, parts) {
|
||||||
this.useBlockParams = true;
|
this.useBlockParams = true;
|
||||||
|
|
||||||
this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
|
this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
|
||||||
@@ -524,7 +524,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// On stack, after: data, ...
|
// On stack, after: data, ...
|
||||||
//
|
//
|
||||||
// Push the data lookup operator
|
// Push the data lookup operator
|
||||||
lookupData: function(depth, parts, strict) {
|
lookupData: function (depth, parts, strict) {
|
||||||
if (!depth) {
|
if (!depth) {
|
||||||
this.pushStackLiteral('data');
|
this.pushStackLiteral('data');
|
||||||
} else {
|
} else {
|
||||||
@@ -534,7 +534,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
this.resolvePath('data', parts, 0, true, strict);
|
this.resolvePath('data', parts, 0, true, strict);
|
||||||
},
|
},
|
||||||
|
|
||||||
resolvePath: function(type, parts, i, falsy, strict) {
|
resolvePath: function (type, parts, i, falsy, strict) {
|
||||||
if (this.options.strict || this.options.assumeObjects) {
|
if (this.options.strict || this.options.assumeObjects) {
|
||||||
this.push(
|
this.push(
|
||||||
strictLookup(this.options.strict && strict, this, parts, i, type)
|
strictLookup(this.options.strict && strict, this, parts, i, type)
|
||||||
@@ -545,7 +545,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
let len = parts.length;
|
let len = parts.length;
|
||||||
for (; i < len; i++) {
|
for (; i < len; i++) {
|
||||||
/* eslint-disable no-loop-func */
|
/* eslint-disable no-loop-func */
|
||||||
this.replaceStack(current => {
|
this.replaceStack((current) => {
|
||||||
let lookup = this.nameLookup(current, parts[i], type);
|
let lookup = this.nameLookup(current, parts[i], type);
|
||||||
// We want to ensure that zero and false are handled properly if the context (falsy flag)
|
// We want to ensure that zero and false are handled properly if the context (falsy flag)
|
||||||
// needs to have the special handling for these values.
|
// needs to have the special handling for these values.
|
||||||
@@ -567,27 +567,27 @@ JavaScriptCompiler.prototype = {
|
|||||||
//
|
//
|
||||||
// If the `value` is a lambda, replace it on the stack by
|
// If the `value` is a lambda, replace it on the stack by
|
||||||
// the return value of the lambda
|
// the return value of the lambda
|
||||||
resolvePossibleLambda: function() {
|
resolvePossibleLambda: function () {
|
||||||
this.push([
|
this.push([
|
||||||
this.aliasable('container.lambda'),
|
this.aliasable('container.lambda'),
|
||||||
'(',
|
'(',
|
||||||
this.popStack(),
|
this.popStack(),
|
||||||
', ',
|
', ',
|
||||||
this.contextName(0),
|
this.contextName(0),
|
||||||
')'
|
')',
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
emptyHash: function(omitEmpty) {
|
emptyHash: function (omitEmpty) {
|
||||||
this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');
|
this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');
|
||||||
},
|
},
|
||||||
pushHash: function() {
|
pushHash: function () {
|
||||||
if (this.hash) {
|
if (this.hash) {
|
||||||
this.hashes.push(this.hash);
|
this.hashes.push(this.hash);
|
||||||
}
|
}
|
||||||
this.hash = { values: {} };
|
this.hash = { values: {} };
|
||||||
},
|
},
|
||||||
popHash: function() {
|
popHash: function () {
|
||||||
let hash = this.hash;
|
let hash = this.hash;
|
||||||
this.hash = this.hashes.pop();
|
this.hash = this.hashes.pop();
|
||||||
|
|
||||||
@@ -600,7 +600,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// On stack, after: quotedString(string), ...
|
// On stack, after: quotedString(string), ...
|
||||||
//
|
//
|
||||||
// Push a quoted version of `string` onto the stack
|
// Push a quoted version of `string` onto the stack
|
||||||
pushString: function(string) {
|
pushString: function (string) {
|
||||||
this.pushStackLiteral(this.quotedString(string));
|
this.pushStackLiteral(this.quotedString(string));
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -612,7 +612,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// Pushes a value onto the stack. This operation prevents
|
// Pushes a value onto the stack. This operation prevents
|
||||||
// the compiler from creating a temporary variable to hold
|
// the compiler from creating a temporary variable to hold
|
||||||
// it.
|
// it.
|
||||||
pushLiteral: function(value) {
|
pushLiteral: function (value) {
|
||||||
this.pushStackLiteral(value);
|
this.pushStackLiteral(value);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -624,7 +624,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// Push a program expression onto the stack. This takes
|
// Push a program expression onto the stack. This takes
|
||||||
// a compile-time guid and converts it into a runtime-accessible
|
// a compile-time guid and converts it into a runtime-accessible
|
||||||
// expression.
|
// expression.
|
||||||
pushProgram: function(guid) {
|
pushProgram: function (guid) {
|
||||||
if (guid != null) {
|
if (guid != null) {
|
||||||
this.pushStackLiteral(this.programExpression(guid));
|
this.pushStackLiteral(this.programExpression(guid));
|
||||||
} else {
|
} else {
|
||||||
@@ -649,9 +649,9 @@ JavaScriptCompiler.prototype = {
|
|||||||
'fn',
|
'fn',
|
||||||
'props',
|
'props',
|
||||||
'container',
|
'container',
|
||||||
options
|
options,
|
||||||
]),
|
]),
|
||||||
' || fn;'
|
' || fn;',
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -664,7 +664,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// and pushes the helper's return value onto the stack.
|
// and pushes the helper's return value onto the stack.
|
||||||
//
|
//
|
||||||
// If the helper is not found, `helperMissing` is called.
|
// If the helper is not found, `helperMissing` is called.
|
||||||
invokeHelper: function(paramSize, name, isSimple) {
|
invokeHelper: function (paramSize, name, isSimple) {
|
||||||
let nonHelper = this.popStack(),
|
let nonHelper = this.popStack(),
|
||||||
helper = this.setupHelper(paramSize, name);
|
helper = this.setupHelper(paramSize, name);
|
||||||
|
|
||||||
@@ -685,7 +685,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
let functionLookupCode = [
|
let functionLookupCode = [
|
||||||
'(',
|
'(',
|
||||||
this.itemsSeparatedBy(possibleFunctionCalls, '||'),
|
this.itemsSeparatedBy(possibleFunctionCalls, '||'),
|
||||||
')'
|
')',
|
||||||
];
|
];
|
||||||
let functionCall = this.source.functionCall(
|
let functionCall = this.source.functionCall(
|
||||||
functionLookupCode,
|
functionLookupCode,
|
||||||
@@ -695,7 +695,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
this.push(functionCall);
|
this.push(functionCall);
|
||||||
},
|
},
|
||||||
|
|
||||||
itemsSeparatedBy: function(items, separator) {
|
itemsSeparatedBy: function (items, separator) {
|
||||||
let result = [];
|
let result = [];
|
||||||
result.push(items[0]);
|
result.push(items[0]);
|
||||||
for (let i = 1; i < items.length; i++) {
|
for (let i = 1; i < items.length; i++) {
|
||||||
@@ -710,7 +710,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
//
|
//
|
||||||
// This operation is used when the helper is known to exist,
|
// This operation is used when the helper is known to exist,
|
||||||
// so a `helperMissing` fallback is not required.
|
// so a `helperMissing` fallback is not required.
|
||||||
invokeKnownHelper: function(paramSize, name) {
|
invokeKnownHelper: function (paramSize, name) {
|
||||||
let helper = this.setupHelper(paramSize, name);
|
let helper = this.setupHelper(paramSize, name);
|
||||||
this.push(this.source.functionCall(helper.name, 'call', helper.callParams));
|
this.push(this.source.functionCall(helper.name, 'call', helper.callParams));
|
||||||
},
|
},
|
||||||
@@ -727,7 +727,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// This operation emits more code than the other options,
|
// This operation emits more code than the other options,
|
||||||
// and can be avoided by passing the `knownHelpers` and
|
// and can be avoided by passing the `knownHelpers` and
|
||||||
// `knownHelpersOnly` flags at compile-time.
|
// `knownHelpersOnly` flags at compile-time.
|
||||||
invokeAmbiguous: function(name, helperCall) {
|
invokeAmbiguous: function (name, helperCall) {
|
||||||
this.useRegister('helper');
|
this.useRegister('helper');
|
||||||
|
|
||||||
let nonHelper = this.popStack();
|
let nonHelper = this.popStack();
|
||||||
@@ -759,7 +759,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
this.aliasable('"function"'),
|
this.aliasable('"function"'),
|
||||||
' ? ',
|
' ? ',
|
||||||
this.source.functionCall('helper', 'call', helper.callParams),
|
this.source.functionCall('helper', 'call', helper.callParams),
|
||||||
' : helper))'
|
' : helper))',
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -770,7 +770,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
//
|
//
|
||||||
// This operation pops off a context, invokes a partial with that context,
|
// This operation pops off a context, invokes a partial with that context,
|
||||||
// and pushes the result of the invocation back.
|
// and pushes the result of the invocation back.
|
||||||
invokePartial: function(isDynamic, name, indent) {
|
invokePartial: function (isDynamic, name, indent) {
|
||||||
let params = [],
|
let params = [],
|
||||||
options = this.setupParams(name, 1, params);
|
options = this.setupParams(name, 1, params);
|
||||||
|
|
||||||
@@ -807,7 +807,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// On stack, after: ..., hash, ...
|
// On stack, after: ..., hash, ...
|
||||||
//
|
//
|
||||||
// Pops a value off the stack and assigns it to the current hash
|
// Pops a value off the stack and assigns it to the current hash
|
||||||
assignToHash: function(key) {
|
assignToHash: function (key) {
|
||||||
this.hash.values[key] = this.popStack();
|
this.hash.values[key] = this.popStack();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -815,7 +815,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
|
|
||||||
compiler: JavaScriptCompiler,
|
compiler: JavaScriptCompiler,
|
||||||
|
|
||||||
compileChildren: function(environment, options) {
|
compileChildren: function (environment, options) {
|
||||||
let children = environment.children,
|
let children = environment.children,
|
||||||
child,
|
child,
|
||||||
compiler;
|
compiler;
|
||||||
@@ -853,7 +853,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
matchExistingProgram: function(child) {
|
matchExistingProgram: function (child) {
|
||||||
for (let i = 0, len = this.context.environments.length; i < len; i++) {
|
for (let i = 0, len = this.context.environments.length; i < len; i++) {
|
||||||
let environment = this.context.environments[i];
|
let environment = this.context.environments[i];
|
||||||
if (environment && environment.equals(child)) {
|
if (environment && environment.equals(child)) {
|
||||||
@@ -862,7 +862,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
programExpression: function(guid) {
|
programExpression: function (guid) {
|
||||||
let child = this.environment.children[guid],
|
let child = this.environment.children[guid],
|
||||||
programParams = [child.index, 'data', child.blockParams];
|
programParams = [child.index, 'data', child.blockParams];
|
||||||
|
|
||||||
@@ -876,14 +876,14 @@ JavaScriptCompiler.prototype = {
|
|||||||
return 'container.program(' + programParams.join(', ') + ')';
|
return 'container.program(' + programParams.join(', ') + ')';
|
||||||
},
|
},
|
||||||
|
|
||||||
useRegister: function(name) {
|
useRegister: function (name) {
|
||||||
if (!this.registers[name]) {
|
if (!this.registers[name]) {
|
||||||
this.registers[name] = true;
|
this.registers[name] = true;
|
||||||
this.registers.list.push(name);
|
this.registers.list.push(name);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
push: function(expr) {
|
push: function (expr) {
|
||||||
if (!(expr instanceof Literal)) {
|
if (!(expr instanceof Literal)) {
|
||||||
expr = this.source.wrap(expr);
|
expr = this.source.wrap(expr);
|
||||||
}
|
}
|
||||||
@@ -892,11 +892,11 @@ JavaScriptCompiler.prototype = {
|
|||||||
return expr;
|
return expr;
|
||||||
},
|
},
|
||||||
|
|
||||||
pushStackLiteral: function(item) {
|
pushStackLiteral: function (item) {
|
||||||
this.push(new Literal(item));
|
this.push(new Literal(item));
|
||||||
},
|
},
|
||||||
|
|
||||||
pushSource: function(source) {
|
pushSource: function (source) {
|
||||||
if (this.pendingContent) {
|
if (this.pendingContent) {
|
||||||
this.source.push(
|
this.source.push(
|
||||||
this.appendToBuffer(
|
this.appendToBuffer(
|
||||||
@@ -912,7 +912,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
replaceStack: function(callback) {
|
replaceStack: function (callback) {
|
||||||
let prefix = ['('],
|
let prefix = ['('],
|
||||||
stack,
|
stack,
|
||||||
createdStack,
|
createdStack,
|
||||||
@@ -951,17 +951,17 @@ JavaScriptCompiler.prototype = {
|
|||||||
this.push(prefix.concat(item, ')'));
|
this.push(prefix.concat(item, ')'));
|
||||||
},
|
},
|
||||||
|
|
||||||
incrStack: function() {
|
incrStack: function () {
|
||||||
this.stackSlot++;
|
this.stackSlot++;
|
||||||
if (this.stackSlot > this.stackVars.length) {
|
if (this.stackSlot > this.stackVars.length) {
|
||||||
this.stackVars.push('stack' + this.stackSlot);
|
this.stackVars.push('stack' + this.stackSlot);
|
||||||
}
|
}
|
||||||
return this.topStackName();
|
return this.topStackName();
|
||||||
},
|
},
|
||||||
topStackName: function() {
|
topStackName: function () {
|
||||||
return 'stack' + this.stackSlot;
|
return 'stack' + this.stackSlot;
|
||||||
},
|
},
|
||||||
flushInline: function() {
|
flushInline: function () {
|
||||||
let inlineStack = this.inlineStack;
|
let inlineStack = this.inlineStack;
|
||||||
this.inlineStack = [];
|
this.inlineStack = [];
|
||||||
for (let i = 0, len = inlineStack.length; i < len; i++) {
|
for (let i = 0, len = inlineStack.length; i < len; i++) {
|
||||||
@@ -976,11 +976,11 @@ JavaScriptCompiler.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isInline: function() {
|
isInline: function () {
|
||||||
return this.inlineStack.length;
|
return this.inlineStack.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
popStack: function(wrapped) {
|
popStack: function (wrapped) {
|
||||||
let inline = this.isInline(),
|
let inline = this.isInline(),
|
||||||
item = (inline ? this.inlineStack : this.compileStack).pop();
|
item = (inline ? this.inlineStack : this.compileStack).pop();
|
||||||
|
|
||||||
@@ -998,7 +998,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
topStack: function() {
|
topStack: function () {
|
||||||
let stack = this.isInline() ? this.inlineStack : this.compileStack,
|
let stack = this.isInline() ? this.inlineStack : this.compileStack,
|
||||||
item = stack[stack.length - 1];
|
item = stack[stack.length - 1];
|
||||||
|
|
||||||
@@ -1010,7 +1010,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
contextName: function(context) {
|
contextName: function (context) {
|
||||||
if (this.useDepths && context) {
|
if (this.useDepths && context) {
|
||||||
return 'depths[' + context + ']';
|
return 'depths[' + context + ']';
|
||||||
} else {
|
} else {
|
||||||
@@ -1018,15 +1018,15 @@ JavaScriptCompiler.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
quotedString: function(str) {
|
quotedString: function (str) {
|
||||||
return this.source.quotedString(str);
|
return this.source.quotedString(str);
|
||||||
},
|
},
|
||||||
|
|
||||||
objectLiteral: function(obj) {
|
objectLiteral: function (obj) {
|
||||||
return this.source.objectLiteral(obj);
|
return this.source.objectLiteral(obj);
|
||||||
},
|
},
|
||||||
|
|
||||||
aliasable: function(name) {
|
aliasable: function (name) {
|
||||||
let ret = this.aliases[name];
|
let ret = this.aliases[name];
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret.referenceCount++;
|
ret.referenceCount++;
|
||||||
@@ -1040,7 +1040,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
|
||||||
setupHelper: function(paramSize, name, blockHelper) {
|
setupHelper: function (paramSize, name, blockHelper) {
|
||||||
let params = [],
|
let params = [],
|
||||||
paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
|
paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
|
||||||
let foundHelper = this.nameLookup('helpers', name, 'helper'),
|
let foundHelper = this.nameLookup('helpers', name, 'helper'),
|
||||||
@@ -1054,11 +1054,11 @@ JavaScriptCompiler.prototype = {
|
|||||||
params: params,
|
params: params,
|
||||||
paramsInit: paramsInit,
|
paramsInit: paramsInit,
|
||||||
name: foundHelper,
|
name: foundHelper,
|
||||||
callParams: [callContext].concat(params)
|
callParams: [callContext].concat(params),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
setupParams: function(helper, paramSize, params) {
|
setupParams: function (helper, paramSize, params) {
|
||||||
let options = {},
|
let options = {},
|
||||||
objectArgs = !params,
|
objectArgs = !params,
|
||||||
param;
|
param;
|
||||||
@@ -1101,7 +1101,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
return options;
|
return options;
|
||||||
},
|
},
|
||||||
|
|
||||||
setupHelperArgs: function(helper, paramSize, params, useRegister) {
|
setupHelperArgs: function (helper, paramSize, params, useRegister) {
|
||||||
let options = this.setupParams(helper, paramSize, params);
|
let options = this.setupParams(helper, paramSize, params);
|
||||||
options.loc = JSON.stringify(this.source.currentLocation);
|
options.loc = JSON.stringify(this.source.currentLocation);
|
||||||
options = this.objectLiteral(options);
|
options = this.objectLiteral(options);
|
||||||
@@ -1115,10 +1115,10 @@ JavaScriptCompiler.prototype = {
|
|||||||
} else {
|
} else {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function () {
|
||||||
const reservedWords = (
|
const reservedWords = (
|
||||||
'break else new var' +
|
'break else new var' +
|
||||||
' case finally return void' +
|
' case finally return void' +
|
||||||
@@ -1148,7 +1148,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
/**
|
/**
|
||||||
* @deprecated May be removed in the next major version
|
* @deprecated May be removed in the next major version
|
||||||
*/
|
*/
|
||||||
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
|
JavaScriptCompiler.isValidJavaScriptVariableName = function (name) {
|
||||||
return (
|
return (
|
||||||
!JavaScriptCompiler.RESERVED_WORDS[name] &&
|
!JavaScriptCompiler.RESERVED_WORDS[name] &&
|
||||||
/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)
|
/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)
|
||||||
@@ -1175,7 +1175,7 @@ function strictLookup(requireTerminal, compiler, parts, i, type) {
|
|||||||
compiler.quotedString(parts[i]),
|
compiler.quotedString(parts[i]),
|
||||||
', ',
|
', ',
|
||||||
JSON.stringify(compiler.source.currentLocation),
|
JSON.stringify(compiler.source.currentLocation),
|
||||||
' )'
|
' )',
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
return stack;
|
return stack;
|
||||||
|
|||||||
@@ -1,22 +1,25 @@
|
|||||||
import { extend } from '../utils';
|
import { extend } from '../utils';
|
||||||
|
|
||||||
export default function(instance) {
|
export default function (instance) {
|
||||||
instance.registerDecorator('inline', function(fn, props, container, options) {
|
instance.registerDecorator(
|
||||||
let ret = fn;
|
'inline',
|
||||||
if (!props.partials) {
|
function (fn, props, container, options) {
|
||||||
props.partials = {};
|
let ret = fn;
|
||||||
ret = function(context, options) {
|
if (!props.partials) {
|
||||||
// Create a new partials stack frame prior to exec.
|
props.partials = {};
|
||||||
let original = container.partials;
|
ret = function (context, options) {
|
||||||
container.partials = extend({}, original, props.partials);
|
// Create a new partials stack frame prior to exec.
|
||||||
let ret = fn(context, options);
|
let original = container.partials;
|
||||||
container.partials = original;
|
container.partials = extend({}, original, props.partials);
|
||||||
return ret;
|
let ret = fn(context, options);
|
||||||
};
|
container.partials = original;
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
props.partials[options.args[0]] = options.fn;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
props.partials[options.args[0]] = options.fn;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { isArray } from '../utils';
|
import { isArray } from '../utils';
|
||||||
|
|
||||||
export default function(instance) {
|
export default function (instance) {
|
||||||
instance.registerHelper('blockHelperMissing', function(context, options) {
|
instance.registerHelper('blockHelperMissing', function (context, options) {
|
||||||
let inverse = options.inverse,
|
let inverse = options.inverse,
|
||||||
fn = options.fn;
|
fn = options.fn;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Exception } from '@handlebars/parser';
|
import { Exception } from '@handlebars/parser';
|
||||||
import { createFrame, isArray, isFunction } from '../utils';
|
import { createFrame, isArray, isFunction } from '../utils';
|
||||||
|
|
||||||
export default function(instance) {
|
export default function (instance) {
|
||||||
instance.registerHelper('each', function(context, options) {
|
instance.registerHelper('each', function (context, options) {
|
||||||
if (!options) {
|
if (!options) {
|
||||||
throw new Exception('Must pass iterator to #each');
|
throw new Exception('Must pass iterator to #each');
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ export default function(instance) {
|
|||||||
ret +
|
ret +
|
||||||
fn(context[field], {
|
fn(context[field], {
|
||||||
data: data,
|
data: data,
|
||||||
blockParams: [context[field], field]
|
blockParams: [context[field], field],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ export default function(instance) {
|
|||||||
} else {
|
} else {
|
||||||
let priorKey;
|
let priorKey;
|
||||||
|
|
||||||
Object.keys(context).forEach(key => {
|
Object.keys(context).forEach((key) => {
|
||||||
// We're running the iterations one step out of sync so we can detect
|
// We're running the iterations one step out of sync so we can detect
|
||||||
// the last iteration without have to scan the object twice and create
|
// the last iteration without have to scan the object twice and create
|
||||||
// an intermediate keys array.
|
// an intermediate keys array.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Exception } from '@handlebars/parser';
|
import { Exception } from '@handlebars/parser';
|
||||||
|
|
||||||
export default function(instance) {
|
export default function (instance) {
|
||||||
instance.registerHelper('helperMissing', function(/* [args, ]options */) {
|
instance.registerHelper('helperMissing', function (/* [args, ]options */) {
|
||||||
if (arguments.length === 1) {
|
if (arguments.length === 1) {
|
||||||
// A missing field in a {{foo}} construct.
|
// A missing field in a {{foo}} construct.
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Exception } from '@handlebars/parser';
|
import { Exception } from '@handlebars/parser';
|
||||||
import { isEmpty, isFunction } from '../utils';
|
import { isEmpty, isFunction } from '../utils';
|
||||||
|
|
||||||
export default function(instance) {
|
export default function (instance) {
|
||||||
instance.registerHelper('if', function(conditional, options) {
|
instance.registerHelper('if', function (conditional, options) {
|
||||||
if (arguments.length != 2) {
|
if (arguments.length != 2) {
|
||||||
throw new Exception('#if requires exactly one argument');
|
throw new Exception('#if requires exactly one argument');
|
||||||
}
|
}
|
||||||
@@ -20,14 +20,14 @@ export default function(instance) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
instance.registerHelper('unless', function(conditional, options) {
|
instance.registerHelper('unless', function (conditional, options) {
|
||||||
if (arguments.length != 2) {
|
if (arguments.length != 2) {
|
||||||
throw new Exception('#unless requires exactly one argument');
|
throw new Exception('#unless requires exactly one argument');
|
||||||
}
|
}
|
||||||
return instance.helpers['if'].call(this, conditional, {
|
return instance.helpers['if'].call(this, conditional, {
|
||||||
fn: options.inverse,
|
fn: options.inverse,
|
||||||
inverse: options.fn,
|
inverse: options.fn,
|
||||||
hash: options.hash
|
hash: options.hash,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default function(instance) {
|
export default function (instance) {
|
||||||
instance.registerHelper('log', function(/* message, options */) {
|
instance.registerHelper('log', function (/* message, options */) {
|
||||||
let args = [undefined],
|
let args = [undefined],
|
||||||
options = arguments[arguments.length - 1];
|
options = arguments[arguments.length - 1];
|
||||||
for (let i = 0; i < arguments.length - 1; i++) {
|
for (let i = 0; i < arguments.length - 1; i++) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default function(instance) {
|
export default function (instance) {
|
||||||
instance.registerHelper('lookup', function(obj, field, options) {
|
instance.registerHelper('lookup', function (obj, field, options) {
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
// Note for 5.0: Change to "obj == null" in 5.0
|
// Note for 5.0: Change to "obj == null" in 5.0
|
||||||
return obj;
|
return obj;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Exception } from '@handlebars/parser';
|
import { Exception } from '@handlebars/parser';
|
||||||
import { isEmpty, isFunction } from '../utils';
|
import { isEmpty, isFunction } from '../utils';
|
||||||
|
|
||||||
export default function(instance) {
|
export default function (instance) {
|
||||||
instance.registerHelper('with', function(context, options) {
|
instance.registerHelper('with', function (context, options) {
|
||||||
if (arguments.length != 2) {
|
if (arguments.length != 2) {
|
||||||
throw new Exception('#with requires exactly one argument');
|
throw new Exception('#with requires exactly one argument');
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ export default function(instance) {
|
|||||||
|
|
||||||
return fn(context, {
|
return fn(context, {
|
||||||
data: data,
|
data: data,
|
||||||
blockParams: [context]
|
blockParams: [context],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return options.inverse(this);
|
return options.inverse(this);
|
||||||
|
|||||||
@@ -20,15 +20,15 @@ export function createProtoAccessControl(runtimeOptions) {
|
|||||||
defaultPropertyWhiteList,
|
defaultPropertyWhiteList,
|
||||||
runtimeOptions.allowedProtoProperties
|
runtimeOptions.allowedProtoProperties
|
||||||
),
|
),
|
||||||
defaultValue: runtimeOptions.allowProtoPropertiesByDefault
|
defaultValue: runtimeOptions.allowProtoPropertiesByDefault,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
whitelist: createNewLookupObject(
|
whitelist: createNewLookupObject(
|
||||||
defaultMethodWhiteList,
|
defaultMethodWhiteList,
|
||||||
runtimeOptions.allowedProtoMethods
|
runtimeOptions.allowedProtoMethods
|
||||||
),
|
),
|
||||||
defaultValue: runtimeOptions.allowProtoMethodsByDefault
|
defaultValue: runtimeOptions.allowProtoMethodsByDefault,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ function logUnexpectedPropertyAccessOnce(propertyName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function resetLoggedProperties() {
|
export function resetLoggedProperties() {
|
||||||
Object.keys(loggedProperties).forEach(propertyName => {
|
Object.keys(loggedProperties).forEach((propertyName) => {
|
||||||
delete loggedProperties[propertyName];
|
delete loggedProperties[propertyName];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export function wrapHelper(helper, transformOptionsFn) {
|
|||||||
// We try to make the wrapper least-invasive by not wrapping it, if the helper is not a function.
|
// We try to make the wrapper least-invasive by not wrapping it, if the helper is not a function.
|
||||||
return helper;
|
return helper;
|
||||||
}
|
}
|
||||||
let wrapper = function(/* dynamic arguments */) {
|
let wrapper = function (/* dynamic arguments */) {
|
||||||
const options = arguments[arguments.length - 1];
|
const options = arguments[arguments.length - 1];
|
||||||
arguments[arguments.length - 1] = transformOptionsFn(options);
|
arguments[arguments.length - 1] = transformOptionsFn(options);
|
||||||
return helper.apply(this, arguments);
|
return helper.apply(this, arguments);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ let logger = {
|
|||||||
level: 'info',
|
level: 'info',
|
||||||
|
|
||||||
// Maps a given level value to the `methodMap` indexes above.
|
// Maps a given level value to the `methodMap` indexes above.
|
||||||
lookupLevel: function(level) {
|
lookupLevel: function (level) {
|
||||||
if (typeof level === 'string') {
|
if (typeof level === 'string') {
|
||||||
let levelMap = indexOf(logger.methodMap, level.toLowerCase());
|
let levelMap = indexOf(logger.methodMap, level.toLowerCase());
|
||||||
if (levelMap >= 0) {
|
if (levelMap >= 0) {
|
||||||
@@ -19,7 +19,7 @@ let logger = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Can be overridden in the host environment
|
// Can be overridden in the host environment
|
||||||
log: function(level, ...message) {
|
log: function (level, ...message) {
|
||||||
level = logger.lookupLevel(level);
|
level = logger.lookupLevel(level);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -33,7 +33,7 @@ let logger = {
|
|||||||
}
|
}
|
||||||
console[method](...message); // eslint-disable-line no-console
|
console[method](...message); // eslint-disable-line no-console
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default logger;
|
export default logger;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
export default function(Handlebars) {
|
export default function (Handlebars) {
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
let root = typeof global !== 'undefined' ? global : window, // eslint-disable-line no-undef
|
let root = typeof global !== 'undefined' ? global : window, // eslint-disable-line no-undef
|
||||||
$Handlebars = root.Handlebars;
|
$Handlebars = root.Handlebars;
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
Handlebars.noConflict = function() {
|
Handlebars.noConflict = function () {
|
||||||
if (root.Handlebars === Handlebars) {
|
if (root.Handlebars === Handlebars) {
|
||||||
root.Handlebars = $Handlebars;
|
root.Handlebars = $Handlebars;
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-15
@@ -4,13 +4,13 @@ import {
|
|||||||
COMPILER_REVISION,
|
COMPILER_REVISION,
|
||||||
createFrame,
|
createFrame,
|
||||||
LAST_COMPATIBLE_COMPILER_REVISION,
|
LAST_COMPATIBLE_COMPILER_REVISION,
|
||||||
REVISION_CHANGES
|
REVISION_CHANGES,
|
||||||
} from './base';
|
} from './base';
|
||||||
import { moveHelperToHooks } from './helpers';
|
import { moveHelperToHooks } from './helpers';
|
||||||
import { wrapHelper } from './internal/wrapHelper';
|
import { wrapHelper } from './internal/wrapHelper';
|
||||||
import {
|
import {
|
||||||
createProtoAccessControl,
|
createProtoAccessControl,
|
||||||
resultIsAllowed
|
resultIsAllowed,
|
||||||
} from './internal/proto-access';
|
} from './internal/proto-access';
|
||||||
|
|
||||||
export function checkRevision(compilerInfo) {
|
export function checkRevision(compilerInfo) {
|
||||||
@@ -73,7 +73,7 @@ export function template(templateSpec, env) {
|
|||||||
|
|
||||||
let extendedOptions = Utils.extend({}, options, {
|
let extendedOptions = Utils.extend({}, options, {
|
||||||
hooks: this.hooks,
|
hooks: this.hooks,
|
||||||
protoAccessControl: this.protoAccessControl
|
protoAccessControl: this.protoAccessControl,
|
||||||
});
|
});
|
||||||
|
|
||||||
let result = env.VM.invokePartial.call(
|
let result = env.VM.invokePartial.call(
|
||||||
@@ -115,15 +115,15 @@ export function template(templateSpec, env) {
|
|||||||
|
|
||||||
// Just add water
|
// Just add water
|
||||||
let container = {
|
let container = {
|
||||||
strict: function(obj, name, loc) {
|
strict: function (obj, name, loc) {
|
||||||
if (!obj || !(name in obj)) {
|
if (!obj || !(name in obj)) {
|
||||||
throw new Exception('"' + name + '" not defined in ' + obj, {
|
throw new Exception('"' + name + '" not defined in ' + obj, {
|
||||||
loc: loc
|
loc: loc,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return container.lookupProperty(obj, name);
|
return container.lookupProperty(obj, name);
|
||||||
},
|
},
|
||||||
lookupProperty: function(parent, propertyName) {
|
lookupProperty: function (parent, propertyName) {
|
||||||
let result = parent[propertyName];
|
let result = parent[propertyName];
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
return result;
|
return result;
|
||||||
@@ -137,7 +137,7 @@ export function template(templateSpec, env) {
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
lookup: function(depths, name) {
|
lookup: function (depths, name) {
|
||||||
const len = depths.length;
|
const len = depths.length;
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
let result = depths[i] && container.lookupProperty(depths[i], name);
|
let result = depths[i] && container.lookupProperty(depths[i], name);
|
||||||
@@ -146,21 +146,21 @@ export function template(templateSpec, env) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
lambda: function(current, context) {
|
lambda: function (current, context) {
|
||||||
return typeof current === 'function' ? current.call(context) : current;
|
return typeof current === 'function' ? current.call(context) : current;
|
||||||
},
|
},
|
||||||
|
|
||||||
escapeExpression: Utils.escapeExpression,
|
escapeExpression: Utils.escapeExpression,
|
||||||
invokePartial: invokePartialWrapper,
|
invokePartial: invokePartialWrapper,
|
||||||
|
|
||||||
fn: function(i) {
|
fn: function (i) {
|
||||||
let ret = templateSpec[i];
|
let ret = templateSpec[i];
|
||||||
ret.decorator = templateSpec[i + '_d'];
|
ret.decorator = templateSpec[i + '_d'];
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
|
||||||
programs: [],
|
programs: [],
|
||||||
program: function(i, data, declaredBlockParams, blockParams, depths) {
|
program: function (i, data, declaredBlockParams, blockParams, depths) {
|
||||||
let programWrapper = this.programs[i],
|
let programWrapper = this.programs[i],
|
||||||
fn = this.fn(i);
|
fn = this.fn(i);
|
||||||
if (data || depths || blockParams || declaredBlockParams) {
|
if (data || depths || blockParams || declaredBlockParams) {
|
||||||
@@ -179,13 +179,13 @@ export function template(templateSpec, env) {
|
|||||||
return programWrapper;
|
return programWrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
data: function(value, depth) {
|
data: function (value, depth) {
|
||||||
while (value && depth--) {
|
while (value && depth--) {
|
||||||
value = value._parent;
|
value = value._parent;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
mergeIfNeeded: function(param, common) {
|
mergeIfNeeded: function (param, common) {
|
||||||
let obj = param || common;
|
let obj = param || common;
|
||||||
|
|
||||||
if (param && common && param !== common) {
|
if (param && common && param !== common) {
|
||||||
@@ -198,7 +198,7 @@ export function template(templateSpec, env) {
|
|||||||
nullContext: Object.seal({}),
|
nullContext: Object.seal({}),
|
||||||
|
|
||||||
noop: env.VM.noop,
|
noop: env.VM.noop,
|
||||||
compilerInfo: templateSpec.compiler
|
compilerInfo: templateSpec.compiler,
|
||||||
};
|
};
|
||||||
|
|
||||||
function ret(context, options = {}) {
|
function ret(context, options = {}) {
|
||||||
@@ -412,7 +412,7 @@ function executeDecorators(fn, prog, container, depths, data, blockParams) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function wrapHelpersToPassLookupProperty(mergedHelpers, container) {
|
function wrapHelpersToPassLookupProperty(mergedHelpers, container) {
|
||||||
Object.keys(mergedHelpers).forEach(helperName => {
|
Object.keys(mergedHelpers).forEach((helperName) => {
|
||||||
let helper = mergedHelpers[helperName];
|
let helper = mergedHelpers[helperName];
|
||||||
mergedHelpers[helperName] = passLookupPropertyOption(helper, container);
|
mergedHelpers[helperName] = passLookupPropertyOption(helper, container);
|
||||||
});
|
});
|
||||||
@@ -420,7 +420,7 @@ function wrapHelpersToPassLookupProperty(mergedHelpers, container) {
|
|||||||
|
|
||||||
function passLookupPropertyOption(helper, container) {
|
function passLookupPropertyOption(helper, container) {
|
||||||
const lookupProperty = container.lookupProperty;
|
const lookupProperty = container.lookupProperty;
|
||||||
return wrapHelper(helper, options => {
|
return wrapHelper(helper, (options) => {
|
||||||
return Utils.extend({ lookupProperty }, options);
|
return Utils.extend({ lookupProperty }, options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ function SafeString(string) {
|
|||||||
this.string = string;
|
this.string = string;
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeString.prototype.toString = SafeString.prototype.toHTML = function() {
|
SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
|
||||||
return '' + this.string;
|
return '' + this.string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const escape = {
|
|||||||
'"': '"',
|
'"': '"',
|
||||||
"'": ''',
|
"'": ''',
|
||||||
'`': '`',
|
'`': '`',
|
||||||
'=': '='
|
'=': '=',
|
||||||
};
|
};
|
||||||
|
|
||||||
const badChars = /[&<>"'`=]/g,
|
const badChars = /[&<>"'`=]/g,
|
||||||
@@ -38,7 +38,7 @@ export function isFunction(value) {
|
|||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
export const isArray =
|
export const isArray =
|
||||||
Array.isArray ||
|
Array.isArray ||
|
||||||
function(value) {
|
function (value) {
|
||||||
return value && typeof value === 'object'
|
return value && typeof value === 'object'
|
||||||
? toString.call(value) === '[object Array]'
|
? toString.call(value) === '[object Array]'
|
||||||
: false;
|
: false;
|
||||||
|
|||||||
+26
-23
@@ -6,12 +6,12 @@ import * as Handlebars from './handlebars';
|
|||||||
import { basename } from 'path';
|
import { basename } from 'path';
|
||||||
import { SourceMapConsumer, SourceNode } from 'source-map';
|
import { SourceMapConsumer, SourceNode } from 'source-map';
|
||||||
|
|
||||||
module.exports.loadTemplates = function(opts, callback) {
|
module.exports.loadTemplates = function (opts, callback) {
|
||||||
loadStrings(opts, function(err, strings) {
|
loadStrings(opts, function (err, strings) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
} else {
|
} else {
|
||||||
loadFiles(opts, function(err, files) {
|
loadFiles(opts, function (err, files) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
} else {
|
} else {
|
||||||
@@ -37,7 +37,7 @@ function loadStrings(opts, callback) {
|
|||||||
|
|
||||||
Async.map(
|
Async.map(
|
||||||
strings,
|
strings,
|
||||||
function(string, callback) {
|
function (string, callback) {
|
||||||
if (string !== '-') {
|
if (string !== '-') {
|
||||||
callback(undefined, string);
|
callback(undefined, string);
|
||||||
} else {
|
} else {
|
||||||
@@ -45,19 +45,19 @@ function loadStrings(opts, callback) {
|
|||||||
let buffer = '';
|
let buffer = '';
|
||||||
process.stdin.setEncoding('utf8');
|
process.stdin.setEncoding('utf8');
|
||||||
|
|
||||||
process.stdin.on('data', function(chunk) {
|
process.stdin.on('data', function (chunk) {
|
||||||
buffer += chunk;
|
buffer += chunk;
|
||||||
});
|
});
|
||||||
process.stdin.on('end', function() {
|
process.stdin.on('end', function () {
|
||||||
callback(undefined, buffer);
|
callback(undefined, buffer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
function(err, strings) {
|
function (err, strings) {
|
||||||
strings = strings.map((string, index) => ({
|
strings = strings.map((string, index) => ({
|
||||||
name: names[index],
|
name: names[index],
|
||||||
path: names[index],
|
path: names[index],
|
||||||
source: string
|
source: string,
|
||||||
}));
|
}));
|
||||||
callback(err, strings);
|
callback(err, strings);
|
||||||
}
|
}
|
||||||
@@ -68,20 +68,23 @@ function loadFiles(opts, callback) {
|
|||||||
// Build file extension pattern
|
// Build file extension pattern
|
||||||
let extension = (opts.extension || 'handlebars').replace(
|
let extension = (opts.extension || 'handlebars').replace(
|
||||||
/[\\^$*+?.():=!|{}\-[\]]/g,
|
/[\\^$*+?.():=!|{}\-[\]]/g,
|
||||||
function(arg) {
|
function (arg) {
|
||||||
return '\\' + arg;
|
return '\\' + arg;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
extension = new RegExp('\\.' + extension + '$');
|
extension = new RegExp('\\.' + extension + '$');
|
||||||
|
|
||||||
let ret = [],
|
let ret = [],
|
||||||
queue = (opts.files || []).map(template => ({ template, root: opts.root }));
|
queue = (opts.files || []).map((template) => ({
|
||||||
|
template,
|
||||||
|
root: opts.root,
|
||||||
|
}));
|
||||||
Async.whilst(
|
Async.whilst(
|
||||||
() => queue.length,
|
() => queue.length,
|
||||||
function(callback) {
|
function (callback) {
|
||||||
let { template: path, root } = queue.shift();
|
let { template: path, root } = queue.shift();
|
||||||
|
|
||||||
fs.stat(path, function(err, stat) {
|
fs.stat(path, function (err, stat) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(
|
return callback(
|
||||||
new Handlebars.Exception(`Unable to open template file "${path}"`)
|
new Handlebars.Exception(`Unable to open template file "${path}"`)
|
||||||
@@ -91,12 +94,12 @@ function loadFiles(opts, callback) {
|
|||||||
if (stat.isDirectory()) {
|
if (stat.isDirectory()) {
|
||||||
opts.hasDirectory = true;
|
opts.hasDirectory = true;
|
||||||
|
|
||||||
fs.readdir(path, function(err, children) {
|
fs.readdir(path, function (err, children) {
|
||||||
/* istanbul ignore next : Race condition that being too lazy to test */
|
/* istanbul ignore next : Race condition that being too lazy to test */
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
children.forEach(function(file) {
|
children.forEach(function (file) {
|
||||||
let childPath = path + '/' + file;
|
let childPath = path + '/' + file;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -110,7 +113,7 @@ function loadFiles(opts, callback) {
|
|||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
fs.readFile(path, 'utf8', function(err, data) {
|
fs.readFile(path, 'utf8', function (err, data) {
|
||||||
/* istanbul ignore next : Race condition that being too lazy to test */
|
/* istanbul ignore next : Race condition that being too lazy to test */
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
@@ -132,7 +135,7 @@ function loadFiles(opts, callback) {
|
|||||||
ret.push({
|
ret.push({
|
||||||
path: path,
|
path: path,
|
||||||
name: name,
|
name: name,
|
||||||
source: data
|
source: data,
|
||||||
});
|
});
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
@@ -140,7 +143,7 @@ function loadFiles(opts, callback) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(err) {
|
function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
} else {
|
} else {
|
||||||
@@ -150,7 +153,7 @@ function loadFiles(opts, callback) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.cli = function(opts) {
|
module.exports.cli = function (opts) {
|
||||||
if (opts.version) {
|
if (opts.version) {
|
||||||
console.log(Handlebars.VERSION);
|
console.log(Handlebars.VERSION);
|
||||||
return;
|
return;
|
||||||
@@ -219,10 +222,10 @@ module.exports.cli = function(opts) {
|
|||||||
output.add('{};\n');
|
output.add('{};\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.templates.forEach(function(template) {
|
opts.templates.forEach(function (template) {
|
||||||
let options = {
|
let options = {
|
||||||
knownHelpers: known,
|
knownHelpers: known,
|
||||||
knownHelpersOnly: opts.o
|
knownHelpersOnly: opts.o,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (opts.map) {
|
if (opts.map) {
|
||||||
@@ -259,7 +262,7 @@ module.exports.cli = function(opts) {
|
|||||||
template.name,
|
template.name,
|
||||||
"'] = template(",
|
"'] = template(",
|
||||||
precompiled,
|
precompiled,
|
||||||
');\n'
|
');\n',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -335,7 +338,7 @@ function minify(output, sourceMapFile) {
|
|||||||
return require('uglify-js').minify(output.code, {
|
return require('uglify-js').minify(output.code, {
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: output.map,
|
content: output.map,
|
||||||
url: sourceMapFile
|
url: sourceMapFile,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -5,5 +5,5 @@ module.exports = {
|
|||||||
functions: 100,
|
functions: 100,
|
||||||
statements: 100,
|
statements: 100,
|
||||||
exclude: ['**/spec/**'],
|
exclude: ['**/spec/**'],
|
||||||
reporter: 'html'
|
reporter: 'html',
|
||||||
};
|
};
|
||||||
|
|||||||
Generated
+11
-8
@@ -51,7 +51,7 @@
|
|||||||
"mock-stdin": "^0.3.0",
|
"mock-stdin": "^0.3.0",
|
||||||
"mustache": "^2.1.3",
|
"mustache": "^2.1.3",
|
||||||
"nyc": "^14.1.1",
|
"nyc": "^14.1.1",
|
||||||
"prettier": "^1.19.1",
|
"prettier": "^2.7.1",
|
||||||
"semver": "^5.0.1",
|
"semver": "^5.0.1",
|
||||||
"sinon": "^7.5.0",
|
"sinon": "^7.5.0",
|
||||||
"typescript": "^3.4.3",
|
"typescript": "^3.4.3",
|
||||||
@@ -11268,15 +11268,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "1.19.1",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||||
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
|
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"prettier": "bin-prettier.js"
|
"prettier": "bin-prettier.js"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4"
|
"node": ">=10.13.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pretty-bytes": {
|
"node_modules/pretty-bytes": {
|
||||||
@@ -23629,9 +23632,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"version": "1.19.1",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||||
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
|
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"pretty-bytes": {
|
"pretty-bytes": {
|
||||||
|
|||||||
+1
-1
@@ -62,7 +62,7 @@
|
|||||||
"mock-stdin": "^0.3.0",
|
"mock-stdin": "^0.3.0",
|
||||||
"mustache": "^2.1.3",
|
"mustache": "^2.1.3",
|
||||||
"nyc": "^14.1.1",
|
"nyc": "^14.1.1",
|
||||||
"prettier": "^1.19.1",
|
"prettier": "^2.7.1",
|
||||||
"semver": "^5.0.1",
|
"semver": "^5.0.1",
|
||||||
"sinon": "^7.5.0",
|
"sinon": "^7.5.0",
|
||||||
"typescript": "^3.4.3",
|
"typescript": "^3.4.3",
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
tabWidth: 2,
|
tabWidth: 2,
|
||||||
semi: true,
|
semi: true,
|
||||||
singleQuote: true
|
singleQuote: true,
|
||||||
};
|
};
|
||||||
|
|||||||
+4
-4
@@ -22,16 +22,16 @@ module.exports = {
|
|||||||
strictEqual: true,
|
strictEqual: true,
|
||||||
define: true,
|
define: true,
|
||||||
expect: true,
|
expect: true,
|
||||||
chai: true
|
chai: true,
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
mocha: true
|
mocha: true,
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
// Disabling for tests, for now.
|
// Disabling for tests, for now.
|
||||||
'no-path-concat': 'off',
|
'no-path-concat': 'off',
|
||||||
|
|
||||||
'no-var': 'off',
|
'no-var': 'off',
|
||||||
'dot-notation': 'off'
|
'dot-notation': 'off',
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
+34
-34
@@ -1,14 +1,14 @@
|
|||||||
describe('ast', function() {
|
describe('ast', function () {
|
||||||
if (!Handlebars.AST) {
|
if (!Handlebars.AST) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var AST = Handlebars.AST;
|
var AST = Handlebars.AST;
|
||||||
|
|
||||||
describe('BlockStatement', function() {
|
describe('BlockStatement', function () {
|
||||||
it('should throw on mustache mismatch', function() {
|
it('should throw on mustache mismatch', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
handlebarsEnv.parse('\n {{#foo}}{{/bar}}');
|
handlebarsEnv.parse('\n {{#foo}}{{/bar}}');
|
||||||
},
|
},
|
||||||
Handlebars.Exception,
|
Handlebars.Exception,
|
||||||
@@ -17,14 +17,14 @@ describe('ast', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('helpers', function() {
|
describe('helpers', function () {
|
||||||
describe('#helperExpression', function() {
|
describe('#helperExpression', function () {
|
||||||
it('should handle mustache statements', function() {
|
it('should handle mustache statements', function () {
|
||||||
equals(
|
equals(
|
||||||
AST.helpers.helperExpression({
|
AST.helpers.helperExpression({
|
||||||
type: 'MustacheStatement',
|
type: 'MustacheStatement',
|
||||||
params: [],
|
params: [],
|
||||||
hash: undefined
|
hash: undefined,
|
||||||
}),
|
}),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
@@ -32,7 +32,7 @@ describe('ast', function() {
|
|||||||
AST.helpers.helperExpression({
|
AST.helpers.helperExpression({
|
||||||
type: 'MustacheStatement',
|
type: 'MustacheStatement',
|
||||||
params: [1],
|
params: [1],
|
||||||
hash: undefined
|
hash: undefined,
|
||||||
}),
|
}),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@@ -40,17 +40,17 @@ describe('ast', function() {
|
|||||||
AST.helpers.helperExpression({
|
AST.helpers.helperExpression({
|
||||||
type: 'MustacheStatement',
|
type: 'MustacheStatement',
|
||||||
params: [],
|
params: [],
|
||||||
hash: {}
|
hash: {},
|
||||||
}),
|
}),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should handle block statements', function() {
|
it('should handle block statements', function () {
|
||||||
equals(
|
equals(
|
||||||
AST.helpers.helperExpression({
|
AST.helpers.helperExpression({
|
||||||
type: 'BlockStatement',
|
type: 'BlockStatement',
|
||||||
params: [],
|
params: [],
|
||||||
hash: undefined
|
hash: undefined,
|
||||||
}),
|
}),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
@@ -58,7 +58,7 @@ describe('ast', function() {
|
|||||||
AST.helpers.helperExpression({
|
AST.helpers.helperExpression({
|
||||||
type: 'BlockStatement',
|
type: 'BlockStatement',
|
||||||
params: [1],
|
params: [1],
|
||||||
hash: undefined
|
hash: undefined,
|
||||||
}),
|
}),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@@ -66,15 +66,15 @@ describe('ast', function() {
|
|||||||
AST.helpers.helperExpression({
|
AST.helpers.helperExpression({
|
||||||
type: 'BlockStatement',
|
type: 'BlockStatement',
|
||||||
params: [],
|
params: [],
|
||||||
hash: {}
|
hash: {},
|
||||||
}),
|
}),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should handle subexpressions', function() {
|
it('should handle subexpressions', function () {
|
||||||
equals(AST.helpers.helperExpression({ type: 'SubExpression' }), true);
|
equals(AST.helpers.helperExpression({ type: 'SubExpression' }), true);
|
||||||
});
|
});
|
||||||
it('should work with non-helper nodes', function() {
|
it('should work with non-helper nodes', function () {
|
||||||
equals(AST.helpers.helperExpression({ type: 'Program' }), false);
|
equals(AST.helpers.helperExpression({ type: 'Program' }), false);
|
||||||
|
|
||||||
equals(
|
equals(
|
||||||
@@ -107,7 +107,7 @@ describe('ast', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Line Numbers', function() {
|
describe('Line Numbers', function () {
|
||||||
var ast, body;
|
var ast, body;
|
||||||
|
|
||||||
function testColumns(node, firstLine, lastLine, firstColumn, lastColumn) {
|
function testColumns(node, firstLine, lastLine, firstColumn, lastColumn) {
|
||||||
@@ -120,59 +120,59 @@ describe('ast', function() {
|
|||||||
/* eslint-disable no-multi-spaces */
|
/* eslint-disable no-multi-spaces */
|
||||||
ast = Handlebars.parse(
|
ast = Handlebars.parse(
|
||||||
'line 1 {{line1Token}}\n' + // 1
|
'line 1 {{line1Token}}\n' + // 1
|
||||||
' line 2 {{line2token}}\n' + // 2
|
' line 2 {{line2token}}\n' + // 2
|
||||||
' line 3 {{#blockHelperOnLine3}}\n' + // 3
|
' line 3 {{#blockHelperOnLine3}}\n' + // 3
|
||||||
'line 4{{line4token}}\n' + // 4
|
'line 4{{line4token}}\n' + // 4
|
||||||
'line5{{else}}\n' + // 5
|
'line5{{else}}\n' + // 5
|
||||||
'{{line6Token}}\n' + // 6
|
'{{line6Token}}\n' + // 6
|
||||||
'{{/blockHelperOnLine3}}\n' + // 7
|
'{{/blockHelperOnLine3}}\n' + // 7
|
||||||
'{{#open}}\n' + // 8
|
'{{#open}}\n' + // 8
|
||||||
'{{else inverse}}\n' + // 9
|
'{{else inverse}}\n' + // 9
|
||||||
'{{else}}\n' + // 10
|
'{{else}}\n' + // 10
|
||||||
'{{/open}}'
|
'{{/open}}'
|
||||||
); // 11
|
); // 11
|
||||||
/* eslint-enable no-multi-spaces */
|
/* eslint-enable no-multi-spaces */
|
||||||
body = ast.body;
|
body = ast.body;
|
||||||
|
|
||||||
it('gets ContentNode line numbers', function() {
|
it('gets ContentNode line numbers', function () {
|
||||||
var contentNode = body[0];
|
var contentNode = body[0];
|
||||||
testColumns(contentNode, 1, 1, 0, 7);
|
testColumns(contentNode, 1, 1, 0, 7);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gets MustacheStatement line numbers', function() {
|
it('gets MustacheStatement line numbers', function () {
|
||||||
var mustacheNode = body[1];
|
var mustacheNode = body[1];
|
||||||
testColumns(mustacheNode, 1, 1, 7, 21);
|
testColumns(mustacheNode, 1, 1, 7, 21);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gets line numbers correct when newlines appear', function() {
|
it('gets line numbers correct when newlines appear', function () {
|
||||||
testColumns(body[2], 1, 2, 21, 8);
|
testColumns(body[2], 1, 2, 21, 8);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gets MustacheStatement line numbers correct across newlines', function() {
|
it('gets MustacheStatement line numbers correct across newlines', function () {
|
||||||
var secondMustacheStatement = body[3];
|
var secondMustacheStatement = body[3];
|
||||||
testColumns(secondMustacheStatement, 2, 2, 8, 22);
|
testColumns(secondMustacheStatement, 2, 2, 8, 22);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gets the block helper information correct', function() {
|
it('gets the block helper information correct', function () {
|
||||||
var blockHelperNode = body[5];
|
var blockHelperNode = body[5];
|
||||||
testColumns(blockHelperNode, 3, 7, 8, 23);
|
testColumns(blockHelperNode, 3, 7, 8, 23);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('correctly records the line numbers the program of a block helper', function() {
|
it('correctly records the line numbers the program of a block helper', function () {
|
||||||
var blockHelperNode = body[5],
|
var blockHelperNode = body[5],
|
||||||
program = blockHelperNode.program;
|
program = blockHelperNode.program;
|
||||||
|
|
||||||
testColumns(program, 3, 5, 31, 5);
|
testColumns(program, 3, 5, 31, 5);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('correctly records the line numbers of an inverse of a block helper', function() {
|
it('correctly records the line numbers of an inverse of a block helper', function () {
|
||||||
var blockHelperNode = body[5],
|
var blockHelperNode = body[5],
|
||||||
inverse = blockHelperNode.inverse;
|
inverse = blockHelperNode.inverse;
|
||||||
|
|
||||||
testColumns(inverse, 5, 7, 13, 0);
|
testColumns(inverse, 5, 7, 13, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('correctly records the line number of chained inverses', function() {
|
it('correctly records the line number of chained inverses', function () {
|
||||||
var chainInverseNode = body[7];
|
var chainInverseNode = body[7];
|
||||||
|
|
||||||
testColumns(chainInverseNode.program, 8, 9, 9, 0);
|
testColumns(chainInverseNode.program, 8, 9, 9, 0);
|
||||||
|
|||||||
+102
-124
@@ -1,17 +1,15 @@
|
|||||||
global.handlebarsEnv = null;
|
global.handlebarsEnv = null;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
global.handlebarsEnv = Handlebars.create();
|
global.handlebarsEnv = Handlebars.create();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('basic context', function() {
|
describe('basic context', function () {
|
||||||
it('most basic', function() {
|
it('most basic', function () {
|
||||||
expectTemplate('{{foo}}')
|
expectTemplate('{{foo}}').withInput({ foo: 'foo' }).toCompileTo('foo');
|
||||||
.withInput({ foo: 'foo' })
|
|
||||||
.toCompileTo('foo');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('escaping', function() {
|
it('escaping', function () {
|
||||||
expectTemplate('\\{{foo}}')
|
expectTemplate('\\{{foo}}')
|
||||||
.withInput({ foo: 'food' })
|
.withInput({ foo: 'food' })
|
||||||
.toCompileTo('{{foo}}');
|
.toCompileTo('{{foo}}');
|
||||||
@@ -33,23 +31,21 @@ describe('basic context', function() {
|
|||||||
.toCompileTo('\\\\ food');
|
.toCompileTo('\\\\ food');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('compiling with a basic context', function() {
|
it('compiling with a basic context', function () {
|
||||||
expectTemplate('Goodbye\n{{cruel}}\n{{world}}!')
|
expectTemplate('Goodbye\n{{cruel}}\n{{world}}!')
|
||||||
.withInput({
|
.withInput({
|
||||||
cruel: 'cruel',
|
cruel: 'cruel',
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('It works if all the required keys are provided')
|
.withMessage('It works if all the required keys are provided')
|
||||||
.toCompileTo('Goodbye\ncruel\nworld!');
|
.toCompileTo('Goodbye\ncruel\nworld!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('compiling with a string context', function() {
|
it('compiling with a string context', function () {
|
||||||
expectTemplate('{{.}}{{length}}')
|
expectTemplate('{{.}}{{length}}').withInput('bye').toCompileTo('bye3');
|
||||||
.withInput('bye')
|
|
||||||
.toCompileTo('bye3');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('compiling with an undefined context', function() {
|
it('compiling with an undefined context', function () {
|
||||||
expectTemplate('Goodbye\n{{cruel}}\n{{world.bar}}!')
|
expectTemplate('Goodbye\n{{cruel}}\n{{world.bar}}!')
|
||||||
.withInput(undefined)
|
.withInput(undefined)
|
||||||
.toCompileTo('Goodbye\n\n!');
|
.toCompileTo('Goodbye\n\n!');
|
||||||
@@ -59,11 +55,11 @@ describe('basic context', function() {
|
|||||||
.toCompileTo('Goodbye');
|
.toCompileTo('Goodbye');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('comments', function() {
|
it('comments', function () {
|
||||||
expectTemplate('{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!')
|
expectTemplate('{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!')
|
||||||
.withInput({
|
.withInput({
|
||||||
cruel: 'cruel',
|
cruel: 'cruel',
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('comments are ignored')
|
.withMessage('comments are ignored')
|
||||||
.toCompileTo('Goodbye\ncruel\nworld!');
|
.toCompileTo('Goodbye\ncruel\nworld!');
|
||||||
@@ -87,12 +83,12 @@ describe('basic context', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('boolean', function() {
|
it('boolean', function () {
|
||||||
var string = '{{#goodbye}}GOODBYE {{/goodbye}}cruel {{world}}!';
|
var string = '{{#goodbye}}GOODBYE {{/goodbye}}cruel {{world}}!';
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: true,
|
goodbye: true,
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('booleans show the contents when true')
|
.withMessage('booleans show the contents when true')
|
||||||
.toCompileTo('GOODBYE cruel world!');
|
.toCompileTo('GOODBYE cruel world!');
|
||||||
@@ -100,41 +96,37 @@ describe('basic context', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: false,
|
goodbye: false,
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('booleans do not show the contents when false')
|
.withMessage('booleans do not show the contents when false')
|
||||||
.toCompileTo('cruel world!');
|
.toCompileTo('cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('zeros', function() {
|
it('zeros', function () {
|
||||||
expectTemplate('num1: {{num1}}, num2: {{num2}}')
|
expectTemplate('num1: {{num1}}, num2: {{num2}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
num1: 42,
|
num1: 42,
|
||||||
num2: 0
|
num2: 0,
|
||||||
})
|
})
|
||||||
.toCompileTo('num1: 42, num2: 0');
|
.toCompileTo('num1: 42, num2: 0');
|
||||||
|
|
||||||
expectTemplate('num: {{.}}')
|
expectTemplate('num: {{.}}').withInput(0).toCompileTo('num: 0');
|
||||||
.withInput(0)
|
|
||||||
.toCompileTo('num: 0');
|
|
||||||
|
|
||||||
expectTemplate('num: {{num1/num2}}')
|
expectTemplate('num: {{num1/num2}}')
|
||||||
.withInput({ num1: { num2: 0 } })
|
.withInput({ num1: { num2: 0 } })
|
||||||
.toCompileTo('num: 0');
|
.toCompileTo('num: 0');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('false', function() {
|
it('false', function () {
|
||||||
/* eslint-disable no-new-wrappers */
|
/* eslint-disable no-new-wrappers */
|
||||||
expectTemplate('val1: {{val1}}, val2: {{val2}}')
|
expectTemplate('val1: {{val1}}, val2: {{val2}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
val1: false,
|
val1: false,
|
||||||
val2: new Boolean(false)
|
val2: new Boolean(false),
|
||||||
})
|
})
|
||||||
.toCompileTo('val1: false, val2: false');
|
.toCompileTo('val1: false, val2: false');
|
||||||
|
|
||||||
expectTemplate('val: {{.}}')
|
expectTemplate('val: {{.}}').withInput(false).toCompileTo('val: false');
|
||||||
.withInput(false)
|
|
||||||
.toCompileTo('val: false');
|
|
||||||
|
|
||||||
expectTemplate('val: {{val1/val2}}')
|
expectTemplate('val: {{val1/val2}}')
|
||||||
.withInput({ val1: { val2: false } })
|
.withInput({ val1: { val2: false } })
|
||||||
@@ -143,7 +135,7 @@ describe('basic context', function() {
|
|||||||
expectTemplate('val1: {{{val1}}}, val2: {{{val2}}}')
|
expectTemplate('val1: {{{val1}}}, val2: {{{val2}}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
val1: false,
|
val1: false,
|
||||||
val2: new Boolean(false)
|
val2: new Boolean(false),
|
||||||
})
|
})
|
||||||
.toCompileTo('val1: false, val2: false');
|
.toCompileTo('val1: false, val2: false');
|
||||||
|
|
||||||
@@ -153,10 +145,10 @@ describe('basic context', function() {
|
|||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle undefined and null', function() {
|
it('should handle undefined and null', function () {
|
||||||
expectTemplate('{{awesome undefined null}}')
|
expectTemplate('{{awesome undefined null}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
awesome: function(_undefined, _null, options) {
|
awesome: function (_undefined, _null, options) {
|
||||||
return (
|
return (
|
||||||
(_undefined === undefined) +
|
(_undefined === undefined) +
|
||||||
' ' +
|
' ' +
|
||||||
@@ -164,34 +156,34 @@ describe('basic context', function() {
|
|||||||
' ' +
|
' ' +
|
||||||
typeof options
|
typeof options
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('true true object');
|
.toCompileTo('true true object');
|
||||||
|
|
||||||
expectTemplate('{{undefined}}')
|
expectTemplate('{{undefined}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
undefined: function() {
|
undefined: function () {
|
||||||
return 'undefined!';
|
return 'undefined!';
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('undefined!');
|
.toCompileTo('undefined!');
|
||||||
|
|
||||||
expectTemplate('{{null}}')
|
expectTemplate('{{null}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
null: function() {
|
null: function () {
|
||||||
return 'null!';
|
return 'null!';
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('null!');
|
.toCompileTo('null!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('newlines', function() {
|
it('newlines', function () {
|
||||||
expectTemplate("Alan's\nTest").toCompileTo("Alan's\nTest");
|
expectTemplate("Alan's\nTest").toCompileTo("Alan's\nTest");
|
||||||
|
|
||||||
expectTemplate("Alan's\rTest").toCompileTo("Alan's\rTest");
|
expectTemplate("Alan's\rTest").toCompileTo("Alan's\rTest");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('escaping text', function() {
|
it('escaping text', function () {
|
||||||
expectTemplate("Awesome's")
|
expectTemplate("Awesome's")
|
||||||
.withMessage(
|
.withMessage(
|
||||||
"text is escaped so that it doesn't get caught on single quotes"
|
"text is escaped so that it doesn't get caught on single quotes"
|
||||||
@@ -216,7 +208,7 @@ describe('basic context', function() {
|
|||||||
.toCompileTo(" ' ' ");
|
.toCompileTo(" ' ' ");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('escaping expressions', function() {
|
it('escaping expressions', function () {
|
||||||
expectTemplate('{{{awesome}}}')
|
expectTemplate('{{{awesome}}}')
|
||||||
.withInput({ awesome: "&'\\<>" })
|
.withInput({ awesome: "&'\\<>" })
|
||||||
.withMessage("expressions with 3 handlebars aren't escaped")
|
.withMessage("expressions with 3 handlebars aren't escaped")
|
||||||
@@ -238,140 +230,140 @@ describe('basic context', function() {
|
|||||||
.toCompileTo('Escaped, <b> looks like: &lt;b&gt;');
|
.toCompileTo('Escaped, <b> looks like: &lt;b&gt;');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("functions returning safestrings shouldn't be escaped", function() {
|
it("functions returning safestrings shouldn't be escaped", function () {
|
||||||
expectTemplate('{{awesome}}')
|
expectTemplate('{{awesome}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
awesome: function() {
|
awesome: function () {
|
||||||
return new Handlebars.SafeString("&'\\<>");
|
return new Handlebars.SafeString("&'\\<>");
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.withMessage("functions returning safestrings aren't escaped")
|
.withMessage("functions returning safestrings aren't escaped")
|
||||||
.toCompileTo("&'\\<>");
|
.toCompileTo("&'\\<>");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('functions', function() {
|
it('functions', function () {
|
||||||
expectTemplate('{{awesome}}')
|
expectTemplate('{{awesome}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
awesome: function() {
|
awesome: function () {
|
||||||
return 'Awesome';
|
return 'Awesome';
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.withMessage('functions are called and render their output')
|
.withMessage('functions are called and render their output')
|
||||||
.toCompileTo('Awesome');
|
.toCompileTo('Awesome');
|
||||||
|
|
||||||
expectTemplate('{{awesome}}')
|
expectTemplate('{{awesome}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
awesome: function() {
|
awesome: function () {
|
||||||
return this.more;
|
return this.more;
|
||||||
},
|
},
|
||||||
more: 'More awesome'
|
more: 'More awesome',
|
||||||
})
|
})
|
||||||
.withMessage('functions are bound to the context')
|
.withMessage('functions are bound to the context')
|
||||||
.toCompileTo('More awesome');
|
.toCompileTo('More awesome');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('functions with context argument', function() {
|
it('functions with context argument', function () {
|
||||||
expectTemplate('{{awesome frank}}')
|
expectTemplate('{{awesome frank}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
awesome: function(context) {
|
awesome: function (context) {
|
||||||
return context;
|
return context;
|
||||||
},
|
},
|
||||||
frank: 'Frank'
|
frank: 'Frank',
|
||||||
})
|
})
|
||||||
.withMessage('functions are called with context arguments')
|
.withMessage('functions are called with context arguments')
|
||||||
.toCompileTo('Frank');
|
.toCompileTo('Frank');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('pathed functions with context argument', function() {
|
it('pathed functions with context argument', function () {
|
||||||
expectTemplate('{{bar.awesome frank}}')
|
expectTemplate('{{bar.awesome frank}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
bar: {
|
bar: {
|
||||||
awesome: function(context) {
|
awesome: function (context) {
|
||||||
return context;
|
return context;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
frank: 'Frank'
|
frank: 'Frank',
|
||||||
})
|
})
|
||||||
.withMessage('functions are called with context arguments')
|
.withMessage('functions are called with context arguments')
|
||||||
.toCompileTo('Frank');
|
.toCompileTo('Frank');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('depthed functions with context argument', function() {
|
it('depthed functions with context argument', function () {
|
||||||
expectTemplate('{{#with frank}}{{../awesome .}}{{/with}}')
|
expectTemplate('{{#with frank}}{{../awesome .}}{{/with}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
awesome: function(context) {
|
awesome: function (context) {
|
||||||
return context;
|
return context;
|
||||||
},
|
},
|
||||||
frank: 'Frank'
|
frank: 'Frank',
|
||||||
})
|
})
|
||||||
.withMessage('functions are called with context arguments')
|
.withMessage('functions are called with context arguments')
|
||||||
.toCompileTo('Frank');
|
.toCompileTo('Frank');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('block functions with context argument', function() {
|
it('block functions with context argument', function () {
|
||||||
expectTemplate('{{#awesome 1}}inner {{.}}{{/awesome}}')
|
expectTemplate('{{#awesome 1}}inner {{.}}{{/awesome}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
awesome: function(context, options) {
|
awesome: function (context, options) {
|
||||||
return options.fn(context);
|
return options.fn(context);
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.withMessage('block functions are called with context and options')
|
.withMessage('block functions are called with context and options')
|
||||||
.toCompileTo('inner 1');
|
.toCompileTo('inner 1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('depthed block functions with context argument', function() {
|
it('depthed block functions with context argument', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#with value}}{{#../awesome 1}}inner {{.}}{{/../awesome}}{{/with}}'
|
'{{#with value}}{{#../awesome 1}}inner {{.}}{{/../awesome}}{{/with}}'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
value: true,
|
value: true,
|
||||||
awesome: function(context, options) {
|
awesome: function (context, options) {
|
||||||
return options.fn(context);
|
return options.fn(context);
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.withMessage('block functions are called with context and options')
|
.withMessage('block functions are called with context and options')
|
||||||
.toCompileTo('inner 1');
|
.toCompileTo('inner 1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('block functions without context argument', function() {
|
it('block functions without context argument', function () {
|
||||||
expectTemplate('{{#awesome}}inner{{/awesome}}')
|
expectTemplate('{{#awesome}}inner{{/awesome}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
awesome: function(options) {
|
awesome: function (options) {
|
||||||
return options.fn(this);
|
return options.fn(this);
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.withMessage('block functions are called with options')
|
.withMessage('block functions are called with options')
|
||||||
.toCompileTo('inner');
|
.toCompileTo('inner');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('pathed block functions without context argument', function() {
|
it('pathed block functions without context argument', function () {
|
||||||
expectTemplate('{{#foo.awesome}}inner{{/foo.awesome}}')
|
expectTemplate('{{#foo.awesome}}inner{{/foo.awesome}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
foo: {
|
foo: {
|
||||||
awesome: function() {
|
awesome: function () {
|
||||||
return this;
|
return this;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.withMessage('block functions are called with options')
|
.withMessage('block functions are called with options')
|
||||||
.toCompileTo('inner');
|
.toCompileTo('inner');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('depthed block functions without context argument', function() {
|
it('depthed block functions without context argument', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#with value}}{{#../awesome}}inner{{/../awesome}}{{/with}}'
|
'{{#with value}}{{#../awesome}}inner{{/../awesome}}{{/with}}'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
value: true,
|
value: true,
|
||||||
awesome: function() {
|
awesome: function () {
|
||||||
return this;
|
return this;
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.withMessage('block functions are called with options')
|
.withMessage('block functions are called with options')
|
||||||
.toCompileTo('inner');
|
.toCompileTo('inner');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('paths with hyphens', function() {
|
it('paths with hyphens', function () {
|
||||||
expectTemplate('{{foo-bar}}')
|
expectTemplate('{{foo-bar}}')
|
||||||
.withInput({ 'foo-bar': 'baz' })
|
.withInput({ 'foo-bar': 'baz' })
|
||||||
.withMessage('Paths can contain hyphens (-)')
|
.withMessage('Paths can contain hyphens (-)')
|
||||||
@@ -388,21 +380,21 @@ describe('basic context', function() {
|
|||||||
.toCompileTo('baz');
|
.toCompileTo('baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('nested paths', function() {
|
it('nested paths', function () {
|
||||||
expectTemplate('Goodbye {{alan/expression}} world!')
|
expectTemplate('Goodbye {{alan/expression}} world!')
|
||||||
.withInput({ alan: { expression: 'beautiful' } })
|
.withInput({ alan: { expression: 'beautiful' } })
|
||||||
.withMessage('Nested paths access nested objects')
|
.withMessage('Nested paths access nested objects')
|
||||||
.toCompileTo('Goodbye beautiful world!');
|
.toCompileTo('Goodbye beautiful world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('nested paths with empty string value', function() {
|
it('nested paths with empty string value', function () {
|
||||||
expectTemplate('Goodbye {{alan/expression}} world!')
|
expectTemplate('Goodbye {{alan/expression}} world!')
|
||||||
.withInput({ alan: { expression: '' } })
|
.withInput({ alan: { expression: '' } })
|
||||||
.withMessage('Nested paths access nested objects with empty string')
|
.withMessage('Nested paths access nested objects with empty string')
|
||||||
.toCompileTo('Goodbye world!');
|
.toCompileTo('Goodbye world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('literal paths', function() {
|
it('literal paths', function () {
|
||||||
expectTemplate('Goodbye {{[@alan]/expression}} world!')
|
expectTemplate('Goodbye {{[@alan]/expression}} world!')
|
||||||
.withInput({ '@alan': { expression: 'beautiful' } })
|
.withInput({ '@alan': { expression: 'beautiful' } })
|
||||||
.withMessage('Literal paths can be used')
|
.withMessage('Literal paths can be used')
|
||||||
@@ -414,7 +406,7 @@ describe('basic context', function() {
|
|||||||
.toCompileTo('Goodbye beautiful world!');
|
.toCompileTo('Goodbye beautiful world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('literal references', function() {
|
it('literal references', function () {
|
||||||
expectTemplate('Goodbye {{[foo bar]}} world!')
|
expectTemplate('Goodbye {{[foo bar]}} world!')
|
||||||
.withInput({ 'foo bar': 'beautiful' })
|
.withInput({ 'foo bar': 'beautiful' })
|
||||||
.toCompileTo('Goodbye beautiful world!');
|
.toCompileTo('Goodbye beautiful world!');
|
||||||
@@ -440,24 +432,22 @@ describe('basic context', function() {
|
|||||||
.toCompileTo('Goodbye beautiful world!');
|
.toCompileTo('Goodbye beautiful world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("that current context path ({{.}}) doesn't hit helpers", function() {
|
it("that current context path ({{.}}) doesn't hit helpers", function () {
|
||||||
expectTemplate('test: {{.}}')
|
expectTemplate('test: {{.}}')
|
||||||
.withInput(null)
|
.withInput(null)
|
||||||
.withHelpers({ helper: 'awesome' })
|
.withHelpers({ helper: 'awesome' })
|
||||||
.toCompileTo('test: ');
|
.toCompileTo('test: ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('complex but empty paths', function() {
|
it('complex but empty paths', function () {
|
||||||
expectTemplate('{{person/name}}')
|
expectTemplate('{{person/name}}')
|
||||||
.withInput({ person: { name: null } })
|
.withInput({ person: { name: null } })
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
|
|
||||||
expectTemplate('{{person/name}}')
|
expectTemplate('{{person/name}}').withInput({ person: {} }).toCompileTo('');
|
||||||
.withInput({ person: {} })
|
|
||||||
.toCompileTo('');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('this keyword in paths', function() {
|
it('this keyword in paths', function () {
|
||||||
expectTemplate('{{#goodbyes}}{{this}}{{/goodbyes}}')
|
expectTemplate('{{#goodbyes}}{{this}}{{/goodbyes}}')
|
||||||
.withInput({ goodbyes: ['goodbye', 'Goodbye', 'GOODBYE'] })
|
.withInput({ goodbyes: ['goodbye', 'Goodbye', 'GOODBYE'] })
|
||||||
.withMessage('This keyword in paths evaluates to current context')
|
.withMessage('This keyword in paths evaluates to current context')
|
||||||
@@ -465,32 +455,30 @@ describe('basic context', function() {
|
|||||||
|
|
||||||
expectTemplate('{{#hellos}}{{this/text}}{{/hellos}}')
|
expectTemplate('{{#hellos}}{{this/text}}{{/hellos}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }]
|
hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }],
|
||||||
})
|
})
|
||||||
.withMessage('This keyword evaluates in more complex paths')
|
.withMessage('This keyword evaluates in more complex paths')
|
||||||
.toCompileTo('helloHelloHELLO');
|
.toCompileTo('helloHelloHELLO');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('this keyword nested inside path', function() {
|
it('this keyword nested inside path', function () {
|
||||||
expectTemplate('{{#hellos}}{{text/this/foo}}{{/hellos}}').toThrow(
|
expectTemplate('{{#hellos}}{{text/this/foo}}{{/hellos}}').toThrow(
|
||||||
Error,
|
Error,
|
||||||
'Invalid path: text/this - 1:13'
|
'Invalid path: text/this - 1:13'
|
||||||
);
|
);
|
||||||
|
|
||||||
expectTemplate('{{[this]}}')
|
expectTemplate('{{[this]}}').withInput({ this: 'bar' }).toCompileTo('bar');
|
||||||
.withInput({ this: 'bar' })
|
|
||||||
.toCompileTo('bar');
|
|
||||||
|
|
||||||
expectTemplate('{{text/[this]}}')
|
expectTemplate('{{text/[this]}}')
|
||||||
.withInput({ text: { this: 'bar' } })
|
.withInput({ text: { this: 'bar' } })
|
||||||
.toCompileTo('bar');
|
.toCompileTo('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('this keyword in helpers', function() {
|
it('this keyword in helpers', function () {
|
||||||
var helpers = {
|
var helpers = {
|
||||||
foo: function(value) {
|
foo: function (value) {
|
||||||
return 'bar ' + value;
|
return 'bar ' + value;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
expectTemplate('{{#goodbyes}}{{foo this}}{{/goodbyes}}')
|
expectTemplate('{{#goodbyes}}{{foo this}}{{/goodbyes}}')
|
||||||
@@ -501,14 +489,14 @@ describe('basic context', function() {
|
|||||||
|
|
||||||
expectTemplate('{{#hellos}}{{foo this/text}}{{/hellos}}')
|
expectTemplate('{{#hellos}}{{foo this/text}}{{/hellos}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }]
|
hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }],
|
||||||
})
|
})
|
||||||
.withHelpers(helpers)
|
.withHelpers(helpers)
|
||||||
.withMessage('This keyword evaluates in more complex paths')
|
.withMessage('This keyword evaluates in more complex paths')
|
||||||
.toCompileTo('bar hellobar Hellobar HELLO');
|
.toCompileTo('bar hellobar Hellobar HELLO');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('this keyword nested inside helpers param', function() {
|
it('this keyword nested inside helpers param', function () {
|
||||||
expectTemplate('{{#hellos}}{{foo text/this/foo}}{{/hellos}}').toThrow(
|
expectTemplate('{{#hellos}}{{foo text/this/foo}}{{/hellos}}').toThrow(
|
||||||
Error,
|
Error,
|
||||||
'Invalid path: text/this - 1:17'
|
'Invalid path: text/this - 1:17'
|
||||||
@@ -516,79 +504,69 @@ describe('basic context', function() {
|
|||||||
|
|
||||||
expectTemplate('{{foo [this]}}')
|
expectTemplate('{{foo [this]}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
foo: function(value) {
|
foo: function (value) {
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
this: 'bar'
|
this: 'bar',
|
||||||
})
|
})
|
||||||
.toCompileTo('bar');
|
.toCompileTo('bar');
|
||||||
|
|
||||||
expectTemplate('{{foo text/[this]}}')
|
expectTemplate('{{foo text/[this]}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
foo: function(value) {
|
foo: function (value) {
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
text: { this: 'bar' }
|
text: { this: 'bar' },
|
||||||
})
|
})
|
||||||
.toCompileTo('bar');
|
.toCompileTo('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('pass string literals', function() {
|
it('pass string literals', function () {
|
||||||
expectTemplate('{{"foo"}}').toCompileTo('');
|
expectTemplate('{{"foo"}}').toCompileTo('');
|
||||||
|
|
||||||
expectTemplate('{{"foo"}}')
|
expectTemplate('{{"foo"}}').withInput({ foo: 'bar' }).toCompileTo('bar');
|
||||||
.withInput({ foo: 'bar' })
|
|
||||||
.toCompileTo('bar');
|
|
||||||
|
|
||||||
expectTemplate('{{#"foo"}}{{.}}{{/"foo"}}')
|
expectTemplate('{{#"foo"}}{{.}}{{/"foo"}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
foo: ['bar', 'baz']
|
foo: ['bar', 'baz'],
|
||||||
})
|
})
|
||||||
.toCompileTo('barbaz');
|
.toCompileTo('barbaz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('pass number literals', function() {
|
it('pass number literals', function () {
|
||||||
expectTemplate('{{12}}').toCompileTo('');
|
expectTemplate('{{12}}').toCompileTo('');
|
||||||
|
|
||||||
expectTemplate('{{12}}')
|
expectTemplate('{{12}}').withInput({ 12: 'bar' }).toCompileTo('bar');
|
||||||
.withInput({ '12': 'bar' })
|
|
||||||
.toCompileTo('bar');
|
|
||||||
|
|
||||||
expectTemplate('{{12.34}}').toCompileTo('');
|
expectTemplate('{{12.34}}').toCompileTo('');
|
||||||
|
|
||||||
expectTemplate('{{12.34}}')
|
expectTemplate('{{12.34}}').withInput({ 12.34: 'bar' }).toCompileTo('bar');
|
||||||
.withInput({ '12.34': 'bar' })
|
|
||||||
.toCompileTo('bar');
|
|
||||||
|
|
||||||
expectTemplate('{{12.34 1}}')
|
expectTemplate('{{12.34 1}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
'12.34': function(arg) {
|
12.34: function (arg) {
|
||||||
return 'bar' + arg;
|
return 'bar' + arg;
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('bar1');
|
.toCompileTo('bar1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('pass boolean literals', function() {
|
it('pass boolean literals', function () {
|
||||||
expectTemplate('{{true}}').toCompileTo('');
|
expectTemplate('{{true}}').toCompileTo('');
|
||||||
|
|
||||||
expectTemplate('{{true}}')
|
expectTemplate('{{true}}').withInput({ '': 'foo' }).toCompileTo('');
|
||||||
.withInput({ '': 'foo' })
|
|
||||||
.toCompileTo('');
|
|
||||||
|
|
||||||
expectTemplate('{{false}}')
|
expectTemplate('{{false}}').withInput({ false: 'foo' }).toCompileTo('foo');
|
||||||
.withInput({ false: 'foo' })
|
|
||||||
.toCompileTo('foo');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle literals in subexpression', function() {
|
it('should handle literals in subexpression', function () {
|
||||||
expectTemplate('{{foo (false)}}')
|
expectTemplate('{{foo (false)}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
false: function() {
|
false: function () {
|
||||||
return 'bar';
|
return 'bar';
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.withHelper('foo', function(arg) {
|
.withHelper('foo', function (arg) {
|
||||||
return arg;
|
return arg;
|
||||||
})
|
})
|
||||||
.toCompileTo('bar');
|
.toCompileTo('bar');
|
||||||
|
|||||||
+84
-84
@@ -1,5 +1,5 @@
|
|||||||
describe('blocks', function() {
|
describe('blocks', function () {
|
||||||
it('array', function() {
|
it('array', function () {
|
||||||
var string = '{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!';
|
var string = '{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!';
|
||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
@@ -7,9 +7,9 @@ describe('blocks', function() {
|
|||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('Arrays iterate over the contents when not empty')
|
.withMessage('Arrays iterate over the contents when not empty')
|
||||||
.toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!');
|
.toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!');
|
||||||
@@ -17,13 +17,13 @@ describe('blocks', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbyes: [],
|
goodbyes: [],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('Arrays ignore the contents when empty')
|
.withMessage('Arrays ignore the contents when empty')
|
||||||
.toCompileTo('cruel world!');
|
.toCompileTo('cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('array without data', function() {
|
it('array without data', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#goodbyes}}{{text}}{{/goodbyes}} {{#goodbyes}}{{text}}{{/goodbyes}}'
|
'{{#goodbyes}}{{text}}{{/goodbyes}} {{#goodbyes}}{{text}}{{/goodbyes}}'
|
||||||
)
|
)
|
||||||
@@ -31,15 +31,15 @@ describe('blocks', function() {
|
|||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withCompileOptions({ compat: false })
|
.withCompileOptions({ compat: false })
|
||||||
.toCompileTo('goodbyeGoodbyeGOODBYE goodbyeGoodbyeGOODBYE');
|
.toCompileTo('goodbyeGoodbyeGOODBYE goodbyeGoodbyeGOODBYE');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('array with @index', function() {
|
it('array with @index', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!'
|
'{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
@@ -47,15 +47,15 @@ describe('blocks', function() {
|
|||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('The @index variable is used')
|
.withMessage('The @index variable is used')
|
||||||
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('empty block', function() {
|
it('empty block', function () {
|
||||||
var string = '{{#goodbyes}}{{/goodbyes}}cruel {{world}}!';
|
var string = '{{#goodbyes}}{{/goodbyes}}cruel {{world}}!';
|
||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
@@ -63,9 +63,9 @@ describe('blocks', function() {
|
|||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('Arrays iterate over the contents when not empty')
|
.withMessage('Arrays iterate over the contents when not empty')
|
||||||
.toCompileTo('cruel world!');
|
.toCompileTo('cruel world!');
|
||||||
@@ -73,21 +73,21 @@ describe('blocks', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbyes: [],
|
goodbyes: [],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('Arrays ignore the contents when empty')
|
.withMessage('Arrays ignore the contents when empty')
|
||||||
.toCompileTo('cruel world!');
|
.toCompileTo('cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('block with complex lookup', function() {
|
it('block with complex lookup', function () {
|
||||||
expectTemplate('{{#goodbyes}}{{text}} cruel {{../name}}! {{/goodbyes}}')
|
expectTemplate('{{#goodbyes}}{{text}} cruel {{../name}}! {{/goodbyes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
name: 'Alan',
|
name: 'Alan',
|
||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withMessage(
|
.withMessage(
|
||||||
'Templates can access variables in contexts up the stack with relative path syntax'
|
'Templates can access variables in contexts up the stack with relative path syntax'
|
||||||
@@ -97,37 +97,37 @@ describe('blocks', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multiple blocks with complex lookup', function() {
|
it('multiple blocks with complex lookup', function () {
|
||||||
expectTemplate('{{#goodbyes}}{{../name}}{{../name}}{{/goodbyes}}')
|
expectTemplate('{{#goodbyes}}{{../name}}{{../name}}{{/goodbyes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
name: 'Alan',
|
name: 'Alan',
|
||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.toCompileTo('AlanAlanAlanAlanAlanAlan');
|
.toCompileTo('AlanAlanAlanAlanAlanAlan');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('block with complex lookup using nested context', function() {
|
it('block with complex lookup using nested context', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#goodbyes}}{{text}} cruel {{foo/../name}}! {{/goodbyes}}'
|
'{{#goodbyes}}{{text}} cruel {{foo/../name}}! {{/goodbyes}}'
|
||||||
).toThrow(Error);
|
).toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('block with deep nested complex lookup', function() {
|
it('block with deep nested complex lookup', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#outer}}Goodbye {{#inner}}cruel {{../sibling}} {{../../omg}}{{/inner}}{{/outer}}'
|
'{{#outer}}Goodbye {{#inner}}cruel {{../sibling}} {{../../omg}}{{/inner}}{{/outer}}'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
omg: 'OMG!',
|
omg: 'OMG!',
|
||||||
outer: [{ sibling: 'sad', inner: [{ text: 'goodbye' }] }]
|
outer: [{ sibling: 'sad', inner: [{ text: 'goodbye' }] }],
|
||||||
})
|
})
|
||||||
.toCompileTo('Goodbye cruel sad OMG!');
|
.toCompileTo('Goodbye cruel sad OMG!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('works with cached blocks', function() {
|
it('works with cached blocks', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each person}}{{#with .}}{{first}} {{last}}{{/with}}{{/each}}'
|
'{{#each person}}{{#with .}}{{first}} {{last}}{{/with}}{{/each}}'
|
||||||
)
|
)
|
||||||
@@ -135,14 +135,14 @@ describe('blocks', function() {
|
|||||||
.withInput({
|
.withInput({
|
||||||
person: [
|
person: [
|
||||||
{ first: 'Alan', last: 'Johnson' },
|
{ first: 'Alan', last: 'Johnson' },
|
||||||
{ first: 'Alan', last: 'Johnson' }
|
{ first: 'Alan', last: 'Johnson' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.toCompileTo('Alan JohnsonAlan Johnson');
|
.toCompileTo('Alan JohnsonAlan Johnson');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('inverted sections', function() {
|
describe('inverted sections', function () {
|
||||||
it('inverted sections with unset value', function() {
|
it('inverted sections with unset value', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
|
'{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
|
||||||
)
|
)
|
||||||
@@ -150,7 +150,7 @@ describe('blocks', function() {
|
|||||||
.toCompileTo('Right On!');
|
.toCompileTo('Right On!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('inverted section with false value', function() {
|
it('inverted section with false value', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
|
'{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
|
||||||
)
|
)
|
||||||
@@ -159,7 +159,7 @@ describe('blocks', function() {
|
|||||||
.toCompileTo('Right On!');
|
.toCompileTo('Right On!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('inverted section with empty set', function() {
|
it('inverted section with empty set', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
|
'{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
|
||||||
)
|
)
|
||||||
@@ -168,13 +168,13 @@ describe('blocks', function() {
|
|||||||
.toCompileTo('Right On!');
|
.toCompileTo('Right On!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('block inverted sections', function() {
|
it('block inverted sections', function () {
|
||||||
expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}')
|
expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}')
|
||||||
.withInput({ none: 'No people' })
|
.withInput({ none: 'No people' })
|
||||||
.toCompileTo('No people');
|
.toCompileTo('No people');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('chained inverted sections', function() {
|
it('chained inverted sections', function () {
|
||||||
expectTemplate('{{#people}}{{name}}{{else if none}}{{none}}{{/people}}')
|
expectTemplate('{{#people}}{{name}}{{else if none}}{{none}}{{/people}}')
|
||||||
.withInput({ none: 'No people' })
|
.withInput({ none: 'No people' })
|
||||||
.toCompileTo('No people');
|
.toCompileTo('No people');
|
||||||
@@ -192,24 +192,24 @@ describe('blocks', function() {
|
|||||||
.toCompileTo('No people');
|
.toCompileTo('No people');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('chained inverted sections with mismatch', function() {
|
it('chained inverted sections with mismatch', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#people}}{{name}}{{else if none}}{{none}}{{/if}}'
|
'{{#people}}{{name}}{{else if none}}{{none}}{{/if}}'
|
||||||
).toThrow(Error);
|
).toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('block inverted sections with empty arrays', function() {
|
it('block inverted sections with empty arrays', function () {
|
||||||
expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}')
|
expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
none: 'No people',
|
none: 'No people',
|
||||||
people: []
|
people: [],
|
||||||
})
|
})
|
||||||
.toCompileTo('No people');
|
.toCompileTo('No people');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('standalone sections', function() {
|
describe('standalone sections', function () {
|
||||||
it('block standalone else sections', function() {
|
it('block standalone else sections', function () {
|
||||||
expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n')
|
expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n')
|
||||||
.withInput({ none: 'No people' })
|
.withInput({ none: 'No people' })
|
||||||
.toCompileTo('No people\n');
|
.toCompileTo('No people\n');
|
||||||
@@ -223,7 +223,7 @@ describe('blocks', function() {
|
|||||||
.toCompileTo('No people\n');
|
.toCompileTo('No people\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('block standalone else sections can be disabled', function() {
|
it('block standalone else sections can be disabled', function () {
|
||||||
expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n')
|
expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n')
|
||||||
.withInput({ none: 'No people' })
|
.withInput({ none: 'No people' })
|
||||||
.withCompileOptions({ ignoreStandalone: true })
|
.withCompileOptions({ ignoreStandalone: true })
|
||||||
@@ -235,7 +235,7 @@ describe('blocks', function() {
|
|||||||
.toCompileTo('\nNo people\n\n');
|
.toCompileTo('\nNo people\n\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('block standalone chained else sections', function() {
|
it('block standalone chained else sections', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n'
|
'{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n'
|
||||||
)
|
)
|
||||||
@@ -249,17 +249,17 @@ describe('blocks', function() {
|
|||||||
.toCompileTo('No people\n');
|
.toCompileTo('No people\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle nesting', function() {
|
it('should handle nesting', function () {
|
||||||
expectTemplate('{{#data}}\n{{#if true}}\n{{.}}\n{{/if}}\n{{/data}}\nOK.')
|
expectTemplate('{{#data}}\n{{#if true}}\n{{.}}\n{{/if}}\n{{/data}}\nOK.')
|
||||||
.withInput({
|
.withInput({
|
||||||
data: [1, 3, 5]
|
data: [1, 3, 5],
|
||||||
})
|
})
|
||||||
.toCompileTo('1\n3\n5\nOK.');
|
.toCompileTo('1\n3\n5\nOK.');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('compat mode', function() {
|
describe('compat mode', function () {
|
||||||
it('block with deep recursive lookup lookup', function() {
|
it('block with deep recursive lookup lookup', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#outer}}Goodbye {{#inner}}cruel {{omg}}{{/inner}}{{/outer}}'
|
'{{#outer}}Goodbye {{#inner}}cruel {{omg}}{{/inner}}{{/outer}}'
|
||||||
)
|
)
|
||||||
@@ -268,108 +268,108 @@ describe('blocks', function() {
|
|||||||
.toCompileTo('Goodbye cruel OMG!');
|
.toCompileTo('Goodbye cruel OMG!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('block with deep recursive pathed lookup', function() {
|
it('block with deep recursive pathed lookup', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}'
|
'{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
omg: { yes: 'OMG!' },
|
omg: { yes: 'OMG!' },
|
||||||
outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }]
|
outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }],
|
||||||
})
|
})
|
||||||
.withCompileOptions({ compat: true })
|
.withCompileOptions({ compat: true })
|
||||||
.toCompileTo('Goodbye cruel OMG!');
|
.toCompileTo('Goodbye cruel OMG!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('block with missed recursive lookup', function() {
|
it('block with missed recursive lookup', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}'
|
'{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
omg: { no: 'OMG!' },
|
omg: { no: 'OMG!' },
|
||||||
outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }]
|
outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }],
|
||||||
})
|
})
|
||||||
.withCompileOptions({ compat: true })
|
.withCompileOptions({ compat: true })
|
||||||
.toCompileTo('Goodbye cruel ');
|
.toCompileTo('Goodbye cruel ');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('decorators', function() {
|
describe('decorators', function () {
|
||||||
it('should apply mustache decorators', function() {
|
it('should apply mustache decorators', function () {
|
||||||
expectTemplate('{{#helper}}{{*decorator}}{{/helper}}')
|
expectTemplate('{{#helper}}{{*decorator}}{{/helper}}')
|
||||||
.withHelper('helper', function(options) {
|
.withHelper('helper', function (options) {
|
||||||
return options.fn.run;
|
return options.fn.run;
|
||||||
})
|
})
|
||||||
.withDecorator('decorator', function(fn) {
|
.withDecorator('decorator', function (fn) {
|
||||||
fn.run = 'success';
|
fn.run = 'success';
|
||||||
return fn;
|
return fn;
|
||||||
})
|
})
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should apply allow undefined return', function() {
|
it('should apply allow undefined return', function () {
|
||||||
expectTemplate('{{#helper}}{{*decorator}}suc{{/helper}}')
|
expectTemplate('{{#helper}}{{*decorator}}suc{{/helper}}')
|
||||||
.withHelper('helper', function(options) {
|
.withHelper('helper', function (options) {
|
||||||
return options.fn() + options.fn.run;
|
return options.fn() + options.fn.run;
|
||||||
})
|
})
|
||||||
.withDecorator('decorator', function(fn) {
|
.withDecorator('decorator', function (fn) {
|
||||||
fn.run = 'cess';
|
fn.run = 'cess';
|
||||||
})
|
})
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should apply block decorators', function() {
|
it('should apply block decorators', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#helper}}{{#*decorator}}success{{/decorator}}{{/helper}}'
|
'{{#helper}}{{#*decorator}}success{{/decorator}}{{/helper}}'
|
||||||
)
|
)
|
||||||
.withHelper('helper', function(options) {
|
.withHelper('helper', function (options) {
|
||||||
return options.fn.run;
|
return options.fn.run;
|
||||||
})
|
})
|
||||||
.withDecorator('decorator', function(fn, props, container, options) {
|
.withDecorator('decorator', function (fn, props, container, options) {
|
||||||
fn.run = options.fn();
|
fn.run = options.fn();
|
||||||
return fn;
|
return fn;
|
||||||
})
|
})
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support nested decorators', function() {
|
it('should support nested decorators', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#helper}}{{#*decorator}}{{#*nested}}suc{{/nested}}cess{{/decorator}}{{/helper}}'
|
'{{#helper}}{{#*decorator}}{{#*nested}}suc{{/nested}}cess{{/decorator}}{{/helper}}'
|
||||||
)
|
)
|
||||||
.withHelper('helper', function(options) {
|
.withHelper('helper', function (options) {
|
||||||
return options.fn.run;
|
return options.fn.run;
|
||||||
})
|
})
|
||||||
.withDecorators({
|
.withDecorators({
|
||||||
decorator: function(fn, props, container, options) {
|
decorator: function (fn, props, container, options) {
|
||||||
fn.run = options.fn.nested + options.fn();
|
fn.run = options.fn.nested + options.fn();
|
||||||
return fn;
|
return fn;
|
||||||
},
|
},
|
||||||
nested: function(fn, props, container, options) {
|
nested: function (fn, props, container, options) {
|
||||||
props.nested = options.fn();
|
props.nested = options.fn();
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should apply multiple decorators', function() {
|
it('should apply multiple decorators', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#helper}}{{#*decorator}}suc{{/decorator}}{{#*decorator}}cess{{/decorator}}{{/helper}}'
|
'{{#helper}}{{#*decorator}}suc{{/decorator}}{{#*decorator}}cess{{/decorator}}{{/helper}}'
|
||||||
)
|
)
|
||||||
.withHelper('helper', function(options) {
|
.withHelper('helper', function (options) {
|
||||||
return options.fn.run;
|
return options.fn.run;
|
||||||
})
|
})
|
||||||
.withDecorator('decorator', function(fn, props, container, options) {
|
.withDecorator('decorator', function (fn, props, container, options) {
|
||||||
fn.run = (fn.run || '') + options.fn();
|
fn.run = (fn.run || '') + options.fn();
|
||||||
return fn;
|
return fn;
|
||||||
})
|
})
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should access parent variables', function() {
|
it('should access parent variables', function () {
|
||||||
expectTemplate('{{#helper}}{{*decorator foo}}{{/helper}}')
|
expectTemplate('{{#helper}}{{*decorator foo}}{{/helper}}')
|
||||||
.withHelper('helper', function(options) {
|
.withHelper('helper', function (options) {
|
||||||
return options.fn.run;
|
return options.fn.run;
|
||||||
})
|
})
|
||||||
.withDecorator('decorator', function(fn, props, container, options) {
|
.withDecorator('decorator', function (fn, props, container, options) {
|
||||||
fn.run = options.args;
|
fn.run = options.args;
|
||||||
return fn;
|
return fn;
|
||||||
})
|
})
|
||||||
@@ -377,10 +377,10 @@ describe('blocks', function() {
|
|||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with root program', function() {
|
it('should work with root program', function () {
|
||||||
var run;
|
var run;
|
||||||
expectTemplate('{{*decorator "success"}}')
|
expectTemplate('{{*decorator "success"}}')
|
||||||
.withDecorator('decorator', function(fn, props, container, options) {
|
.withDecorator('decorator', function (fn, props, container, options) {
|
||||||
equals(options.args[0], 'success');
|
equals(options.args[0], 'success');
|
||||||
run = true;
|
run = true;
|
||||||
return fn;
|
return fn;
|
||||||
@@ -390,10 +390,10 @@ describe('blocks', function() {
|
|||||||
equals(run, true);
|
equals(run, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when accessing variables from root', function() {
|
it('should fail when accessing variables from root', function () {
|
||||||
var run;
|
var run;
|
||||||
expectTemplate('{{*decorator foo}}')
|
expectTemplate('{{*decorator foo}}')
|
||||||
.withDecorator('decorator', function(fn, props, container, options) {
|
.withDecorator('decorator', function (fn, props, container, options) {
|
||||||
equals(options.args[0], undefined);
|
equals(options.args[0], undefined);
|
||||||
run = true;
|
run = true;
|
||||||
return fn;
|
return fn;
|
||||||
@@ -403,11 +403,11 @@ describe('blocks', function() {
|
|||||||
equals(run, true);
|
equals(run, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('registration', function() {
|
describe('registration', function () {
|
||||||
it('unregisters', function() {
|
it('unregisters', function () {
|
||||||
handlebarsEnv.decorators = {};
|
handlebarsEnv.decorators = {};
|
||||||
|
|
||||||
handlebarsEnv.registerDecorator('foo', function() {
|
handlebarsEnv.registerDecorator('foo', function () {
|
||||||
return 'fail';
|
return 'fail';
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -416,12 +416,12 @@ describe('blocks', function() {
|
|||||||
equals(handlebarsEnv.decorators.foo, undefined);
|
equals(handlebarsEnv.decorators.foo, undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows multiple globals', function() {
|
it('allows multiple globals', function () {
|
||||||
handlebarsEnv.decorators = {};
|
handlebarsEnv.decorators = {};
|
||||||
|
|
||||||
handlebarsEnv.registerDecorator({
|
handlebarsEnv.registerDecorator({
|
||||||
foo: function() {},
|
foo: function () {},
|
||||||
bar: function() {}
|
bar: function () {},
|
||||||
});
|
});
|
||||||
|
|
||||||
equals(!!handlebarsEnv.decorators.foo, true);
|
equals(!!handlebarsEnv.decorators.foo, true);
|
||||||
@@ -432,17 +432,17 @@ describe('blocks', function() {
|
|||||||
equals(handlebarsEnv.decorators.bar, undefined);
|
equals(handlebarsEnv.decorators.bar, undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails with multiple and args', function() {
|
it('fails with multiple and args', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
handlebarsEnv.registerDecorator(
|
handlebarsEnv.registerDecorator(
|
||||||
{
|
{
|
||||||
world: function() {
|
world: function () {
|
||||||
return 'world!';
|
return 'world!';
|
||||||
},
|
},
|
||||||
testHelper: function() {
|
testHelper: function () {
|
||||||
return 'found it!';
|
return 'found it!';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|||||||
+128
-126
@@ -1,12 +1,12 @@
|
|||||||
describe('builtin helpers', function() {
|
describe('builtin helpers', function () {
|
||||||
describe('#if', function() {
|
describe('#if', function () {
|
||||||
it('if', function() {
|
it('if', function () {
|
||||||
var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
|
var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
|
||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: true,
|
goodbye: true,
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('if with boolean argument shows the contents when true')
|
.withMessage('if with boolean argument shows the contents when true')
|
||||||
.toCompileTo('GOODBYE cruel world!');
|
.toCompileTo('GOODBYE cruel world!');
|
||||||
@@ -14,7 +14,7 @@ describe('builtin helpers', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: 'dummy',
|
goodbye: 'dummy',
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('if with string argument shows the contents')
|
.withMessage('if with string argument shows the contents')
|
||||||
.toCompileTo('GOODBYE cruel world!');
|
.toCompileTo('GOODBYE cruel world!');
|
||||||
@@ -22,7 +22,7 @@ describe('builtin helpers', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: false,
|
goodbye: false,
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage(
|
.withMessage(
|
||||||
'if with boolean argument does not show the contents when false'
|
'if with boolean argument does not show the contents when false'
|
||||||
@@ -37,7 +37,7 @@ describe('builtin helpers', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: ['foo'],
|
goodbye: ['foo'],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('if with non-empty array shows the contents')
|
.withMessage('if with non-empty array shows the contents')
|
||||||
.toCompileTo('GOODBYE cruel world!');
|
.toCompileTo('GOODBYE cruel world!');
|
||||||
@@ -45,7 +45,7 @@ describe('builtin helpers', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: [],
|
goodbye: [],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('if with empty array does not show the contents')
|
.withMessage('if with empty array does not show the contents')
|
||||||
.toCompileTo('cruel world!');
|
.toCompileTo('cruel world!');
|
||||||
@@ -53,7 +53,7 @@ describe('builtin helpers', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: 0,
|
goodbye: 0,
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('if with zero does not show the contents')
|
.withMessage('if with zero does not show the contents')
|
||||||
.toCompileTo('cruel world!');
|
.toCompileTo('cruel world!');
|
||||||
@@ -63,21 +63,21 @@ describe('builtin helpers', function() {
|
|||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: 0,
|
goodbye: 0,
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('if with zero does not show the contents')
|
.withMessage('if with zero does not show the contents')
|
||||||
.toCompileTo('GOODBYE cruel world!');
|
.toCompileTo('GOODBYE cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('if with function argument', function() {
|
it('if with function argument', function () {
|
||||||
var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
|
var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
|
||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: function() {
|
goodbye: function () {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage(
|
.withMessage(
|
||||||
'if with function shows the contents when function returns true'
|
'if with function shows the contents when function returns true'
|
||||||
@@ -86,10 +86,10 @@ describe('builtin helpers', function() {
|
|||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: function() {
|
goodbye: function () {
|
||||||
return this.world;
|
return this.world;
|
||||||
},
|
},
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage(
|
.withMessage(
|
||||||
'if with function shows the contents when function returns string'
|
'if with function shows the contents when function returns string'
|
||||||
@@ -98,10 +98,10 @@ describe('builtin helpers', function() {
|
|||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: function() {
|
goodbye: function () {
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage(
|
.withMessage(
|
||||||
'if with function does not show the contents when returns false'
|
'if with function does not show the contents when returns false'
|
||||||
@@ -110,10 +110,10 @@ describe('builtin helpers', function() {
|
|||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbye: function() {
|
goodbye: function () {
|
||||||
return this.foo;
|
return this.foo;
|
||||||
},
|
},
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage(
|
.withMessage(
|
||||||
'if with function does not show the contents when returns undefined'
|
'if with function does not show the contents when returns undefined'
|
||||||
@@ -121,61 +121,61 @@ describe('builtin helpers', function() {
|
|||||||
.toCompileTo('cruel world!');
|
.toCompileTo('cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change the depth list', function() {
|
it('should not change the depth list', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#with foo}}{{#if goodbye}}GOODBYE cruel {{../world}}!{{/if}}{{/with}}'
|
'{{#with foo}}{{#if goodbye}}GOODBYE cruel {{../world}}!{{/if}}{{/with}}'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
foo: { goodbye: true },
|
foo: { goodbye: true },
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.toCompileTo('GOODBYE cruel world!');
|
.toCompileTo('GOODBYE cruel world!');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#with', function() {
|
describe('#with', function () {
|
||||||
it('with', function() {
|
it('with', function () {
|
||||||
expectTemplate('{{#with person}}{{first}} {{last}}{{/with}}')
|
expectTemplate('{{#with person}}{{first}} {{last}}{{/with}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
person: {
|
person: {
|
||||||
first: 'Alan',
|
first: 'Alan',
|
||||||
last: 'Johnson'
|
last: 'Johnson',
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('Alan Johnson');
|
.toCompileTo('Alan Johnson');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with with function argument', function() {
|
it('with with function argument', function () {
|
||||||
expectTemplate('{{#with person}}{{first}} {{last}}{{/with}}')
|
expectTemplate('{{#with person}}{{first}} {{last}}{{/with}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
person: function() {
|
person: function () {
|
||||||
return {
|
return {
|
||||||
first: 'Alan',
|
first: 'Alan',
|
||||||
last: 'Johnson'
|
last: 'Johnson',
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('Alan Johnson');
|
.toCompileTo('Alan Johnson');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with with else', function() {
|
it('with with else', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#with person}}Person is present{{else}}Person is not present{{/with}}'
|
'{{#with person}}Person is present{{else}}Person is not present{{/with}}'
|
||||||
).toCompileTo('Person is not present');
|
).toCompileTo('Person is not present');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with provides block parameter', function() {
|
it('with provides block parameter', function () {
|
||||||
expectTemplate('{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}')
|
expectTemplate('{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
person: {
|
person: {
|
||||||
first: 'Alan',
|
first: 'Alan',
|
||||||
last: 'Johnson'
|
last: 'Johnson',
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('Alan Johnson');
|
.toCompileTo('Alan Johnson');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('works when data is disabled', function() {
|
it('works when data is disabled', function () {
|
||||||
expectTemplate('{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}')
|
expectTemplate('{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}')
|
||||||
.withInput({ person: { first: 'Alan', last: 'Johnson' } })
|
.withInput({ person: { first: 'Alan', last: 'Johnson' } })
|
||||||
.withCompileOptions({ data: false })
|
.withCompileOptions({ data: false })
|
||||||
@@ -183,14 +183,14 @@ describe('builtin helpers', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#each', function() {
|
describe('#each', function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
handlebarsEnv.registerHelper('detectDataInsideEach', function(options) {
|
handlebarsEnv.registerHelper('detectDataInsideEach', function (options) {
|
||||||
return options.data && options.data.exclaim;
|
return options.data && options.data.exclaim;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each', function() {
|
it('each', function () {
|
||||||
var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
|
var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
|
||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
@@ -198,9 +198,9 @@ describe('builtin helpers', function() {
|
|||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage(
|
.withMessage(
|
||||||
'each with array argument iterates over the contents when not empty'
|
'each with array argument iterates over the contents when not empty'
|
||||||
@@ -210,21 +210,21 @@ describe('builtin helpers', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbyes: [],
|
goodbyes: [],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('each with array argument ignores the contents when empty')
|
.withMessage('each with array argument ignores the contents when empty')
|
||||||
.toCompileTo('cruel world!');
|
.toCompileTo('cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each without data', function() {
|
it('each without data', function () {
|
||||||
expectTemplate('{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!')
|
expectTemplate('{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!')
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withRuntimeOptions({ data: false })
|
.withRuntimeOptions({ data: false })
|
||||||
.withCompileOptions({ data: false })
|
.withCompileOptions({ data: false })
|
||||||
@@ -237,13 +237,13 @@ describe('builtin helpers', function() {
|
|||||||
.toCompileTo('cruelworld');
|
.toCompileTo('cruelworld');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each without context', function() {
|
it('each without context', function () {
|
||||||
expectTemplate('{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!')
|
expectTemplate('{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!')
|
||||||
.withInput(undefined)
|
.withInput(undefined)
|
||||||
.toCompileTo('cruel !');
|
.toCompileTo('cruel !');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each with an object and @key', function() {
|
it('each with an object and @key', function () {
|
||||||
var string =
|
var string =
|
||||||
'{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!';
|
'{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!';
|
||||||
|
|
||||||
@@ -272,12 +272,12 @@ describe('builtin helpers', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbyes: {},
|
goodbyes: {},
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.toCompileTo('cruel world!');
|
.toCompileTo('cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each with @index', function() {
|
it('each with @index', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
|
'{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
@@ -285,15 +285,15 @@ describe('builtin helpers', function() {
|
|||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('The @index variable is used')
|
.withMessage('The @index variable is used')
|
||||||
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each with nested @index', function() {
|
it('each with nested @index', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes}}{{@index}}. {{text}}! {{#each ../goodbyes}}{{@index}} {{/each}}After {{@index}} {{/each}}{{@index}}cruel {{world}}!'
|
'{{#each goodbyes}}{{@index}}. {{text}}! {{#each ../goodbyes}}{{@index}} {{/each}}After {{@index}} {{/each}}{{@index}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
@@ -301,9 +301,9 @@ describe('builtin helpers', function() {
|
|||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('The @index variable is used')
|
.withMessage('The @index variable is used')
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
@@ -311,20 +311,20 @@ describe('builtin helpers', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each with block params', function() {
|
it('each with block params', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes as |value index|}}{{index}}. {{value.text}}! {{#each ../goodbyes as |childValue childIndex|}} {{index}} {{childIndex}}{{/each}} After {{index}} {{/each}}{{index}}cruel {{world}}!'
|
'{{#each goodbyes as |value index|}}{{index}}. {{value.text}}! {{#each ../goodbyes as |childValue childIndex|}} {{index}} {{childIndex}}{{/each}} After {{index}} {{/each}}{{index}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }],
|
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
'0. goodbye! 0 0 0 1 After 0 1. Goodbye! 1 0 1 1 After 1 cruel world!'
|
'0. goodbye! 0 0 0 1 After 0 1. Goodbye! 1 0 1 1 After 1 cruel world!'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each with block params and strict compilation', function() {
|
it('each with block params and strict compilation', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes as |value index|}}{{index}}. {{value.text}}!{{/each}}'
|
'{{#each goodbyes as |value index|}}{{index}}. {{value.text}}!{{/each}}'
|
||||||
)
|
)
|
||||||
@@ -333,7 +333,7 @@ describe('builtin helpers', function() {
|
|||||||
.toCompileTo('0. goodbye!1. Goodbye!');
|
.toCompileTo('0. goodbye!1. Goodbye!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each object with @index', function() {
|
it('each object with @index', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
|
'{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
@@ -341,15 +341,15 @@ describe('builtin helpers', function() {
|
|||||||
goodbyes: {
|
goodbyes: {
|
||||||
a: { text: 'goodbye' },
|
a: { text: 'goodbye' },
|
||||||
b: { text: 'Goodbye' },
|
b: { text: 'Goodbye' },
|
||||||
c: { text: 'GOODBYE' }
|
c: { text: 'GOODBYE' },
|
||||||
},
|
},
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('The @index variable is used')
|
.withMessage('The @index variable is used')
|
||||||
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each with @first', function() {
|
it('each with @first', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
'{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
@@ -357,15 +357,15 @@ describe('builtin helpers', function() {
|
|||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('The @first variable is used')
|
.withMessage('The @first variable is used')
|
||||||
.toCompileTo('goodbye! cruel world!');
|
.toCompileTo('goodbye! cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each with nested @first', function() {
|
it('each with nested @first', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes}}({{#if @first}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @first}}{{text}}!{{/if}}{{/each}}{{#if @first}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!'
|
'{{#each goodbyes}}({{#if @first}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @first}}{{text}}!{{/if}}{{/each}}{{#if @first}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
@@ -373,9 +373,9 @@ describe('builtin helpers', function() {
|
|||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('The @first variable is used')
|
.withMessage('The @first variable is used')
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
@@ -383,19 +383,19 @@ describe('builtin helpers', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each object with @first', function() {
|
it('each object with @first', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
'{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } },
|
goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } },
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('The @first variable is used')
|
.withMessage('The @first variable is used')
|
||||||
.toCompileTo('goodbye! cruel world!');
|
.toCompileTo('goodbye! cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each with @last', function() {
|
it('each with @last', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
'{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
@@ -403,27 +403,27 @@ describe('builtin helpers', function() {
|
|||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('The @last variable is used')
|
.withMessage('The @last variable is used')
|
||||||
.toCompileTo('GOODBYE! cruel world!');
|
.toCompileTo('GOODBYE! cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each object with @last', function() {
|
it('each object with @last', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
'{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } },
|
goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } },
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('The @last variable is used')
|
.withMessage('The @last variable is used')
|
||||||
.toCompileTo('Goodbye! cruel world!');
|
.toCompileTo('Goodbye! cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each with nested @last', function() {
|
it('each with nested @last', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes}}({{#if @last}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @last}}{{text}}!{{/if}}{{/each}}{{#if @last}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!'
|
'{{#each goodbyes}}({{#if @last}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @last}}{{text}}!{{/if}}{{/each}}{{#if @last}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
@@ -431,9 +431,9 @@ describe('builtin helpers', function() {
|
|||||||
goodbyes: [
|
goodbyes: [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
],
|
],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('The @last variable is used')
|
.withMessage('The @last variable is used')
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
@@ -441,19 +441,19 @@ describe('builtin helpers', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each with function argument', function() {
|
it('each with function argument', function () {
|
||||||
var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
|
var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
|
||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbyes: function() {
|
goodbyes: function () {
|
||||||
return [
|
return [
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage(
|
.withMessage(
|
||||||
'each with array function argument iterates over the contents when not empty'
|
'each with array function argument iterates over the contents when not empty'
|
||||||
@@ -463,7 +463,7 @@ describe('builtin helpers', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbyes: [],
|
goodbyes: [],
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage(
|
.withMessage(
|
||||||
'each with array function argument ignores the contents when empty'
|
'each with array function argument ignores the contents when empty'
|
||||||
@@ -471,7 +471,7 @@ describe('builtin helpers', function() {
|
|||||||
.toCompileTo('cruel world!');
|
.toCompileTo('cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each object when last key is an empty string', function() {
|
it('each object when last key is an empty string', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
|
'{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
|
||||||
)
|
)
|
||||||
@@ -479,15 +479,15 @@ describe('builtin helpers', function() {
|
|||||||
goodbyes: {
|
goodbyes: {
|
||||||
a: { text: 'goodbye' },
|
a: { text: 'goodbye' },
|
||||||
b: { text: 'Goodbye' },
|
b: { text: 'Goodbye' },
|
||||||
'': { text: 'GOODBYE' }
|
'': { text: 'GOODBYE' },
|
||||||
},
|
},
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage('Empty string key is not skipped')
|
.withMessage('Empty string key is not skipped')
|
||||||
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('data passed to helpers', function() {
|
it('data passed to helpers', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each letters}}{{this}}{{detectDataInsideEach}}{{/each}}'
|
'{{#each letters}}{{this}}{{detectDataInsideEach}}{{/each}}'
|
||||||
)
|
)
|
||||||
@@ -495,13 +495,13 @@ describe('builtin helpers', function() {
|
|||||||
.withMessage('should output data')
|
.withMessage('should output data')
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
data: {
|
data: {
|
||||||
exclaim: '!'
|
exclaim: '!',
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('a!b!c!');
|
.toCompileTo('a!b!c!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('each on implicit context', function() {
|
it('each on implicit context', function () {
|
||||||
expectTemplate('{{#each}}{{text}}! {{/each}}cruel world!').toThrow(
|
expectTemplate('{{#each}}{{text}}! {{/each}}cruel world!').toThrow(
|
||||||
handlebarsEnv.Exception,
|
handlebarsEnv.Exception,
|
||||||
'Must pass iterator to #each'
|
'Must pass iterator to #each'
|
||||||
@@ -509,12 +509,12 @@ describe('builtin helpers', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (global.Symbol && global.Symbol.iterator) {
|
if (global.Symbol && global.Symbol.iterator) {
|
||||||
it('each on iterable', function() {
|
it('each on iterable', function () {
|
||||||
function Iterator(arr) {
|
function Iterator(arr) {
|
||||||
this.arr = arr;
|
this.arr = arr;
|
||||||
this.index = 0;
|
this.index = 0;
|
||||||
}
|
}
|
||||||
Iterator.prototype.next = function() {
|
Iterator.prototype.next = function () {
|
||||||
var value = this.arr[this.index];
|
var value = this.arr[this.index];
|
||||||
var done = this.index === this.arr.length;
|
var done = this.index === this.arr.length;
|
||||||
if (!done) {
|
if (!done) {
|
||||||
@@ -525,7 +525,7 @@ describe('builtin helpers', function() {
|
|||||||
function Iterable(arr) {
|
function Iterable(arr) {
|
||||||
this.arr = arr;
|
this.arr = arr;
|
||||||
}
|
}
|
||||||
Iterable.prototype[global.Symbol.iterator] = function() {
|
Iterable.prototype[global.Symbol.iterator] = function () {
|
||||||
return new Iterator(this.arr);
|
return new Iterator(this.arr);
|
||||||
};
|
};
|
||||||
var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
|
var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
|
||||||
@@ -535,9 +535,9 @@ describe('builtin helpers', function() {
|
|||||||
goodbyes: new Iterable([
|
goodbyes: new Iterable([
|
||||||
{ text: 'goodbye' },
|
{ text: 'goodbye' },
|
||||||
{ text: 'Goodbye' },
|
{ text: 'Goodbye' },
|
||||||
{ text: 'GOODBYE' }
|
{ text: 'GOODBYE' },
|
||||||
]),
|
]),
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage(
|
.withMessage(
|
||||||
'each with array argument iterates over the contents when not empty'
|
'each with array argument iterates over the contents when not empty'
|
||||||
@@ -547,7 +547,7 @@ describe('builtin helpers', function() {
|
|||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
.withInput({
|
.withInput({
|
||||||
goodbyes: new Iterable([]),
|
goodbyes: new Iterable([]),
|
||||||
world: 'world'
|
world: 'world',
|
||||||
})
|
})
|
||||||
.withMessage(
|
.withMessage(
|
||||||
'each with array argument ignores the contents when empty'
|
'each with array argument ignores the contents when empty'
|
||||||
@@ -557,27 +557,27 @@ describe('builtin helpers', function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#log', function() {
|
describe('#log', function () {
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
if (typeof console === 'undefined') {
|
if (typeof console === 'undefined') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var $log, $info, $error;
|
var $log, $info, $error;
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
$log = console.log;
|
$log = console.log;
|
||||||
$info = console.info;
|
$info = console.info;
|
||||||
$error = console.error;
|
$error = console.error;
|
||||||
});
|
});
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
console.log = $log;
|
console.log = $log;
|
||||||
console.info = $info;
|
console.info = $info;
|
||||||
console.error = $error;
|
console.error = $error;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call logger at default level', function() {
|
it('should call logger at default level', function () {
|
||||||
var levelArg, logArg;
|
var levelArg, logArg;
|
||||||
handlebarsEnv.log = function(level, arg) {
|
handlebarsEnv.log = function (level, arg) {
|
||||||
levelArg = level;
|
levelArg = level;
|
||||||
logArg = arg;
|
logArg = arg;
|
||||||
};
|
};
|
||||||
@@ -590,9 +590,9 @@ describe('builtin helpers', function() {
|
|||||||
equals('whee', logArg, "should call log with 'whee'");
|
equals('whee', logArg, "should call log with 'whee'");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call logger at data level', function() {
|
it('should call logger at data level', function () {
|
||||||
var levelArg, logArg;
|
var levelArg, logArg;
|
||||||
handlebarsEnv.log = function(level, arg) {
|
handlebarsEnv.log = function (level, arg) {
|
||||||
levelArg = level;
|
levelArg = level;
|
||||||
logArg = arg;
|
logArg = arg;
|
||||||
};
|
};
|
||||||
@@ -606,16 +606,16 @@ describe('builtin helpers', function() {
|
|||||||
equals('whee', logArg);
|
equals('whee', logArg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should output to info', function() {
|
it('should output to info', function () {
|
||||||
var called;
|
var called;
|
||||||
|
|
||||||
console.info = function(info) {
|
console.info = function (info) {
|
||||||
equals('whee', info);
|
equals('whee', info);
|
||||||
called = true;
|
called = true;
|
||||||
console.info = $info;
|
console.info = $info;
|
||||||
console.log = $log;
|
console.log = $log;
|
||||||
};
|
};
|
||||||
console.log = function(log) {
|
console.log = function (log) {
|
||||||
equals('whee', log);
|
equals('whee', log);
|
||||||
called = true;
|
called = true;
|
||||||
console.info = $info;
|
console.info = $info;
|
||||||
@@ -628,10 +628,10 @@ describe('builtin helpers', function() {
|
|||||||
equals(true, called);
|
equals(true, called);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log at data level', function() {
|
it('should log at data level', function () {
|
||||||
var called;
|
var called;
|
||||||
|
|
||||||
console.error = function(log) {
|
console.error = function (log) {
|
||||||
equals('whee', log);
|
equals('whee', log);
|
||||||
called = true;
|
called = true;
|
||||||
console.error = $error;
|
console.error = $error;
|
||||||
@@ -645,11 +645,11 @@ describe('builtin helpers', function() {
|
|||||||
equals(true, called);
|
equals(true, called);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle missing logger', function() {
|
it('should handle missing logger', function () {
|
||||||
var called = false;
|
var called = false;
|
||||||
|
|
||||||
console.error = undefined;
|
console.error = undefined;
|
||||||
console.log = function(log) {
|
console.log = function (log) {
|
||||||
equals('whee', log);
|
equals('whee', log);
|
||||||
called = true;
|
called = true;
|
||||||
console.log = $log;
|
console.log = $log;
|
||||||
@@ -663,10 +663,10 @@ describe('builtin helpers', function() {
|
|||||||
equals(true, called);
|
equals(true, called);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle string log levels', function() {
|
it('should handle string log levels', function () {
|
||||||
var called;
|
var called;
|
||||||
|
|
||||||
console.error = function(log) {
|
console.error = function (log) {
|
||||||
equals('whee', log);
|
equals('whee', log);
|
||||||
called = true;
|
called = true;
|
||||||
};
|
};
|
||||||
@@ -688,10 +688,10 @@ describe('builtin helpers', function() {
|
|||||||
equals(true, called);
|
equals(true, called);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle hash log levels', function() {
|
it('should handle hash log levels', function () {
|
||||||
var called;
|
var called;
|
||||||
|
|
||||||
console.error = function(log) {
|
console.error = function (log) {
|
||||||
equals('whee', log);
|
equals('whee', log);
|
||||||
called = true;
|
called = true;
|
||||||
};
|
};
|
||||||
@@ -702,13 +702,17 @@ describe('builtin helpers', function() {
|
|||||||
equals(true, called);
|
equals(true, called);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle hash log levels', function() {
|
it('should handle hash log levels', function () {
|
||||||
var called = false;
|
var called = false;
|
||||||
|
|
||||||
console.info = console.log = console.error = console.debug = function() {
|
console.info =
|
||||||
called = true;
|
console.log =
|
||||||
console.info = console.log = console.error = console.debug = $log;
|
console.error =
|
||||||
};
|
console.debug =
|
||||||
|
function () {
|
||||||
|
called = true;
|
||||||
|
console.info = console.log = console.error = console.debug = $log;
|
||||||
|
};
|
||||||
|
|
||||||
expectTemplate('{{log blah level="debug"}}')
|
expectTemplate('{{log blah level="debug"}}')
|
||||||
.withInput({ blah: 'whee' })
|
.withInput({ blah: 'whee' })
|
||||||
@@ -716,10 +720,10 @@ describe('builtin helpers', function() {
|
|||||||
equals(false, called);
|
equals(false, called);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass multiple log arguments', function() {
|
it('should pass multiple log arguments', function () {
|
||||||
var called;
|
var called;
|
||||||
|
|
||||||
console.info = console.log = function(log1, log2, log3) {
|
console.info = console.log = function (log1, log2, log3) {
|
||||||
equals('whee', log1);
|
equals('whee', log1);
|
||||||
equals('foo', log2);
|
equals('foo', log2);
|
||||||
equals(1, log3);
|
equals(1, log3);
|
||||||
@@ -733,31 +737,29 @@ describe('builtin helpers', function() {
|
|||||||
equals(true, called);
|
equals(true, called);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass zero log arguments', function() {
|
it('should pass zero log arguments', function () {
|
||||||
var called;
|
var called;
|
||||||
|
|
||||||
console.info = console.log = function() {
|
console.info = console.log = function () {
|
||||||
expect(arguments.length).to.equal(0);
|
expect(arguments.length).to.equal(0);
|
||||||
called = true;
|
called = true;
|
||||||
console.log = $log;
|
console.log = $log;
|
||||||
};
|
};
|
||||||
|
|
||||||
expectTemplate('{{log}}')
|
expectTemplate('{{log}}').withInput({ blah: 'whee' }).toCompileTo('');
|
||||||
.withInput({ blah: 'whee' })
|
|
||||||
.toCompileTo('');
|
|
||||||
expect(called).to.be.true();
|
expect(called).to.be.true();
|
||||||
});
|
});
|
||||||
/* eslint-enable no-console */
|
/* eslint-enable no-console */
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#lookup', function() {
|
describe('#lookup', function () {
|
||||||
it('should lookup arbitrary content', function() {
|
it('should lookup arbitrary content', function () {
|
||||||
expectTemplate('{{#each goodbyes}}{{lookup ../data .}}{{/each}}')
|
expectTemplate('{{#each goodbyes}}{{lookup ../data .}}{{/each}}')
|
||||||
.withInput({ goodbyes: [0, 1], data: ['foo', 'bar'] })
|
.withInput({ goodbyes: [0, 1], data: ['foo', 'bar'] })
|
||||||
.toCompileTo('foobar');
|
.toCompileTo('foobar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not fail on undefined value', function() {
|
it('should not fail on undefined value', function () {
|
||||||
expectTemplate('{{#each goodbyes}}{{lookup ../bar .}}{{/each}}')
|
expectTemplate('{{#each goodbyes}}{{lookup ../bar .}}{{/each}}')
|
||||||
.withInput({ goodbyes: [0, 1], data: ['foo', 'bar'] })
|
.withInput({ goodbyes: [0, 1], data: ['foo', 'bar'] })
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
|
|||||||
+25
-25
@@ -1,15 +1,15 @@
|
|||||||
describe('compiler', function() {
|
describe('compiler', function () {
|
||||||
if (!Handlebars.compile) {
|
if (!Handlebars.compile) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('#equals', function() {
|
describe('#equals', function () {
|
||||||
function compile(string) {
|
function compile(string) {
|
||||||
var ast = Handlebars.parse(string);
|
var ast = Handlebars.parse(string);
|
||||||
return new Handlebars.Compiler().compile(ast, {});
|
return new Handlebars.Compiler().compile(ast, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should treat as equal', function() {
|
it('should treat as equal', function () {
|
||||||
equal(compile('foo').equals(compile('foo')), true);
|
equal(compile('foo').equals(compile('foo')), true);
|
||||||
equal(compile('{{foo}}').equals(compile('{{foo}}')), true);
|
equal(compile('{{foo}}').equals(compile('{{foo}}')), true);
|
||||||
equal(compile('{{foo.bar}}').equals(compile('{{foo.bar}}')), true);
|
equal(compile('{{foo.bar}}').equals(compile('{{foo.bar}}')), true);
|
||||||
@@ -30,7 +30,7 @@ describe('compiler', function() {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should treat as not equal', function() {
|
it('should treat as not equal', function () {
|
||||||
equal(compile('foo').equals(compile('bar')), false);
|
equal(compile('foo').equals(compile('bar')), false);
|
||||||
equal(compile('{{foo}}').equals(compile('{{bar}}')), false);
|
equal(compile('{{foo}}').equals(compile('{{bar}}')), false);
|
||||||
equal(compile('{{foo.bar}}').equals(compile('{{bar.bar}}')), false);
|
equal(compile('{{foo.bar}}').equals(compile('{{bar.bar}}')), false);
|
||||||
@@ -59,17 +59,17 @@ describe('compiler', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#compile', function() {
|
describe('#compile', function () {
|
||||||
it('should fail with invalid input', function() {
|
it('should fail with invalid input', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.compile(null);
|
Handlebars.compile(null);
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
'You must pass a string or Handlebars AST to Handlebars.compile. You passed null'
|
'You must pass a string or Handlebars AST to Handlebars.compile. You passed null'
|
||||||
);
|
);
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.compile({});
|
Handlebars.compile({});
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
@@ -77,7 +77,7 @@ describe('compiler', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should include the location in the error (row and column)', function() {
|
it('should include the location in the error (row and column)', function () {
|
||||||
try {
|
try {
|
||||||
Handlebars.compile(' \n {{#if}}\n{{/def}}')();
|
Handlebars.compile(' \n {{#if}}\n{{/def}}')();
|
||||||
equal(
|
equal(
|
||||||
@@ -101,7 +101,7 @@ describe('compiler', function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should include the location as enumerable property', function() {
|
it('should include the location as enumerable property', function () {
|
||||||
try {
|
try {
|
||||||
Handlebars.compile(' \n {{#if}}\n{{/def}}')();
|
Handlebars.compile(' \n {{#if}}\n{{/def}}')();
|
||||||
equal(
|
equal(
|
||||||
@@ -118,30 +118,30 @@ describe('compiler', function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can utilize AST instance', function() {
|
it('can utilize AST instance', function () {
|
||||||
equal(
|
equal(
|
||||||
Handlebars.compile({
|
Handlebars.compile({
|
||||||
type: 'Program',
|
type: 'Program',
|
||||||
body: [{ type: 'ContentStatement', value: 'Hello' }]
|
body: [{ type: 'ContentStatement', value: 'Hello' }],
|
||||||
})(),
|
})(),
|
||||||
'Hello'
|
'Hello'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can pass through an empty string', function() {
|
it('can pass through an empty string', function () {
|
||||||
equal(Handlebars.compile('')(), '');
|
equal(Handlebars.compile('')(), '');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws on desupported options', function() {
|
it('throws on desupported options', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.compile('Dudes', { trackIds: true });
|
Handlebars.compile('Dudes', { trackIds: true });
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
'TrackIds and stringParams are no longer supported. See Github #1145'
|
'TrackIds and stringParams are no longer supported. See Github #1145'
|
||||||
);
|
);
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.compile('Dudes', { stringParams: true });
|
Handlebars.compile('Dudes', { stringParams: true });
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
@@ -149,7 +149,7 @@ describe('compiler', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not modify the options.data property(GH-1327)', function() {
|
it('should not modify the options.data property(GH-1327)', function () {
|
||||||
var options = { data: [{ a: 'foo' }, { a: 'bar' }] };
|
var options = { data: [{ a: 'foo' }, { a: 'bar' }] };
|
||||||
Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
|
Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
|
||||||
equal(
|
equal(
|
||||||
@@ -158,7 +158,7 @@ describe('compiler', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not modify the options.knownHelpers property(GH-1327)', function() {
|
it('should not modify the options.knownHelpers property(GH-1327)', function () {
|
||||||
var options = { knownHelpers: {} };
|
var options = { knownHelpers: {} };
|
||||||
Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
|
Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
|
||||||
equal(
|
equal(
|
||||||
@@ -168,17 +168,17 @@ describe('compiler', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#precompile', function() {
|
describe('#precompile', function () {
|
||||||
it('should fail with invalid input', function() {
|
it('should fail with invalid input', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.precompile(null);
|
Handlebars.precompile(null);
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
'You must pass a string or Handlebars AST to Handlebars.compile. You passed null'
|
'You must pass a string or Handlebars AST to Handlebars.compile. You passed null'
|
||||||
);
|
);
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.precompile({});
|
Handlebars.precompile({});
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
@@ -186,19 +186,19 @@ describe('compiler', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can utilize AST instance', function() {
|
it('can utilize AST instance', function () {
|
||||||
equal(
|
equal(
|
||||||
/return "Hello"/.test(
|
/return "Hello"/.test(
|
||||||
Handlebars.precompile({
|
Handlebars.precompile({
|
||||||
type: 'Program',
|
type: 'Program',
|
||||||
body: [{ type: 'ContentStatement', value: 'Hello' }]
|
body: [{ type: 'ContentStatement', value: 'Hello' }],
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can pass through an empty string', function() {
|
it('can pass through an empty string', function () {
|
||||||
equal(/return ""/.test(Handlebars.precompile('')), true);
|
equal(/return ""/.test(Handlebars.precompile('')), true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+53
-53
@@ -1,8 +1,8 @@
|
|||||||
describe('data', function() {
|
describe('data', function () {
|
||||||
it('passing in data to a compiled function that expects data - works with helpers', function() {
|
it('passing in data to a compiled function that expects data - works with helpers', function () {
|
||||||
expectTemplate('{{hello}}')
|
expectTemplate('{{hello}}')
|
||||||
.withCompileOptions({ data: true })
|
.withCompileOptions({ data: true })
|
||||||
.withHelper('hello', function(options) {
|
.withHelper('hello', function (options) {
|
||||||
return options.data.adjective + ' ' + this.noun;
|
return options.data.adjective + ' ' + this.noun;
|
||||||
})
|
})
|
||||||
.withRuntimeOptions({ data: { adjective: 'happy' } })
|
.withRuntimeOptions({ data: { adjective: 'happy' } })
|
||||||
@@ -11,17 +11,17 @@ describe('data', function() {
|
|||||||
.toCompileTo('happy cat');
|
.toCompileTo('happy cat');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('data can be looked up via @foo', function() {
|
it('data can be looked up via @foo', function () {
|
||||||
expectTemplate('{{@hello}}')
|
expectTemplate('{{@hello}}')
|
||||||
.withRuntimeOptions({ data: { hello: 'hello' } })
|
.withRuntimeOptions({ data: { hello: 'hello' } })
|
||||||
.withMessage('@foo retrieves template data')
|
.withMessage('@foo retrieves template data')
|
||||||
.toCompileTo('hello');
|
.toCompileTo('hello');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('deep @foo triggers automatic top-level data', function() {
|
it('deep @foo triggers automatic top-level data', function () {
|
||||||
var helpers = Handlebars.createFrame(handlebarsEnv.helpers);
|
var helpers = Handlebars.createFrame(handlebarsEnv.helpers);
|
||||||
|
|
||||||
helpers.let = function(options) {
|
helpers.let = function (options) {
|
||||||
var frame = Handlebars.createFrame(options.data);
|
var frame = Handlebars.createFrame(options.data);
|
||||||
|
|
||||||
for (var prop in options.hash) {
|
for (var prop in options.hash) {
|
||||||
@@ -41,83 +41,83 @@ describe('data', function() {
|
|||||||
.toCompileTo('Hello world');
|
.toCompileTo('Hello world');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parameter data can be looked up via @foo', function() {
|
it('parameter data can be looked up via @foo', function () {
|
||||||
expectTemplate('{{hello @world}}')
|
expectTemplate('{{hello @world}}')
|
||||||
.withRuntimeOptions({ data: { world: 'world' } })
|
.withRuntimeOptions({ data: { world: 'world' } })
|
||||||
.withHelper('hello', function(noun) {
|
.withHelper('hello', function (noun) {
|
||||||
return 'Hello ' + noun;
|
return 'Hello ' + noun;
|
||||||
})
|
})
|
||||||
.withMessage('@foo as a parameter retrieves template data')
|
.withMessage('@foo as a parameter retrieves template data')
|
||||||
.toCompileTo('Hello world');
|
.toCompileTo('Hello world');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('hash values can be looked up via @foo', function() {
|
it('hash values can be looked up via @foo', function () {
|
||||||
expectTemplate('{{hello noun=@world}}')
|
expectTemplate('{{hello noun=@world}}')
|
||||||
.withRuntimeOptions({ data: { world: 'world' } })
|
.withRuntimeOptions({ data: { world: 'world' } })
|
||||||
.withHelper('hello', function(options) {
|
.withHelper('hello', function (options) {
|
||||||
return 'Hello ' + options.hash.noun;
|
return 'Hello ' + options.hash.noun;
|
||||||
})
|
})
|
||||||
.withMessage('@foo as a parameter retrieves template data')
|
.withMessage('@foo as a parameter retrieves template data')
|
||||||
.toCompileTo('Hello world');
|
.toCompileTo('Hello world');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('nested parameter data can be looked up via @foo.bar', function() {
|
it('nested parameter data can be looked up via @foo.bar', function () {
|
||||||
expectTemplate('{{hello @world.bar}}')
|
expectTemplate('{{hello @world.bar}}')
|
||||||
.withRuntimeOptions({ data: { world: { bar: 'world' } } })
|
.withRuntimeOptions({ data: { world: { bar: 'world' } } })
|
||||||
.withHelper('hello', function(noun) {
|
.withHelper('hello', function (noun) {
|
||||||
return 'Hello ' + noun;
|
return 'Hello ' + noun;
|
||||||
})
|
})
|
||||||
.withMessage('@foo as a parameter retrieves template data')
|
.withMessage('@foo as a parameter retrieves template data')
|
||||||
.toCompileTo('Hello world');
|
.toCompileTo('Hello world');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('nested parameter data does not fail with @world.bar', function() {
|
it('nested parameter data does not fail with @world.bar', function () {
|
||||||
expectTemplate('{{hello @world.bar}}')
|
expectTemplate('{{hello @world.bar}}')
|
||||||
.withRuntimeOptions({ data: { foo: { bar: 'world' } } })
|
.withRuntimeOptions({ data: { foo: { bar: 'world' } } })
|
||||||
.withHelper('hello', function(noun) {
|
.withHelper('hello', function (noun) {
|
||||||
return 'Hello ' + noun;
|
return 'Hello ' + noun;
|
||||||
})
|
})
|
||||||
.withMessage('@foo as a parameter retrieves template data')
|
.withMessage('@foo as a parameter retrieves template data')
|
||||||
.toCompileTo('Hello undefined');
|
.toCompileTo('Hello undefined');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parameter data throws when using complex scope references', function() {
|
it('parameter data throws when using complex scope references', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}'
|
'{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}'
|
||||||
).toThrow(Error);
|
).toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('data can be functions', function() {
|
it('data can be functions', function () {
|
||||||
expectTemplate('{{@hello}}')
|
expectTemplate('{{@hello}}')
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
data: {
|
data: {
|
||||||
hello: function() {
|
hello: function () {
|
||||||
return 'hello';
|
return 'hello';
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('hello');
|
.toCompileTo('hello');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('data can be functions with params', function() {
|
it('data can be functions with params', function () {
|
||||||
expectTemplate('{{@hello "hello"}}')
|
expectTemplate('{{@hello "hello"}}')
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
data: {
|
data: {
|
||||||
hello: function(arg) {
|
hello: function (arg) {
|
||||||
return arg;
|
return arg;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('hello');
|
.toCompileTo('hello');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('data is inherited downstream', function() {
|
it('data is inherited downstream', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#let foo=1 bar=2}}{{#let foo=bar.baz}}{{@bar}}{{@foo}}{{/let}}{{@foo}}{{/let}}'
|
'{{#let foo=1 bar=2}}{{#let foo=bar.baz}}{{@bar}}{{@foo}}{{/let}}{{@foo}}{{/let}}'
|
||||||
)
|
)
|
||||||
.withInput({ bar: { baz: 'hello world' } })
|
.withInput({ bar: { baz: 'hello world' } })
|
||||||
.withCompileOptions({ data: true })
|
.withCompileOptions({ data: true })
|
||||||
.withHelper('let', function(options) {
|
.withHelper('let', function (options) {
|
||||||
var frame = Handlebars.createFrame(options.data);
|
var frame = Handlebars.createFrame(options.data);
|
||||||
for (var prop in options.hash) {
|
for (var prop in options.hash) {
|
||||||
if (prop in options.hash) {
|
if (prop in options.hash) {
|
||||||
@@ -131,11 +131,11 @@ describe('data', function() {
|
|||||||
.toCompileTo('2hello world1');
|
.toCompileTo('2hello world1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('passing in data to a compiled function that expects data - works with helpers in partials', function() {
|
it('passing in data to a compiled function that expects data - works with helpers in partials', function () {
|
||||||
expectTemplate('{{>myPartial}}')
|
expectTemplate('{{>myPartial}}')
|
||||||
.withCompileOptions({ data: true })
|
.withCompileOptions({ data: true })
|
||||||
.withPartial('myPartial', '{{hello}}')
|
.withPartial('myPartial', '{{hello}}')
|
||||||
.withHelper('hello', function(options) {
|
.withHelper('hello', function (options) {
|
||||||
return options.data.adjective + ' ' + this.noun;
|
return options.data.adjective + ' ' + this.noun;
|
||||||
})
|
})
|
||||||
.withInput({ noun: 'cat' })
|
.withInput({ noun: 'cat' })
|
||||||
@@ -144,10 +144,10 @@ describe('data', function() {
|
|||||||
.toCompileTo('happy cat');
|
.toCompileTo('happy cat');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('passing in data to a compiled function that expects data - works with helpers and parameters', function() {
|
it('passing in data to a compiled function that expects data - works with helpers and parameters', function () {
|
||||||
expectTemplate('{{hello world}}')
|
expectTemplate('{{hello world}}')
|
||||||
.withCompileOptions({ data: true })
|
.withCompileOptions({ data: true })
|
||||||
.withHelper('hello', function(noun, options) {
|
.withHelper('hello', function (noun, options) {
|
||||||
return options.data.adjective + ' ' + noun + (this.exclaim ? '!' : '');
|
return options.data.adjective + ' ' + noun + (this.exclaim ? '!' : '');
|
||||||
})
|
})
|
||||||
.withInput({ exclaim: true, world: 'world' })
|
.withInput({ exclaim: true, world: 'world' })
|
||||||
@@ -156,15 +156,15 @@ describe('data', function() {
|
|||||||
.toCompileTo('happy world!');
|
.toCompileTo('happy world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('passing in data to a compiled function that expects data - works with block helpers', function() {
|
it('passing in data to a compiled function that expects data - works with block helpers', function () {
|
||||||
expectTemplate('{{#hello}}{{world}}{{/hello}}')
|
expectTemplate('{{#hello}}{{world}}{{/hello}}')
|
||||||
.withCompileOptions({
|
.withCompileOptions({
|
||||||
data: true
|
data: true,
|
||||||
})
|
})
|
||||||
.withHelper('hello', function(options) {
|
.withHelper('hello', function (options) {
|
||||||
return options.fn(this);
|
return options.fn(this);
|
||||||
})
|
})
|
||||||
.withHelper('world', function(options) {
|
.withHelper('world', function (options) {
|
||||||
return options.data.adjective + ' world' + (this.exclaim ? '!' : '');
|
return options.data.adjective + ' world' + (this.exclaim ? '!' : '');
|
||||||
})
|
})
|
||||||
.withInput({ exclaim: true })
|
.withInput({ exclaim: true })
|
||||||
@@ -173,13 +173,13 @@ describe('data', function() {
|
|||||||
.toCompileTo('happy world!');
|
.toCompileTo('happy world!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('passing in data to a compiled function that expects data - works with block helpers that use ..', function() {
|
it('passing in data to a compiled function that expects data - works with block helpers that use ..', function () {
|
||||||
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
|
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
|
||||||
.withCompileOptions({ data: true })
|
.withCompileOptions({ data: true })
|
||||||
.withHelper('hello', function(options) {
|
.withHelper('hello', function (options) {
|
||||||
return options.fn({ exclaim: '?' });
|
return options.fn({ exclaim: '?' });
|
||||||
})
|
})
|
||||||
.withHelper('world', function(thing, options) {
|
.withHelper('world', function (thing, options) {
|
||||||
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
||||||
})
|
})
|
||||||
.withInput({ exclaim: true, zomg: 'world' })
|
.withInput({ exclaim: true, zomg: 'world' })
|
||||||
@@ -188,13 +188,13 @@ describe('data', function() {
|
|||||||
.toCompileTo('happy world?');
|
.toCompileTo('happy world?');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('passing in data to a compiled function that expects data - data is passed to with block helpers where children use ..', function() {
|
it('passing in data to a compiled function that expects data - data is passed to with block helpers where children use ..', function () {
|
||||||
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
|
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
|
||||||
.withCompileOptions({ data: true })
|
.withCompileOptions({ data: true })
|
||||||
.withHelper('hello', function(options) {
|
.withHelper('hello', function (options) {
|
||||||
return options.data.accessData + ' ' + options.fn({ exclaim: '?' });
|
return options.data.accessData + ' ' + options.fn({ exclaim: '?' });
|
||||||
})
|
})
|
||||||
.withHelper('world', function(thing, options) {
|
.withHelper('world', function (thing, options) {
|
||||||
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
||||||
})
|
})
|
||||||
.withInput({ exclaim: true, zomg: 'world' })
|
.withInput({ exclaim: true, zomg: 'world' })
|
||||||
@@ -203,16 +203,16 @@ describe('data', function() {
|
|||||||
.toCompileTo('#win happy world?');
|
.toCompileTo('#win happy world?');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('you can override inherited data when invoking a helper', function() {
|
it('you can override inherited data when invoking a helper', function () {
|
||||||
expectTemplate('{{#hello}}{{world zomg}}{{/hello}}')
|
expectTemplate('{{#hello}}{{world zomg}}{{/hello}}')
|
||||||
.withCompileOptions({ data: true })
|
.withCompileOptions({ data: true })
|
||||||
.withHelper('hello', function(options) {
|
.withHelper('hello', function (options) {
|
||||||
return options.fn(
|
return options.fn(
|
||||||
{ exclaim: '?', zomg: 'world' },
|
{ exclaim: '?', zomg: 'world' },
|
||||||
{ data: { adjective: 'sad' } }
|
{ data: { adjective: 'sad' } }
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.withHelper('world', function(thing, options) {
|
.withHelper('world', function (thing, options) {
|
||||||
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
||||||
})
|
})
|
||||||
.withInput({ exclaim: true, zomg: 'planet' })
|
.withInput({ exclaim: true, zomg: 'planet' })
|
||||||
@@ -221,13 +221,13 @@ describe('data', function() {
|
|||||||
.toCompileTo('sad world?');
|
.toCompileTo('sad world?');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('you can override inherited data when invoking a helper with depth', function() {
|
it('you can override inherited data when invoking a helper with depth', function () {
|
||||||
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
|
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
|
||||||
.withCompileOptions({ data: true })
|
.withCompileOptions({ data: true })
|
||||||
.withHelper('hello', function(options) {
|
.withHelper('hello', function (options) {
|
||||||
return options.fn({ exclaim: '?' }, { data: { adjective: 'sad' } });
|
return options.fn({ exclaim: '?' }, { data: { adjective: 'sad' } });
|
||||||
})
|
})
|
||||||
.withHelper('world', function(thing, options) {
|
.withHelper('world', function (thing, options) {
|
||||||
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
||||||
})
|
})
|
||||||
.withInput({ exclaim: true, zomg: 'world' })
|
.withInput({ exclaim: true, zomg: 'world' })
|
||||||
@@ -236,8 +236,8 @@ describe('data', function() {
|
|||||||
.toCompileTo('sad world?');
|
.toCompileTo('sad world?');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('@root', function() {
|
describe('@root', function () {
|
||||||
it('the root context can be looked up via @root', function() {
|
it('the root context can be looked up via @root', function () {
|
||||||
expectTemplate('{{@root.foo}}')
|
expectTemplate('{{@root.foo}}')
|
||||||
.withInput({ foo: 'hello' })
|
.withInput({ foo: 'hello' })
|
||||||
.withRuntimeOptions({ data: {} })
|
.withRuntimeOptions({ data: {} })
|
||||||
@@ -248,7 +248,7 @@ describe('data', function() {
|
|||||||
.toCompileTo('hello');
|
.toCompileTo('hello');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('passed root values take priority', function() {
|
it('passed root values take priority', function () {
|
||||||
expectTemplate('{{@root.foo}}')
|
expectTemplate('{{@root.foo}}')
|
||||||
.withInput({ foo: 'should not be used' })
|
.withInput({ foo: 'should not be used' })
|
||||||
.withRuntimeOptions({ data: { root: { foo: 'hello' } } })
|
.withRuntimeOptions({ data: { root: { foo: 'hello' } } })
|
||||||
@@ -256,21 +256,21 @@ describe('data', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('nesting', function() {
|
describe('nesting', function () {
|
||||||
it('the root context can be looked up via @root', function() {
|
it('the root context can be looked up via @root', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#helper}}{{#helper}}{{@./depth}} {{@../depth}} {{@../../depth}}{{/helper}}{{/helper}}'
|
'{{#helper}}{{#helper}}{{@./depth}} {{@../depth}} {{@../../depth}}{{/helper}}{{/helper}}'
|
||||||
)
|
)
|
||||||
.withInput({ foo: 'hello' })
|
.withInput({ foo: 'hello' })
|
||||||
.withHelper('helper', function(options) {
|
.withHelper('helper', function (options) {
|
||||||
var frame = Handlebars.createFrame(options.data);
|
var frame = Handlebars.createFrame(options.data);
|
||||||
frame.depth = options.data.depth + 1;
|
frame.depth = options.data.depth + 1;
|
||||||
return options.fn(this, { data: frame });
|
return options.fn(this, { data: frame });
|
||||||
})
|
})
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
data: {
|
data: {
|
||||||
depth: 0
|
depth: 0,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('2 1 0');
|
.toCompileTo('2 1 0');
|
||||||
});
|
});
|
||||||
|
|||||||
Vendored
+3
-3
@@ -26,13 +26,13 @@ vm.runInThisContext(distHandlebars, filename);
|
|||||||
global.CompilerContext = {
|
global.CompilerContext = {
|
||||||
browser: true,
|
browser: true,
|
||||||
|
|
||||||
compile: function(template, options) {
|
compile: function (template, options) {
|
||||||
var templateSpec = handlebarsEnv.precompile(template, options);
|
var templateSpec = handlebarsEnv.precompile(template, options);
|
||||||
return handlebarsEnv.template(safeEval(templateSpec));
|
return handlebarsEnv.template(safeEval(templateSpec));
|
||||||
},
|
},
|
||||||
compileWithPartial: function(template, options) {
|
compileWithPartial: function (template, options) {
|
||||||
return handlebarsEnv.compile(template, options);
|
return handlebarsEnv.compile(template, options);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function safeEval(templateSpec) {
|
function safeEval(templateSpec) {
|
||||||
|
|||||||
Vendored
+24
-24
@@ -1,4 +1,4 @@
|
|||||||
var global = (function() {
|
var global = (function () {
|
||||||
return this;
|
return this;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ if (Error.captureStackTrace) {
|
|||||||
/**
|
/**
|
||||||
* @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
|
* @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
|
||||||
*/
|
*/
|
||||||
global.shouldCompileTo = function(string, hashOrArray, expected, message) {
|
global.shouldCompileTo = function (string, hashOrArray, expected, message) {
|
||||||
shouldCompileToWithPartials(string, hashOrArray, false, expected, message);
|
shouldCompileToWithPartials(string, hashOrArray, false, expected, message);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ global.shouldCompileToWithPartials = function shouldCompileToWithPartials(
|
|||||||
/**
|
/**
|
||||||
* @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
|
* @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
|
||||||
*/
|
*/
|
||||||
global.compileWithPartials = function(string, hashOrArray, partials) {
|
global.compileWithPartials = function (string, hashOrArray, partials) {
|
||||||
var template, ary, options;
|
var template, ary, options;
|
||||||
if (hashOrArray && hashOrArray.hash) {
|
if (hashOrArray && hashOrArray.hash) {
|
||||||
ary = [hashOrArray.hash, hashOrArray];
|
ary = [hashOrArray.hash, hashOrArray];
|
||||||
@@ -92,7 +92,7 @@ global.equals = global.equal = function equals(a, b, msg) {
|
|||||||
* @deprecated Use chai's expect-style API instead (`expect(actualValue).to.equal(expectedValue)`)
|
* @deprecated Use chai's expect-style API instead (`expect(actualValue).to.equal(expectedValue)`)
|
||||||
* @see https://www.chaijs.com/api/bdd/#method_throw
|
* @see https://www.chaijs.com/api/bdd/#method_throw
|
||||||
*/
|
*/
|
||||||
global.shouldThrow = function(callback, type, msg) {
|
global.shouldThrow = function (callback, type, msg) {
|
||||||
var failed;
|
var failed;
|
||||||
try {
|
try {
|
||||||
callback();
|
callback();
|
||||||
@@ -121,7 +121,7 @@ global.shouldThrow = function(callback, type, msg) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
global.expectTemplate = function(templateAsString) {
|
global.expectTemplate = function (templateAsString) {
|
||||||
return new HandlebarsTestBench(templateAsString);
|
return new HandlebarsTestBench(templateAsString);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -137,38 +137,38 @@ function HandlebarsTestBench(templateAsString) {
|
|||||||
this.runtimeOptions = {};
|
this.runtimeOptions = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.withInput = function(input) {
|
HandlebarsTestBench.prototype.withInput = function (input) {
|
||||||
this.input = input;
|
this.input = input;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.withHelper = function(name, helperFunction) {
|
HandlebarsTestBench.prototype.withHelper = function (name, helperFunction) {
|
||||||
this.helpers[name] = helperFunction;
|
this.helpers[name] = helperFunction;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.withHelpers = function(helperFunctions) {
|
HandlebarsTestBench.prototype.withHelpers = function (helperFunctions) {
|
||||||
var self = this;
|
var self = this;
|
||||||
Object.keys(helperFunctions).forEach(function(name) {
|
Object.keys(helperFunctions).forEach(function (name) {
|
||||||
self.withHelper(name, helperFunctions[name]);
|
self.withHelper(name, helperFunctions[name]);
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.withPartial = function(name, partialAsString) {
|
HandlebarsTestBench.prototype.withPartial = function (name, partialAsString) {
|
||||||
this.partials[name] = partialAsString;
|
this.partials[name] = partialAsString;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.withPartials = function(partials) {
|
HandlebarsTestBench.prototype.withPartials = function (partials) {
|
||||||
var self = this;
|
var self = this;
|
||||||
Object.keys(partials).forEach(function(name) {
|
Object.keys(partials).forEach(function (name) {
|
||||||
self.withPartial(name, partials[name]);
|
self.withPartial(name, partials[name]);
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.withDecorator = function(
|
HandlebarsTestBench.prototype.withDecorator = function (
|
||||||
name,
|
name,
|
||||||
decoratorFunction
|
decoratorFunction
|
||||||
) {
|
) {
|
||||||
@@ -176,30 +176,30 @@ HandlebarsTestBench.prototype.withDecorator = function(
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.withDecorators = function(decorators) {
|
HandlebarsTestBench.prototype.withDecorators = function (decorators) {
|
||||||
var self = this;
|
var self = this;
|
||||||
Object.keys(decorators).forEach(function(name) {
|
Object.keys(decorators).forEach(function (name) {
|
||||||
self.withDecorator(name, decorators[name]);
|
self.withDecorator(name, decorators[name]);
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.withCompileOptions = function(compileOptions) {
|
HandlebarsTestBench.prototype.withCompileOptions = function (compileOptions) {
|
||||||
this.compileOptions = compileOptions;
|
this.compileOptions = compileOptions;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.withRuntimeOptions = function(runtimeOptions) {
|
HandlebarsTestBench.prototype.withRuntimeOptions = function (runtimeOptions) {
|
||||||
this.runtimeOptions = runtimeOptions;
|
this.runtimeOptions = runtimeOptions;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.withMessage = function(message) {
|
HandlebarsTestBench.prototype.withMessage = function (message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.toCompileTo = function(expectedOutputAsString) {
|
HandlebarsTestBench.prototype.toCompileTo = function (expectedOutputAsString) {
|
||||||
expect(this._compileAndExecute()).to.equal(
|
expect(this._compileAndExecute()).to.equal(
|
||||||
expectedOutputAsString,
|
expectedOutputAsString,
|
||||||
this.message
|
this.message
|
||||||
@@ -207,14 +207,14 @@ HandlebarsTestBench.prototype.toCompileTo = function(expectedOutputAsString) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// see chai "to.throw" (https://www.chaijs.com/api/bdd/#method_throw)
|
// see chai "to.throw" (https://www.chaijs.com/api/bdd/#method_throw)
|
||||||
HandlebarsTestBench.prototype.toThrow = function(errorLike, errMsgMatcher) {
|
HandlebarsTestBench.prototype.toThrow = function (errorLike, errMsgMatcher) {
|
||||||
var self = this;
|
var self = this;
|
||||||
expect(function() {
|
expect(function () {
|
||||||
self._compileAndExecute();
|
self._compileAndExecute();
|
||||||
}).to.throw(errorLike, errMsgMatcher, this.message);
|
}).to.throw(errorLike, errMsgMatcher, this.message);
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype._compileAndExecute = function() {
|
HandlebarsTestBench.prototype._compileAndExecute = function () {
|
||||||
var compile =
|
var compile =
|
||||||
Object.keys(this.partials).length > 0
|
Object.keys(this.partials).length > 0
|
||||||
? CompilerContext.compileWithPartial
|
? CompilerContext.compileWithPartial
|
||||||
@@ -226,10 +226,10 @@ HandlebarsTestBench.prototype._compileAndExecute = function() {
|
|||||||
return template(this.input, combinedRuntimeOptions);
|
return template(this.input, combinedRuntimeOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype._combineRuntimeOptions = function() {
|
HandlebarsTestBench.prototype._combineRuntimeOptions = function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
var combinedRuntimeOptions = {};
|
var combinedRuntimeOptions = {};
|
||||||
Object.keys(this.runtimeOptions).forEach(function(key) {
|
Object.keys(this.runtimeOptions).forEach(function (key) {
|
||||||
combinedRuntimeOptions[key] = self.runtimeOptions[key];
|
combinedRuntimeOptions[key] = self.runtimeOptions[key];
|
||||||
});
|
});
|
||||||
combinedRuntimeOptions.helpers = this.helpers;
|
combinedRuntimeOptions.helpers = this.helpers;
|
||||||
|
|||||||
Vendored
+3
-3
@@ -11,13 +11,13 @@ global.sinon = require('sinon');
|
|||||||
global.Handlebars = require('../../lib');
|
global.Handlebars = require('../../lib');
|
||||||
|
|
||||||
global.CompilerContext = {
|
global.CompilerContext = {
|
||||||
compile: function(template, options) {
|
compile: function (template, options) {
|
||||||
var templateSpec = handlebarsEnv.precompile(template, options);
|
var templateSpec = handlebarsEnv.precompile(template, options);
|
||||||
return handlebarsEnv.template(safeEval(templateSpec));
|
return handlebarsEnv.template(safeEval(templateSpec));
|
||||||
},
|
},
|
||||||
compileWithPartial: function(template, options) {
|
compileWithPartial: function (template, options) {
|
||||||
return handlebarsEnv.compile(template, options);
|
return handlebarsEnv.compile(template, options);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function safeEval(templateSpec) {
|
function safeEval(templateSpec) {
|
||||||
|
|||||||
Vendored
+9
-9
@@ -15,25 +15,25 @@ if (grep === '--min') {
|
|||||||
|
|
||||||
var files = fs
|
var files = fs
|
||||||
.readdirSync(testDir)
|
.readdirSync(testDir)
|
||||||
.filter(function(name) {
|
.filter(function (name) {
|
||||||
return /.*\.js$/.test(name);
|
return /.*\.js$/.test(name);
|
||||||
})
|
})
|
||||||
.map(function(name) {
|
.map(function (name) {
|
||||||
return testDir + path.sep + name;
|
return testDir + path.sep + name;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (global.minimizedTest) {
|
if (global.minimizedTest) {
|
||||||
run('./runtime', function() {
|
run('./runtime', function () {
|
||||||
run('./browser', function() {
|
run('./browser', function () {
|
||||||
/* eslint-disable no-process-exit */
|
/* eslint-disable no-process-exit */
|
||||||
process.exit(errors);
|
process.exit(errors);
|
||||||
/* eslint-enable no-process-exit */
|
/* eslint-enable no-process-exit */
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
run('./runtime', function() {
|
run('./runtime', function () {
|
||||||
run('./browser', function() {
|
run('./browser', function () {
|
||||||
run('./node', function() {
|
run('./node', function () {
|
||||||
/* eslint-disable no-process-exit */
|
/* eslint-disable no-process-exit */
|
||||||
process.exit(errors);
|
process.exit(errors);
|
||||||
/* eslint-enable no-process-exit */
|
/* eslint-enable no-process-exit */
|
||||||
@@ -50,13 +50,13 @@ function run(env, callback) {
|
|||||||
mocha.grep(grep);
|
mocha.grep(grep);
|
||||||
}
|
}
|
||||||
|
|
||||||
files.forEach(function(name) {
|
files.forEach(function (name) {
|
||||||
delete require.cache[name];
|
delete require.cache[name];
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Running env: ' + env);
|
console.log('Running env: ' + env);
|
||||||
require(env);
|
require(env);
|
||||||
mocha.run(function(errorCount) {
|
mocha.run(function (errorCount) {
|
||||||
errors += errorCount;
|
errors += errorCount;
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
|
|||||||
Vendored
+8
-5
@@ -29,9 +29,12 @@ var JavaScriptCompiler = require('../../dist/cjs/handlebars/compiler/javascript-
|
|||||||
global.CompilerContext = {
|
global.CompilerContext = {
|
||||||
browser: true,
|
browser: true,
|
||||||
|
|
||||||
compile: function(template, options) {
|
compile: function (template, options) {
|
||||||
// Hack the compiler on to the environment for these specific tests
|
// Hack the compiler on to the environment for these specific tests
|
||||||
handlebarsEnv.precompile = function(precompileTemplate, precompileOptions) {
|
handlebarsEnv.precompile = function (
|
||||||
|
precompileTemplate,
|
||||||
|
precompileOptions
|
||||||
|
) {
|
||||||
return compiler.precompile(
|
return compiler.precompile(
|
||||||
precompileTemplate,
|
precompileTemplate,
|
||||||
precompileOptions,
|
precompileOptions,
|
||||||
@@ -45,9 +48,9 @@ global.CompilerContext = {
|
|||||||
var templateSpec = handlebarsEnv.precompile(template, options);
|
var templateSpec = handlebarsEnv.precompile(template, options);
|
||||||
return handlebarsEnv.template(safeEval(templateSpec));
|
return handlebarsEnv.template(safeEval(templateSpec));
|
||||||
},
|
},
|
||||||
compileWithPartial: function(template, options) {
|
compileWithPartial: function (template, options) {
|
||||||
// Hack the compiler on to the environment for these specific tests
|
// Hack the compiler on to the environment for these specific tests
|
||||||
handlebarsEnv.compile = function(compileTemplate, compileOptions) {
|
handlebarsEnv.compile = function (compileTemplate, compileOptions) {
|
||||||
return compiler.compile(compileTemplate, compileOptions, handlebarsEnv);
|
return compiler.compile(compileTemplate, compileOptions, handlebarsEnv);
|
||||||
};
|
};
|
||||||
handlebarsEnv.parse = parse;
|
handlebarsEnv.parse = parse;
|
||||||
@@ -55,7 +58,7 @@ global.CompilerContext = {
|
|||||||
handlebarsEnv.JavaScriptCompiler = JavaScriptCompiler;
|
handlebarsEnv.JavaScriptCompiler = JavaScriptCompiler;
|
||||||
|
|
||||||
return handlebarsEnv.compile(template, options);
|
return handlebarsEnv.compile(template, options);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function safeEval(templateSpec) {
|
function safeEval(templateSpec) {
|
||||||
|
|||||||
+200
-200
File diff suppressed because it is too large
Load Diff
+30
-28
@@ -1,19 +1,19 @@
|
|||||||
describe('javascript-compiler api', function() {
|
describe('javascript-compiler api', function () {
|
||||||
if (!Handlebars.JavaScriptCompiler) {
|
if (!Handlebars.JavaScriptCompiler) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('#nameLookup', function() {
|
describe('#nameLookup', function () {
|
||||||
var $superName;
|
var $superName;
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
$superName = handlebarsEnv.JavaScriptCompiler.prototype.nameLookup;
|
$superName = handlebarsEnv.JavaScriptCompiler.prototype.nameLookup;
|
||||||
});
|
});
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = $superName;
|
handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = $superName;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow override', function() {
|
it('should allow override', function () {
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = function(
|
handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = function (
|
||||||
parent,
|
parent,
|
||||||
name
|
name
|
||||||
) {
|
) {
|
||||||
@@ -28,27 +28,27 @@ describe('javascript-compiler api', function() {
|
|||||||
|
|
||||||
// Tests nameLookup dot vs. bracket behavior. Bracket is required in certain cases
|
// Tests nameLookup dot vs. bracket behavior. Bracket is required in certain cases
|
||||||
// to avoid errors in older browsers.
|
// to avoid errors in older browsers.
|
||||||
it('should handle reserved words', function() {
|
it('should handle reserved words', function () {
|
||||||
expectTemplate('{{foo}} {{~null~}}')
|
expectTemplate('{{foo}} {{~null~}}')
|
||||||
.withInput({ foo: 'food' })
|
.withInput({ foo: 'food' })
|
||||||
.toCompileTo('food');
|
.toCompileTo('food');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#compilerInfo', function() {
|
describe('#compilerInfo', function () {
|
||||||
var $superCheck, $superInfo;
|
var $superCheck, $superInfo;
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
$superCheck = handlebarsEnv.VM.checkRevision;
|
$superCheck = handlebarsEnv.VM.checkRevision;
|
||||||
$superInfo = handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo;
|
$superInfo = handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo;
|
||||||
});
|
});
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
handlebarsEnv.VM.checkRevision = $superCheck;
|
handlebarsEnv.VM.checkRevision = $superCheck;
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = $superInfo;
|
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = $superInfo;
|
||||||
});
|
});
|
||||||
it('should allow compilerInfo override', function() {
|
it('should allow compilerInfo override', function () {
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = function() {
|
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = function () {
|
||||||
return 'crazy';
|
return 'crazy';
|
||||||
};
|
};
|
||||||
handlebarsEnv.VM.checkRevision = function(compilerInfo) {
|
handlebarsEnv.VM.checkRevision = function (compilerInfo) {
|
||||||
if (compilerInfo !== 'crazy') {
|
if (compilerInfo !== 'crazy') {
|
||||||
throw new Error("It didn't work");
|
throw new Error("It didn't work");
|
||||||
}
|
}
|
||||||
@@ -58,30 +58,32 @@ describe('javascript-compiler api', function() {
|
|||||||
.toCompileTo('food ');
|
.toCompileTo('food ');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('buffer', function() {
|
describe('buffer', function () {
|
||||||
var $superAppend, $superCreate;
|
var $superAppend, $superCreate;
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.forceBuffer = true;
|
handlebarsEnv.JavaScriptCompiler.prototype.forceBuffer = true;
|
||||||
$superAppend = handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer;
|
$superAppend = handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer;
|
||||||
$superCreate =
|
$superCreate =
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer;
|
handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer;
|
||||||
});
|
});
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.forceBuffer = false;
|
handlebarsEnv.JavaScriptCompiler.prototype.forceBuffer = false;
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = $superAppend;
|
handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = $superAppend;
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer = $superCreate;
|
handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer =
|
||||||
|
$superCreate;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow init buffer override', function() {
|
it('should allow init buffer override', function () {
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer = function() {
|
handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer =
|
||||||
return this.quotedString('foo_');
|
function () {
|
||||||
};
|
return this.quotedString('foo_');
|
||||||
|
};
|
||||||
expectTemplate('{{foo}} ')
|
expectTemplate('{{foo}} ')
|
||||||
.withInput({ foo: 'food' })
|
.withInput({ foo: 'food' })
|
||||||
.toCompileTo('foo_food ');
|
.toCompileTo('foo_food ');
|
||||||
});
|
});
|
||||||
it('should allow append buffer override', function() {
|
it('should allow append buffer override', function () {
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = function(
|
handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = function (
|
||||||
string
|
string
|
||||||
) {
|
) {
|
||||||
return $superAppend.call(this, [string, ' + "_foo"']);
|
return $superAppend.call(this, [string, ' + "_foo"']);
|
||||||
@@ -92,13 +94,13 @@ describe('javascript-compiler api', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#isValidJavaScriptVariableName', function() {
|
describe('#isValidJavaScriptVariableName', function () {
|
||||||
// It is there and accessible and could be used by someone. That's why we don't remove it
|
// It is there and accessible and could be used by someone. That's why we don't remove it
|
||||||
// it 4.x. But if we keep it, we add a test
|
// it 4.x. But if we keep it, we add a test
|
||||||
// This test should not encourage you to use the function. It is not needed any more
|
// This test should not encourage you to use the function. It is not needed any more
|
||||||
// and might be removed in 5.0
|
// and might be removed in 5.0
|
||||||
['test', 'abc123', 'abc_123'].forEach(function(validVariableName) {
|
['test', 'abc123', 'abc_123'].forEach(function (validVariableName) {
|
||||||
it("should return true for '" + validVariableName + "'", function() {
|
it("should return true for '" + validVariableName + "'", function () {
|
||||||
expect(
|
expect(
|
||||||
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
||||||
validVariableName
|
validVariableName
|
||||||
@@ -106,8 +108,8 @@ describe('javascript-compiler api', function() {
|
|||||||
).to.be.true();
|
).to.be.true();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
[('123test', 'abc()', 'abc.cde')].forEach(function(invalidVariableName) {
|
[('123test', 'abc()', 'abc.cde')].forEach(function (invalidVariableName) {
|
||||||
it("should return true for '" + invalidVariableName + "'", function() {
|
it("should return true for '" + invalidVariableName + "'", function () {
|
||||||
expect(
|
expect(
|
||||||
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
||||||
invalidVariableName
|
invalidVariableName
|
||||||
|
|||||||
+118
-121
@@ -1,12 +1,12 @@
|
|||||||
describe('partials', function() {
|
describe('partials', function () {
|
||||||
it('basic partials', function() {
|
it('basic partials', function () {
|
||||||
var string = 'Dudes: {{#dudes}}{{> dude}}{{/dudes}}';
|
var string = 'Dudes: {{#dudes}}{{> dude}}{{/dudes}}';
|
||||||
var partial = '{{name}} ({{url}}) ';
|
var partial = '{{name}} ({{url}}) ';
|
||||||
var hash = {
|
var hash = {
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
@@ -22,19 +22,19 @@ describe('partials', function() {
|
|||||||
.toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
|
.toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dynamic partials', function() {
|
it('dynamic partials', function () {
|
||||||
var string = 'Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}';
|
var string = 'Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}';
|
||||||
var partial = '{{name}} ({{url}}) ';
|
var partial = '{{name}} ({{url}}) ';
|
||||||
var hash = {
|
var hash = {
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
var helpers = {
|
var helpers = {
|
||||||
partial: function() {
|
partial: function () {
|
||||||
return 'dude';
|
return 'dude';
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
@@ -52,41 +52,41 @@ describe('partials', function() {
|
|||||||
.toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
|
.toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('failing dynamic partials', function() {
|
it('failing dynamic partials', function () {
|
||||||
expectTemplate('Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}')
|
expectTemplate('Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withHelper('partial', function() {
|
.withHelper('partial', function () {
|
||||||
return 'missing';
|
return 'missing';
|
||||||
})
|
})
|
||||||
.withPartial('dude', '{{name}} ({{url}}) ')
|
.withPartial('dude', '{{name}} ({{url}}) ')
|
||||||
.toThrow(Handlebars.Exception, 'The partial missing could not be found');
|
.toThrow(Handlebars.Exception, 'The partial missing could not be found');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('partials with context', function() {
|
it('partials with context', function () {
|
||||||
expectTemplate('Dudes: {{>dude dudes}}')
|
expectTemplate('Dudes: {{>dude dudes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartial('dude', '{{#this}}{{name}} ({{url}}) {{/this}}')
|
.withPartial('dude', '{{#this}}{{name}} ({{url}}) {{/this}}')
|
||||||
.withMessage('Partials can be passed a context')
|
.withMessage('Partials can be passed a context')
|
||||||
.toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
|
.toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('partials with no context', function() {
|
it('partials with no context', function () {
|
||||||
var partial = '{{name}} ({{url}}) ';
|
var partial = '{{name}} ({{url}}) ';
|
||||||
var hash = {
|
var hash = {
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
expectTemplate('Dudes: {{#dudes}}{{>dude}}{{/dudes}}')
|
expectTemplate('Dudes: {{#dudes}}{{>dude}}{{/dudes}}')
|
||||||
@@ -102,50 +102,50 @@ describe('partials', function() {
|
|||||||
.toCompileTo('Dudes: foo () foo () ');
|
.toCompileTo('Dudes: foo () foo () ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('partials with string context', function() {
|
it('partials with string context', function () {
|
||||||
expectTemplate('Dudes: {{>dude "dudes"}}')
|
expectTemplate('Dudes: {{>dude "dudes"}}')
|
||||||
.withPartial('dude', '{{.}}')
|
.withPartial('dude', '{{.}}')
|
||||||
.toCompileTo('Dudes: dudes');
|
.toCompileTo('Dudes: dudes');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('partials with undefined context', function() {
|
it('partials with undefined context', function () {
|
||||||
expectTemplate('Dudes: {{>dude dudes}}')
|
expectTemplate('Dudes: {{>dude dudes}}')
|
||||||
.withPartial('dude', '{{foo}} Empty')
|
.withPartial('dude', '{{foo}} Empty')
|
||||||
.toCompileTo('Dudes: Empty');
|
.toCompileTo('Dudes: Empty');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('partials with duplicate parameters', function() {
|
it('partials with duplicate parameters', function () {
|
||||||
expectTemplate('Dudes: {{>dude dudes foo bar=baz}}').toThrow(
|
expectTemplate('Dudes: {{>dude dudes foo bar=baz}}').toThrow(
|
||||||
Error,
|
Error,
|
||||||
'Unsupported number of partial arguments: 2 - 1:7'
|
'Unsupported number of partial arguments: 2 - 1:7'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('partials with parameters', function() {
|
it('partials with parameters', function () {
|
||||||
expectTemplate('Dudes: {{#dudes}}{{> dude others=..}}{{/dudes}}')
|
expectTemplate('Dudes: {{#dudes}}{{> dude others=..}}{{/dudes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
foo: 'bar',
|
foo: 'bar',
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartial('dude', '{{others.foo}}{{name}} ({{url}}) ')
|
.withPartial('dude', '{{others.foo}}{{name}} ({{url}}) ')
|
||||||
.withMessage('Basic partials output based on current context.')
|
.withMessage('Basic partials output based on current context.')
|
||||||
.toCompileTo('Dudes: barYehuda (http://yehuda) barAlan (http://alan) ');
|
.toCompileTo('Dudes: barYehuda (http://yehuda) barAlan (http://alan) ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('partial in a partial', function() {
|
it('partial in a partial', function () {
|
||||||
expectTemplate('Dudes: {{#dudes}}{{>dude}}{{/dudes}}')
|
expectTemplate('Dudes: {{#dudes}}{{>dude}}{{/dudes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartials({
|
.withPartials({
|
||||||
dude: '{{name}} {{> url}} ',
|
dude: '{{name}} {{> url}} ',
|
||||||
url: '<a href="{{url}}">{{url}}</a>'
|
url: '<a href="{{url}}">{{url}}</a>',
|
||||||
})
|
})
|
||||||
.withMessage('Partials are rendered inside of other partials')
|
.withMessage('Partials are rendered inside of other partials')
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
@@ -153,16 +153,16 @@ describe('partials', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rendering undefined partial throws an exception', function() {
|
it('rendering undefined partial throws an exception', function () {
|
||||||
expectTemplate('{{> whatever}}').toThrow(
|
expectTemplate('{{> whatever}}').toThrow(
|
||||||
Handlebars.Exception,
|
Handlebars.Exception,
|
||||||
'The partial whatever could not be found'
|
'The partial whatever could not be found'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('registering undefined partial throws an exception', function() {
|
it('registering undefined partial throws an exception', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
var undef;
|
var undef;
|
||||||
handlebarsEnv.registerPartial('undefined_test', undef);
|
handlebarsEnv.registerPartial('undefined_test', undef);
|
||||||
},
|
},
|
||||||
@@ -171,14 +171,14 @@ describe('partials', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rendering template partial in vm mode throws an exception', function() {
|
it('rendering template partial in vm mode throws an exception', function () {
|
||||||
expectTemplate('{{> whatever}}').toThrow(
|
expectTemplate('{{> whatever}}').toThrow(
|
||||||
Handlebars.Exception,
|
Handlebars.Exception,
|
||||||
'The partial whatever could not be found'
|
'The partial whatever could not be found'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rendering function partial in vm mode', function() {
|
it('rendering function partial in vm mode', function () {
|
||||||
function partial(context) {
|
function partial(context) {
|
||||||
return context.name + ' (' + context.url + ') ';
|
return context.name + ' (' + context.url + ') ';
|
||||||
}
|
}
|
||||||
@@ -186,15 +186,15 @@ describe('partials', function() {
|
|||||||
.withInput({
|
.withInput({
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartial('dude', partial)
|
.withPartial('dude', partial)
|
||||||
.withMessage('Function partials output based in VM.')
|
.withMessage('Function partials output based in VM.')
|
||||||
.toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
|
.toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-14: a partial preceding a selector', function() {
|
it('GH-14: a partial preceding a selector', function () {
|
||||||
expectTemplate('Dudes: {{>dude}} {{anotherDude}}')
|
expectTemplate('Dudes: {{>dude}} {{anotherDude}}')
|
||||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||||
.withPartial('dude', '{{name}}')
|
.withPartial('dude', '{{name}}')
|
||||||
@@ -202,7 +202,7 @@ describe('partials', function() {
|
|||||||
.toCompileTo('Dudes: Jeepers Creepers');
|
.toCompileTo('Dudes: Jeepers Creepers');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Partials with slash paths', function() {
|
it('Partials with slash paths', function () {
|
||||||
expectTemplate('Dudes: {{> shared/dude}}')
|
expectTemplate('Dudes: {{> shared/dude}}')
|
||||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||||
.withPartial('shared/dude', '{{name}}')
|
.withPartial('shared/dude', '{{name}}')
|
||||||
@@ -210,7 +210,7 @@ describe('partials', function() {
|
|||||||
.toCompileTo('Dudes: Jeepers');
|
.toCompileTo('Dudes: Jeepers');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Partials with slash and point paths', function() {
|
it('Partials with slash and point paths', function () {
|
||||||
expectTemplate('Dudes: {{> shared/dude.thing}}')
|
expectTemplate('Dudes: {{> shared/dude.thing}}')
|
||||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||||
.withPartial('shared/dude.thing', '{{name}}')
|
.withPartial('shared/dude.thing', '{{name}}')
|
||||||
@@ -218,7 +218,7 @@ describe('partials', function() {
|
|||||||
.toCompileTo('Dudes: Jeepers');
|
.toCompileTo('Dudes: Jeepers');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Global Partials', function() {
|
it('Global Partials', function () {
|
||||||
handlebarsEnv.registerPartial('globalTest', '{{anotherDude}}');
|
handlebarsEnv.registerPartial('globalTest', '{{anotherDude}}');
|
||||||
|
|
||||||
expectTemplate('Dudes: {{> shared/dude}} {{> globalTest}}')
|
expectTemplate('Dudes: {{> shared/dude}} {{> globalTest}}')
|
||||||
@@ -231,10 +231,10 @@ describe('partials', function() {
|
|||||||
equals(handlebarsEnv.partials.globalTest, undefined);
|
equals(handlebarsEnv.partials.globalTest, undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Multiple partial registration', function() {
|
it('Multiple partial registration', function () {
|
||||||
handlebarsEnv.registerPartial({
|
handlebarsEnv.registerPartial({
|
||||||
'shared/dude': '{{name}}',
|
'shared/dude': '{{name}}',
|
||||||
globalTest: '{{anotherDude}}'
|
globalTest: '{{anotherDude}}',
|
||||||
});
|
});
|
||||||
|
|
||||||
expectTemplate('Dudes: {{> shared/dude}} {{> globalTest}}')
|
expectTemplate('Dudes: {{> shared/dude}} {{> globalTest}}')
|
||||||
@@ -244,7 +244,7 @@ describe('partials', function() {
|
|||||||
.toCompileTo('Dudes: Jeepers Creepers');
|
.toCompileTo('Dudes: Jeepers Creepers');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Partials with integer path', function() {
|
it('Partials with integer path', function () {
|
||||||
expectTemplate('Dudes: {{> 404}}')
|
expectTemplate('Dudes: {{> 404}}')
|
||||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||||
.withPartial(404, '{{name}}')
|
.withPartial(404, '{{name}}')
|
||||||
@@ -252,7 +252,7 @@ describe('partials', function() {
|
|||||||
.toCompileTo('Dudes: Jeepers');
|
.toCompileTo('Dudes: Jeepers');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Partials with complex path', function() {
|
it('Partials with complex path', function () {
|
||||||
expectTemplate('Dudes: {{> 404/asdf?.bar}}')
|
expectTemplate('Dudes: {{> 404/asdf?.bar}}')
|
||||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||||
.withPartial('404/asdf?.bar', '{{name}}')
|
.withPartial('404/asdf?.bar', '{{name}}')
|
||||||
@@ -260,7 +260,7 @@ describe('partials', function() {
|
|||||||
.toCompileTo('Dudes: Jeepers');
|
.toCompileTo('Dudes: Jeepers');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Partials with escaped', function() {
|
it('Partials with escaped', function () {
|
||||||
expectTemplate('Dudes: {{> [+404/asdf?.bar]}}')
|
expectTemplate('Dudes: {{> [+404/asdf?.bar]}}')
|
||||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||||
.withPartial('+404/asdf?.bar', '{{name}}')
|
.withPartial('+404/asdf?.bar', '{{name}}')
|
||||||
@@ -268,7 +268,7 @@ describe('partials', function() {
|
|||||||
.toCompileTo('Dudes: Jeepers');
|
.toCompileTo('Dudes: Jeepers');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Partials with string', function() {
|
it('Partials with string', function () {
|
||||||
expectTemplate("Dudes: {{> '+404/asdf?.bar'}}")
|
expectTemplate("Dudes: {{> '+404/asdf?.bar'}}")
|
||||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||||
.withPartial('+404/asdf?.bar', '{{name}}')
|
.withPartial('+404/asdf?.bar', '{{name}}')
|
||||||
@@ -276,19 +276,19 @@ describe('partials', function() {
|
|||||||
.toCompileTo('Dudes: Jeepers');
|
.toCompileTo('Dudes: Jeepers');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle empty partial', function() {
|
it('should handle empty partial', function () {
|
||||||
expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}')
|
expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartial('dude', '')
|
.withPartial('dude', '')
|
||||||
.toCompileTo('Dudes: ');
|
.toCompileTo('Dudes: ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throw on missing partial', function() {
|
it('throw on missing partial', function () {
|
||||||
var compile = handlebarsEnv.compile;
|
var compile = handlebarsEnv.compile;
|
||||||
var compileWithPartial = CompilerContext.compileWithPartial;
|
var compileWithPartial = CompilerContext.compileWithPartial;
|
||||||
handlebarsEnv.compile = undefined;
|
handlebarsEnv.compile = undefined;
|
||||||
@@ -300,18 +300,18 @@ describe('partials', function() {
|
|||||||
CompilerContext.compileWithPartial = compileWithPartial;
|
CompilerContext.compileWithPartial = compileWithPartial;
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('partial blocks', function() {
|
describe('partial blocks', function () {
|
||||||
it('should render partial block as default', function() {
|
it('should render partial block as default', function () {
|
||||||
expectTemplate('{{#> dude}}success{{/dude}}').toCompileTo('success');
|
expectTemplate('{{#> dude}}success{{/dude}}').toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should execute default block with proper context', function() {
|
it('should execute default block with proper context', function () {
|
||||||
expectTemplate('{{#> dude context}}{{value}}{{/dude}}')
|
expectTemplate('{{#> dude context}}{{value}}{{/dude}}')
|
||||||
.withInput({ context: { value: 'success' } })
|
.withInput({ context: { value: 'success' } })
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should propagate block parameters to default block', function() {
|
it('should propagate block parameters to default block', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}'
|
'{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}'
|
||||||
)
|
)
|
||||||
@@ -319,79 +319,76 @@ describe('partials', function() {
|
|||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not use partial block if partial exists', function() {
|
it('should not use partial block if partial exists', function () {
|
||||||
expectTemplate('{{#> dude}}fail{{/dude}}')
|
expectTemplate('{{#> dude}}fail{{/dude}}')
|
||||||
.withPartials({ dude: 'success' })
|
.withPartials({ dude: 'success' })
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render block from partial', function() {
|
it('should render block from partial', function () {
|
||||||
expectTemplate('{{#> dude}}success{{/dude}}')
|
expectTemplate('{{#> dude}}success{{/dude}}')
|
||||||
.withPartials({ dude: '{{> @partial-block }}' })
|
.withPartials({ dude: '{{> @partial-block }}' })
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to render the partial-block twice', function() {
|
it('should be able to render the partial-block twice', function () {
|
||||||
expectTemplate('{{#> dude}}success{{/dude}}')
|
expectTemplate('{{#> dude}}success{{/dude}}')
|
||||||
.withPartials({ dude: '{{> @partial-block }} {{> @partial-block }}' })
|
.withPartials({ dude: '{{> @partial-block }} {{> @partial-block }}' })
|
||||||
.toCompileTo('success success');
|
.toCompileTo('success success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render block from partial with context', function() {
|
it('should render block from partial with context', function () {
|
||||||
expectTemplate('{{#> dude}}{{value}}{{/dude}}')
|
expectTemplate('{{#> dude}}{{value}}{{/dude}}')
|
||||||
.withInput({ context: { value: 'success' } })
|
.withInput({ context: { value: 'success' } })
|
||||||
.withPartials({
|
.withPartials({
|
||||||
dude: '{{#with context}}{{> @partial-block }}{{/with}}'
|
dude: '{{#with context}}{{> @partial-block }}{{/with}}',
|
||||||
})
|
})
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to access the @data frame from a partial-block', function() {
|
it('should be able to access the @data frame from a partial-block', function () {
|
||||||
expectTemplate('{{#> dude}}in-block: {{@root/value}}{{/dude}}')
|
expectTemplate('{{#> dude}}in-block: {{@root/value}}{{/dude}}')
|
||||||
.withInput({ value: 'success' })
|
.withInput({ value: 'success' })
|
||||||
.withPartials({
|
.withPartials({
|
||||||
dude:
|
dude: '<code>before-block: {{@root/value}} {{> @partial-block }}</code>',
|
||||||
'<code>before-block: {{@root/value}} {{> @partial-block }}</code>'
|
|
||||||
})
|
})
|
||||||
.toCompileTo('<code>before-block: success in-block: success</code>');
|
.toCompileTo('<code>before-block: success in-block: success</code>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow the #each-helper to be used along with partial-blocks', function() {
|
it('should allow the #each-helper to be used along with partial-blocks', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'<template>{{#> list value}}value = {{.}}{{/list}}</template>'
|
'<template>{{#> list value}}value = {{.}}{{/list}}</template>'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
value: ['a', 'b', 'c']
|
value: ['a', 'b', 'c'],
|
||||||
})
|
})
|
||||||
.withPartials({
|
.withPartials({
|
||||||
list:
|
list: '<list>{{#each .}}<item>{{> @partial-block}}</item>{{/each}}</list>',
|
||||||
'<list>{{#each .}}<item>{{> @partial-block}}</item>{{/each}}</list>'
|
|
||||||
})
|
})
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
'<template><list><item>value = a</item><item>value = b</item><item>value = c</item></list></template>'
|
'<template><list><item>value = a</item><item>value = b</item><item>value = c</item></list></template>'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render block from partial with context (twice)', function() {
|
it('should render block from partial with context (twice)', function () {
|
||||||
expectTemplate('{{#> dude}}{{value}}{{/dude}}')
|
expectTemplate('{{#> dude}}{{value}}{{/dude}}')
|
||||||
.withInput({ context: { value: 'success' } })
|
.withInput({ context: { value: 'success' } })
|
||||||
.withPartials({
|
.withPartials({
|
||||||
dude:
|
dude: '{{#with context}}{{> @partial-block }} {{> @partial-block }}{{/with}}',
|
||||||
'{{#with context}}{{> @partial-block }} {{> @partial-block }}{{/with}}'
|
|
||||||
})
|
})
|
||||||
.toCompileTo('success success');
|
.toCompileTo('success success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render block from partial with context', function() {
|
it('should render block from partial with context', function () {
|
||||||
expectTemplate('{{#> dude}}{{../context/value}}{{/dude}}')
|
expectTemplate('{{#> dude}}{{../context/value}}{{/dude}}')
|
||||||
.withInput({ context: { value: 'success' } })
|
.withInput({ context: { value: 'success' } })
|
||||||
.withPartials({
|
.withPartials({
|
||||||
dude: '{{#with context}}{{> @partial-block }}{{/with}}'
|
dude: '{{#with context}}{{> @partial-block }}{{/with}}',
|
||||||
})
|
})
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render block from partial with block params', function() {
|
it('should render block from partial with block params', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}'
|
'{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}'
|
||||||
)
|
)
|
||||||
@@ -400,52 +397,52 @@ describe('partials', function() {
|
|||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render nested partial blocks', function() {
|
it('should render nested partial blocks', function () {
|
||||||
expectTemplate('<template>{{#> outer}}{{value}}{{/outer}}</template>')
|
expectTemplate('<template>{{#> outer}}{{value}}{{/outer}}</template>')
|
||||||
.withInput({ value: 'success' })
|
.withInput({ value: 'success' })
|
||||||
.withPartials({
|
.withPartials({
|
||||||
outer:
|
outer:
|
||||||
'<outer>{{#> nested}}<outer-block>{{> @partial-block}}</outer-block>{{/nested}}</outer>',
|
'<outer>{{#> nested}}<outer-block>{{> @partial-block}}</outer-block>{{/nested}}</outer>',
|
||||||
nested: '<nested>{{> @partial-block}}</nested>'
|
nested: '<nested>{{> @partial-block}}</nested>',
|
||||||
})
|
})
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
'<template><outer><nested><outer-block>success</outer-block></nested></outer></template>'
|
'<template><outer><nested><outer-block>success</outer-block></nested></outer></template>'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render nested partial blocks at different nesting levels', function() {
|
it('should render nested partial blocks at different nesting levels', function () {
|
||||||
expectTemplate('<template>{{#> outer}}{{value}}{{/outer}}</template>')
|
expectTemplate('<template>{{#> outer}}{{value}}{{/outer}}</template>')
|
||||||
.withInput({ value: 'success' })
|
.withInput({ value: 'success' })
|
||||||
.withPartials({
|
.withPartials({
|
||||||
outer:
|
outer:
|
||||||
'<outer>{{#> nested}}<outer-block>{{> @partial-block}}</outer-block>{{/nested}}{{> @partial-block}}</outer>',
|
'<outer>{{#> nested}}<outer-block>{{> @partial-block}}</outer-block>{{/nested}}{{> @partial-block}}</outer>',
|
||||||
nested: '<nested>{{> @partial-block}}</nested>'
|
nested: '<nested>{{> @partial-block}}</nested>',
|
||||||
})
|
})
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
'<template><outer><nested><outer-block>success</outer-block></nested>success</outer></template>'
|
'<template><outer><nested><outer-block>success</outer-block></nested>success</outer></template>'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render nested partial blocks at different nesting levels (twice)', function() {
|
it('should render nested partial blocks at different nesting levels (twice)', function () {
|
||||||
expectTemplate('<template>{{#> outer}}{{value}}{{/outer}}</template>')
|
expectTemplate('<template>{{#> outer}}{{value}}{{/outer}}</template>')
|
||||||
.withInput({ value: 'success' })
|
.withInput({ value: 'success' })
|
||||||
.withPartials({
|
.withPartials({
|
||||||
outer:
|
outer:
|
||||||
'<outer>{{#> nested}}<outer-block>{{> @partial-block}} {{> @partial-block}}</outer-block>{{/nested}}{{> @partial-block}}+{{> @partial-block}}</outer>',
|
'<outer>{{#> nested}}<outer-block>{{> @partial-block}} {{> @partial-block}}</outer-block>{{/nested}}{{> @partial-block}}+{{> @partial-block}}</outer>',
|
||||||
nested: '<nested>{{> @partial-block}}</nested>'
|
nested: '<nested>{{> @partial-block}}</nested>',
|
||||||
})
|
})
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
'<template><outer><nested><outer-block>success success</outer-block></nested>success+success</outer></template>'
|
'<template><outer><nested><outer-block>success success</outer-block></nested>success+success</outer></template>'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render nested partial blocks (twice at each level)', function() {
|
it('should render nested partial blocks (twice at each level)', function () {
|
||||||
expectTemplate('<template>{{#> outer}}{{value}}{{/outer}}</template>')
|
expectTemplate('<template>{{#> outer}}{{value}}{{/outer}}</template>')
|
||||||
.withInput({ value: 'success' })
|
.withInput({ value: 'success' })
|
||||||
.withPartials({
|
.withPartials({
|
||||||
outer:
|
outer:
|
||||||
'<outer>{{#> nested}}<outer-block>{{> @partial-block}} {{> @partial-block}}</outer-block>{{/nested}}</outer>',
|
'<outer>{{#> nested}}<outer-block>{{> @partial-block}} {{> @partial-block}}</outer-block>{{/nested}}</outer>',
|
||||||
nested: '<nested>{{> @partial-block}}{{> @partial-block}}</nested>'
|
nested: '<nested>{{> @partial-block}}{{> @partial-block}}</nested>',
|
||||||
})
|
})
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
'<template><outer>' +
|
'<template><outer>' +
|
||||||
@@ -455,20 +452,20 @@ describe('partials', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('inline partials', function() {
|
describe('inline partials', function () {
|
||||||
it('should define inline partials for template', function() {
|
it('should define inline partials for template', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}'
|
'{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}'
|
||||||
).toCompileTo('success');
|
).toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should overwrite multiple partials in the same template', function() {
|
it('should overwrite multiple partials in the same template', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#*inline "myPartial"}}fail{{/inline}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}'
|
'{{#*inline "myPartial"}}fail{{/inline}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}'
|
||||||
).toCompileTo('success');
|
).toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should define inline partials for block', function() {
|
it('should define inline partials for block', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}'
|
'{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}'
|
||||||
).toCompileTo('success');
|
).toCompileTo('success');
|
||||||
@@ -478,37 +475,37 @@ describe('partials', function() {
|
|||||||
).toThrow(Error, /myPartial could not/);
|
).toThrow(Error, /myPartial could not/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should override global partials', function() {
|
it('should override global partials', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}'
|
'{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}'
|
||||||
)
|
)
|
||||||
.withPartials({
|
.withPartials({
|
||||||
myPartial: function() {
|
myPartial: function () {
|
||||||
return 'fail';
|
return 'fail';
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should override template partials', function() {
|
it('should override template partials', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#*inline "myPartial"}}fail{{/inline}}{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}'
|
'{{#*inline "myPartial"}}fail{{/inline}}{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}'
|
||||||
).toCompileTo('success');
|
).toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should override partials down the entire stack', function() {
|
it('should override partials down the entire stack', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{#with .}}{{#with .}}{{> myPartial}}{{/with}}{{/with}}{{/with}}'
|
'{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{#with .}}{{#with .}}{{> myPartial}}{{/with}}{{/with}}{{/with}}'
|
||||||
).toCompileTo('success');
|
).toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should define inline partials for partial call', function() {
|
it('should define inline partials for partial call', function () {
|
||||||
expectTemplate('{{#*inline "myPartial"}}success{{/inline}}{{> dude}}')
|
expectTemplate('{{#*inline "myPartial"}}success{{/inline}}{{> dude}}')
|
||||||
.withPartials({ dude: '{{> myPartial }}' })
|
.withPartials({ dude: '{{> myPartial }}' })
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should define inline partials in partial block call', function() {
|
it('should define inline partials in partial block call', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#> dude}}{{#*inline "myPartial"}}success{{/inline}}{{/dude}}'
|
'{{#> dude}}{{#*inline "myPartial"}}success{{/inline}}{{/dude}}'
|
||||||
)
|
)
|
||||||
@@ -516,7 +513,7 @@ describe('partials', function() {
|
|||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render nested inline partials', function() {
|
it('should render nested inline partials', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}}</outer-block>{{/inner}}{{/inline}}' +
|
'{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}}</outer-block>{{/inner}}{{/inline}}' +
|
||||||
'{{#*inline "inner"}}<inner>{{>@partial-block}}</inner>{{/inline}}' +
|
'{{#*inline "inner"}}<inner>{{>@partial-block}}</inner>{{/inline}}' +
|
||||||
@@ -526,7 +523,7 @@ describe('partials', function() {
|
|||||||
.toCompileTo('<inner><outer-block>success</outer-block></inner>');
|
.toCompileTo('<inner><outer-block>success</outer-block></inner>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render nested inline partials with partial-blocks on different nesting levels', function() {
|
it('should render nested inline partials with partial-blocks on different nesting levels', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}}</outer-block>{{/inner}}{{>@partial-block}}{{/inline}}' +
|
'{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}}</outer-block>{{/inner}}{{>@partial-block}}{{/inline}}' +
|
||||||
'{{#*inline "inner"}}<inner>{{>@partial-block}}</inner>{{/inline}}' +
|
'{{#*inline "inner"}}<inner>{{>@partial-block}}</inner>{{/inline}}' +
|
||||||
@@ -538,7 +535,7 @@ describe('partials', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render nested inline partials (twice at each level)', function() {
|
it('should render nested inline partials (twice at each level)', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}} {{>@partial-block}}</outer-block>{{/inner}}{{/inline}}' +
|
'{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}} {{>@partial-block}}</outer-block>{{/inner}}{{/inline}}' +
|
||||||
'{{#*inline "inner"}}<inner>{{>@partial-block}}{{>@partial-block}}</inner>{{/inline}}' +
|
'{{#*inline "inner"}}<inner>{{>@partial-block}}{{>@partial-block}}</inner>{{/inline}}' +
|
||||||
@@ -551,7 +548,7 @@ describe('partials', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass compiler flags', function() {
|
it('should pass compiler flags', function () {
|
||||||
if (Handlebars.compile) {
|
if (Handlebars.compile) {
|
||||||
var env = Handlebars.create();
|
var env = Handlebars.create();
|
||||||
env.registerPartial('partial', '{{foo}}');
|
env.registerPartial('partial', '{{foo}}');
|
||||||
@@ -560,47 +557,47 @@ describe('partials', function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('standalone partials', function() {
|
describe('standalone partials', function () {
|
||||||
it('indented partials', function() {
|
it('indented partials', function () {
|
||||||
expectTemplate('Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}')
|
expectTemplate('Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartial('dude', '{{name}}\n')
|
.withPartial('dude', '{{name}}\n')
|
||||||
.toCompileTo('Dudes:\n Yehuda\n Alan\n');
|
.toCompileTo('Dudes:\n Yehuda\n Alan\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('nested indented partials', function() {
|
it('nested indented partials', function () {
|
||||||
expectTemplate('Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}')
|
expectTemplate('Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartials({
|
.withPartials({
|
||||||
dude: '{{name}}\n {{> url}}',
|
dude: '{{name}}\n {{> url}}',
|
||||||
url: '{{url}}!\n'
|
url: '{{url}}!\n',
|
||||||
})
|
})
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
'Dudes:\n Yehuda\n http://yehuda!\n Alan\n http://alan!\n'
|
'Dudes:\n Yehuda\n http://yehuda!\n Alan\n http://alan!\n'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('prevent nested indented partials', function() {
|
it('prevent nested indented partials', function () {
|
||||||
expectTemplate('Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}')
|
expectTemplate('Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartials({
|
.withPartials({
|
||||||
dude: '{{name}}\n {{> url}}',
|
dude: '{{name}}\n {{> url}}',
|
||||||
url: '{{url}}!\n'
|
url: '{{url}}!\n',
|
||||||
})
|
})
|
||||||
.withCompileOptions({ preventIndent: true })
|
.withCompileOptions({ preventIndent: true })
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
@@ -609,15 +606,15 @@ describe('partials', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('compat mode', function() {
|
describe('compat mode', function () {
|
||||||
it('partials can access parents', function() {
|
it('partials can access parents', function () {
|
||||||
expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}')
|
expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
root: 'yes',
|
root: 'yes',
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartials({ dude: '{{name}} ({{url}}) {{root}} ' })
|
.withPartials({ dude: '{{name}} ({{url}}) {{root}} ' })
|
||||||
.withCompileOptions({ compat: true })
|
.withCompileOptions({ compat: true })
|
||||||
@@ -626,14 +623,14 @@ describe('partials', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('partials can access parents with custom context', function() {
|
it('partials can access parents with custom context', function () {
|
||||||
expectTemplate('Dudes: {{#dudes}}{{> dude "test"}}{{/dudes}}')
|
expectTemplate('Dudes: {{#dudes}}{{> dude "test"}}{{/dudes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
root: 'yes',
|
root: 'yes',
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartials({ dude: '{{name}} ({{url}}) {{root}} ' })
|
.withPartials({ dude: '{{name}} ({{url}}) {{root}} ' })
|
||||||
.withCompileOptions({ compat: true })
|
.withCompileOptions({ compat: true })
|
||||||
@@ -642,14 +639,14 @@ describe('partials', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('partials can access parents without data', function() {
|
it('partials can access parents without data', function () {
|
||||||
expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}')
|
expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
root: 'yes',
|
root: 'yes',
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartials({ dude: '{{name}} ({{url}}) {{root}} ' })
|
.withPartials({ dude: '{{name}} ({{url}}) {{root}} ' })
|
||||||
.withRuntimeOptions({ data: false })
|
.withRuntimeOptions({ data: false })
|
||||||
@@ -659,17 +656,17 @@ describe('partials', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('partials inherit compat', function() {
|
it('partials inherit compat', function () {
|
||||||
expectTemplate('Dudes: {{> dude}}')
|
expectTemplate('Dudes: {{> dude}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
root: 'yes',
|
root: 'yes',
|
||||||
dudes: [
|
dudes: [
|
||||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||||
{ name: 'Alan', url: 'http://alan' }
|
{ name: 'Alan', url: 'http://alan' },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withPartials({
|
.withPartials({
|
||||||
dude: '{{#dudes}}{{name}} ({{url}}) {{root}} {{/dudes}}'
|
dude: '{{#dudes}}{{name}} ({{url}}) {{root}} {{/dudes}}',
|
||||||
})
|
})
|
||||||
.withCompileOptions({ compat: true })
|
.withCompileOptions({ compat: true })
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
|
|||||||
+83
-83
@@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
describe('precompiler', function() {
|
describe('precompiler', function () {
|
||||||
// NOP Under non-node environments
|
// NOP Under non-node environments
|
||||||
if (typeof process === 'undefined') {
|
if (typeof process === 'undefined') {
|
||||||
return;
|
return;
|
||||||
@@ -19,7 +19,7 @@ describe('precompiler', function() {
|
|||||||
emptyTemplate = {
|
emptyTemplate = {
|
||||||
path: __dirname + '/artifacts/empty.handlebars',
|
path: __dirname + '/artifacts/empty.handlebars',
|
||||||
name: 'empty',
|
name: 'empty',
|
||||||
source: ''
|
source: '',
|
||||||
},
|
},
|
||||||
file,
|
file,
|
||||||
content,
|
content,
|
||||||
@@ -38,7 +38,7 @@ describe('precompiler', function() {
|
|||||||
var _resolveFilename = Module._resolveFilename;
|
var _resolveFilename = Module._resolveFilename;
|
||||||
delete require.cache[require.resolve('uglify-js')];
|
delete require.cache[require.resolve('uglify-js')];
|
||||||
delete require.cache[require.resolve('../dist/cjs/precompiler')];
|
delete require.cache[require.resolve('../dist/cjs/precompiler')];
|
||||||
Module._resolveFilename = function(request, mod) {
|
Module._resolveFilename = function (request, mod) {
|
||||||
if (request === 'uglify-js') {
|
if (request === 'uglify-js') {
|
||||||
throw loadError;
|
throw loadError;
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ describe('precompiler', function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
precompile = Handlebars.precompile;
|
precompile = Handlebars.precompile;
|
||||||
minify = uglify.minify;
|
minify = uglify.minify;
|
||||||
writeFileSync = fs.writeFileSync;
|
writeFileSync = fs.writeFileSync;
|
||||||
@@ -61,21 +61,21 @@ describe('precompiler', function() {
|
|||||||
// Mock stdout and stderr
|
// Mock stdout and stderr
|
||||||
logFunction = console.log;
|
logFunction = console.log;
|
||||||
log = '';
|
log = '';
|
||||||
console.log = function() {
|
console.log = function () {
|
||||||
log += Array.prototype.join.call(arguments, '');
|
log += Array.prototype.join.call(arguments, '');
|
||||||
};
|
};
|
||||||
errorLogFunction = console.error;
|
errorLogFunction = console.error;
|
||||||
errorLog = '';
|
errorLog = '';
|
||||||
console.error = function() {
|
console.error = function () {
|
||||||
errorLog += Array.prototype.join.call(arguments, '');
|
errorLog += Array.prototype.join.call(arguments, '');
|
||||||
};
|
};
|
||||||
|
|
||||||
fs.writeFileSync = function(_file, _content) {
|
fs.writeFileSync = function (_file, _content) {
|
||||||
file = _file;
|
file = _file;
|
||||||
content = _content;
|
content = _content;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
Handlebars.precompile = precompile;
|
Handlebars.precompile = precompile;
|
||||||
uglify.minify = minify;
|
uglify.minify = minify;
|
||||||
fs.writeFileSync = writeFileSync;
|
fs.writeFileSync = writeFileSync;
|
||||||
@@ -83,59 +83,59 @@ describe('precompiler', function() {
|
|||||||
console.error = errorLogFunction;
|
console.error = errorLogFunction;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should output version', function() {
|
it('should output version', function () {
|
||||||
Precompiler.cli({ templates: [], version: true });
|
Precompiler.cli({ templates: [], version: true });
|
||||||
equals(log, Handlebars.VERSION);
|
equals(log, Handlebars.VERSION);
|
||||||
});
|
});
|
||||||
it('should throw if lacking templates', function() {
|
it('should throw if lacking templates', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Precompiler.cli({ templates: [] });
|
Precompiler.cli({ templates: [] });
|
||||||
},
|
},
|
||||||
Handlebars.Exception,
|
Handlebars.Exception,
|
||||||
'Must define at least one template or directory.'
|
'Must define at least one template or directory.'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should handle empty/filtered directories', function() {
|
it('should handle empty/filtered directories', function () {
|
||||||
Precompiler.cli({ hasDirectory: true, templates: [] });
|
Precompiler.cli({ hasDirectory: true, templates: [] });
|
||||||
// Success is not throwing
|
// Success is not throwing
|
||||||
});
|
});
|
||||||
it('should throw when combining simple and minimized', function() {
|
it('should throw when combining simple and minimized', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Precompiler.cli({ templates: [__dirname], simple: true, min: true });
|
Precompiler.cli({ templates: [__dirname], simple: true, min: true });
|
||||||
},
|
},
|
||||||
Handlebars.Exception,
|
Handlebars.Exception,
|
||||||
'Unable to minimize simple output'
|
'Unable to minimize simple output'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw when combining simple and multiple templates', function() {
|
it('should throw when combining simple and multiple templates', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Precompiler.cli({
|
Precompiler.cli({
|
||||||
templates: [
|
templates: [
|
||||||
__dirname + '/artifacts/empty.handlebars',
|
__dirname + '/artifacts/empty.handlebars',
|
||||||
__dirname + '/artifacts/empty.handlebars'
|
__dirname + '/artifacts/empty.handlebars',
|
||||||
],
|
],
|
||||||
simple: true
|
simple: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
Handlebars.Exception,
|
Handlebars.Exception,
|
||||||
'Unable to output multiple templates in simple mode'
|
'Unable to output multiple templates in simple mode'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw when missing name', function() {
|
it('should throw when missing name', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Precompiler.cli({ templates: [{ source: '' }], amd: true });
|
Precompiler.cli({ templates: [{ source: '' }], amd: true });
|
||||||
},
|
},
|
||||||
Handlebars.Exception,
|
Handlebars.Exception,
|
||||||
'Name missing for template'
|
'Name missing for template'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw when combining simple and directories', function() {
|
it('should throw when combining simple and directories', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Precompiler.cli({ hasDirectory: true, templates: [1], simple: true });
|
Precompiler.cli({ hasDirectory: true, templates: [1], simple: true });
|
||||||
},
|
},
|
||||||
Handlebars.Exception,
|
Handlebars.Exception,
|
||||||
@@ -143,70 +143,70 @@ describe('precompiler', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should output simple templates', function() {
|
it('should output simple templates', function () {
|
||||||
Handlebars.precompile = function() {
|
Handlebars.precompile = function () {
|
||||||
return 'simple';
|
return 'simple';
|
||||||
};
|
};
|
||||||
Precompiler.cli({ templates: [emptyTemplate], simple: true });
|
Precompiler.cli({ templates: [emptyTemplate], simple: true });
|
||||||
equal(log, 'simple\n');
|
equal(log, 'simple\n');
|
||||||
});
|
});
|
||||||
it('should default to simple templates', function() {
|
it('should default to simple templates', function () {
|
||||||
Handlebars.precompile = function() {
|
Handlebars.precompile = function () {
|
||||||
return 'simple';
|
return 'simple';
|
||||||
};
|
};
|
||||||
Precompiler.cli({ templates: [{ source: '' }] });
|
Precompiler.cli({ templates: [{ source: '' }] });
|
||||||
equal(log, 'simple\n');
|
equal(log, 'simple\n');
|
||||||
});
|
});
|
||||||
it('should output amd templates', function() {
|
it('should output amd templates', function () {
|
||||||
Handlebars.precompile = function() {
|
Handlebars.precompile = function () {
|
||||||
return 'amd';
|
return 'amd';
|
||||||
};
|
};
|
||||||
Precompiler.cli({ templates: [emptyTemplate], amd: true });
|
Precompiler.cli({ templates: [emptyTemplate], amd: true });
|
||||||
equal(/template\(amd\)/.test(log), true);
|
equal(/template\(amd\)/.test(log), true);
|
||||||
});
|
});
|
||||||
it('should output multiple amd', function() {
|
it('should output multiple amd', function () {
|
||||||
Handlebars.precompile = function() {
|
Handlebars.precompile = function () {
|
||||||
return 'amd';
|
return 'amd';
|
||||||
};
|
};
|
||||||
Precompiler.cli({
|
Precompiler.cli({
|
||||||
templates: [emptyTemplate, emptyTemplate],
|
templates: [emptyTemplate, emptyTemplate],
|
||||||
amd: true,
|
amd: true,
|
||||||
namespace: 'foo'
|
namespace: 'foo',
|
||||||
});
|
});
|
||||||
equal(/templates = foo = foo \|\|/.test(log), true);
|
equal(/templates = foo = foo \|\|/.test(log), true);
|
||||||
equal(/return templates/.test(log), true);
|
equal(/return templates/.test(log), true);
|
||||||
equal(/template\(amd\)/.test(log), true);
|
equal(/template\(amd\)/.test(log), true);
|
||||||
});
|
});
|
||||||
it('should output amd partials', function() {
|
it('should output amd partials', function () {
|
||||||
Handlebars.precompile = function() {
|
Handlebars.precompile = function () {
|
||||||
return 'amd';
|
return 'amd';
|
||||||
};
|
};
|
||||||
Precompiler.cli({ templates: [emptyTemplate], amd: true, partial: true });
|
Precompiler.cli({ templates: [emptyTemplate], amd: true, partial: true });
|
||||||
equal(/return Handlebars\.partials\['empty'\]/.test(log), true);
|
equal(/return Handlebars\.partials\['empty'\]/.test(log), true);
|
||||||
equal(/template\(amd\)/.test(log), true);
|
equal(/template\(amd\)/.test(log), true);
|
||||||
});
|
});
|
||||||
it('should output multiple amd partials', function() {
|
it('should output multiple amd partials', function () {
|
||||||
Handlebars.precompile = function() {
|
Handlebars.precompile = function () {
|
||||||
return 'amd';
|
return 'amd';
|
||||||
};
|
};
|
||||||
Precompiler.cli({
|
Precompiler.cli({
|
||||||
templates: [emptyTemplate, emptyTemplate],
|
templates: [emptyTemplate, emptyTemplate],
|
||||||
amd: true,
|
amd: true,
|
||||||
partial: true
|
partial: true,
|
||||||
});
|
});
|
||||||
equal(/return Handlebars\.partials\[/.test(log), false);
|
equal(/return Handlebars\.partials\[/.test(log), false);
|
||||||
equal(/template\(amd\)/.test(log), true);
|
equal(/template\(amd\)/.test(log), true);
|
||||||
});
|
});
|
||||||
it('should output commonjs templates', function() {
|
it('should output commonjs templates', function () {
|
||||||
Handlebars.precompile = function() {
|
Handlebars.precompile = function () {
|
||||||
return 'commonjs';
|
return 'commonjs';
|
||||||
};
|
};
|
||||||
Precompiler.cli({ templates: [emptyTemplate], commonjs: true });
|
Precompiler.cli({ templates: [emptyTemplate], commonjs: true });
|
||||||
equal(/template\(commonjs\)/.test(log), true);
|
equal(/template\(commonjs\)/.test(log), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set data flag', function() {
|
it('should set data flag', function () {
|
||||||
Handlebars.precompile = function(data, options) {
|
Handlebars.precompile = function (data, options) {
|
||||||
equal(options.data, true);
|
equal(options.data, true);
|
||||||
return 'simple';
|
return 'simple';
|
||||||
};
|
};
|
||||||
@@ -214,45 +214,45 @@ describe('precompiler', function() {
|
|||||||
equal(log, 'simple\n');
|
equal(log, 'simple\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set known helpers', function() {
|
it('should set known helpers', function () {
|
||||||
Handlebars.precompile = function(data, options) {
|
Handlebars.precompile = function (data, options) {
|
||||||
equal(options.knownHelpers.foo, true);
|
equal(options.knownHelpers.foo, true);
|
||||||
return 'simple';
|
return 'simple';
|
||||||
};
|
};
|
||||||
Precompiler.cli({ templates: [emptyTemplate], simple: true, known: 'foo' });
|
Precompiler.cli({ templates: [emptyTemplate], simple: true, known: 'foo' });
|
||||||
equal(log, 'simple\n');
|
equal(log, 'simple\n');
|
||||||
});
|
});
|
||||||
it('should output to file system', function() {
|
it('should output to file system', function () {
|
||||||
Handlebars.precompile = function() {
|
Handlebars.precompile = function () {
|
||||||
return 'simple';
|
return 'simple';
|
||||||
};
|
};
|
||||||
Precompiler.cli({
|
Precompiler.cli({
|
||||||
templates: [emptyTemplate],
|
templates: [emptyTemplate],
|
||||||
simple: true,
|
simple: true,
|
||||||
output: 'file!'
|
output: 'file!',
|
||||||
});
|
});
|
||||||
equal(file, 'file!');
|
equal(file, 'file!');
|
||||||
equal(content, 'simple\n');
|
equal(content, 'simple\n');
|
||||||
equal(log, '');
|
equal(log, '');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should output minimized templates', function() {
|
it('should output minimized templates', function () {
|
||||||
Handlebars.precompile = function() {
|
Handlebars.precompile = function () {
|
||||||
return 'amd';
|
return 'amd';
|
||||||
};
|
};
|
||||||
uglify.minify = function() {
|
uglify.minify = function () {
|
||||||
return { code: 'min' };
|
return { code: 'min' };
|
||||||
};
|
};
|
||||||
Precompiler.cli({ templates: [emptyTemplate], min: true });
|
Precompiler.cli({ templates: [emptyTemplate], min: true });
|
||||||
equal(log, 'min');
|
equal(log, 'min');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should omit minimization gracefully, if uglify-js is missing', function() {
|
it('should omit minimization gracefully, if uglify-js is missing', function () {
|
||||||
var error = new Error("Cannot find module 'uglify-js'");
|
var error = new Error("Cannot find module 'uglify-js'");
|
||||||
error.code = 'MODULE_NOT_FOUND';
|
error.code = 'MODULE_NOT_FOUND';
|
||||||
mockRequireUglify(error, function() {
|
mockRequireUglify(error, function () {
|
||||||
var Precompiler = require('../dist/cjs/precompiler');
|
var Precompiler = require('../dist/cjs/precompiler');
|
||||||
Handlebars.precompile = function() {
|
Handlebars.precompile = function () {
|
||||||
return 'amd';
|
return 'amd';
|
||||||
};
|
};
|
||||||
Precompiler.cli({ templates: [emptyTemplate], min: true });
|
Precompiler.cli({ templates: [emptyTemplate], min: true });
|
||||||
@@ -262,12 +262,12 @@ describe('precompiler', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail on errors (other than missing module) while loading uglify-js', function() {
|
it('should fail on errors (other than missing module) while loading uglify-js', function () {
|
||||||
mockRequireUglify(new Error('Mock Error'), function() {
|
mockRequireUglify(new Error('Mock Error'), function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
var Precompiler = require('../dist/cjs/precompiler');
|
var Precompiler = require('../dist/cjs/precompiler');
|
||||||
Handlebars.precompile = function() {
|
Handlebars.precompile = function () {
|
||||||
return 'amd';
|
return 'amd';
|
||||||
};
|
};
|
||||||
Precompiler.cli({ templates: [emptyTemplate], min: true });
|
Precompiler.cli({ templates: [emptyTemplate], min: true });
|
||||||
@@ -278,35 +278,35 @@ describe('precompiler', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should output map', function() {
|
it('should output map', function () {
|
||||||
Precompiler.cli({ templates: [emptyTemplate], map: 'foo.js.map' });
|
Precompiler.cli({ templates: [emptyTemplate], map: 'foo.js.map' });
|
||||||
|
|
||||||
equal(file, 'foo.js.map');
|
equal(file, 'foo.js.map');
|
||||||
equal(log.match(/sourceMappingURL=/g).length, 1);
|
equal(log.match(/sourceMappingURL=/g).length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should output map', function() {
|
it('should output map', function () {
|
||||||
Precompiler.cli({
|
Precompiler.cli({
|
||||||
templates: [emptyTemplate],
|
templates: [emptyTemplate],
|
||||||
min: true,
|
min: true,
|
||||||
map: 'foo.js.map'
|
map: 'foo.js.map',
|
||||||
});
|
});
|
||||||
|
|
||||||
equal(file, 'foo.js.map');
|
equal(file, 'foo.js.map');
|
||||||
equal(log.match(/sourceMappingURL=/g).length, 1);
|
equal(log.match(/sourceMappingURL=/g).length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#loadTemplates', function() {
|
describe('#loadTemplates', function () {
|
||||||
it('should throw on missing template', function(done) {
|
it('should throw on missing template', function (done) {
|
||||||
Precompiler.loadTemplates({ files: ['foo'] }, function(err) {
|
Precompiler.loadTemplates({ files: ['foo'] }, function (err) {
|
||||||
equal(err.message, 'Unable to open template file "foo"');
|
equal(err.message, 'Unable to open template file "foo"');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should enumerate directories by extension', function(done) {
|
it('should enumerate directories by extension', function (done) {
|
||||||
Precompiler.loadTemplates(
|
Precompiler.loadTemplates(
|
||||||
{ files: [__dirname + '/artifacts'], extension: 'hbs' },
|
{ files: [__dirname + '/artifacts'], extension: 'hbs' },
|
||||||
function(err, opts) {
|
function (err, opts) {
|
||||||
equal(opts.templates.length, 2);
|
equal(opts.templates.length, 2);
|
||||||
equal(opts.templates[0].name, 'example_2');
|
equal(opts.templates[0].name, 'example_2');
|
||||||
|
|
||||||
@@ -314,10 +314,10 @@ describe('precompiler', function() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should enumerate all templates by extension', function(done) {
|
it('should enumerate all templates by extension', function (done) {
|
||||||
Precompiler.loadTemplates(
|
Precompiler.loadTemplates(
|
||||||
{ files: [__dirname + '/artifacts'], extension: 'handlebars' },
|
{ files: [__dirname + '/artifacts'], extension: 'handlebars' },
|
||||||
function(err, opts) {
|
function (err, opts) {
|
||||||
equal(opts.templates.length, 5);
|
equal(opts.templates.length, 5);
|
||||||
equal(opts.templates[0].name, 'bom');
|
equal(opts.templates[0].name, 'bom');
|
||||||
equal(opts.templates[1].name, 'empty');
|
equal(opts.templates[1].name, 'empty');
|
||||||
@@ -326,50 +326,50 @@ describe('precompiler', function() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should handle regular expression characters in extensions', function(done) {
|
it('should handle regular expression characters in extensions', function (done) {
|
||||||
Precompiler.loadTemplates(
|
Precompiler.loadTemplates(
|
||||||
{ files: [__dirname + '/artifacts'], extension: 'hb(s' },
|
{ files: [__dirname + '/artifacts'], extension: 'hb(s' },
|
||||||
function(err) {
|
function (err) {
|
||||||
// Success is not throwing
|
// Success is not throwing
|
||||||
done(err);
|
done(err);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should handle BOM', function(done) {
|
it('should handle BOM', function (done) {
|
||||||
var opts = {
|
var opts = {
|
||||||
files: [__dirname + '/artifacts/bom.handlebars'],
|
files: [__dirname + '/artifacts/bom.handlebars'],
|
||||||
extension: 'handlebars',
|
extension: 'handlebars',
|
||||||
bom: true
|
bom: true,
|
||||||
};
|
};
|
||||||
Precompiler.loadTemplates(opts, function(err, opts) {
|
Precompiler.loadTemplates(opts, function (err, opts) {
|
||||||
equal(opts.templates[0].source, 'a');
|
equal(opts.templates[0].source, 'a');
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle different root', function(done) {
|
it('should handle different root', function (done) {
|
||||||
var opts = {
|
var opts = {
|
||||||
files: [__dirname + '/artifacts/empty.handlebars'],
|
files: [__dirname + '/artifacts/empty.handlebars'],
|
||||||
simple: true,
|
simple: true,
|
||||||
root: 'foo/'
|
root: 'foo/',
|
||||||
};
|
};
|
||||||
Precompiler.loadTemplates(opts, function(err, opts) {
|
Precompiler.loadTemplates(opts, function (err, opts) {
|
||||||
equal(opts.templates[0].name, __dirname + '/artifacts/empty');
|
equal(opts.templates[0].name, __dirname + '/artifacts/empty');
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept string inputs', function(done) {
|
it('should accept string inputs', function (done) {
|
||||||
var opts = { string: '' };
|
var opts = { string: '' };
|
||||||
Precompiler.loadTemplates(opts, function(err, opts) {
|
Precompiler.loadTemplates(opts, function (err, opts) {
|
||||||
equal(opts.templates[0].name, undefined);
|
equal(opts.templates[0].name, undefined);
|
||||||
equal(opts.templates[0].source, '');
|
equal(opts.templates[0].source, '');
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should accept string array inputs', function(done) {
|
it('should accept string array inputs', function (done) {
|
||||||
var opts = { string: ['', 'bar'], name: ['beep', 'boop'] };
|
var opts = { string: ['', 'bar'], name: ['beep', 'boop'] };
|
||||||
Precompiler.loadTemplates(opts, function(err, opts) {
|
Precompiler.loadTemplates(opts, function (err, opts) {
|
||||||
equal(opts.templates[0].name, 'beep');
|
equal(opts.templates[0].name, 'beep');
|
||||||
equal(opts.templates[0].source, '');
|
equal(opts.templates[0].source, '');
|
||||||
equal(opts.templates[1].name, 'boop');
|
equal(opts.templates[1].name, 'boop');
|
||||||
@@ -377,9 +377,9 @@ describe('precompiler', function() {
|
|||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should accept stdin input', function(done) {
|
it('should accept stdin input', function (done) {
|
||||||
var stdin = require('mock-stdin').stdin();
|
var stdin = require('mock-stdin').stdin();
|
||||||
Precompiler.loadTemplates({ string: '-' }, function(err, opts) {
|
Precompiler.loadTemplates({ string: '-' }, function (err, opts) {
|
||||||
equal(opts.templates[0].source, 'foo');
|
equal(opts.templates[0].source, 'foo');
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
@@ -387,9 +387,9 @@ describe('precompiler', function() {
|
|||||||
stdin.send('o');
|
stdin.send('o');
|
||||||
stdin.end();
|
stdin.end();
|
||||||
});
|
});
|
||||||
it('error on name missing', function(done) {
|
it('error on name missing', function (done) {
|
||||||
var opts = { string: ['', 'bar'] };
|
var opts = { string: ['', 'bar'] };
|
||||||
Precompiler.loadTemplates(opts, function(err) {
|
Precompiler.loadTemplates(opts, function (err) {
|
||||||
equal(
|
equal(
|
||||||
err.message,
|
err.message,
|
||||||
'Number of names did not match the number of string inputs'
|
'Number of names did not match the number of string inputs'
|
||||||
@@ -398,8 +398,8 @@ describe('precompiler', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should complete when no args are passed', function(done) {
|
it('should complete when no args are passed', function (done) {
|
||||||
Precompiler.loadTemplates({}, function(err, opts) {
|
Precompiler.loadTemplates({}, function (err, opts) {
|
||||||
equal(opts.templates.length, 0);
|
equal(opts.templates.length, 0);
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
|
|||||||
+91
-99
@@ -1,24 +1,24 @@
|
|||||||
describe('Regressions', function() {
|
describe('Regressions', function () {
|
||||||
it('GH-94: Cannot read property of undefined', function() {
|
it('GH-94: Cannot read property of undefined', function () {
|
||||||
expectTemplate('{{#books}}{{title}}{{author.name}}{{/books}}')
|
expectTemplate('{{#books}}{{title}}{{author.name}}{{/books}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
books: [
|
books: [
|
||||||
{
|
{
|
||||||
title: 'The origin of species',
|
title: 'The origin of species',
|
||||||
author: {
|
author: {
|
||||||
name: 'Charles Darwin'
|
name: 'Charles Darwin',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Lazarillo de Tormes'
|
title: 'Lazarillo de Tormes',
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
.withMessage('Renders without an undefined property error')
|
.withMessage('Renders without an undefined property error')
|
||||||
.toCompileTo('The origin of speciesCharles DarwinLazarillo de Tormes');
|
.toCompileTo('The origin of speciesCharles DarwinLazarillo de Tormes');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("GH-150: Inverted sections print when they shouldn't", function() {
|
it("GH-150: Inverted sections print when they shouldn't", function () {
|
||||||
var string = '{{^set}}not set{{/set}} :: {{#set}}set{{/set}}';
|
var string = '{{^set}}not set{{/set}} :: {{#set}}set{{/set}}';
|
||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string)
|
||||||
@@ -43,14 +43,14 @@ describe('Regressions', function() {
|
|||||||
.toCompileTo(' :: set');
|
.toCompileTo(' :: set');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-158: Using array index twice, breaks the template', function() {
|
it('GH-158: Using array index twice, breaks the template', function () {
|
||||||
expectTemplate('{{arr.[0]}}, {{arr.[1]}}')
|
expectTemplate('{{arr.[0]}}, {{arr.[1]}}')
|
||||||
.withInput({ arr: [1, 2] })
|
.withInput({ arr: [1, 2] })
|
||||||
.withMessage('it works as expected')
|
.withMessage('it works as expected')
|
||||||
.toCompileTo('1, 2');
|
.toCompileTo('1, 2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("bug reported by @fat where lambdas weren't being properly resolved", function() {
|
it("bug reported by @fat where lambdas weren't being properly resolved", function () {
|
||||||
var string =
|
var string =
|
||||||
'<strong>This is a slightly more complicated {{thing}}.</strong>.\n' +
|
'<strong>This is a slightly more complicated {{thing}}.</strong>.\n' +
|
||||||
'{{! Just ignore this business. }}\n' +
|
'{{! Just ignore this business. }}\n' +
|
||||||
@@ -67,17 +67,17 @@ describe('Regressions', function() {
|
|||||||
'{{/hasThings}}';
|
'{{/hasThings}}';
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
thing: function() {
|
thing: function () {
|
||||||
return 'blah';
|
return 'blah';
|
||||||
},
|
},
|
||||||
things: [
|
things: [
|
||||||
{ className: 'one', word: '@fat' },
|
{ className: 'one', word: '@fat' },
|
||||||
{ className: 'two', word: '@dhg' },
|
{ className: 'two', word: '@dhg' },
|
||||||
{ className: 'three', word: '@sayrer' }
|
{ className: 'three', word: '@sayrer' },
|
||||||
],
|
],
|
||||||
hasThings: function() {
|
hasThings: function () {
|
||||||
return true;
|
return true;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var output =
|
var output =
|
||||||
@@ -89,36 +89,34 @@ describe('Regressions', function() {
|
|||||||
'<li class=three>@sayrer</li>\n' +
|
'<li class=three>@sayrer</li>\n' +
|
||||||
'</ul>.\n';
|
'</ul>.\n';
|
||||||
|
|
||||||
expectTemplate(string)
|
expectTemplate(string).withInput(data).toCompileTo(output);
|
||||||
.withInput(data)
|
|
||||||
.toCompileTo(output);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-408: Multiple loops fail', function() {
|
it('GH-408: Multiple loops fail', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}'
|
'{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}'
|
||||||
)
|
)
|
||||||
.withInput([
|
.withInput([
|
||||||
{ name: 'John Doe', location: { city: 'Chicago' } },
|
{ name: 'John Doe', location: { city: 'Chicago' } },
|
||||||
{ name: 'Jane Doe', location: { city: 'New York' } }
|
{ name: 'Jane Doe', location: { city: 'New York' } },
|
||||||
])
|
])
|
||||||
.withMessage('It should output multiple times')
|
.withMessage('It should output multiple times')
|
||||||
.toCompileTo('John DoeJane DoeJohn DoeJane DoeJohn DoeJane Doe');
|
.toCompileTo('John DoeJane DoeJohn DoeJane DoeJohn DoeJane Doe');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GS-428: Nested if else rendering', function() {
|
it('GS-428: Nested if else rendering', function () {
|
||||||
var succeedingTemplate =
|
var succeedingTemplate =
|
||||||
'{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}';
|
'{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}';
|
||||||
var failingTemplate =
|
var failingTemplate =
|
||||||
'{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}';
|
'{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}';
|
||||||
|
|
||||||
var helpers = {
|
var helpers = {
|
||||||
blk: function(block) {
|
blk: function (block) {
|
||||||
return block.fn('');
|
return block.fn('');
|
||||||
},
|
},
|
||||||
inverse: function(block) {
|
inverse: function (block) {
|
||||||
return block.inverse('');
|
return block.inverse('');
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
expectTemplate(succeedingTemplate)
|
expectTemplate(succeedingTemplate)
|
||||||
@@ -130,34 +128,30 @@ describe('Regressions', function() {
|
|||||||
.toCompileTo(' Expected ');
|
.toCompileTo(' Expected ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-458: Scoped this identifier', function() {
|
it('GH-458: Scoped this identifier', function () {
|
||||||
expectTemplate('{{./foo}}')
|
expectTemplate('{{./foo}}').withInput({ foo: 'bar' }).toCompileTo('bar');
|
||||||
.withInput({ foo: 'bar' })
|
|
||||||
.toCompileTo('bar');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-375: Unicode line terminators', function() {
|
it('GH-375: Unicode line terminators', function () {
|
||||||
expectTemplate('\u2028').toCompileTo('\u2028');
|
expectTemplate('\u2028').toCompileTo('\u2028');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-534: Object prototype aliases', function() {
|
it('GH-534: Object prototype aliases', function () {
|
||||||
/* eslint-disable no-extend-native */
|
/* eslint-disable no-extend-native */
|
||||||
Object.prototype[0xd834] = true;
|
Object.prototype[0xd834] = true;
|
||||||
|
|
||||||
expectTemplate('{{foo}}')
|
expectTemplate('{{foo}}').withInput({ foo: 'bar' }).toCompileTo('bar');
|
||||||
.withInput({ foo: 'bar' })
|
|
||||||
.toCompileTo('bar');
|
|
||||||
|
|
||||||
delete Object.prototype[0xd834];
|
delete Object.prototype[0xd834];
|
||||||
/* eslint-enable no-extend-native */
|
/* eslint-enable no-extend-native */
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-437: Matching escaping', function() {
|
it('GH-437: Matching escaping', function () {
|
||||||
expectTemplate('{{{a}}').toThrow(Error, /Parse error on/);
|
expectTemplate('{{{a}}').toThrow(Error, /Parse error on/);
|
||||||
expectTemplate('{{a}}}').toThrow(Error, /Parse error on/);
|
expectTemplate('{{a}}}').toThrow(Error, /Parse error on/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-676: Using array in escaping mustache fails', function() {
|
it('GH-676: Using array in escaping mustache fails', function () {
|
||||||
var data = { arr: [1, 2] };
|
var data = { arr: [1, 2] };
|
||||||
|
|
||||||
expectTemplate('{{arr}}')
|
expectTemplate('{{arr}}')
|
||||||
@@ -166,7 +160,7 @@ describe('Regressions', function() {
|
|||||||
.toCompileTo(data.arr.toString());
|
.toCompileTo(data.arr.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Mustache man page', function() {
|
it('Mustache man page', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'Hello {{name}}. You have just won ${{value}}!{{#in_ca}} Well, ${{taxed_value}}, after taxes.{{/in_ca}}'
|
'Hello {{name}}. You have just won ${{value}}!{{#in_ca}} Well, ${{taxed_value}}, after taxes.{{/in_ca}}'
|
||||||
)
|
)
|
||||||
@@ -174,7 +168,7 @@ describe('Regressions', function() {
|
|||||||
name: 'Chris',
|
name: 'Chris',
|
||||||
value: 10000,
|
value: 10000,
|
||||||
taxed_value: 10000 - 10000 * 0.4,
|
taxed_value: 10000 - 10000 * 0.4,
|
||||||
in_ca: true
|
in_ca: true,
|
||||||
})
|
})
|
||||||
.withMessage('the hello world mustache example works')
|
.withMessage('the hello world mustache example works')
|
||||||
.toCompileTo(
|
.toCompileTo(
|
||||||
@@ -182,69 +176,67 @@ describe('Regressions', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-731: zero context rendering', function() {
|
it('GH-731: zero context rendering', function () {
|
||||||
expectTemplate('{{#foo}} This is {{bar}} ~ {{/foo}}')
|
expectTemplate('{{#foo}} This is {{bar}} ~ {{/foo}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
foo: 0,
|
foo: 0,
|
||||||
bar: 'OK'
|
bar: 'OK',
|
||||||
})
|
})
|
||||||
.toCompileTo(' This is ~ ');
|
.toCompileTo(' This is ~ ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-820: zero pathed rendering', function() {
|
it('GH-820: zero pathed rendering', function () {
|
||||||
expectTemplate('{{foo.bar}}')
|
expectTemplate('{{foo.bar}}').withInput({ foo: 0 }).toCompileTo('');
|
||||||
.withInput({ foo: 0 })
|
|
||||||
.toCompileTo('');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-837: undefined values for helpers', function() {
|
it('GH-837: undefined values for helpers', function () {
|
||||||
expectTemplate('{{str bar.baz}}')
|
expectTemplate('{{str bar.baz}}')
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
str: function(value) {
|
str: function (value) {
|
||||||
return value + '';
|
return value + '';
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('undefined');
|
.toCompileTo('undefined');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-926: Depths and de-dupe', function() {
|
it('GH-926: Depths and de-dupe', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#if dater}}{{#each data}}{{../name}}{{/each}}{{else}}{{#each notData}}{{../name}}{{/each}}{{/if}}'
|
'{{#if dater}}{{#each data}}{{../name}}{{/each}}{{else}}{{#each notData}}{{../name}}{{/each}}{{/if}}'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
data: [1],
|
data: [1],
|
||||||
notData: [1]
|
notData: [1],
|
||||||
})
|
})
|
||||||
.toCompileTo('foo');
|
.toCompileTo('foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-1021: Each empty string key', function() {
|
it('GH-1021: Each empty string key', function () {
|
||||||
expectTemplate('{{#each data}}Key: {{@key}}\n{{/each}}')
|
expectTemplate('{{#each data}}Key: {{@key}}\n{{/each}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
data: {
|
data: {
|
||||||
'': 'foo',
|
'': 'foo',
|
||||||
name: 'Chris',
|
name: 'Chris',
|
||||||
value: 10000
|
value: 10000,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('Key: \nKey: name\nKey: value\n');
|
.toCompileTo('Key: \nKey: name\nKey: value\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-1054: Should handle simple safe string responses', function() {
|
it('GH-1054: Should handle simple safe string responses', function () {
|
||||||
expectTemplate('{{#wrap}}{{>partial}}{{/wrap}}')
|
expectTemplate('{{#wrap}}{{>partial}}{{/wrap}}')
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
wrap: function(options) {
|
wrap: function (options) {
|
||||||
return new Handlebars.SafeString(options.fn());
|
return new Handlebars.SafeString(options.fn());
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.withPartials({
|
.withPartials({
|
||||||
partial: '{{#wrap}}<partial>{{/wrap}}'
|
partial: '{{#wrap}}<partial>{{/wrap}}',
|
||||||
})
|
})
|
||||||
.toCompileTo('<partial>');
|
.toCompileTo('<partial>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-1065: Sparse arrays', function() {
|
it('GH-1065: Sparse arrays', function () {
|
||||||
var array = [];
|
var array = [];
|
||||||
array[1] = 'foo';
|
array[1] = 'foo';
|
||||||
array[3] = 'bar';
|
array[3] = 'bar';
|
||||||
@@ -253,11 +245,11 @@ describe('Regressions', function() {
|
|||||||
.toCompileTo('1foo3bar');
|
.toCompileTo('1foo3bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-1093: Undefined helper context', function() {
|
it('GH-1093: Undefined helper context', function () {
|
||||||
expectTemplate('{{#each obj}}{{{helper}}}{{.}}{{/each}}')
|
expectTemplate('{{#each obj}}{{{helper}}}{{.}}{{/each}}')
|
||||||
.withInput({ obj: { foo: undefined, bar: 'bat' } })
|
.withInput({ obj: { foo: undefined, bar: 'bat' } })
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
helper: function() {
|
helper: function () {
|
||||||
// It's valid to execute a block against an undefined context, but
|
// It's valid to execute a block against an undefined context, but
|
||||||
// helpers can not do so, so we expect to have an empty object here;
|
// helpers can not do so, so we expect to have an empty object here;
|
||||||
for (var name in this) {
|
for (var name in this) {
|
||||||
@@ -267,43 +259,43 @@ describe('Regressions', function() {
|
|||||||
}
|
}
|
||||||
// And to make IE happy, check for the known string as length is not enumerated.
|
// And to make IE happy, check for the known string as length is not enumerated.
|
||||||
return this === 'bat' ? 'found' : 'not';
|
return this === 'bat' ? 'found' : 'not';
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('notfoundbat');
|
.toCompileTo('notfoundbat');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support multiple levels of inline partials', function() {
|
it('should support multiple levels of inline partials', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#> layout}}{{#*inline "subcontent"}}subcontent{{/inline}}{{/layout}}'
|
'{{#> layout}}{{#*inline "subcontent"}}subcontent{{/inline}}{{/layout}}'
|
||||||
)
|
)
|
||||||
.withPartials({
|
.withPartials({
|
||||||
doctype: 'doctype{{> content}}',
|
doctype: 'doctype{{> content}}',
|
||||||
layout:
|
layout:
|
||||||
'{{#> doctype}}{{#*inline "content"}}layout{{> subcontent}}{{/inline}}{{/doctype}}'
|
'{{#> doctype}}{{#*inline "content"}}layout{{> subcontent}}{{/inline}}{{/doctype}}',
|
||||||
})
|
})
|
||||||
.toCompileTo('doctypelayoutsubcontent');
|
.toCompileTo('doctypelayoutsubcontent');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-1089: should support failover content in multiple levels of inline partials', function() {
|
it('GH-1089: should support failover content in multiple levels of inline partials', function () {
|
||||||
expectTemplate('{{#> layout}}{{/layout}}')
|
expectTemplate('{{#> layout}}{{/layout}}')
|
||||||
.withPartials({
|
.withPartials({
|
||||||
doctype: 'doctype{{> content}}',
|
doctype: 'doctype{{> content}}',
|
||||||
layout:
|
layout:
|
||||||
'{{#> doctype}}{{#*inline "content"}}layout{{#> subcontent}}subcontent{{/subcontent}}{{/inline}}{{/doctype}}'
|
'{{#> doctype}}{{#*inline "content"}}layout{{#> subcontent}}subcontent{{/subcontent}}{{/inline}}{{/doctype}}',
|
||||||
})
|
})
|
||||||
.toCompileTo('doctypelayoutsubcontent');
|
.toCompileTo('doctypelayoutsubcontent');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-1099: should support greater than 3 nested levels of inline partials', function() {
|
it('GH-1099: should support greater than 3 nested levels of inline partials', function () {
|
||||||
expectTemplate('{{#> layout}}Outer{{/layout}}')
|
expectTemplate('{{#> layout}}Outer{{/layout}}')
|
||||||
.withPartials({
|
.withPartials({
|
||||||
layout: '{{#> inner}}Inner{{/inner}}{{> @partial-block }}',
|
layout: '{{#> inner}}Inner{{/inner}}{{> @partial-block }}',
|
||||||
inner: ''
|
inner: '',
|
||||||
})
|
})
|
||||||
.toCompileTo('Outer');
|
.toCompileTo('Outer');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-1135 : Context handling within each iteration', function() {
|
it('GH-1135 : Context handling within each iteration', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each array}}\n' +
|
'{{#each array}}\n' +
|
||||||
' 1. IF: {{#if true}}{{../name}}-{{../../name}}-{{../../../name}}{{/if}}\n' +
|
' 1. IF: {{#if true}}{{../name}}-{{../../name}}-{{../../../name}}{{/if}}\n' +
|
||||||
@@ -312,18 +304,18 @@ describe('Regressions', function() {
|
|||||||
)
|
)
|
||||||
.withInput({ array: [1], name: 'John' })
|
.withInput({ array: [1], name: 'John' })
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
myif: function(conditional, options) {
|
myif: function (conditional, options) {
|
||||||
if (conditional) {
|
if (conditional) {
|
||||||
return options.fn(this);
|
return options.fn(this);
|
||||||
} else {
|
} else {
|
||||||
return options.inverse(this);
|
return options.inverse(this);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo(' 1. IF: John--\n' + ' 2. MYIF: John==\n');
|
.toCompileTo(' 1. IF: John--\n' + ' 2. MYIF: John==\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-1186: Support block params for existing programs', function() {
|
it('GH-1186: Support block params for existing programs', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#*inline "test"}}{{> @partial-block }}{{/inline}}' +
|
'{{#*inline "test"}}{{> @partial-block }}{{/inline}}' +
|
||||||
'{{#>test }}{{#each listOne as |item|}}{{ item }}{{/each}}{{/test}}' +
|
'{{#>test }}{{#each listOne as |item|}}{{ item }}{{/each}}{{/test}}' +
|
||||||
@@ -331,64 +323,64 @@ describe('Regressions', function() {
|
|||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
listOne: ['a'],
|
listOne: ['a'],
|
||||||
listTwo: ['b']
|
listTwo: ['b'],
|
||||||
})
|
})
|
||||||
.withMessage('')
|
.withMessage('')
|
||||||
.toCompileTo('ab');
|
.toCompileTo('ab');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow hash with protected array names', function() {
|
it('should allow hash with protected array names', function () {
|
||||||
var obj = { array: [1], name: 'John' };
|
var obj = { array: [1], name: 'John' };
|
||||||
var helpers = {
|
var helpers = {
|
||||||
helpa: function(options) {
|
helpa: function (options) {
|
||||||
return options.hash.length;
|
return options.hash.length;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
shouldCompileTo('{{helpa length="foo"}}', [obj, helpers], 'foo');
|
shouldCompileTo('{{helpa length="foo"}}', [obj, helpers], 'foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-1319: "unless" breaks when "each" value equals "null"', function() {
|
it('GH-1319: "unless" breaks when "each" value equals "null"', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}'
|
'{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
value: 'parent',
|
value: 'parent',
|
||||||
list: [null, 'a']
|
list: [null, 'a'],
|
||||||
})
|
})
|
||||||
.withMessage('')
|
.withMessage('')
|
||||||
.toCompileTo('parent=parent parent=parent ');
|
.toCompileTo('parent=parent parent=parent ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-1341: 4.0.7 release breaks {{#if @partial-block}} usage', function() {
|
it('GH-1341: 4.0.7 release breaks {{#if @partial-block}} usage', function () {
|
||||||
expectTemplate('template {{>partial}} template')
|
expectTemplate('template {{>partial}} template')
|
||||||
.withPartials({
|
.withPartials({
|
||||||
partialWithBlock:
|
partialWithBlock:
|
||||||
'{{#if @partial-block}} block {{> @partial-block}} block {{/if}}',
|
'{{#if @partial-block}} block {{> @partial-block}} block {{/if}}',
|
||||||
partial: '{{#> partialWithBlock}} partial {{/partialWithBlock}}'
|
partial: '{{#> partialWithBlock}} partial {{/partialWithBlock}}',
|
||||||
})
|
})
|
||||||
.toCompileTo('template block partial block template');
|
.toCompileTo('template block partial block template');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GH-1561: 4.3.x should still work with precompiled templates from 4.0.0 <= x < 4.3.0', function() {
|
describe('GH-1561: 4.3.x should still work with precompiled templates from 4.0.0 <= x < 4.3.0', function () {
|
||||||
it('should compile and execute templates', function() {
|
it('should compile and execute templates', function () {
|
||||||
var newHandlebarsInstance = Handlebars.create();
|
var newHandlebarsInstance = Handlebars.create();
|
||||||
|
|
||||||
registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
|
registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
|
||||||
newHandlebarsInstance.registerHelper('loud', function(value) {
|
newHandlebarsInstance.registerHelper('loud', function (value) {
|
||||||
return value.toUpperCase();
|
return value.toUpperCase();
|
||||||
});
|
});
|
||||||
var result = newHandlebarsInstance.templates['test.hbs']({
|
var result = newHandlebarsInstance.templates['test.hbs']({
|
||||||
name: 'yehuda'
|
name: 'yehuda',
|
||||||
});
|
});
|
||||||
equals(result.trim(), 'YEHUDA');
|
equals(result.trim(), 'YEHUDA');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call "helperMissing" if a helper is missing', function() {
|
it('should call "helperMissing" if a helper is missing', function () {
|
||||||
var newHandlebarsInstance = Handlebars.create();
|
var newHandlebarsInstance = Handlebars.create();
|
||||||
|
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
|
registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
|
||||||
newHandlebarsInstance.templates['test.hbs']({});
|
newHandlebarsInstance.templates['test.hbs']({});
|
||||||
},
|
},
|
||||||
@@ -397,7 +389,7 @@ describe('Regressions', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass "options.lookupProperty" to "lookup"-helper, even with old templates', function() {
|
it('should pass "options.lookupProperty" to "lookup"-helper, even with old templates', function () {
|
||||||
var newHandlebarsInstance = Handlebars.create();
|
var newHandlebarsInstance = Handlebars.create();
|
||||||
registerTemplate(
|
registerTemplate(
|
||||||
newHandlebarsInstance,
|
newHandlebarsInstance,
|
||||||
@@ -409,7 +401,7 @@ describe('Regressions', function() {
|
|||||||
expect(
|
expect(
|
||||||
newHandlebarsInstance.templates['test.hbs']({
|
newHandlebarsInstance.templates['test.hbs']({
|
||||||
property: 'a',
|
property: 'a',
|
||||||
test: { a: 'b' }
|
test: { a: 'b' },
|
||||||
})
|
})
|
||||||
).to.equal('b');
|
).to.equal('b');
|
||||||
});
|
});
|
||||||
@@ -423,7 +415,7 @@ describe('Regressions', function() {
|
|||||||
function compiledTemplateVersion7() {
|
function compiledTemplateVersion7() {
|
||||||
return {
|
return {
|
||||||
compiler: [7, '>= 4.0.0'],
|
compiler: [7, '>= 4.0.0'],
|
||||||
main: function(container, depth0, helpers, partials, data) {
|
main: function (container, depth0, helpers, partials, data) {
|
||||||
return (
|
return (
|
||||||
container.escapeExpression(
|
container.escapeExpression(
|
||||||
(
|
(
|
||||||
@@ -438,7 +430,7 @@ describe('Regressions', function() {
|
|||||||
) + '\n\n'
|
) + '\n\n'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
useData: true
|
useData: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,7 +438,7 @@ describe('Regressions', function() {
|
|||||||
// This is the compiled version of "{{lookup test property}}"
|
// This is the compiled version of "{{lookup test property}}"
|
||||||
return {
|
return {
|
||||||
compiler: [7, '>= 4.0.0'],
|
compiler: [7, '>= 4.0.0'],
|
||||||
main: function(container, depth0, helpers, partials, data) {
|
main: function (container, depth0, helpers, partials, data) {
|
||||||
return container.escapeExpression(
|
return container.escapeExpression(
|
||||||
helpers.lookup.call(
|
helpers.lookup.call(
|
||||||
depth0 != null ? depth0 : container.nullContext || {},
|
depth0 != null ? depth0 : container.nullContext || {},
|
||||||
@@ -455,45 +447,45 @@ describe('Regressions', function() {
|
|||||||
{
|
{
|
||||||
name: 'lookup',
|
name: 'lookup',
|
||||||
hash: {},
|
hash: {},
|
||||||
data: data
|
data: data,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
useData: true
|
useData: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow hash with protected array names', function() {
|
it('should allow hash with protected array names', function () {
|
||||||
expectTemplate('{{helpa length="foo"}}')
|
expectTemplate('{{helpa length="foo"}}')
|
||||||
.withInput({ array: [1], name: 'John' })
|
.withInput({ array: [1], name: 'John' })
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
helpa: function(options) {
|
helpa: function (options) {
|
||||||
return options.hash.length;
|
return options.hash.length;
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('foo');
|
.toCompileTo('foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GH-1598: Performance degradation for partials since v4.3.0', function() {
|
describe('GH-1598: Performance degradation for partials since v4.3.0', function () {
|
||||||
// Do not run test for runs without compiler
|
// Do not run test for runs without compiler
|
||||||
if (!Handlebars.compile) {
|
if (!Handlebars.compile) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newHandlebarsInstance;
|
var newHandlebarsInstance;
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
newHandlebarsInstance = Handlebars.create();
|
newHandlebarsInstance = Handlebars.create();
|
||||||
});
|
});
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should only compile global partials once', function() {
|
it('should only compile global partials once', function () {
|
||||||
var templateSpy = sinon.spy(newHandlebarsInstance, 'template');
|
var templateSpy = sinon.spy(newHandlebarsInstance, 'template');
|
||||||
newHandlebarsInstance.registerPartial({
|
newHandlebarsInstance.registerPartial({
|
||||||
dude: 'I am a partial'
|
dude: 'I am a partial',
|
||||||
});
|
});
|
||||||
var string = 'Dudes: {{> dude}} {{> dude}}';
|
var string = 'Dudes: {{> dude}} {{> dude}}';
|
||||||
newHandlebarsInstance.compile(string)(); // This should compile template + partial once
|
newHandlebarsInstance.compile(string)(); // This should compile template + partial once
|
||||||
@@ -503,8 +495,8 @@ describe('Regressions', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("GH-1639: TypeError: Cannot read property 'apply' of undefined\" when handlebars version > 4.6.0 (undocumented, deprecated usage)", function() {
|
describe("GH-1639: TypeError: Cannot read property 'apply' of undefined\" when handlebars version > 4.6.0 (undocumented, deprecated usage)", function () {
|
||||||
it('should treat undefined helpers like non-existing helpers', function() {
|
it('should treat undefined helpers like non-existing helpers', function () {
|
||||||
expectTemplate('{{foo}}')
|
expectTemplate('{{foo}}')
|
||||||
.withHelper('foo', undefined)
|
.withHelper('foo', undefined)
|
||||||
.withInput({ foo: 'bar' })
|
.withInput({ foo: 'bar' })
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
if (typeof require !== 'undefined' && require.extensions['.handlebars']) {
|
if (typeof require !== 'undefined' && require.extensions['.handlebars']) {
|
||||||
describe('Require', function() {
|
describe('Require', function () {
|
||||||
it('Load .handlebars files with require()', function() {
|
it('Load .handlebars files with require()', function () {
|
||||||
var template = require('./artifacts/example_1');
|
var template = require('./artifacts/example_1');
|
||||||
equal(template, require('./artifacts/example_1.handlebars'));
|
equal(template, require('./artifacts/example_1.handlebars'));
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ if (typeof require !== 'undefined' && require.extensions['.handlebars']) {
|
|||||||
equal(result, expected);
|
equal(result, expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Load .hbs files with require()', function() {
|
it('Load .hbs files with require()', function () {
|
||||||
var template = require('./artifacts/example_2');
|
var template = require('./artifacts/example_2');
|
||||||
equal(template, require('./artifacts/example_2.hbs'));
|
equal(template, require('./artifacts/example_2.hbs'));
|
||||||
|
|
||||||
|
|||||||
+15
-15
@@ -1,53 +1,53 @@
|
|||||||
describe('runtime', function() {
|
describe('runtime', function () {
|
||||||
describe('#template', function() {
|
describe('#template', function () {
|
||||||
it('should throw on invalid templates', function() {
|
it('should throw on invalid templates', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.template({});
|
Handlebars.template({});
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
'Unknown template object: object'
|
'Unknown template object: object'
|
||||||
);
|
);
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.template();
|
Handlebars.template();
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
'Unknown template object: undefined'
|
'Unknown template object: undefined'
|
||||||
);
|
);
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.template('');
|
Handlebars.template('');
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
'Unknown template object: string'
|
'Unknown template object: string'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw on version mismatch', function() {
|
it('should throw on version mismatch', function () {
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.template({
|
Handlebars.template({
|
||||||
main: {},
|
main: {},
|
||||||
compiler: [Handlebars.COMPILER_REVISION + 1]
|
compiler: [Handlebars.COMPILER_REVISION + 1],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
/Template was precompiled with a newer version of Handlebars than the current runtime/
|
/Template was precompiled with a newer version of Handlebars than the current runtime/
|
||||||
);
|
);
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.template({
|
Handlebars.template({
|
||||||
main: {},
|
main: {},
|
||||||
compiler: [Handlebars.LAST_COMPATIBLE_COMPILER_REVISION - 1]
|
compiler: [Handlebars.LAST_COMPATIBLE_COMPILER_REVISION - 1],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
/Template was precompiled with an older version of Handlebars than the current runtime/
|
/Template was precompiled with an older version of Handlebars than the current runtime/
|
||||||
);
|
);
|
||||||
shouldThrow(
|
shouldThrow(
|
||||||
function() {
|
function () {
|
||||||
Handlebars.template({
|
Handlebars.template({
|
||||||
main: {}
|
main: {},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
@@ -56,12 +56,12 @@ describe('runtime', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#noConflict', function() {
|
describe('#noConflict', function () {
|
||||||
if (!CompilerContext.browser) {
|
if (!CompilerContext.browser) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should reset on no conflict', function() {
|
it('should reset on no conflict', function () {
|
||||||
var reset = Handlebars;
|
var reset = Handlebars;
|
||||||
Handlebars.noConflict();
|
Handlebars.noConflict();
|
||||||
equal(Handlebars, 'no-conflict');
|
equal(Handlebars, 'no-conflict');
|
||||||
|
|||||||
+81
-85
@@ -1,25 +1,23 @@
|
|||||||
describe('security issues', function() {
|
describe('security issues', function () {
|
||||||
describe('GH-1495: Prevent Remote Code Execution via constructor', function() {
|
describe('GH-1495: Prevent Remote Code Execution via constructor', function () {
|
||||||
it('should not allow constructors to be accessed', function() {
|
it('should not allow constructors to be accessed', function () {
|
||||||
expectTemplate('{{lookup (lookup this "constructor") "name"}}')
|
expectTemplate('{{lookup (lookup this "constructor") "name"}}')
|
||||||
.withInput({})
|
.withInput({})
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
|
|
||||||
expectTemplate('{{constructor.name}}')
|
expectTemplate('{{constructor.name}}').withInput({}).toCompileTo('');
|
||||||
.withInput({})
|
|
||||||
.toCompileTo('');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-1603: should not allow constructors to be accessed (lookup via toString)', function() {
|
it('GH-1603: should not allow constructors to be accessed (lookup via toString)', function () {
|
||||||
expectTemplate('{{lookup (lookup this (list "constructor")) "name"}}')
|
expectTemplate('{{lookup (lookup this (list "constructor")) "name"}}')
|
||||||
.withInput({})
|
.withInput({})
|
||||||
.withHelper('list', function(element) {
|
.withHelper('list', function (element) {
|
||||||
return [element];
|
return [element];
|
||||||
})
|
})
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow the "constructor" property to be accessed if it is an "ownProperty"', function() {
|
it('should allow the "constructor" property to be accessed if it is an "ownProperty"', function () {
|
||||||
expectTemplate('{{constructor.name}}')
|
expectTemplate('{{constructor.name}}')
|
||||||
.withInput({ constructor: { name: 'here we go' } })
|
.withInput({ constructor: { name: 'here we go' } })
|
||||||
.toCompileTo('here we go');
|
.toCompileTo('here we go');
|
||||||
@@ -29,79 +27,79 @@ describe('security issues', function() {
|
|||||||
.toCompileTo('here we go');
|
.toCompileTo('here we go');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow the "constructor" property to be accessed if it is an "own property"', function() {
|
it('should allow the "constructor" property to be accessed if it is an "own property"', function () {
|
||||||
expectTemplate('{{lookup (lookup this "constructor") "name"}}')
|
expectTemplate('{{lookup (lookup this "constructor") "name"}}')
|
||||||
.withInput({ constructor: { name: 'here we go' } })
|
.withInput({ constructor: { name: 'here we go' } })
|
||||||
.toCompileTo('here we go');
|
.toCompileTo('here we go');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GH-1558: Prevent explicit call of helperMissing-helpers', function() {
|
describe('GH-1558: Prevent explicit call of helperMissing-helpers', function () {
|
||||||
if (!Handlebars.compile) {
|
if (!Handlebars.compile) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('without the option "allowExplicitCallOfHelperMissing"', function() {
|
describe('without the option "allowExplicitCallOfHelperMissing"', function () {
|
||||||
it('should throw an exception when calling "{{helperMissing}}" ', function() {
|
it('should throw an exception when calling "{{helperMissing}}" ', function () {
|
||||||
expectTemplate('{{helperMissing}}').toThrow(Error);
|
expectTemplate('{{helperMissing}}').toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', function() {
|
it('should throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', function () {
|
||||||
expectTemplate('{{#helperMissing}}{{/helperMissing}}').toThrow(Error);
|
expectTemplate('{{#helperMissing}}{{/helperMissing}}').toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function() {
|
it('should throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function () {
|
||||||
var functionCalls = [];
|
var functionCalls = [];
|
||||||
expect(function() {
|
expect(function () {
|
||||||
var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
|
var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
|
||||||
template({
|
template({
|
||||||
fn: function() {
|
fn: function () {
|
||||||
functionCalls.push('called');
|
functionCalls.push('called');
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}).to.throw(Error);
|
}).to.throw(Error);
|
||||||
expect(functionCalls.length).to.equal(0);
|
expect(functionCalls.length).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() {
|
it('should throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function () {
|
||||||
expectTemplate('{{#blockHelperMissing .}}{{/blockHelperMissing}}')
|
expectTemplate('{{#blockHelperMissing .}}{{/blockHelperMissing}}')
|
||||||
.withInput({
|
.withInput({
|
||||||
fn: function() {
|
fn: function () {
|
||||||
return 'functionInData';
|
return 'functionInData';
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toThrow(Error);
|
.toThrow(Error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with the option "allowCallsToHelperMissing" set to true', function() {
|
describe('with the option "allowCallsToHelperMissing" set to true', function () {
|
||||||
it('should not throw an exception when calling "{{helperMissing}}" ', function() {
|
it('should not throw an exception when calling "{{helperMissing}}" ', function () {
|
||||||
var template = Handlebars.compile('{{helperMissing}}');
|
var template = Handlebars.compile('{{helperMissing}}');
|
||||||
template({}, { allowCallsToHelperMissing: true });
|
template({}, { allowCallsToHelperMissing: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', function() {
|
it('should not throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', function () {
|
||||||
var template = Handlebars.compile(
|
var template = Handlebars.compile(
|
||||||
'{{#helperMissing}}{{/helperMissing}}'
|
'{{#helperMissing}}{{/helperMissing}}'
|
||||||
);
|
);
|
||||||
template({}, { allowCallsToHelperMissing: true });
|
template({}, { allowCallsToHelperMissing: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function() {
|
it('should not throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function () {
|
||||||
var functionCalls = [];
|
var functionCalls = [];
|
||||||
var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
|
var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
|
||||||
template(
|
template(
|
||||||
{
|
{
|
||||||
fn: function() {
|
fn: function () {
|
||||||
functionCalls.push('called');
|
functionCalls.push('called');
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{ allowCallsToHelperMissing: true }
|
{ allowCallsToHelperMissing: true }
|
||||||
);
|
);
|
||||||
equals(functionCalls.length, 1);
|
equals(functionCalls.length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() {
|
it('should not throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function () {
|
||||||
var template = Handlebars.compile(
|
var template = Handlebars.compile(
|
||||||
'{{#blockHelperMissing true}}sdads{{/blockHelperMissing}}'
|
'{{#blockHelperMissing true}}sdads{{/blockHelperMissing}}'
|
||||||
);
|
);
|
||||||
@@ -110,8 +108,8 @@ describe('security issues', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GH-1563', function() {
|
describe('GH-1563', function () {
|
||||||
it('should not allow to access constructor after overriding via __defineGetter__', function() {
|
it('should not allow to access constructor after overriding via __defineGetter__', function () {
|
||||||
if ({}.__defineGetter__ == null || {}.__lookupGetter__ == null) {
|
if ({}.__defineGetter__ == null || {}.__lookupGetter__ == null) {
|
||||||
return this.skip(); // Browser does not support this exploit anyway
|
return this.skip(); // Browser does not support this exploit anyway
|
||||||
}
|
}
|
||||||
@@ -127,7 +125,7 @@ describe('security issues', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GH-1595: dangerous properties', function() {
|
describe('GH-1595: dangerous properties', function () {
|
||||||
var templates = [
|
var templates = [
|
||||||
'{{constructor}}',
|
'{{constructor}}',
|
||||||
'{{__defineGetter__}}',
|
'{{__defineGetter__}}',
|
||||||
@@ -138,53 +136,51 @@ describe('security issues', function() {
|
|||||||
'{{lookup this "__defineGetter__"}}',
|
'{{lookup this "__defineGetter__"}}',
|
||||||
'{{lookup this "__defineSetter__"}}',
|
'{{lookup this "__defineSetter__"}}',
|
||||||
'{{lookup this "__lookupGetter__"}}',
|
'{{lookup this "__lookupGetter__"}}',
|
||||||
'{{lookup this "__proto__"}}'
|
'{{lookup this "__proto__"}}',
|
||||||
];
|
];
|
||||||
|
|
||||||
templates.forEach(function(template) {
|
templates.forEach(function (template) {
|
||||||
describe('access should be denied to ' + template, function() {
|
describe('access should be denied to ' + template, function () {
|
||||||
it('by default', function() {
|
it('by default', function () {
|
||||||
expectTemplate(template)
|
expectTemplate(template).withInput({}).toCompileTo('');
|
||||||
.withInput({})
|
|
||||||
.toCompileTo('');
|
|
||||||
});
|
});
|
||||||
it(' with proto-access enabled', function() {
|
it(' with proto-access enabled', function () {
|
||||||
expectTemplate(template)
|
expectTemplate(template)
|
||||||
.withInput({})
|
.withInput({})
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
allowProtoPropertiesByDefault: true,
|
allowProtoPropertiesByDefault: true,
|
||||||
allowProtoMethodsByDefault: true
|
allowProtoMethodsByDefault: true,
|
||||||
})
|
})
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('GH-1631: disallow access to prototype functions', function() {
|
describe('GH-1631: disallow access to prototype functions', function () {
|
||||||
function TestClass() {}
|
function TestClass() {}
|
||||||
|
|
||||||
TestClass.prototype.aProperty = 'propertyValue';
|
TestClass.prototype.aProperty = 'propertyValue';
|
||||||
TestClass.prototype.aMethod = function() {
|
TestClass.prototype.aMethod = function () {
|
||||||
return 'returnValue';
|
return 'returnValue';
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
handlebarsEnv.resetLoggedPropertyAccesses();
|
handlebarsEnv.resetLoggedPropertyAccesses();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('control access to prototype methods via "allowedProtoMethods"', function() {
|
describe('control access to prototype methods via "allowedProtoMethods"', function () {
|
||||||
checkProtoMethodAccess({});
|
checkProtoMethodAccess({});
|
||||||
|
|
||||||
describe('in compat mode', function() {
|
describe('in compat mode', function () {
|
||||||
checkProtoMethodAccess({ compat: true });
|
checkProtoMethodAccess({ compat: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
function checkProtoMethodAccess(compileOptions) {
|
function checkProtoMethodAccess(compileOptions) {
|
||||||
it('should be prohibited by default and log a warning', function() {
|
it('should be prohibited by default and log a warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = sinon.spy(console, 'error');
|
||||||
|
|
||||||
expectTemplate('{{aMethod}}')
|
expectTemplate('{{aMethod}}')
|
||||||
@@ -196,7 +192,7 @@ describe('security issues', function() {
|
|||||||
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should only log the warning once', function() {
|
it('should only log the warning once', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = sinon.spy(console, 'error');
|
||||||
|
|
||||||
expectTemplate('{{aMethod}}')
|
expectTemplate('{{aMethod}}')
|
||||||
@@ -213,7 +209,7 @@ describe('security issues', function() {
|
|||||||
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be allowed, which disables the warning', function() {
|
it('can be allowed, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = sinon.spy(console, 'error');
|
||||||
|
|
||||||
expectTemplate('{{aMethod}}')
|
expectTemplate('{{aMethod}}')
|
||||||
@@ -221,89 +217,89 @@ describe('security issues', function() {
|
|||||||
.withCompileOptions(compileOptions)
|
.withCompileOptions(compileOptions)
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
allowedProtoMethods: {
|
allowedProtoMethods: {
|
||||||
aMethod: true
|
aMethod: true,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('returnValue');
|
.toCompileTo('returnValue');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy.callCount).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned on by default, which disables the warning', function() {
|
it('can be turned on by default, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = sinon.spy(console, 'error');
|
||||||
|
|
||||||
expectTemplate('{{aMethod}}')
|
expectTemplate('{{aMethod}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
.withCompileOptions(compileOptions)
|
.withCompileOptions(compileOptions)
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
allowProtoMethodsByDefault: true
|
allowProtoMethodsByDefault: true,
|
||||||
})
|
})
|
||||||
.toCompileTo('returnValue');
|
.toCompileTo('returnValue');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy.callCount).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned off by default, which disables the warning', function() {
|
it('can be turned off by default, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = sinon.spy(console, 'error');
|
||||||
|
|
||||||
expectTemplate('{{aMethod}}')
|
expectTemplate('{{aMethod}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
.withCompileOptions(compileOptions)
|
.withCompileOptions(compileOptions)
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
allowProtoMethodsByDefault: false
|
allowProtoMethodsByDefault: false,
|
||||||
})
|
})
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy.callCount).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned off, if turned on by default', function() {
|
it('can be turned off, if turned on by default', function () {
|
||||||
expectTemplate('{{aMethod}}')
|
expectTemplate('{{aMethod}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
.withCompileOptions(compileOptions)
|
.withCompileOptions(compileOptions)
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
allowProtoMethodsByDefault: true,
|
allowProtoMethodsByDefault: true,
|
||||||
allowedProtoMethods: {
|
allowedProtoMethods: {
|
||||||
aMethod: false
|
aMethod: false,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should cause the recursive lookup by default (in "compat" mode)', function() {
|
it('should cause the recursive lookup by default (in "compat" mode)', function () {
|
||||||
expectTemplate('{{#aString}}{{trim}}{{/aString}}')
|
expectTemplate('{{#aString}}{{trim}}{{/aString}}')
|
||||||
.withInput({ aString: ' abc ', trim: 'trim' })
|
.withInput({ aString: ' abc ', trim: 'trim' })
|
||||||
.withCompileOptions({ compat: true })
|
.withCompileOptions({ compat: true })
|
||||||
.toCompileTo('trim');
|
.toCompileTo('trim');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not cause the recursive lookup if allowed through options(in "compat" mode)', function() {
|
it('should not cause the recursive lookup if allowed through options(in "compat" mode)', function () {
|
||||||
expectTemplate('{{#aString}}{{trim}}{{/aString}}')
|
expectTemplate('{{#aString}}{{trim}}{{/aString}}')
|
||||||
.withInput({ aString: ' abc ', trim: 'trim' })
|
.withInput({ aString: ' abc ', trim: 'trim' })
|
||||||
.withCompileOptions({ compat: true })
|
.withCompileOptions({ compat: true })
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
allowedProtoMethods: {
|
allowedProtoMethods: {
|
||||||
trim: true
|
trim: true,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('abc');
|
.toCompileTo('abc');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('control access to prototype non-methods via "allowedProtoProperties" and "allowProtoPropertiesByDefault', function() {
|
describe('control access to prototype non-methods via "allowedProtoProperties" and "allowProtoPropertiesByDefault', function () {
|
||||||
checkProtoPropertyAccess({});
|
checkProtoPropertyAccess({});
|
||||||
|
|
||||||
describe('in compat-mode', function() {
|
describe('in compat-mode', function () {
|
||||||
checkProtoPropertyAccess({ compat: true });
|
checkProtoPropertyAccess({ compat: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('in strict-mode', function() {
|
describe('in strict-mode', function () {
|
||||||
checkProtoPropertyAccess({ strict: true });
|
checkProtoPropertyAccess({ strict: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
function checkProtoPropertyAccess(compileOptions) {
|
function checkProtoPropertyAccess(compileOptions) {
|
||||||
it('should be prohibited by default and log a warning', function() {
|
it('should be prohibited by default and log a warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = sinon.spy(console, 'error');
|
||||||
|
|
||||||
expectTemplate('{{aProperty}}')
|
expectTemplate('{{aProperty}}')
|
||||||
@@ -315,21 +311,21 @@ describe('security issues', function() {
|
|||||||
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be explicitly prohibited by default, which disables the warning', function() {
|
it('can be explicitly prohibited by default, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = sinon.spy(console, 'error');
|
||||||
|
|
||||||
expectTemplate('{{aProperty}}')
|
expectTemplate('{{aProperty}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
.withCompileOptions(compileOptions)
|
.withCompileOptions(compileOptions)
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
allowProtoPropertiesByDefault: false
|
allowProtoPropertiesByDefault: false,
|
||||||
})
|
})
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy.callCount).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned on, which disables the warning', function() {
|
it('can be turned on, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = sinon.spy(console, 'error');
|
||||||
|
|
||||||
expectTemplate('{{aProperty}}')
|
expectTemplate('{{aProperty}}')
|
||||||
@@ -337,63 +333,63 @@ describe('security issues', function() {
|
|||||||
.withCompileOptions(compileOptions)
|
.withCompileOptions(compileOptions)
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
allowedProtoProperties: {
|
allowedProtoProperties: {
|
||||||
aProperty: true
|
aProperty: true,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('propertyValue');
|
.toCompileTo('propertyValue');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy.callCount).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned on by default, which disables the warning', function() {
|
it('can be turned on by default, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = sinon.spy(console, 'error');
|
||||||
|
|
||||||
expectTemplate('{{aProperty}}')
|
expectTemplate('{{aProperty}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
.withCompileOptions(compileOptions)
|
.withCompileOptions(compileOptions)
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
allowProtoPropertiesByDefault: true
|
allowProtoPropertiesByDefault: true,
|
||||||
})
|
})
|
||||||
.toCompileTo('propertyValue');
|
.toCompileTo('propertyValue');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy.callCount).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned off, if turned on by default', function() {
|
it('can be turned off, if turned on by default', function () {
|
||||||
expectTemplate('{{aProperty}}')
|
expectTemplate('{{aProperty}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
.withCompileOptions(compileOptions)
|
.withCompileOptions(compileOptions)
|
||||||
.withRuntimeOptions({
|
.withRuntimeOptions({
|
||||||
allowProtoPropertiesByDefault: true,
|
allowProtoPropertiesByDefault: true,
|
||||||
allowedProtoProperties: {
|
allowedProtoProperties: {
|
||||||
aProperty: false
|
aProperty: false,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('compatibility with old runtimes, that do not provide the function "container.lookupProperty"', function() {
|
describe('compatibility with old runtimes, that do not provide the function "container.lookupProperty"', function () {
|
||||||
beforeEach(function simulateRuntimeWithoutLookupProperty() {
|
beforeEach(function simulateRuntimeWithoutLookupProperty() {
|
||||||
var oldTemplateMethod = handlebarsEnv.template;
|
var oldTemplateMethod = handlebarsEnv.template;
|
||||||
sinon.replace(handlebarsEnv, 'template', function(templateSpec) {
|
sinon.replace(handlebarsEnv, 'template', function (templateSpec) {
|
||||||
templateSpec.main = wrapToAdjustContainer(templateSpec.main);
|
templateSpec.main = wrapToAdjustContainer(templateSpec.main);
|
||||||
return oldTemplateMethod.call(this, templateSpec);
|
return oldTemplateMethod.call(this, templateSpec);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with simple properties', function() {
|
it('should work with simple properties', function () {
|
||||||
expectTemplate('{{aProperty}}')
|
expectTemplate('{{aProperty}}')
|
||||||
.withInput({ aProperty: 'propertyValue' })
|
.withInput({ aProperty: 'propertyValue' })
|
||||||
.toCompileTo('propertyValue');
|
.toCompileTo('propertyValue');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with Array.prototype.length', function() {
|
it('should work with Array.prototype.length', function () {
|
||||||
expectTemplate('{{anArray.length}}')
|
expectTemplate('{{anArray.length}}')
|
||||||
.withInput({ anArray: ['a', 'b', 'c'] })
|
.withInput({ anArray: ['a', 'b', 'c'] })
|
||||||
.toCompileTo('3');
|
.toCompileTo('3');
|
||||||
@@ -401,21 +397,21 @@ describe('security issues', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('escapes template variables', function() {
|
describe('escapes template variables', function () {
|
||||||
it('in compat mode', function() {
|
it('in compat mode', function () {
|
||||||
expectTemplate("{{'a\\b'}}")
|
expectTemplate("{{'a\\b'}}")
|
||||||
.withCompileOptions({ compat: true })
|
.withCompileOptions({ compat: true })
|
||||||
.withInput({ 'a\\b': 'c' })
|
.withInput({ 'a\\b': 'c' })
|
||||||
.toCompileTo('c');
|
.toCompileTo('c');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('in default mode', function() {
|
it('in default mode', function () {
|
||||||
expectTemplate("{{'a\\b'}}")
|
expectTemplate("{{'a\\b'}}")
|
||||||
.withCompileOptions()
|
.withCompileOptions()
|
||||||
.withInput({ 'a\\b': 'c' })
|
.withInput({ 'a\\b': 'c' })
|
||||||
.toCompileTo('c');
|
.toCompileTo('c');
|
||||||
});
|
});
|
||||||
it('in default mode', function() {
|
it('in default mode', function () {
|
||||||
expectTemplate("{{'a\\b'}}")
|
expectTemplate("{{'a\\b'}}")
|
||||||
.withCompileOptions({ strict: true })
|
.withCompileOptions({ strict: true })
|
||||||
.withInput({ 'a\\b': 'c' })
|
.withInput({ 'a\\b': 'c' })
|
||||||
|
|||||||
+6
-6
@@ -7,26 +7,26 @@ try {
|
|||||||
/* NOP for in browser */
|
/* NOP for in browser */
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('source-map', function() {
|
describe('source-map', function () {
|
||||||
if (!Handlebars.precompile || !SourceMap) {
|
if (!Handlebars.precompile || !SourceMap) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should safely include source map info', function() {
|
it('should safely include source map info', function () {
|
||||||
var template = Handlebars.precompile('{{hello}}', {
|
var template = Handlebars.precompile('{{hello}}', {
|
||||||
destName: 'dest.js',
|
destName: 'dest.js',
|
||||||
srcName: 'src.hbs'
|
srcName: 'src.hbs',
|
||||||
});
|
});
|
||||||
|
|
||||||
equal(!!template.code, true);
|
equal(!!template.code, true);
|
||||||
equal(!!template.map, !CompilerContext.browser);
|
equal(!!template.map, !CompilerContext.browser);
|
||||||
});
|
});
|
||||||
it('should map source properly', function() {
|
it('should map source properly', function () {
|
||||||
var templateSource =
|
var templateSource =
|
||||||
' b{{hello}} \n {{bar}}a {{#block arg hash=(subex 1 subval)}}{{/block}}',
|
' b{{hello}} \n {{bar}}a {{#block arg hash=(subex 1 subval)}}{{/block}}',
|
||||||
template = Handlebars.precompile(templateSource, {
|
template = Handlebars.precompile(templateSource, {
|
||||||
destName: 'dest.js',
|
destName: 'dest.js',
|
||||||
srcName: 'src.hbs'
|
srcName: 'src.hbs',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (template.map) {
|
if (template.map) {
|
||||||
@@ -49,7 +49,7 @@ function grepLine(token, lines) {
|
|||||||
if (column >= 0) {
|
if (column >= 0) {
|
||||||
return {
|
return {
|
||||||
line: i + 1,
|
line: i + 1,
|
||||||
column: column
|
column: column,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -1,4 +1,4 @@
|
|||||||
describe('spec', function() {
|
describe('spec', function () {
|
||||||
// NOP Under non-node environments
|
// NOP Under non-node environments
|
||||||
if (typeof process === 'undefined') {
|
if (typeof process === 'undefined') {
|
||||||
return;
|
return;
|
||||||
@@ -7,11 +7,11 @@ describe('spec', function() {
|
|||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
var specDir = __dirname + '/mustache/specs/';
|
var specDir = __dirname + '/mustache/specs/';
|
||||||
var specs = fs.readdirSync(specDir).filter(name => /.*\.json$/.test(name));
|
var specs = fs.readdirSync(specDir).filter((name) => /.*\.json$/.test(name));
|
||||||
|
|
||||||
specs.forEach(function(name) {
|
specs.forEach(function (name) {
|
||||||
var spec = require(specDir + name);
|
var spec = require(specDir + name);
|
||||||
spec.tests.forEach(function(test) {
|
spec.tests.forEach(function (test) {
|
||||||
// Our lambda implementation knowingly deviates from the optional Mustache lambda spec
|
// Our lambda implementation knowingly deviates from the optional Mustache lambda spec
|
||||||
// We also do not support alternative delimiters
|
// We also do not support alternative delimiters
|
||||||
if (
|
if (
|
||||||
@@ -21,7 +21,7 @@ describe('spec', function() {
|
|||||||
// We nest the entire response from partials, not just the literals
|
// We nest the entire response from partials, not just the literals
|
||||||
(name === 'partials.json' && test.name === 'Standalone Indentation') ||
|
(name === 'partials.json' && test.name === 'Standalone Indentation') ||
|
||||||
/\{\{=/.test(test.template) ||
|
/\{\{=/.test(test.template) ||
|
||||||
Object.values(test.partials || {}).some(value => /\{\{=/.test(value))
|
Object.values(test.partials || {}).some((value) => /\{\{=/.test(value))
|
||||||
) {
|
) {
|
||||||
it.skip(name + ' - ' + test.name);
|
it.skip(name + ' - ' + test.name);
|
||||||
return;
|
return;
|
||||||
@@ -33,7 +33,7 @@ describe('spec', function() {
|
|||||||
/* eslint-disable-next-line no-eval */
|
/* eslint-disable-next-line no-eval */
|
||||||
data.lambda = eval('(' + data.lambda.js + ')');
|
data.lambda = eval('(' + data.lambda.js + ')');
|
||||||
}
|
}
|
||||||
it(name + ' - ' + test.name, function() {
|
it(name + ' - ' + test.name, function () {
|
||||||
expectTemplate(test.template)
|
expectTemplate(test.template)
|
||||||
.withInput(data)
|
.withInput(data)
|
||||||
.withPartials(test.partials || {})
|
.withPartials(test.partials || {})
|
||||||
|
|||||||
+27
-27
@@ -1,14 +1,14 @@
|
|||||||
var Exception = Handlebars.Exception;
|
var Exception = Handlebars.Exception;
|
||||||
|
|
||||||
describe('strict', function() {
|
describe('strict', function () {
|
||||||
describe('strict mode', function() {
|
describe('strict mode', function () {
|
||||||
it('should error on missing property lookup', function() {
|
it('should error on missing property lookup', function () {
|
||||||
expectTemplate('{{hello}}')
|
expectTemplate('{{hello}}')
|
||||||
.withCompileOptions({ strict: true })
|
.withCompileOptions({ strict: true })
|
||||||
.toThrow(Exception, /"hello" not defined in/);
|
.toThrow(Exception, /"hello" not defined in/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error on missing child', function() {
|
it('should error on missing child', function () {
|
||||||
expectTemplate('{{hello.bar}}')
|
expectTemplate('{{hello.bar}}')
|
||||||
.withCompileOptions({ strict: true })
|
.withCompileOptions({ strict: true })
|
||||||
.withInput({ hello: { bar: 'foo' } })
|
.withInput({ hello: { bar: 'foo' } })
|
||||||
@@ -20,31 +20,31 @@ describe('strict', function() {
|
|||||||
.toThrow(Exception, /"bar" not defined in/);
|
.toThrow(Exception, /"bar" not defined in/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle explicit undefined', function() {
|
it('should handle explicit undefined', function () {
|
||||||
expectTemplate('{{hello.bar}}')
|
expectTemplate('{{hello.bar}}')
|
||||||
.withCompileOptions({ strict: true })
|
.withCompileOptions({ strict: true })
|
||||||
.withInput({ hello: { bar: undefined } })
|
.withInput({ hello: { bar: undefined } })
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error on missing property lookup in known helpers mode', function() {
|
it('should error on missing property lookup in known helpers mode', function () {
|
||||||
expectTemplate('{{hello}}')
|
expectTemplate('{{hello}}')
|
||||||
.withCompileOptions({
|
.withCompileOptions({
|
||||||
strict: true,
|
strict: true,
|
||||||
knownHelpersOnly: true
|
knownHelpersOnly: true,
|
||||||
})
|
})
|
||||||
.toThrow(Exception, /"hello" not defined in/);
|
.toThrow(Exception, /"hello" not defined in/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error on missing context', function() {
|
it('should error on missing context', function () {
|
||||||
expectTemplate('{{hello}}')
|
expectTemplate('{{hello}}')
|
||||||
.withCompileOptions({ strict: true })
|
.withCompileOptions({ strict: true })
|
||||||
.toThrow(Error);
|
.toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error on missing data lookup', function() {
|
it('should error on missing data lookup', function () {
|
||||||
var xt = expectTemplate('{{@hello}}').withCompileOptions({
|
var xt = expectTemplate('{{@hello}}').withCompileOptions({
|
||||||
strict: true
|
strict: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
xt.toThrow(Error);
|
xt.toThrow(Error);
|
||||||
@@ -52,7 +52,7 @@ describe('strict', function() {
|
|||||||
xt.withRuntimeOptions({ data: { hello: 'foo' } }).toCompileTo('foo');
|
xt.withRuntimeOptions({ data: { hello: 'foo' } }).toCompileTo('foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not run helperMissing for helper calls', function() {
|
it('should not run helperMissing for helper calls', function () {
|
||||||
expectTemplate('{{hello foo}}')
|
expectTemplate('{{hello foo}}')
|
||||||
.withCompileOptions({ strict: true })
|
.withCompileOptions({ strict: true })
|
||||||
.withInput({ foo: true })
|
.withInput({ foo: true })
|
||||||
@@ -64,7 +64,7 @@ describe('strict', function() {
|
|||||||
.toThrow(Exception, /"hello" not defined in/);
|
.toThrow(Exception, /"hello" not defined in/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw on ambiguous blocks', function() {
|
it('should throw on ambiguous blocks', function () {
|
||||||
expectTemplate('{{#hello}}{{/hello}}')
|
expectTemplate('{{#hello}}{{/hello}}')
|
||||||
.withCompileOptions({ strict: true })
|
.withCompileOptions({ strict: true })
|
||||||
.toThrow(Exception, /"hello" not defined in/);
|
.toThrow(Exception, /"hello" not defined in/);
|
||||||
@@ -79,37 +79,37 @@ describe('strict', function() {
|
|||||||
.toThrow(Exception, /"bar" not defined in/);
|
.toThrow(Exception, /"bar" not defined in/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow undefined parameters when passed to helpers', function() {
|
it('should allow undefined parameters when passed to helpers', function () {
|
||||||
expectTemplate('{{#unless foo}}success{{/unless}}')
|
expectTemplate('{{#unless foo}}success{{/unless}}')
|
||||||
.withCompileOptions({ strict: true })
|
.withCompileOptions({ strict: true })
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow undefined hash when passed to helpers', function() {
|
it('should allow undefined hash when passed to helpers', function () {
|
||||||
expectTemplate('{{helper value=@foo}}')
|
expectTemplate('{{helper value=@foo}}')
|
||||||
.withCompileOptions({
|
.withCompileOptions({
|
||||||
strict: true
|
strict: true,
|
||||||
})
|
})
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
helper: function(options) {
|
helper: function (options) {
|
||||||
equals('value' in options.hash, true);
|
equals('value' in options.hash, true);
|
||||||
equals(options.hash.value, undefined);
|
equals(options.hash.value, undefined);
|
||||||
return 'success';
|
return 'success';
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('success');
|
.toCompileTo('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show error location on missing property lookup', function() {
|
it('should show error location on missing property lookup', function () {
|
||||||
expectTemplate('\n\n\n {{hello}}')
|
expectTemplate('\n\n\n {{hello}}')
|
||||||
.withCompileOptions({ strict: true })
|
.withCompileOptions({ strict: true })
|
||||||
.toThrow(Exception, '"hello" not defined in [object Object] - 4:5');
|
.toThrow(Exception, '"hello" not defined in [object Object] - 4:5');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error contains correct location properties on missing property lookup', function() {
|
it('should error contains correct location properties on missing property lookup', function () {
|
||||||
try {
|
try {
|
||||||
var template = CompilerContext.compile('\n\n\n {{hello}}', {
|
var template = CompilerContext.compile('\n\n\n {{hello}}', {
|
||||||
strict: true
|
strict: true,
|
||||||
});
|
});
|
||||||
template({});
|
template({});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -121,41 +121,41 @@ describe('strict', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('assume objects', function() {
|
describe('assume objects', function () {
|
||||||
it('should ignore missing property', function() {
|
it('should ignore missing property', function () {
|
||||||
expectTemplate('{{hello}}')
|
expectTemplate('{{hello}}')
|
||||||
.withCompileOptions({ assumeObjects: true })
|
.withCompileOptions({ assumeObjects: true })
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should ignore missing child', function() {
|
it('should ignore missing child', function () {
|
||||||
expectTemplate('{{hello.bar}}')
|
expectTemplate('{{hello.bar}}')
|
||||||
.withCompileOptions({ assumeObjects: true })
|
.withCompileOptions({ assumeObjects: true })
|
||||||
.withInput({ hello: {} })
|
.withInput({ hello: {} })
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error on missing object', function() {
|
it('should error on missing object', function () {
|
||||||
expectTemplate('{{hello.bar}}')
|
expectTemplate('{{hello.bar}}')
|
||||||
.withCompileOptions({ assumeObjects: true })
|
.withCompileOptions({ assumeObjects: true })
|
||||||
.toThrow(Error);
|
.toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error on missing context', function() {
|
it('should error on missing context', function () {
|
||||||
expectTemplate('{{hello}}')
|
expectTemplate('{{hello}}')
|
||||||
.withCompileOptions({ assumeObjects: true })
|
.withCompileOptions({ assumeObjects: true })
|
||||||
.withInput(undefined)
|
.withInput(undefined)
|
||||||
.toThrow(Error);
|
.toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error on missing data lookup', function() {
|
it('should error on missing data lookup', function () {
|
||||||
expectTemplate('{{@hello.bar}}')
|
expectTemplate('{{@hello.bar}}')
|
||||||
.withCompileOptions({ assumeObjects: true })
|
.withCompileOptions({ assumeObjects: true })
|
||||||
.withInput(undefined)
|
.withInput(undefined)
|
||||||
.toThrow(Error);
|
.toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should execute blockHelperMissing', function() {
|
it('should execute blockHelperMissing', function () {
|
||||||
expectTemplate('{{^hello}}foo{{/hello}}')
|
expectTemplate('{{^hello}}foo{{/hello}}')
|
||||||
.withCompileOptions({ assumeObjects: true })
|
.withCompileOptions({ assumeObjects: true })
|
||||||
.toCompileTo('foo');
|
.toCompileTo('foo');
|
||||||
|
|||||||
+51
-51
@@ -1,68 +1,68 @@
|
|||||||
describe('subexpressions', function() {
|
describe('subexpressions', function () {
|
||||||
it('arg-less helper', function() {
|
it('arg-less helper', function () {
|
||||||
expectTemplate('{{foo (bar)}}!')
|
expectTemplate('{{foo (bar)}}!')
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
foo: function(val) {
|
foo: function (val) {
|
||||||
return val + val;
|
return val + val;
|
||||||
},
|
},
|
||||||
bar: function() {
|
bar: function () {
|
||||||
return 'LOL';
|
return 'LOL';
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('LOLLOL!');
|
.toCompileTo('LOLLOL!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('helper w args', function() {
|
it('helper w args', function () {
|
||||||
expectTemplate('{{blog (equal a b)}}')
|
expectTemplate('{{blog (equal a b)}}')
|
||||||
.withInput({ bar: 'LOL' })
|
.withInput({ bar: 'LOL' })
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
blog: function(val) {
|
blog: function (val) {
|
||||||
return 'val is ' + val;
|
return 'val is ' + val;
|
||||||
},
|
},
|
||||||
equal: function(x, y) {
|
equal: function (x, y) {
|
||||||
return x === y;
|
return x === y;
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('val is true');
|
.toCompileTo('val is true');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('mixed paths and helpers', function() {
|
it('mixed paths and helpers', function () {
|
||||||
expectTemplate('{{blog baz.bat (equal a b) baz.bar}}')
|
expectTemplate('{{blog baz.bat (equal a b) baz.bar}}')
|
||||||
.withInput({ bar: 'LOL', baz: { bat: 'foo!', bar: 'bar!' } })
|
.withInput({ bar: 'LOL', baz: { bat: 'foo!', bar: 'bar!' } })
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
blog: function(val, that, theOther) {
|
blog: function (val, that, theOther) {
|
||||||
return 'val is ' + val + ', ' + that + ' and ' + theOther;
|
return 'val is ' + val + ', ' + that + ' and ' + theOther;
|
||||||
},
|
},
|
||||||
equal: function(x, y) {
|
equal: function (x, y) {
|
||||||
return x === y;
|
return x === y;
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('val is foo!, true and bar!');
|
.toCompileTo('val is foo!, true and bar!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports much nesting', function() {
|
it('supports much nesting', function () {
|
||||||
expectTemplate('{{blog (equal (equal true true) true)}}')
|
expectTemplate('{{blog (equal (equal true true) true)}}')
|
||||||
.withInput({ bar: 'LOL' })
|
.withInput({ bar: 'LOL' })
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
blog: function(val) {
|
blog: function (val) {
|
||||||
return 'val is ' + val;
|
return 'val is ' + val;
|
||||||
},
|
},
|
||||||
equal: function(x, y) {
|
equal: function (x, y) {
|
||||||
return x === y;
|
return x === y;
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('val is true');
|
.toCompileTo('val is true');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('GH-800 : Complex subexpressions', function() {
|
it('GH-800 : Complex subexpressions', function () {
|
||||||
var context = { a: 'a', b: 'b', c: { c: 'c' }, d: 'd', e: { e: 'e' } };
|
var context = { a: 'a', b: 'b', c: { c: 'c' }, d: 'd', e: { e: 'e' } };
|
||||||
var helpers = {
|
var helpers = {
|
||||||
dash: function(a, b) {
|
dash: function (a, b) {
|
||||||
return a + '-' + b;
|
return a + '-' + b;
|
||||||
},
|
},
|
||||||
concat: function(a, b) {
|
concat: function (a, b) {
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
expectTemplate("{{dash 'abc' (concat a b)}}")
|
expectTemplate("{{dash 'abc' (concat a b)}}")
|
||||||
@@ -91,55 +91,55 @@ describe('subexpressions', function() {
|
|||||||
.toCompileTo('ae-c');
|
.toCompileTo('ae-c');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('provides each nested helper invocation its own options hash', function() {
|
it('provides each nested helper invocation its own options hash', function () {
|
||||||
var lastOptions = null;
|
var lastOptions = null;
|
||||||
var helpers = {
|
var helpers = {
|
||||||
equal: function(x, y, options) {
|
equal: function (x, y, options) {
|
||||||
if (!options || options === lastOptions) {
|
if (!options || options === lastOptions) {
|
||||||
throw new Error('options hash was reused');
|
throw new Error('options hash was reused');
|
||||||
}
|
}
|
||||||
lastOptions = options;
|
lastOptions = options;
|
||||||
return x === y;
|
return x === y;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
expectTemplate('{{equal (equal true true) true}}')
|
expectTemplate('{{equal (equal true true) true}}')
|
||||||
.withHelpers(helpers)
|
.withHelpers(helpers)
|
||||||
.toCompileTo('true');
|
.toCompileTo('true');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with hashes', function() {
|
it('with hashes', function () {
|
||||||
expectTemplate("{{blog (equal (equal true true) true fun='yes')}}")
|
expectTemplate("{{blog (equal (equal true true) true fun='yes')}}")
|
||||||
.withInput({ bar: 'LOL' })
|
.withInput({ bar: 'LOL' })
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
blog: function(val) {
|
blog: function (val) {
|
||||||
return 'val is ' + val;
|
return 'val is ' + val;
|
||||||
},
|
},
|
||||||
equal: function(x, y) {
|
equal: function (x, y) {
|
||||||
return x === y;
|
return x === y;
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('val is true');
|
.toCompileTo('val is true');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('as hashes', function() {
|
it('as hashes', function () {
|
||||||
expectTemplate("{{blog fun=(equal (blog fun=1) 'val is 1')}}")
|
expectTemplate("{{blog fun=(equal (blog fun=1) 'val is 1')}}")
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
blog: function(options) {
|
blog: function (options) {
|
||||||
return 'val is ' + options.hash.fun;
|
return 'val is ' + options.hash.fun;
|
||||||
},
|
},
|
||||||
equal: function(x, y) {
|
equal: function (x, y) {
|
||||||
return x === y;
|
return x === y;
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('val is true');
|
.toCompileTo('val is true');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multiple subexpressions in a hash', function() {
|
it('multiple subexpressions in a hash', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{input aria-label=(t "Name") placeholder=(t "Example User")}}'
|
'{{input aria-label=(t "Name") placeholder=(t "Example User")}}'
|
||||||
)
|
)
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
input: function(options) {
|
input: function (options) {
|
||||||
var hash = options.hash;
|
var hash = options.hash;
|
||||||
var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
|
var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
|
||||||
var placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
|
var placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
|
||||||
@@ -151,25 +151,25 @@ describe('subexpressions', function() {
|
|||||||
'" />'
|
'" />'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
t: function(defaultString) {
|
t: function (defaultString) {
|
||||||
return new Handlebars.SafeString(defaultString);
|
return new Handlebars.SafeString(defaultString);
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('<input aria-label="Name" placeholder="Example User" />');
|
.toCompileTo('<input aria-label="Name" placeholder="Example User" />');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multiple subexpressions in a hash with context', function() {
|
it('multiple subexpressions in a hash with context', function () {
|
||||||
expectTemplate(
|
expectTemplate(
|
||||||
'{{input aria-label=(t item.field) placeholder=(t item.placeholder)}}'
|
'{{input aria-label=(t item.field) placeholder=(t item.placeholder)}}'
|
||||||
)
|
)
|
||||||
.withInput({
|
.withInput({
|
||||||
item: {
|
item: {
|
||||||
field: 'Name',
|
field: 'Name',
|
||||||
placeholder: 'Example User'
|
placeholder: 'Example User',
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
input: function(options) {
|
input: function (options) {
|
||||||
var hash = options.hash;
|
var hash = options.hash;
|
||||||
var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
|
var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
|
||||||
var placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
|
var placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
|
||||||
@@ -181,37 +181,37 @@ describe('subexpressions', function() {
|
|||||||
'" />'
|
'" />'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
t: function(defaultString) {
|
t: function (defaultString) {
|
||||||
return new Handlebars.SafeString(defaultString);
|
return new Handlebars.SafeString(defaultString);
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('<input aria-label="Name" placeholder="Example User" />');
|
.toCompileTo('<input aria-label="Name" placeholder="Example User" />');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('subexpression functions on the context', function() {
|
it('subexpression functions on the context', function () {
|
||||||
expectTemplate('{{foo (bar)}}!')
|
expectTemplate('{{foo (bar)}}!')
|
||||||
.withInput({
|
.withInput({
|
||||||
bar: function() {
|
bar: function () {
|
||||||
return 'LOL';
|
return 'LOL';
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
foo: function(val) {
|
foo: function (val) {
|
||||||
return val + val;
|
return val + val;
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toCompileTo('LOLLOL!');
|
.toCompileTo('LOLLOL!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("subexpressions can't just be property lookups", function() {
|
it("subexpressions can't just be property lookups", function () {
|
||||||
expectTemplate('{{foo (bar)}}!')
|
expectTemplate('{{foo (bar)}}!')
|
||||||
.withInput({
|
.withInput({
|
||||||
bar: 'LOL'
|
bar: 'LOL',
|
||||||
})
|
})
|
||||||
.withHelpers({
|
.withHelpers({
|
||||||
foo: function(val) {
|
foo: function (val) {
|
||||||
return val + val;
|
return val + val;
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.toThrow();
|
.toThrow();
|
||||||
});
|
});
|
||||||
|
|||||||
+93
-93
@@ -8,7 +8,7 @@ function shouldBeToken(result, name, text) {
|
|||||||
equals(result.text, text);
|
equals(result.text, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Tokenizer', function() {
|
describe('Tokenizer', function () {
|
||||||
if (!Handlebars.Parser) {
|
if (!Handlebars.Parser) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -32,13 +32,13 @@ describe('Tokenizer', function() {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
it('tokenizes a simple mustache as "OPEN ID CLOSE"', function() {
|
it('tokenizes a simple mustache as "OPEN ID CLOSE"', function () {
|
||||||
var result = tokenize('{{foo}}');
|
var result = tokenize('{{foo}}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']);
|
||||||
shouldBeToken(result[1], 'ID', 'foo');
|
shouldBeToken(result[1], 'ID', 'foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports unescaping with &', function() {
|
it('supports unescaping with &', function () {
|
||||||
var result = tokenize('{{&bar}}');
|
var result = tokenize('{{&bar}}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']);
|
||||||
|
|
||||||
@@ -46,14 +46,14 @@ describe('Tokenizer', function() {
|
|||||||
shouldBeToken(result[1], 'ID', 'bar');
|
shouldBeToken(result[1], 'ID', 'bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports unescaping with {{{', function() {
|
it('supports unescaping with {{{', function () {
|
||||||
var result = tokenize('{{{bar}}}');
|
var result = tokenize('{{{bar}}}');
|
||||||
shouldMatchTokens(result, ['OPEN_UNESCAPED', 'ID', 'CLOSE_UNESCAPED']);
|
shouldMatchTokens(result, ['OPEN_UNESCAPED', 'ID', 'CLOSE_UNESCAPED']);
|
||||||
|
|
||||||
shouldBeToken(result[1], 'ID', 'bar');
|
shouldBeToken(result[1], 'ID', 'bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports escaping delimiters', function() {
|
it('supports escaping delimiters', function () {
|
||||||
var result = tokenize('{{foo}} \\{{bar}} {{baz}}');
|
var result = tokenize('{{foo}} \\{{bar}} {{baz}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -63,14 +63,14 @@ describe('Tokenizer', function() {
|
|||||||
'CONTENT',
|
'CONTENT',
|
||||||
'OPEN',
|
'OPEN',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
shouldBeToken(result[3], 'CONTENT', ' ');
|
shouldBeToken(result[3], 'CONTENT', ' ');
|
||||||
shouldBeToken(result[4], 'CONTENT', '{{bar}} ');
|
shouldBeToken(result[4], 'CONTENT', '{{bar}} ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports escaping multiple delimiters', function() {
|
it('supports escaping multiple delimiters', function () {
|
||||||
var result = tokenize('{{foo}} \\{{bar}} \\{{baz}}');
|
var result = tokenize('{{foo}} \\{{bar}} \\{{baz}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -78,7 +78,7 @@ describe('Tokenizer', function() {
|
|||||||
'CLOSE',
|
'CLOSE',
|
||||||
'CONTENT',
|
'CONTENT',
|
||||||
'CONTENT',
|
'CONTENT',
|
||||||
'CONTENT'
|
'CONTENT',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
shouldBeToken(result[3], 'CONTENT', ' ');
|
shouldBeToken(result[3], 'CONTENT', ' ');
|
||||||
@@ -86,7 +86,7 @@ describe('Tokenizer', function() {
|
|||||||
shouldBeToken(result[5], 'CONTENT', '{{baz}}');
|
shouldBeToken(result[5], 'CONTENT', '{{baz}}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports escaping a triple stash', function() {
|
it('supports escaping a triple stash', function () {
|
||||||
var result = tokenize('{{foo}} \\{{{bar}}} {{baz}}');
|
var result = tokenize('{{foo}} \\{{{bar}}} {{baz}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -96,13 +96,13 @@ describe('Tokenizer', function() {
|
|||||||
'CONTENT',
|
'CONTENT',
|
||||||
'OPEN',
|
'OPEN',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
shouldBeToken(result[4], 'CONTENT', '{{{bar}}} ');
|
shouldBeToken(result[4], 'CONTENT', '{{{bar}}} ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports escaping escape character', function() {
|
it('supports escaping escape character', function () {
|
||||||
var result = tokenize('{{foo}} \\\\{{bar}} {{baz}}');
|
var result = tokenize('{{foo}} \\\\{{bar}} {{baz}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -115,14 +115,14 @@ describe('Tokenizer', function() {
|
|||||||
'CONTENT',
|
'CONTENT',
|
||||||
'OPEN',
|
'OPEN',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
shouldBeToken(result[3], 'CONTENT', ' \\');
|
shouldBeToken(result[3], 'CONTENT', ' \\');
|
||||||
shouldBeToken(result[5], 'ID', 'bar');
|
shouldBeToken(result[5], 'ID', 'bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports escaping multiple escape characters', function() {
|
it('supports escaping multiple escape characters', function () {
|
||||||
var result = tokenize('{{foo}} \\\\{{bar}} \\\\{{baz}}');
|
var result = tokenize('{{foo}} \\\\{{bar}} \\\\{{baz}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -135,7 +135,7 @@ describe('Tokenizer', function() {
|
|||||||
'CONTENT',
|
'CONTENT',
|
||||||
'OPEN',
|
'OPEN',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
shouldBeToken(result[3], 'CONTENT', ' \\');
|
shouldBeToken(result[3], 'CONTENT', ' \\');
|
||||||
@@ -144,7 +144,7 @@ describe('Tokenizer', function() {
|
|||||||
shouldBeToken(result[9], 'ID', 'baz');
|
shouldBeToken(result[9], 'ID', 'baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports escaped mustaches after escaped escape characters', function() {
|
it('supports escaped mustaches after escaped escape characters', function () {
|
||||||
var result = tokenize('{{foo}} \\\\{{bar}} \\{{baz}}');
|
var result = tokenize('{{foo}} \\\\{{bar}} \\{{baz}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -156,7 +156,7 @@ describe('Tokenizer', function() {
|
|||||||
'CLOSE',
|
'CLOSE',
|
||||||
'CONTENT',
|
'CONTENT',
|
||||||
'CONTENT',
|
'CONTENT',
|
||||||
'CONTENT'
|
'CONTENT',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
shouldBeToken(result[3], 'CONTENT', ' \\');
|
shouldBeToken(result[3], 'CONTENT', ' \\');
|
||||||
@@ -166,7 +166,7 @@ describe('Tokenizer', function() {
|
|||||||
shouldBeToken(result[8], 'CONTENT', '{{baz}}');
|
shouldBeToken(result[8], 'CONTENT', '{{baz}}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports escaped escape characters after escaped mustaches', function() {
|
it('supports escaped escape characters after escaped mustaches', function () {
|
||||||
var result = tokenize('{{foo}} \\{{bar}} \\\\{{baz}}');
|
var result = tokenize('{{foo}} \\{{bar}} \\\\{{baz}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -177,7 +177,7 @@ describe('Tokenizer', function() {
|
|||||||
'CONTENT',
|
'CONTENT',
|
||||||
'OPEN',
|
'OPEN',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
shouldBeToken(result[4], 'CONTENT', '{{bar}} ');
|
shouldBeToken(result[4], 'CONTENT', '{{bar}} ');
|
||||||
@@ -186,7 +186,7 @@ describe('Tokenizer', function() {
|
|||||||
shouldBeToken(result[7], 'ID', 'baz');
|
shouldBeToken(result[7], 'ID', 'baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports escaped escape character on a triple stash', function() {
|
it('supports escaped escape character on a triple stash', function () {
|
||||||
var result = tokenize('{{foo}} \\\\{{{bar}}} {{baz}}');
|
var result = tokenize('{{foo}} \\\\{{{bar}}} {{baz}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -199,19 +199,19 @@ describe('Tokenizer', function() {
|
|||||||
'CONTENT',
|
'CONTENT',
|
||||||
'OPEN',
|
'OPEN',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
shouldBeToken(result[3], 'CONTENT', ' \\');
|
shouldBeToken(result[3], 'CONTENT', ' \\');
|
||||||
shouldBeToken(result[5], 'ID', 'bar');
|
shouldBeToken(result[5], 'ID', 'bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a simple path', function() {
|
it('tokenizes a simple path', function () {
|
||||||
var result = tokenize('{{foo/bar}}');
|
var result = tokenize('{{foo/bar}}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows dot notation', function() {
|
it('allows dot notation', function () {
|
||||||
var result = tokenize('{{foo.bar}}');
|
var result = tokenize('{{foo.bar}}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
||||||
|
|
||||||
@@ -222,16 +222,16 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'SEP',
|
'SEP',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows path literals with []', function() {
|
it('allows path literals with []', function () {
|
||||||
var result = tokenize('{{foo.[bar]}}');
|
var result = tokenize('{{foo.[bar]}}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows multiple path literals on a line with []', function() {
|
it('allows multiple path literals on a line with []', function () {
|
||||||
var result = tokenize('{{foo.[bar]}}{{foo.[baz]}}');
|
var result = tokenize('{{foo.[bar]}}{{foo.[baz]}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -243,21 +243,21 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'SEP',
|
'SEP',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows escaped literals in []', function() {
|
it('allows escaped literals in []', function () {
|
||||||
var result = tokenize('{{foo.[bar\\]]}}');
|
var result = tokenize('{{foo.[bar\\]]}}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes {{.}} as OPEN ID CLOSE', function() {
|
it('tokenizes {{.}} as OPEN ID CLOSE', function () {
|
||||||
var result = tokenize('{{.}}');
|
var result = tokenize('{{.}}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a path as "OPEN (ID SEP)* ID CLOSE"', function() {
|
it('tokenizes a path as "OPEN (ID SEP)* ID CLOSE"', function () {
|
||||||
var result = tokenize('{{../foo/bar}}');
|
var result = tokenize('{{../foo/bar}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -266,12 +266,12 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'SEP',
|
'SEP',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
shouldBeToken(result[1], 'ID', '..');
|
shouldBeToken(result[1], 'ID', '..');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a path with .. as a parent path', function() {
|
it('tokenizes a path with .. as a parent path', function () {
|
||||||
var result = tokenize('{{../foo.bar}}');
|
var result = tokenize('{{../foo.bar}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -280,58 +280,58 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'SEP',
|
'SEP',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
shouldBeToken(result[1], 'ID', '..');
|
shouldBeToken(result[1], 'ID', '..');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a path with this/foo as OPEN ID SEP ID CLOSE', function() {
|
it('tokenizes a path with this/foo as OPEN ID SEP ID CLOSE', function () {
|
||||||
var result = tokenize('{{this/foo}}');
|
var result = tokenize('{{this/foo}}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
||||||
shouldBeToken(result[1], 'ID', 'this');
|
shouldBeToken(result[1], 'ID', 'this');
|
||||||
shouldBeToken(result[3], 'ID', 'foo');
|
shouldBeToken(result[3], 'ID', 'foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a simple mustache with spaces as "OPEN ID CLOSE"', function() {
|
it('tokenizes a simple mustache with spaces as "OPEN ID CLOSE"', function () {
|
||||||
var result = tokenize('{{ foo }}');
|
var result = tokenize('{{ foo }}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']);
|
||||||
shouldBeToken(result[1], 'ID', 'foo');
|
shouldBeToken(result[1], 'ID', 'foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a simple mustache with line breaks as "OPEN ID ID CLOSE"', function() {
|
it('tokenizes a simple mustache with line breaks as "OPEN ID ID CLOSE"', function () {
|
||||||
var result = tokenize('{{ foo \n bar }}');
|
var result = tokenize('{{ foo \n bar }}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'CLOSE']);
|
||||||
shouldBeToken(result[1], 'ID', 'foo');
|
shouldBeToken(result[1], 'ID', 'foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes raw content as "CONTENT"', function() {
|
it('tokenizes raw content as "CONTENT"', function () {
|
||||||
var result = tokenize('foo {{ bar }} baz');
|
var result = tokenize('foo {{ bar }} baz');
|
||||||
shouldMatchTokens(result, ['CONTENT', 'OPEN', 'ID', 'CLOSE', 'CONTENT']);
|
shouldMatchTokens(result, ['CONTENT', 'OPEN', 'ID', 'CLOSE', 'CONTENT']);
|
||||||
shouldBeToken(result[0], 'CONTENT', 'foo ');
|
shouldBeToken(result[0], 'CONTENT', 'foo ');
|
||||||
shouldBeToken(result[4], 'CONTENT', ' baz');
|
shouldBeToken(result[4], 'CONTENT', ' baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a partial as "OPEN_PARTIAL ID CLOSE"', function() {
|
it('tokenizes a partial as "OPEN_PARTIAL ID CLOSE"', function () {
|
||||||
var result = tokenize('{{> foo}}');
|
var result = tokenize('{{> foo}}');
|
||||||
shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'CLOSE']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a partial with context as "OPEN_PARTIAL ID ID CLOSE"', function() {
|
it('tokenizes a partial with context as "OPEN_PARTIAL ID ID CLOSE"', function () {
|
||||||
var result = tokenize('{{> foo bar }}');
|
var result = tokenize('{{> foo bar }}');
|
||||||
shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'ID', 'CLOSE']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a partial without spaces as "OPEN_PARTIAL ID CLOSE"', function() {
|
it('tokenizes a partial without spaces as "OPEN_PARTIAL ID CLOSE"', function () {
|
||||||
var result = tokenize('{{>foo}}');
|
var result = tokenize('{{>foo}}');
|
||||||
shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'CLOSE']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a partial space at the }); as "OPEN_PARTIAL ID CLOSE"', function() {
|
it('tokenizes a partial space at the }); as "OPEN_PARTIAL ID CLOSE"', function () {
|
||||||
var result = tokenize('{{>foo }}');
|
var result = tokenize('{{>foo }}');
|
||||||
shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'CLOSE']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a partial space at the }); as "OPEN_PARTIAL ID CLOSE"', function() {
|
it('tokenizes a partial space at the }); as "OPEN_PARTIAL ID CLOSE"', function () {
|
||||||
var result = tokenize('{{>foo/bar.baz }}');
|
var result = tokenize('{{>foo/bar.baz }}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN_PARTIAL',
|
'OPEN_PARTIAL',
|
||||||
@@ -340,15 +340,15 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'SEP',
|
'SEP',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes partial block declarations', function() {
|
it('tokenizes partial block declarations', function () {
|
||||||
var result = tokenize('{{#> foo}}');
|
var result = tokenize('{{#> foo}}');
|
||||||
shouldMatchTokens(result, ['OPEN_PARTIAL_BLOCK', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN_PARTIAL_BLOCK', 'ID', 'CLOSE']);
|
||||||
});
|
});
|
||||||
it('tokenizes a comment as "COMMENT"', function() {
|
it('tokenizes a comment as "COMMENT"', function () {
|
||||||
var result = tokenize('foo {{! this is a comment }} bar {{ baz }}');
|
var result = tokenize('foo {{! this is a comment }} bar {{ baz }}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'CONTENT',
|
'CONTENT',
|
||||||
@@ -356,12 +356,12 @@ describe('Tokenizer', function() {
|
|||||||
'CONTENT',
|
'CONTENT',
|
||||||
'OPEN',
|
'OPEN',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
shouldBeToken(result[1], 'COMMENT', '{{! this is a comment }}');
|
shouldBeToken(result[1], 'COMMENT', '{{! this is a comment }}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a block comment as "COMMENT"', function() {
|
it('tokenizes a block comment as "COMMENT"', function () {
|
||||||
var result = tokenize('foo {{!-- this is a {{comment}} --}} bar {{ baz }}');
|
var result = tokenize('foo {{!-- this is a {{comment}} --}} bar {{ baz }}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'CONTENT',
|
'CONTENT',
|
||||||
@@ -369,12 +369,12 @@ describe('Tokenizer', function() {
|
|||||||
'CONTENT',
|
'CONTENT',
|
||||||
'OPEN',
|
'OPEN',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
shouldBeToken(result[1], 'COMMENT', '{{!-- this is a {{comment}} --}}');
|
shouldBeToken(result[1], 'COMMENT', '{{!-- this is a {{comment}} --}}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes a block comment with whitespace as "COMMENT"', function() {
|
it('tokenizes a block comment with whitespace as "COMMENT"', function () {
|
||||||
var result = tokenize(
|
var result = tokenize(
|
||||||
'foo {{!-- this is a\n{{comment}}\n--}} bar {{ baz }}'
|
'foo {{!-- this is a\n{{comment}}\n--}} bar {{ baz }}'
|
||||||
);
|
);
|
||||||
@@ -384,12 +384,12 @@ describe('Tokenizer', function() {
|
|||||||
'CONTENT',
|
'CONTENT',
|
||||||
'OPEN',
|
'OPEN',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
shouldBeToken(result[1], 'COMMENT', '{{!-- this is a\n{{comment}}\n--}}');
|
shouldBeToken(result[1], 'COMMENT', '{{!-- this is a\n{{comment}}\n--}}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes open and closing blocks as OPEN_BLOCK, ID, CLOSE ..., OPEN_ENDBLOCK ID CLOSE', function() {
|
it('tokenizes open and closing blocks as OPEN_BLOCK, ID, CLOSE ..., OPEN_ENDBLOCK ID CLOSE', function () {
|
||||||
var result = tokenize('{{#foo}}content{{/foo}}');
|
var result = tokenize('{{#foo}}content{{/foo}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN_BLOCK',
|
'OPEN_BLOCK',
|
||||||
@@ -398,11 +398,11 @@ describe('Tokenizer', function() {
|
|||||||
'CONTENT',
|
'CONTENT',
|
||||||
'OPEN_ENDBLOCK',
|
'OPEN_ENDBLOCK',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes directives', function() {
|
it('tokenizes directives', function () {
|
||||||
shouldMatchTokens(tokenize('{{#*foo}}content{{/foo}}'), [
|
shouldMatchTokens(tokenize('{{#*foo}}content{{/foo}}'), [
|
||||||
'OPEN_BLOCK',
|
'OPEN_BLOCK',
|
||||||
'ID',
|
'ID',
|
||||||
@@ -410,30 +410,30 @@ describe('Tokenizer', function() {
|
|||||||
'CONTENT',
|
'CONTENT',
|
||||||
'OPEN_ENDBLOCK',
|
'OPEN_ENDBLOCK',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
shouldMatchTokens(tokenize('{{*foo}}'), ['OPEN', 'ID', 'CLOSE']);
|
shouldMatchTokens(tokenize('{{*foo}}'), ['OPEN', 'ID', 'CLOSE']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes inverse sections as "INVERSE"', function() {
|
it('tokenizes inverse sections as "INVERSE"', function () {
|
||||||
shouldMatchTokens(tokenize('{{^}}'), ['INVERSE']);
|
shouldMatchTokens(tokenize('{{^}}'), ['INVERSE']);
|
||||||
shouldMatchTokens(tokenize('{{else}}'), ['INVERSE']);
|
shouldMatchTokens(tokenize('{{else}}'), ['INVERSE']);
|
||||||
shouldMatchTokens(tokenize('{{ else }}'), ['INVERSE']);
|
shouldMatchTokens(tokenize('{{ else }}'), ['INVERSE']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes inverse sections with ID as "OPEN_INVERSE ID CLOSE"', function() {
|
it('tokenizes inverse sections with ID as "OPEN_INVERSE ID CLOSE"', function () {
|
||||||
var result = tokenize('{{^foo}}');
|
var result = tokenize('{{^foo}}');
|
||||||
shouldMatchTokens(result, ['OPEN_INVERSE', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN_INVERSE', 'ID', 'CLOSE']);
|
||||||
shouldBeToken(result[1], 'ID', 'foo');
|
shouldBeToken(result[1], 'ID', 'foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes inverse sections with ID and spaces as "OPEN_INVERSE ID CLOSE"', function() {
|
it('tokenizes inverse sections with ID and spaces as "OPEN_INVERSE ID CLOSE"', function () {
|
||||||
var result = tokenize('{{^ foo }}');
|
var result = tokenize('{{^ foo }}');
|
||||||
shouldMatchTokens(result, ['OPEN_INVERSE', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN_INVERSE', 'ID', 'CLOSE']);
|
||||||
shouldBeToken(result[1], 'ID', 'foo');
|
shouldBeToken(result[1], 'ID', 'foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes mustaches with params as "OPEN ID ID ID CLOSE"', function() {
|
it('tokenizes mustaches with params as "OPEN ID ID ID CLOSE"', function () {
|
||||||
var result = tokenize('{{ foo bar baz }}');
|
var result = tokenize('{{ foo bar baz }}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'CLOSE']);
|
||||||
shouldBeToken(result[1], 'ID', 'foo');
|
shouldBeToken(result[1], 'ID', 'foo');
|
||||||
@@ -441,37 +441,37 @@ describe('Tokenizer', function() {
|
|||||||
shouldBeToken(result[3], 'ID', 'baz');
|
shouldBeToken(result[3], 'ID', 'baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes mustaches with String params as "OPEN ID ID STRING CLOSE"', function() {
|
it('tokenizes mustaches with String params as "OPEN ID ID STRING CLOSE"', function () {
|
||||||
var result = tokenize('{{ foo bar "baz" }}');
|
var result = tokenize('{{ foo bar "baz" }}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']);
|
||||||
shouldBeToken(result[3], 'STRING', 'baz');
|
shouldBeToken(result[3], 'STRING', 'baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes mustaches with String params using single quotes as "OPEN ID ID STRING CLOSE"', function() {
|
it('tokenizes mustaches with String params using single quotes as "OPEN ID ID STRING CLOSE"', function () {
|
||||||
var result = tokenize("{{ foo bar 'baz' }}");
|
var result = tokenize("{{ foo bar 'baz' }}");
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']);
|
||||||
shouldBeToken(result[3], 'STRING', 'baz');
|
shouldBeToken(result[3], 'STRING', 'baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes String params with spaces inside as "STRING"', function() {
|
it('tokenizes String params with spaces inside as "STRING"', function () {
|
||||||
var result = tokenize('{{ foo bar "baz bat" }}');
|
var result = tokenize('{{ foo bar "baz bat" }}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']);
|
||||||
shouldBeToken(result[3], 'STRING', 'baz bat');
|
shouldBeToken(result[3], 'STRING', 'baz bat');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes String params with escapes quotes as STRING', function() {
|
it('tokenizes String params with escapes quotes as STRING', function () {
|
||||||
var result = tokenize('{{ foo "bar\\"baz" }}');
|
var result = tokenize('{{ foo "bar\\"baz" }}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'STRING', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'STRING', 'CLOSE']);
|
||||||
shouldBeToken(result[2], 'STRING', 'bar"baz');
|
shouldBeToken(result[2], 'STRING', 'bar"baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes String params using single quotes with escapes quotes as STRING', function() {
|
it('tokenizes String params using single quotes with escapes quotes as STRING', function () {
|
||||||
var result = tokenize("{{ foo 'bar\\'baz' }}");
|
var result = tokenize("{{ foo 'bar\\'baz' }}");
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'STRING', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'STRING', 'CLOSE']);
|
||||||
shouldBeToken(result[2], 'STRING', "bar'baz");
|
shouldBeToken(result[2], 'STRING', "bar'baz");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes numbers', function() {
|
it('tokenizes numbers', function () {
|
||||||
var result = tokenize('{{ foo 1 }}');
|
var result = tokenize('{{ foo 1 }}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'NUMBER', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'NUMBER', 'CLOSE']);
|
||||||
shouldBeToken(result[2], 'NUMBER', '1');
|
shouldBeToken(result[2], 'NUMBER', '1');
|
||||||
@@ -489,7 +489,7 @@ describe('Tokenizer', function() {
|
|||||||
shouldBeToken(result[2], 'NUMBER', '-1.1');
|
shouldBeToken(result[2], 'NUMBER', '-1.1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes booleans', function() {
|
it('tokenizes booleans', function () {
|
||||||
var result = tokenize('{{ foo true }}');
|
var result = tokenize('{{ foo true }}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'BOOLEAN', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'BOOLEAN', 'CLOSE']);
|
||||||
shouldBeToken(result[2], 'BOOLEAN', 'true');
|
shouldBeToken(result[2], 'BOOLEAN', 'true');
|
||||||
@@ -499,14 +499,14 @@ describe('Tokenizer', function() {
|
|||||||
shouldBeToken(result[2], 'BOOLEAN', 'false');
|
shouldBeToken(result[2], 'BOOLEAN', 'false');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes undefined and null', function() {
|
it('tokenizes undefined and null', function () {
|
||||||
var result = tokenize('{{ foo undefined null }}');
|
var result = tokenize('{{ foo undefined null }}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'UNDEFINED', 'NULL', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'UNDEFINED', 'NULL', 'CLOSE']);
|
||||||
shouldBeToken(result[2], 'UNDEFINED', 'undefined');
|
shouldBeToken(result[2], 'UNDEFINED', 'undefined');
|
||||||
shouldBeToken(result[3], 'NULL', 'null');
|
shouldBeToken(result[3], 'NULL', 'null');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes hash arguments', function() {
|
it('tokenizes hash arguments', function () {
|
||||||
var result = tokenize('{{ foo bar=baz }}');
|
var result = tokenize('{{ foo bar=baz }}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'EQUALS', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'EQUALS', 'ID', 'CLOSE']);
|
||||||
|
|
||||||
@@ -518,7 +518,7 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'EQUALS',
|
'EQUALS',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
result = tokenize('{{ foo bar baz=1 }}');
|
result = tokenize('{{ foo bar baz=1 }}');
|
||||||
@@ -529,7 +529,7 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'EQUALS',
|
'EQUALS',
|
||||||
'NUMBER',
|
'NUMBER',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
result = tokenize('{{ foo bar baz=true }}');
|
result = tokenize('{{ foo bar baz=true }}');
|
||||||
@@ -540,7 +540,7 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'EQUALS',
|
'EQUALS',
|
||||||
'BOOLEAN',
|
'BOOLEAN',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
result = tokenize('{{ foo bar baz=false }}');
|
result = tokenize('{{ foo bar baz=false }}');
|
||||||
@@ -551,7 +551,7 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'EQUALS',
|
'EQUALS',
|
||||||
'BOOLEAN',
|
'BOOLEAN',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
result = tokenize('{{ foo bar\n baz=bat }}');
|
result = tokenize('{{ foo bar\n baz=bat }}');
|
||||||
@@ -562,7 +562,7 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'EQUALS',
|
'EQUALS',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
result = tokenize('{{ foo bar baz="bat" }}');
|
result = tokenize('{{ foo bar baz="bat" }}');
|
||||||
@@ -573,7 +573,7 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'EQUALS',
|
'EQUALS',
|
||||||
'STRING',
|
'STRING',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
result = tokenize('{{ foo bar baz="bat" bam=wot }}');
|
result = tokenize('{{ foo bar baz="bat" bam=wot }}');
|
||||||
@@ -587,7 +587,7 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'EQUALS',
|
'EQUALS',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
result = tokenize('{{foo omg bar=baz bat="bam"}}');
|
result = tokenize('{{foo omg bar=baz bat="bam"}}');
|
||||||
@@ -601,12 +601,12 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'EQUALS',
|
'EQUALS',
|
||||||
'STRING',
|
'STRING',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
shouldBeToken(result[2], 'ID', 'omg');
|
shouldBeToken(result[2], 'ID', 'omg');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes special @ identifiers', function() {
|
it('tokenizes special @ identifiers', function () {
|
||||||
var result = tokenize('{{ @foo }}');
|
var result = tokenize('{{ @foo }}');
|
||||||
shouldMatchTokens(result, ['OPEN', 'DATA', 'ID', 'CLOSE']);
|
shouldMatchTokens(result, ['OPEN', 'DATA', 'ID', 'CLOSE']);
|
||||||
shouldBeToken(result[2], 'ID', 'foo');
|
shouldBeToken(result[2], 'ID', 'foo');
|
||||||
@@ -623,20 +623,20 @@ describe('Tokenizer', function() {
|
|||||||
'EQUALS',
|
'EQUALS',
|
||||||
'DATA',
|
'DATA',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
shouldBeToken(result[5], 'ID', 'baz');
|
shouldBeToken(result[5], 'ID', 'baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not time out in a mustache with a single } followed by EOF', function() {
|
it('does not time out in a mustache with a single } followed by EOF', function () {
|
||||||
shouldMatchTokens(tokenize('{{foo}'), ['OPEN', 'ID']);
|
shouldMatchTokens(tokenize('{{foo}'), ['OPEN', 'ID']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not time out in a mustache when invalid ID characters are used', function() {
|
it('does not time out in a mustache when invalid ID characters are used', function () {
|
||||||
shouldMatchTokens(tokenize('{{foo & }}'), ['OPEN', 'ID']);
|
shouldMatchTokens(tokenize('{{foo & }}'), ['OPEN', 'ID']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes subexpressions', function() {
|
it('tokenizes subexpressions', function () {
|
||||||
var result = tokenize('{{foo (bar)}}');
|
var result = tokenize('{{foo (bar)}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -644,7 +644,7 @@ describe('Tokenizer', function() {
|
|||||||
'OPEN_SEXPR',
|
'OPEN_SEXPR',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE_SEXPR',
|
'CLOSE_SEXPR',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
shouldBeToken(result[1], 'ID', 'foo');
|
shouldBeToken(result[1], 'ID', 'foo');
|
||||||
shouldBeToken(result[3], 'ID', 'bar');
|
shouldBeToken(result[3], 'ID', 'bar');
|
||||||
@@ -657,14 +657,14 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE_SEXPR',
|
'CLOSE_SEXPR',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
shouldBeToken(result[1], 'ID', 'foo');
|
shouldBeToken(result[1], 'ID', 'foo');
|
||||||
shouldBeToken(result[3], 'ID', 'a-x');
|
shouldBeToken(result[3], 'ID', 'a-x');
|
||||||
shouldBeToken(result[4], 'ID', 'b-y');
|
shouldBeToken(result[4], 'ID', 'b-y');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes nested subexpressions', function() {
|
it('tokenizes nested subexpressions', function () {
|
||||||
var result = tokenize('{{foo (bar (lol rofl)) (baz)}}');
|
var result = tokenize('{{foo (bar (lol rofl)) (baz)}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN',
|
'OPEN',
|
||||||
@@ -679,7 +679,7 @@ describe('Tokenizer', function() {
|
|||||||
'OPEN_SEXPR',
|
'OPEN_SEXPR',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE_SEXPR',
|
'CLOSE_SEXPR',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
shouldBeToken(result[3], 'ID', 'bar');
|
shouldBeToken(result[3], 'ID', 'bar');
|
||||||
shouldBeToken(result[5], 'ID', 'lol');
|
shouldBeToken(result[5], 'ID', 'lol');
|
||||||
@@ -687,7 +687,7 @@ describe('Tokenizer', function() {
|
|||||||
shouldBeToken(result[10], 'ID', 'baz');
|
shouldBeToken(result[10], 'ID', 'baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes nested subexpressions: literals', function() {
|
it('tokenizes nested subexpressions: literals', function () {
|
||||||
var result = tokenize(
|
var result = tokenize(
|
||||||
'{{foo (bar (lol true) false) (baz 1) (blah \'b\') (blorg "c")}}'
|
'{{foo (bar (lol true) false) (baz 1) (blah \'b\') (blorg "c")}}'
|
||||||
);
|
);
|
||||||
@@ -714,11 +714,11 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'STRING',
|
'STRING',
|
||||||
'CLOSE_SEXPR',
|
'CLOSE_SEXPR',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes block params', function() {
|
it('tokenizes block params', function () {
|
||||||
var result = tokenize('{{#foo as |bar|}}');
|
var result = tokenize('{{#foo as |bar|}}');
|
||||||
shouldMatchTokens(result, [
|
shouldMatchTokens(result, [
|
||||||
'OPEN_BLOCK',
|
'OPEN_BLOCK',
|
||||||
@@ -726,7 +726,7 @@ describe('Tokenizer', function() {
|
|||||||
'OPEN_BLOCK_PARAMS',
|
'OPEN_BLOCK_PARAMS',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE_BLOCK_PARAMS',
|
'CLOSE_BLOCK_PARAMS',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
result = tokenize('{{#foo as |bar baz|}}');
|
result = tokenize('{{#foo as |bar baz|}}');
|
||||||
@@ -737,7 +737,7 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE_BLOCK_PARAMS',
|
'CLOSE_BLOCK_PARAMS',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
result = tokenize('{{#foo as | bar baz |}}');
|
result = tokenize('{{#foo as | bar baz |}}');
|
||||||
@@ -748,7 +748,7 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE_BLOCK_PARAMS',
|
'CLOSE_BLOCK_PARAMS',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
result = tokenize('{{#foo as as | bar baz |}}');
|
result = tokenize('{{#foo as as | bar baz |}}');
|
||||||
@@ -760,7 +760,7 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE_BLOCK_PARAMS',
|
'CLOSE_BLOCK_PARAMS',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
result = tokenize('{{else foo as |bar baz|}}');
|
result = tokenize('{{else foo as |bar baz|}}');
|
||||||
@@ -771,11 +771,11 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'ID',
|
'ID',
|
||||||
'CLOSE_BLOCK_PARAMS',
|
'CLOSE_BLOCK_PARAMS',
|
||||||
'CLOSE'
|
'CLOSE',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tokenizes raw blocks', function() {
|
it('tokenizes raw blocks', function () {
|
||||||
var result = tokenize(
|
var result = tokenize(
|
||||||
'{{{{a}}}} abc {{{{/a}}}} aaa {{{{a}}}} abc {{{{/a}}}}'
|
'{{{{a}}}} abc {{{{/a}}}} aaa {{{{a}}}} abc {{{{/a}}}}'
|
||||||
);
|
);
|
||||||
@@ -790,7 +790,7 @@ describe('Tokenizer', function() {
|
|||||||
'ID',
|
'ID',
|
||||||
'CLOSE_RAW_BLOCK',
|
'CLOSE_RAW_BLOCK',
|
||||||
'CONTENT',
|
'CONTENT',
|
||||||
'END_RAW_BLOCK'
|
'END_RAW_BLOCK',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+16
-16
@@ -1,6 +1,6 @@
|
|||||||
describe('utils', function() {
|
describe('utils', function () {
|
||||||
describe('#SafeString', function() {
|
describe('#SafeString', function () {
|
||||||
it('constructing a safestring from a string and checking its type', function() {
|
it('constructing a safestring from a string and checking its type', function () {
|
||||||
var safe = new Handlebars.SafeString('testing 1, 2, 3');
|
var safe = new Handlebars.SafeString('testing 1, 2, 3');
|
||||||
if (!(safe instanceof Handlebars.SafeString)) {
|
if (!(safe instanceof Handlebars.SafeString)) {
|
||||||
throw new Error('Must be instance of SafeString');
|
throw new Error('Must be instance of SafeString');
|
||||||
@@ -12,7 +12,7 @@ describe('utils', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it should not escape SafeString properties', function() {
|
it('it should not escape SafeString properties', function () {
|
||||||
var name = new Handlebars.SafeString('<em>Sean O'Malley</em>');
|
var name = new Handlebars.SafeString('<em>Sean O'Malley</em>');
|
||||||
|
|
||||||
expectTemplate('{{name}}')
|
expectTemplate('{{name}}')
|
||||||
@@ -21,26 +21,26 @@ describe('utils', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#escapeExpression', function() {
|
describe('#escapeExpression', function () {
|
||||||
it('should escape html', function() {
|
it('should escape html', function () {
|
||||||
equals(
|
equals(
|
||||||
Handlebars.Utils.escapeExpression('foo<&"\'>'),
|
Handlebars.Utils.escapeExpression('foo<&"\'>'),
|
||||||
'foo<&"'>'
|
'foo<&"'>'
|
||||||
);
|
);
|
||||||
equals(Handlebars.Utils.escapeExpression('foo='), 'foo=');
|
equals(Handlebars.Utils.escapeExpression('foo='), 'foo=');
|
||||||
});
|
});
|
||||||
it('should not escape SafeString', function() {
|
it('should not escape SafeString', function () {
|
||||||
var string = new Handlebars.SafeString('foo<&"\'>');
|
var string = new Handlebars.SafeString('foo<&"\'>');
|
||||||
equals(Handlebars.Utils.escapeExpression(string), 'foo<&"\'>');
|
equals(Handlebars.Utils.escapeExpression(string), 'foo<&"\'>');
|
||||||
|
|
||||||
var obj = {
|
var obj = {
|
||||||
toHTML: function() {
|
toHTML: function () {
|
||||||
return 'foo<&"\'>';
|
return 'foo<&"\'>';
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
equals(Handlebars.Utils.escapeExpression(obj), 'foo<&"\'>');
|
equals(Handlebars.Utils.escapeExpression(obj), 'foo<&"\'>');
|
||||||
});
|
});
|
||||||
it('should handle falsy', function() {
|
it('should handle falsy', function () {
|
||||||
equals(Handlebars.Utils.escapeExpression(''), '');
|
equals(Handlebars.Utils.escapeExpression(''), '');
|
||||||
equals(Handlebars.Utils.escapeExpression(undefined), '');
|
equals(Handlebars.Utils.escapeExpression(undefined), '');
|
||||||
equals(Handlebars.Utils.escapeExpression(null), '');
|
equals(Handlebars.Utils.escapeExpression(null), '');
|
||||||
@@ -48,14 +48,14 @@ describe('utils', function() {
|
|||||||
equals(Handlebars.Utils.escapeExpression(false), 'false');
|
equals(Handlebars.Utils.escapeExpression(false), 'false');
|
||||||
equals(Handlebars.Utils.escapeExpression(0), '0');
|
equals(Handlebars.Utils.escapeExpression(0), '0');
|
||||||
});
|
});
|
||||||
it('should handle empty objects', function() {
|
it('should handle empty objects', function () {
|
||||||
equals(Handlebars.Utils.escapeExpression({}), {}.toString());
|
equals(Handlebars.Utils.escapeExpression({}), {}.toString());
|
||||||
equals(Handlebars.Utils.escapeExpression([]), [].toString());
|
equals(Handlebars.Utils.escapeExpression([]), [].toString());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#isEmpty', function() {
|
describe('#isEmpty', function () {
|
||||||
it('should not be empty', function() {
|
it('should not be empty', function () {
|
||||||
equals(Handlebars.Utils.isEmpty(undefined), true);
|
equals(Handlebars.Utils.isEmpty(undefined), true);
|
||||||
equals(Handlebars.Utils.isEmpty(null), true);
|
equals(Handlebars.Utils.isEmpty(null), true);
|
||||||
equals(Handlebars.Utils.isEmpty(false), true);
|
equals(Handlebars.Utils.isEmpty(false), true);
|
||||||
@@ -63,7 +63,7 @@ describe('utils', function() {
|
|||||||
equals(Handlebars.Utils.isEmpty([]), true);
|
equals(Handlebars.Utils.isEmpty([]), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be empty', function() {
|
it('should be empty', function () {
|
||||||
equals(Handlebars.Utils.isEmpty(0), false);
|
equals(Handlebars.Utils.isEmpty(0), false);
|
||||||
equals(Handlebars.Utils.isEmpty([1]), false);
|
equals(Handlebars.Utils.isEmpty([1]), false);
|
||||||
equals(Handlebars.Utils.isEmpty('foo'), false);
|
equals(Handlebars.Utils.isEmpty('foo'), false);
|
||||||
@@ -71,8 +71,8 @@ describe('utils', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#extend', function() {
|
describe('#extend', function () {
|
||||||
it('should ignore prototype values', function() {
|
it('should ignore prototype values', function () {
|
||||||
function A() {
|
function A() {
|
||||||
this.a = 1;
|
this.a = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-23
@@ -1,32 +1,22 @@
|
|||||||
describe('whitespace control', function() {
|
describe('whitespace control', function () {
|
||||||
it('should strip whitespace around mustache calls', function() {
|
it('should strip whitespace around mustache calls', function () {
|
||||||
var hash = { foo: 'bar<' };
|
var hash = { foo: 'bar<' };
|
||||||
|
|
||||||
expectTemplate(' {{~foo~}} ')
|
expectTemplate(' {{~foo~}} ').withInput(hash).toCompileTo('bar<');
|
||||||
.withInput(hash)
|
|
||||||
.toCompileTo('bar<');
|
|
||||||
|
|
||||||
expectTemplate(' {{~foo}} ')
|
expectTemplate(' {{~foo}} ').withInput(hash).toCompileTo('bar< ');
|
||||||
.withInput(hash)
|
|
||||||
.toCompileTo('bar< ');
|
|
||||||
|
|
||||||
expectTemplate(' {{foo~}} ')
|
expectTemplate(' {{foo~}} ').withInput(hash).toCompileTo(' bar<');
|
||||||
.withInput(hash)
|
|
||||||
.toCompileTo(' bar<');
|
|
||||||
|
|
||||||
expectTemplate(' {{~&foo~}} ')
|
expectTemplate(' {{~&foo~}} ').withInput(hash).toCompileTo('bar<');
|
||||||
.withInput(hash)
|
|
||||||
.toCompileTo('bar<');
|
|
||||||
|
|
||||||
expectTemplate(' {{~{foo}~}} ')
|
expectTemplate(' {{~{foo}~}} ').withInput(hash).toCompileTo('bar<');
|
||||||
.withInput(hash)
|
|
||||||
.toCompileTo('bar<');
|
|
||||||
|
|
||||||
expectTemplate('1\n{{foo~}} \n\n 23\n{{bar}}4').toCompileTo('1\n23\n4');
|
expectTemplate('1\n{{foo~}} \n\n 23\n{{bar}}4').toCompileTo('1\n23\n4');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('blocks', function() {
|
describe('blocks', function () {
|
||||||
it('should strip whitespace around simple block calls', function() {
|
it('should strip whitespace around simple block calls', function () {
|
||||||
var hash = { foo: 'bar<' };
|
var hash = { foo: 'bar<' };
|
||||||
|
|
||||||
expectTemplate(' {{~#if foo~}} bar {{~/if~}} ')
|
expectTemplate(' {{~#if foo~}} bar {{~/if~}} ')
|
||||||
@@ -54,7 +44,7 @@ describe('whitespace control', function() {
|
|||||||
.toCompileTo(' abara ');
|
.toCompileTo(' abara ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should strip whitespace around inverse block calls', function() {
|
it('should strip whitespace around inverse block calls', function () {
|
||||||
expectTemplate(' {{~^if foo~}} bar {{~/if~}} ').toCompileTo('bar');
|
expectTemplate(' {{~^if foo~}} bar {{~/if~}} ').toCompileTo('bar');
|
||||||
|
|
||||||
expectTemplate(' {{^if foo~}} bar {{/if~}} ').toCompileTo(' bar ');
|
expectTemplate(' {{^if foo~}} bar {{/if~}} ').toCompileTo(' bar ');
|
||||||
@@ -68,7 +58,7 @@ describe('whitespace control', function() {
|
|||||||
).toCompileTo('bar');
|
).toCompileTo('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should strip whitespace around complex block calls', function() {
|
it('should strip whitespace around complex block calls', function () {
|
||||||
var hash = { foo: 'bar<' };
|
var hash = { foo: 'bar<' };
|
||||||
|
|
||||||
expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}')
|
expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}')
|
||||||
@@ -127,7 +117,7 @@ describe('whitespace control', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should strip whitespace around partials', function() {
|
it('should strip whitespace around partials', function () {
|
||||||
expectTemplate('foo {{~> dude~}} ')
|
expectTemplate('foo {{~> dude~}} ')
|
||||||
.withPartials({ dude: 'bar' })
|
.withPartials({ dude: 'bar' })
|
||||||
.toCompileTo('foobar');
|
.toCompileTo('foobar');
|
||||||
@@ -149,7 +139,7 @@ describe('whitespace control', function() {
|
|||||||
.toCompileTo('foo\n bar');
|
.toCompileTo('foo\n bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should only strip whitespace once', function() {
|
it('should only strip whitespace once', function () {
|
||||||
expectTemplate(' {{~foo~}} {{foo}} {{foo}} ')
|
expectTemplate(' {{~foo~}} {{foo}} {{foo}} ')
|
||||||
.withInput({ foo: 'bar' })
|
.withInput({ foo: 'bar' })
|
||||||
.toCompileTo('barbar bar ');
|
.toCompileTo('barbar bar ');
|
||||||
|
|||||||
+2
-2
@@ -3,6 +3,6 @@ module.exports = {
|
|||||||
'no-process-env': 'off',
|
'no-process-env': 'off',
|
||||||
'prefer-const': 'warn',
|
'prefer-const': 'warn',
|
||||||
'compat/compat': 'off',
|
'compat/compat': 'off',
|
||||||
'dot-notation': ['error', { allowKeywords: true }]
|
'dot-notation': ['error', { allowKeywords: true }],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
+5
-5
@@ -1,14 +1,14 @@
|
|||||||
const metrics = require('../tests/bench');
|
const metrics = require('../tests/bench');
|
||||||
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
module.exports = function (grunt) {
|
||||||
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
||||||
|
|
||||||
registerAsyncTask('metrics', function() {
|
registerAsyncTask('metrics', function () {
|
||||||
const onlyExecuteName = grunt.option('name');
|
const onlyExecuteName = grunt.option('name');
|
||||||
const events = {};
|
const events = {};
|
||||||
|
|
||||||
const promises = Object.keys(metrics).map(async name => {
|
const promises = Object.keys(metrics).map(async (name) => {
|
||||||
if (/^_/.test(name)) {
|
if (/^_/.test(name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -16,8 +16,8 @@ module.exports = function(grunt) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise((resolve) => {
|
||||||
metrics[name](grunt, function(data) {
|
metrics[name](grunt, function (data) {
|
||||||
events[name] = data;
|
events[name] = data;
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ const git = require('./util/git');
|
|||||||
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
||||||
const semver = require('semver');
|
const semver = require('semver');
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
module.exports = function (grunt) {
|
||||||
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
||||||
|
|
||||||
registerAsyncTask('publish-to-aws', async () => {
|
registerAsyncTask('publish-to-aws', async () => {
|
||||||
@@ -48,7 +48,7 @@ module.exports = function(grunt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function publish(suffixes) {
|
async function publish(suffixes) {
|
||||||
const publishPromises = suffixes.map(suffix => publishSuffix(suffix));
|
const publishPromises = suffixes.map((suffix) => publishSuffix(suffix));
|
||||||
return Promise.all(publishPromises);
|
return Promise.all(publishPromises);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,9 +57,9 @@ module.exports = function(grunt) {
|
|||||||
'handlebars.js',
|
'handlebars.js',
|
||||||
'handlebars.min.js',
|
'handlebars.min.js',
|
||||||
'handlebars.runtime.js',
|
'handlebars.runtime.js',
|
||||||
'handlebars.runtime.min.js'
|
'handlebars.runtime.min.js',
|
||||||
];
|
];
|
||||||
const publishPromises = filenames.map(async filename => {
|
const publishPromises = filenames.map(async (filename) => {
|
||||||
const nameInBucket = getNameInBucket(filename, suffix);
|
const nameInBucket = getNameInBucket(filename, suffix);
|
||||||
const localFile = getLocalFile(filename);
|
const localFile = getLocalFile(filename);
|
||||||
await uploadToBucket(localFile, nameInBucket);
|
await uploadToBucket(localFile, nameInBucket);
|
||||||
@@ -75,7 +75,7 @@ module.exports = function(grunt) {
|
|||||||
const uploadParams = {
|
const uploadParams = {
|
||||||
Bucket: bucket,
|
Bucket: bucket,
|
||||||
Key: nameInBucket,
|
Key: nameInBucket,
|
||||||
Body: grunt.file.read(localFile)
|
Body: grunt.file.read(localFile),
|
||||||
};
|
};
|
||||||
return s3PutObject(uploadParams);
|
return s3PutObject(uploadParams);
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ module.exports = function(grunt) {
|
|||||||
function s3PutObject(uploadParams) {
|
function s3PutObject(uploadParams) {
|
||||||
const s3 = new AWS.S3();
|
const s3 = new AWS.S3();
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
s3.putObject(uploadParams, err => {
|
s3.putObject(uploadParams, (err) => {
|
||||||
if (err != null) {
|
if (err != null) {
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-36
@@ -11,47 +11,47 @@ const testCases = [
|
|||||||
{
|
{
|
||||||
binInputParameters: ['-a', 'spec/artifacts/empty.handlebars'],
|
binInputParameters: ['-a', 'spec/artifacts/empty.handlebars'],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/empty.amd.js'
|
expectedOutputSpec: './spec/expected/empty.amd.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
'-a',
|
'-a',
|
||||||
'-f',
|
'-f',
|
||||||
'TEST_OUTPUT',
|
'TEST_OUTPUT',
|
||||||
'spec/artifacts/empty.handlebars'
|
'spec/artifacts/empty.handlebars',
|
||||||
],
|
],
|
||||||
outputLocation: 'TEST_OUTPUT',
|
outputLocation: 'TEST_OUTPUT',
|
||||||
expectedOutputSpec: './spec/expected/empty.amd.js'
|
expectedOutputSpec: './spec/expected/empty.amd.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
'-a',
|
'-a',
|
||||||
'-n',
|
'-n',
|
||||||
'CustomNamespace.templates',
|
'CustomNamespace.templates',
|
||||||
'spec/artifacts/empty.handlebars'
|
'spec/artifacts/empty.handlebars',
|
||||||
],
|
],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/empty.amd.namespace.js'
|
expectedOutputSpec: './spec/expected/empty.amd.namespace.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
'-a',
|
'-a',
|
||||||
'--namespace',
|
'--namespace',
|
||||||
'CustomNamespace.templates',
|
'CustomNamespace.templates',
|
||||||
'spec/artifacts/empty.handlebars'
|
'spec/artifacts/empty.handlebars',
|
||||||
],
|
],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/empty.amd.namespace.js'
|
expectedOutputSpec: './spec/expected/empty.amd.namespace.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: ['-a', '-s', 'spec/artifacts/empty.handlebars'],
|
binInputParameters: ['-a', '-s', 'spec/artifacts/empty.handlebars'],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/empty.amd.simple.js'
|
expectedOutputSpec: './spec/expected/empty.amd.simple.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: ['-a', '-m', 'spec/artifacts/empty.handlebars'],
|
binInputParameters: ['-a', '-m', 'spec/artifacts/empty.handlebars'],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/empty.amd.min.js'
|
expectedOutputSpec: './spec/expected/empty.amd.min.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
@@ -61,44 +61,44 @@ const testCases = [
|
|||||||
'someHelper',
|
'someHelper',
|
||||||
'-k',
|
'-k',
|
||||||
'anotherHelper',
|
'anotherHelper',
|
||||||
'-o'
|
'-o',
|
||||||
],
|
],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/non.empty.amd.known.helper.js'
|
expectedOutputSpec: './spec/expected/non.empty.amd.known.helper.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: ['--help'],
|
binInputParameters: ['--help'],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/help.menu.txt'
|
expectedOutputSpec: './spec/expected/help.menu.txt',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: ['-v'],
|
binInputParameters: ['-v'],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutput: require('../package.json').version
|
expectedOutput: require('../package.json').version,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
'-a',
|
'-a',
|
||||||
'-e',
|
'-e',
|
||||||
'hbs',
|
'hbs',
|
||||||
'./spec/artifacts/non.default.extension.hbs'
|
'./spec/artifacts/non.default.extension.hbs',
|
||||||
],
|
],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/non.default.extension.amd.js'
|
expectedOutputSpec: './spec/expected/non.default.extension.amd.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
'-a',
|
'-a',
|
||||||
'-p',
|
'-p',
|
||||||
'./spec/artifacts/partial.template.handlebars'
|
'./spec/artifacts/partial.template.handlebars',
|
||||||
],
|
],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/partial.template.js'
|
expectedOutputSpec: './spec/expected/partial.template.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: ['spec/artifacts/empty.handlebars', '-c'],
|
binInputParameters: ['spec/artifacts/empty.handlebars', '-c'],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/empty.common.js'
|
expectedOutputSpec: './spec/expected/empty.common.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
@@ -106,30 +106,30 @@ const testCases = [
|
|||||||
'spec/artifacts/empty.handlebars',
|
'spec/artifacts/empty.handlebars',
|
||||||
'-a',
|
'-a',
|
||||||
'-n',
|
'-n',
|
||||||
'someNameSpace'
|
'someNameSpace',
|
||||||
],
|
],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/namespace.amd.js'
|
expectedOutputSpec: './spec/expected/namespace.amd.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
'spec/artifacts/empty.handlebars',
|
'spec/artifacts/empty.handlebars',
|
||||||
'-h',
|
'-h',
|
||||||
'some-path/',
|
'some-path/',
|
||||||
'-a'
|
'-a',
|
||||||
],
|
],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/handlebar.path.amd.js'
|
expectedOutputSpec: './spec/expected/handlebar.path.amd.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
'spec/artifacts/partial.template.handlebars',
|
'spec/artifacts/partial.template.handlebars',
|
||||||
'-r',
|
'-r',
|
||||||
'spec',
|
'spec',
|
||||||
'-a'
|
'-a',
|
||||||
],
|
],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/empty.root.amd.js'
|
expectedOutputSpec: './spec/expected/empty.root.amd.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
@@ -141,10 +141,10 @@ const testCases = [
|
|||||||
'firstTemplate',
|
'firstTemplate',
|
||||||
'-N',
|
'-N',
|
||||||
'secondTemplate',
|
'secondTemplate',
|
||||||
'-a'
|
'-a',
|
||||||
],
|
],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/empty.name.amd.js'
|
expectedOutputSpec: './spec/expected/empty.name.amd.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
@@ -155,36 +155,36 @@ const testCases = [
|
|||||||
'-N',
|
'-N',
|
||||||
'test',
|
'test',
|
||||||
'--map',
|
'--map',
|
||||||
'./spec/tmp/source.map.amd.txt'
|
'./spec/tmp/source.map.amd.txt',
|
||||||
],
|
],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/source.map.amd.js'
|
expectedOutputSpec: './spec/expected/source.map.amd.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: ['./spec/artifacts/bom.handlebars', '-b', '-a'],
|
binInputParameters: ['./spec/artifacts/bom.handlebars', '-b', '-a'],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/bom.amd.js'
|
expectedOutputSpec: './spec/expected/bom.amd.js',
|
||||||
},
|
},
|
||||||
// Issue #1673
|
// Issue #1673
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
'--amd',
|
'--amd',
|
||||||
'--no-amd',
|
'--no-amd',
|
||||||
'spec/artifacts/empty.handlebars'
|
'spec/artifacts/empty.handlebars',
|
||||||
],
|
],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutputSpec: './spec/expected/empty.common.js'
|
expectedOutputSpec: './spec/expected/empty.common.js',
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
module.exports = function (grunt) {
|
||||||
grunt.registerTask('test:bin', function() {
|
grunt.registerTask('test:bin', function () {
|
||||||
testCases.forEach(
|
testCases.forEach(
|
||||||
({
|
({
|
||||||
binInputParameters,
|
binInputParameters,
|
||||||
outputLocation,
|
outputLocation,
|
||||||
expectedOutputSpec,
|
expectedOutputSpec,
|
||||||
expectedOutput
|
expectedOutput,
|
||||||
}) => {
|
}) => {
|
||||||
const stdout = executeBinHandlebars(...binInputParameters);
|
const stdout = executeBinHandlebars(...binInputParameters);
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ module.exports = function(grunt) {
|
|||||||
expect(normalizedOutput).not.to.be.differentFrom(
|
expect(normalizedOutput).not.to.be.differentFrom(
|
||||||
normalizedExpectedOutput,
|
normalizedExpectedOutput,
|
||||||
{
|
{
|
||||||
relaxedSpace: true
|
relaxedSpace: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ const { execNodeJsScriptWithInheritedOutput } = require('./util/exec-file');
|
|||||||
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
||||||
const nodeJs = process.argv0;
|
const nodeJs = process.argv0;
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
module.exports = function (grunt) {
|
||||||
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
||||||
|
|
||||||
registerAsyncTask('test:mocha', async () =>
|
registerAsyncTask('test:mocha', async () =>
|
||||||
@@ -12,7 +12,7 @@ module.exports = function(grunt) {
|
|||||||
registerAsyncTask('test:cov', async () =>
|
registerAsyncTask('test:cov', async () =>
|
||||||
execNodeJsScriptWithInheritedOutput('node_modules/nyc/bin/nyc', [
|
execNodeJsScriptWithInheritedOutput('node_modules/nyc/bin/nyc', [
|
||||||
nodeJs,
|
nodeJs,
|
||||||
'./spec/env/runner.js'
|
'./spec/env/runner.js',
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
env: {
|
env: {
|
||||||
mocha: true
|
mocha: true,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
+17
-17
@@ -14,8 +14,8 @@ const remoteDir = path.join(tmpDir, 'remote-repo');
|
|||||||
const cloneDir = path.join(tmpDir, 'clone-repo');
|
const cloneDir = path.join(tmpDir, 'clone-repo');
|
||||||
const oldCwd = process.cwd();
|
const oldCwd = process.cwd();
|
||||||
|
|
||||||
describe('utils/git', function() {
|
describe('utils/git', function () {
|
||||||
beforeEach(async function() {
|
beforeEach(async function () {
|
||||||
await fs.remove(tmpDir);
|
await fs.remove(tmpDir);
|
||||||
await createRepositoryThatActsAsRemote();
|
await createRepositoryThatActsAsRemote();
|
||||||
process.chdir(tmpDir);
|
process.chdir(tmpDir);
|
||||||
@@ -33,12 +33,12 @@ describe('utils/git', function() {
|
|||||||
await git.commit('commit message');
|
await git.commit('commit message');
|
||||||
}
|
}
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
process.chdir(oldCwd);
|
process.chdir(oldCwd);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('the "remotes"-function', function() {
|
describe('the "remotes"-function', function () {
|
||||||
it('should list all remotes', async function() {
|
it('should list all remotes', async function () {
|
||||||
await git.git('remote', 'set-url', 'origin', 'https://test.org/test');
|
await git.git('remote', 'set-url', 'origin', 'https://test.org/test');
|
||||||
await git.git('remote', 'add', 'second-remote', 'https://test.org/test2');
|
await git.git('remote', 'add', 'second-remote', 'https://test.org/test2');
|
||||||
|
|
||||||
@@ -48,13 +48,13 @@ describe('utils/git', function() {
|
|||||||
'origin\thttps://test.org/test (fetch)',
|
'origin\thttps://test.org/test (fetch)',
|
||||||
'origin\thttps://test.org/test (push)',
|
'origin\thttps://test.org/test (push)',
|
||||||
'second-remote\thttps://test.org/test2 (fetch)',
|
'second-remote\thttps://test.org/test2 (fetch)',
|
||||||
'second-remote\thttps://test.org/test2 (push)'
|
'second-remote\thttps://test.org/test2 (push)',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('the "branches"-function', function() {
|
describe('the "branches"-function', function () {
|
||||||
it('should list all branches', async function() {
|
it('should list all branches', async function () {
|
||||||
await git.git('branch', 'test');
|
await git.git('branch', 'test');
|
||||||
await git.git('branch', 'test2');
|
await git.git('branch', 'test2');
|
||||||
|
|
||||||
@@ -64,32 +64,32 @@ describe('utils/git', function() {
|
|||||||
' test',
|
' test',
|
||||||
' test2',
|
' test2',
|
||||||
' remotes/origin/HEAD -> origin/master',
|
' remotes/origin/HEAD -> origin/master',
|
||||||
' remotes/origin/master'
|
' remotes/origin/master',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('the "commitInfo"-function', function() {
|
describe('the "commitInfo"-function', function () {
|
||||||
it('should list head and master sha', async function() {
|
it('should list head and master sha', async function () {
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.masterSha).to.equal(result.headSha);
|
expect(result.masterSha).to.equal(result.headSha);
|
||||||
expect(result.masterSha).to.match(/^[0-9a-f]+$/);
|
expect(result.masterSha).to.match(/^[0-9a-f]+$/);
|
||||||
expect(result.headSha).to.match(/^[0-9a-f]+$/);
|
expect(result.headSha).to.match(/^[0-9a-f]+$/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have "isMaster=true" if the master branch is checked out', async function() {
|
it('should have "isMaster=true" if the master branch is checked out', async function () {
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.isMaster).to.be.true();
|
expect(result.isMaster).to.be.true();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have "isMaster=true" if the current commit is the last commit of the master branch', async function() {
|
it('should have "isMaster=true" if the current commit is the last commit of the master branch', async function () {
|
||||||
await git.git('checkout', '-b', 'new-branch');
|
await git.git('checkout', '-b', 'new-branch');
|
||||||
|
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.isMaster).to.be.true();
|
expect(result.isMaster).to.be.true();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have "isMaster=false" if the current commit is NOT the last commit of the master branch', async function() {
|
it('should have "isMaster=false" if the current commit is NOT the last commit of the master branch', async function () {
|
||||||
await git.git('checkout', '-b', 'new-branch');
|
await git.git('checkout', '-b', 'new-branch');
|
||||||
fs.writeFile('new-file.txt', 'new-file');
|
fs.writeFile('new-file.txt', 'new-file');
|
||||||
await git.add('new-file.txt');
|
await git.add('new-file.txt');
|
||||||
@@ -99,13 +99,13 @@ describe('utils/git', function() {
|
|||||||
expect(result.isMaster).to.be.false();
|
expect(result.isMaster).to.be.false();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show the current tag', async function() {
|
it('should show the current tag', async function () {
|
||||||
await git.git('tag', 'test-tag');
|
await git.git('tag', 'test-tag');
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.tagName).to.be.equal('test-tag');
|
expect(result.tagName).to.be.equal('test-tag');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show a version tag rather than standard tags', async function() {
|
it('should show a version tag rather than standard tags', async function () {
|
||||||
await git.git('tag', 'test-tag');
|
await git.git('tag', 'test-tag');
|
||||||
await git.git('tag', 'v1.2');
|
await git.git('tag', 'v1.2');
|
||||||
await git.git('tag', 'test-tag2');
|
await git.git('tag', 'test-tag2');
|
||||||
@@ -113,7 +113,7 @@ describe('utils/git', function() {
|
|||||||
expect(result.tagName).to.be.equal('v1.2');
|
expect(result.tagName).to.be.equal('v1.2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show no tag if there is no tag', async function() {
|
it('should show no tag if there is no tag', async function () {
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.tagName).to.be.null();
|
expect(result.tagName).to.be.null();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ module.exports = { createRegisterAsyncTaskFn };
|
|||||||
|
|
||||||
function createRegisterAsyncTaskFn(grunt) {
|
function createRegisterAsyncTaskFn(grunt) {
|
||||||
return function registerAsyncTask(name, asyncFunction) {
|
return function registerAsyncTask(name, asyncFunction) {
|
||||||
grunt.registerTask(name, function() {
|
grunt.registerTask(name, function () {
|
||||||
asyncFunction()
|
asyncFunction()
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
grunt.fatal(error);
|
grunt.fatal(error);
|
||||||
})
|
})
|
||||||
.finally(this.async());
|
.finally(this.async());
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
const childProcess = require('child_process');
|
const childProcess = require('child_process');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
execNodeJsScriptWithInheritedOutput
|
execNodeJsScriptWithInheritedOutput,
|
||||||
};
|
};
|
||||||
|
|
||||||
async function execNodeJsScriptWithInheritedOutput(command, args) {
|
async function execNodeJsScriptWithInheritedOutput(command, args) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const child = childProcess.fork(command, args, { stdio: 'inherit' });
|
const child = childProcess.fork(command, args, { stdio: 'inherit' });
|
||||||
child.on('close', code => {
|
child.on('close', (code) => {
|
||||||
if (code !== 0) {
|
if (code !== 0) {
|
||||||
reject(new Error(`Child process failed with exit-code ${code}`));
|
reject(new Error(`Child process failed with exit-code ${code}`));
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -14,7 +14,7 @@ module.exports = {
|
|||||||
headSha,
|
headSha,
|
||||||
masterSha,
|
masterSha,
|
||||||
tagName: await getTagName(),
|
tagName: await getTagName(),
|
||||||
isMaster: headSha === masterSha
|
isMaster: headSha === masterSha,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async add(path) {
|
async add(path) {
|
||||||
@@ -23,7 +23,7 @@ module.exports = {
|
|||||||
async commit(message) {
|
async commit(message) {
|
||||||
return git('commit', '--message', message);
|
return git('commit', '--message', message);
|
||||||
},
|
},
|
||||||
git // visible for testing
|
git, // visible for testing
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getHeadSha() {
|
async function getHeadSha() {
|
||||||
@@ -52,7 +52,7 @@ async function getTagName() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const tags = trimmedStdout.split(/\n|\r\n/);
|
const tags = trimmedStdout.split(/\n|\r\n/);
|
||||||
const versionTags = tags.filter(tag => /^v/.test(tag));
|
const versionTags = tags.filter((tag) => /^v/.test(tag));
|
||||||
if (versionTags[0] != null) {
|
if (versionTags[0] != null) {
|
||||||
return versionTags[0];
|
return versionTags[0];
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -2,7 +2,7 @@ const git = require('./util/git');
|
|||||||
const semver = require('semver');
|
const semver = require('semver');
|
||||||
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
module.exports = function (grunt) {
|
||||||
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
||||||
|
|
||||||
registerAsyncTask('version', async () => {
|
registerAsyncTask('version', async () => {
|
||||||
@@ -22,27 +22,27 @@ module.exports = function(grunt) {
|
|||||||
{
|
{
|
||||||
path: 'lib/handlebars/base.js',
|
path: 'lib/handlebars/base.js',
|
||||||
regex: /const VERSION = ['"](.*)['"];/,
|
regex: /const VERSION = ['"](.*)['"];/,
|
||||||
replacement: `const VERSION = '${version}';`
|
replacement: `const VERSION = '${version}';`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'components/bower.json',
|
path: 'components/bower.json',
|
||||||
regex: /"version":.*/,
|
regex: /"version":.*/,
|
||||||
replacement: `"version": "${version}",`
|
replacement: `"version": "${version}",`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'components/package.json',
|
path: 'components/package.json',
|
||||||
regex: /"version":.*/,
|
regex: /"version":.*/,
|
||||||
replacement: `"version": "${version}",`
|
replacement: `"version": "${version}",`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'components/handlebars.js.nuspec',
|
path: 'components/handlebars.js.nuspec',
|
||||||
regex: /<version>.*<\/version>/,
|
regex: /<version>.*<\/version>/,
|
||||||
replacement: `<version>${version}</version>`
|
replacement: `<version>${version}</version>`,
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
replaceSpec.map(replaceSpec =>
|
replaceSpec.map((replaceSpec) =>
|
||||||
replaceAndAdd(
|
replaceAndAdd(
|
||||||
replaceSpec.path,
|
replaceSpec.path,
|
||||||
replaceSpec.regex,
|
replaceSpec.regex,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
rules: {
|
rules: {
|
||||||
'no-console': 'off',
|
'no-console': 'off',
|
||||||
'no-var': 'off'
|
'no-var': 'off',
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ var async = require('neo-async'),
|
|||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
zlib = require('zlib');
|
zlib = require('zlib');
|
||||||
|
|
||||||
module.exports = function(grunt, callback) {
|
module.exports = function (grunt, callback) {
|
||||||
var distFiles = fs.readdirSync('dist'),
|
var distFiles = fs.readdirSync('dist'),
|
||||||
distSizes = {};
|
distSizes = {};
|
||||||
|
|
||||||
async.each(
|
async.each(
|
||||||
distFiles,
|
distFiles,
|
||||||
function(file, callback) {
|
function (file, callback) {
|
||||||
var content;
|
var content;
|
||||||
try {
|
try {
|
||||||
content = fs.readFileSync('dist/' + file);
|
content = fs.readFileSync('dist/' + file);
|
||||||
@@ -24,7 +24,7 @@ module.exports = function(grunt, callback) {
|
|||||||
file = file.replace(/\.js/, '').replace(/\./g, '_');
|
file = file.replace(/\.js/, '').replace(/\./g, '_');
|
||||||
distSizes[file] = content.length;
|
distSizes[file] = content.length;
|
||||||
|
|
||||||
zlib.gzip(content, function(err, data) {
|
zlib.gzip(content, function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ module.exports = function(grunt, callback) {
|
|||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function() {
|
function () {
|
||||||
grunt.log.writeln(
|
grunt.log.writeln(
|
||||||
'Distribution sizes: ' + JSON.stringify(distSizes, undefined, 2)
|
'Distribution sizes: ' + JSON.stringify(distSizes, undefined, 2)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
var metrics = fs.readdirSync(__dirname);
|
var metrics = fs.readdirSync(__dirname);
|
||||||
metrics.forEach(function(metric) {
|
metrics.forEach(function (metric) {
|
||||||
if (metric === 'index.js' || !/(.*)\.js$/.test(metric)) {
|
if (metric === 'index.js' || !/(.*)\.js$/.test(metric)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
var _ = require('underscore'),
|
var _ = require('underscore'),
|
||||||
templates = require('./templates');
|
templates = require('./templates');
|
||||||
|
|
||||||
module.exports = function(grunt, callback) {
|
module.exports = function (grunt, callback) {
|
||||||
// Deferring to here in case we have a build for parser, etc as part of this grunt exec
|
// Deferring to here in case we have a build for parser, etc as part of this grunt exec
|
||||||
var Handlebars = require('../../lib');
|
var Handlebars = require('../../lib');
|
||||||
|
|
||||||
var templateSizes = {};
|
var templateSizes = {};
|
||||||
_.each(templates, function(info, template) {
|
_.each(templates, function (info, template) {
|
||||||
var src = info.handlebars,
|
var src = info.handlebars,
|
||||||
compiled = Handlebars.precompile(src, {}),
|
compiled = Handlebars.precompile(src, {}),
|
||||||
knownHelpers = Handlebars.precompile(src, {
|
knownHelpers = Handlebars.precompile(src, {
|
||||||
knownHelpersOnly: true,
|
knownHelpersOnly: true,
|
||||||
knownHelpers: info.helpers
|
knownHelpers: info.helpers,
|
||||||
});
|
});
|
||||||
|
|
||||||
templateSizes[template] = compiled.length;
|
templateSizes[template] = compiled.length;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
helpers: {
|
helpers: {
|
||||||
foo: function() {
|
foo: function () {
|
||||||
return '';
|
return '';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
context: {
|
context: {
|
||||||
bar: true
|
bar: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
handlebars:
|
handlebars:
|
||||||
'{{foo person "person" 1 true foo=bar foo="person" foo=1 foo=true}}'
|
'{{foo person "person" 1 true foo=bar foo="person" foo=1 foo=true}}',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ module.exports = {
|
|||||||
{ name: 'Moe' },
|
{ name: 'Moe' },
|
||||||
{ name: 'Larry' },
|
{ name: 'Larry' },
|
||||||
{ name: 'Curly' },
|
{ name: 'Curly' },
|
||||||
{ name: 'Shemp' }
|
{ name: 'Shemp' },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
handlebars: '{{#each names}}{{name}}{{/each}}',
|
handlebars: '{{#each names}}{{name}}{{/each}}',
|
||||||
dust: '{#names}{name}{/names}',
|
dust: '{#names}{name}{/names}',
|
||||||
mustache: '{{#names}}{{name}}{{/names}}'
|
mustache: '{{#names}}{{name}}{{/names}}',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ module.exports = {
|
|||||||
{ name: 'Moe' },
|
{ name: 'Moe' },
|
||||||
{ name: 'Larry' },
|
{ name: 'Larry' },
|
||||||
{ name: 'Curly' },
|
{ name: 'Curly' },
|
||||||
{ name: 'Shemp' }
|
{ name: 'Shemp' },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
handlebars: '{{#names}}{{name}}{{/names}}'
|
handlebars: '{{#names}}{{name}}{{/names}}',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,18 +2,18 @@ var fs = require('fs');
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
context: {
|
context: {
|
||||||
header: function() {
|
header: function () {
|
||||||
return 'Colors';
|
return 'Colors';
|
||||||
},
|
},
|
||||||
hasItems: true, // To make things fairer in mustache land due to no `{{if}}` construct on arrays
|
hasItems: true, // To make things fairer in mustache land due to no `{{if}}` construct on arrays
|
||||||
items: [
|
items: [
|
||||||
{ name: 'red', current: true, url: '#Red' },
|
{ name: 'red', current: true, url: '#Red' },
|
||||||
{ name: 'green', current: false, url: '#Green' },
|
{ name: 'green', current: false, url: '#Green' },
|
||||||
{ name: 'blue', current: false, url: '#Blue' }
|
{ name: 'blue', current: false, url: '#Blue' },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
handlebars: fs.readFileSync(__dirname + '/complex.handlebars').toString(),
|
handlebars: fs.readFileSync(__dirname + '/complex.handlebars').toString(),
|
||||||
dust: fs.readFileSync(__dirname + '/complex.dust').toString(),
|
dust: fs.readFileSync(__dirname + '/complex.dust').toString(),
|
||||||
mustache: fs.readFileSync(__dirname + '/complex.mustache').toString()
|
mustache: fs.readFileSync(__dirname + '/complex.mustache').toString(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ module.exports = {
|
|||||||
{ name: 'Moe' },
|
{ name: 'Moe' },
|
||||||
{ name: 'Larry' },
|
{ name: 'Larry' },
|
||||||
{ name: 'Curly' },
|
{ name: 'Curly' },
|
||||||
{ name: 'Shemp' }
|
{ name: 'Shemp' },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
handlebars: '{{#each names}}{{@index}}{{name}}{{/each}}'
|
handlebars: '{{#each names}}{{@index}}{{name}}{{/each}}',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ module.exports = {
|
|||||||
{ name: 'Moe' },
|
{ name: 'Moe' },
|
||||||
{ name: 'Larry' },
|
{ name: 'Larry' },
|
||||||
{ name: 'Curly' },
|
{ name: 'Curly' },
|
||||||
{ name: 'Shemp' }
|
{ name: 'Shemp' },
|
||||||
],
|
],
|
||||||
foo: 'bar'
|
foo: 'bar',
|
||||||
},
|
},
|
||||||
handlebars: '{{#each names}}{{../foo}}{{/each}}',
|
handlebars: '{{#each names}}{{../foo}}{{/each}}',
|
||||||
mustache: '{{#names}}{{foo}}{{/names}}'
|
mustache: '{{#names}}{{foo}}{{/names}}',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ module.exports = {
|
|||||||
{ bat: 'foo', name: ['Moe'] },
|
{ bat: 'foo', name: ['Moe'] },
|
||||||
{ bat: 'foo', name: ['Larry'] },
|
{ bat: 'foo', name: ['Larry'] },
|
||||||
{ bat: 'foo', name: ['Curly'] },
|
{ bat: 'foo', name: ['Curly'] },
|
||||||
{ bat: 'foo', name: ['Shemp'] }
|
{ bat: 'foo', name: ['Shemp'] },
|
||||||
],
|
],
|
||||||
foo: 'bar'
|
foo: 'bar',
|
||||||
},
|
},
|
||||||
handlebars:
|
handlebars:
|
||||||
'{{#each names}}{{#each name}}{{../bat}}{{../../foo}}{{/each}}{{/each}}',
|
'{{#each names}}{{#each name}}{{../bat}}{{../../foo}}{{/each}}{{/each}}',
|
||||||
mustache: '{{#names}}{{#name}}{{bat}}{{foo}}{{/name}}{{/names}}'
|
mustache: '{{#names}}{{#name}}{{bat}}{{foo}}{{/name}}{{/names}}',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
var templates = fs.readdirSync(__dirname);
|
var templates = fs.readdirSync(__dirname);
|
||||||
templates.forEach(function(template) {
|
templates.forEach(function (template) {
|
||||||
if (template === 'index.js' || !/(.*)\.js$/.test(template)) {
|
if (template === 'index.js' || !/(.*)\.js$/.test(template)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
context: { person: { name: 'Larry', age: 45 } },
|
context: { person: { name: 'Larry', age: 45 } },
|
||||||
handlebars: '{{#person}}{{name}}{{age}}{{/person}}'
|
handlebars: '{{#person}}{{name}}{{age}}{{/person}}',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ module.exports = {
|
|||||||
context: { person: { name: 'Larry', age: 45 } },
|
context: { person: { name: 'Larry', age: 45 } },
|
||||||
handlebars: '{{#with person}}{{name}}{{age}}{{/with}}',
|
handlebars: '{{#with person}}{{name}}{{age}}{{/with}}',
|
||||||
dust: '{#person}{name}{age}{/person}',
|
dust: '{#person}{name}{age}{/person}',
|
||||||
mustache: '{{#person}}{{name}}{{age}}{{/person}}'
|
mustache: '{{#person}}{{name}}{{age}}{{/person}}',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
context: {
|
context: {
|
||||||
name: '1',
|
name: '1',
|
||||||
kids: [{ name: '1.1', kids: [{ name: '1.1.1', kids: [] }] }]
|
kids: [{ name: '1.1', kids: [{ name: '1.1.1', kids: [] }] }],
|
||||||
},
|
},
|
||||||
partials: {
|
partials: {
|
||||||
mustache: { recursion: '{{name}}{{#kids}}{{>recursion}}{{/kids}}' },
|
mustache: { recursion: '{{name}}{{#kids}}{{>recursion}}{{/kids}}' },
|
||||||
handlebars: { recursion: '{{name}}{{#each kids}}{{>recursion}}{{/each}}' }
|
handlebars: { recursion: '{{name}}{{#each kids}}{{>recursion}}{{/each}}' },
|
||||||
},
|
},
|
||||||
handlebars: '{{name}}{{#each kids}}{{>recursion}}{{/each}}',
|
handlebars: '{{name}}{{#each kids}}{{>recursion}}{{/each}}',
|
||||||
dust: '{name}{#kids}{>recursion:./}{/kids}',
|
dust: '{name}{#kids}{>recursion:./}{/kids}',
|
||||||
mustache: '{{name}}{{#kids}}{{>recursion}}{{/kids}}'
|
mustache: '{{name}}{{#kids}}{{>recursion}}{{/kids}}',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ module.exports = {
|
|||||||
peeps: [
|
peeps: [
|
||||||
{ name: 'Moe', count: 15 },
|
{ name: 'Moe', count: 15 },
|
||||||
{ name: 'Larry', count: 5 },
|
{ name: 'Larry', count: 5 },
|
||||||
{ name: 'Curly', count: 1 }
|
{ name: 'Curly', count: 1 },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
partials: {
|
partials: {
|
||||||
mustache: { variables: 'Hello {{name}}! You have {{count}} new messages.' },
|
mustache: { variables: 'Hello {{name}}! You have {{count}} new messages.' },
|
||||||
handlebars: {
|
handlebars: {
|
||||||
variables: 'Hello {{name}}! You have {{count}} new messages.'
|
variables: 'Hello {{name}}! You have {{count}} new messages.',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
handlebars: '{{#each peeps}}{{>variables}}{{/each}}',
|
handlebars: '{{#each peeps}}{{>variables}}{{/each}}',
|
||||||
dust: '{#peeps}{>variables/}{/peeps}',
|
dust: '{#peeps}{>variables/}{/peeps}',
|
||||||
mustache: '{{#peeps}}{{>variables}}{{/peeps}}'
|
mustache: '{{#peeps}}{{>variables}}{{/peeps}}',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ module.exports = {
|
|||||||
handlebars:
|
handlebars:
|
||||||
'{{person.name.bar.baz}}{{person.age}}{{person.foo}}{{animal.age}}',
|
'{{person.name.bar.baz}}{{person.age}}{{person.foo}}{{animal.age}}',
|
||||||
dust: '{person.name.bar.baz}{person.age}{person.foo}{animal.age}',
|
dust: '{person.name.bar.baz}{person.age}{person.foo}{animal.age}',
|
||||||
mustache: '{{person.name.bar.baz}}{{person.age}}{{person.foo}}{{animal.age}}'
|
mustache: '{{person.name.bar.baz}}{{person.age}}{{person.foo}}{{animal.age}}',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ module.exports = {
|
|||||||
context: {},
|
context: {},
|
||||||
handlebars: 'Hello world',
|
handlebars: 'Hello world',
|
||||||
dust: 'Hello world',
|
dust: 'Hello world',
|
||||||
mustache: 'Hello world'
|
mustache: 'Hello world',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
helpers: {
|
helpers: {
|
||||||
echo: function(value) {
|
echo: function (value) {
|
||||||
return 'foo ' + value;
|
return 'foo ' + value;
|
||||||
},
|
},
|
||||||
header: function() {
|
header: function () {
|
||||||
return 'Colors';
|
return 'Colors';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
handlebars: '{{echo (header)}}'
|
handlebars: '{{echo (header)}}',
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.context = module.exports.helpers;
|
module.exports.context = module.exports.helpers;
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ module.exports = {
|
|||||||
context: { name: 'Mick', count: 30 },
|
context: { name: 'Mick', count: 30 },
|
||||||
handlebars: 'Hello {{name}}! You have {{count}} new messages.',
|
handlebars: 'Hello {{name}}! You have {{count}} new messages.',
|
||||||
dust: 'Hello {name}! You have {count} new messages.',
|
dust: 'Hello {name}! You have {count} new messages.',
|
||||||
mustache: 'Hello {{name}}! You have {{count}} new messages.'
|
mustache: 'Hello {{name}}! You have {{count}} new messages.',
|
||||||
};
|
};
|
||||||
|
|||||||
+18
-18
@@ -33,26 +33,26 @@ function makeSuite(bench, name, template, handlebarsOnly) {
|
|||||||
var handlebar = Handlebars.compile(template.handlebars, { data: false }),
|
var handlebar = Handlebars.compile(template.handlebars, { data: false }),
|
||||||
compat = Handlebars.compile(template.handlebars, {
|
compat = Handlebars.compile(template.handlebars, {
|
||||||
data: false,
|
data: false,
|
||||||
compat: true
|
compat: true,
|
||||||
}),
|
}),
|
||||||
options = { helpers: template.helpers };
|
options = { helpers: template.helpers };
|
||||||
_.each(template.partials && template.partials.handlebars, function(
|
_.each(
|
||||||
partial,
|
template.partials && template.partials.handlebars,
|
||||||
partialName
|
function (partial, partialName) {
|
||||||
) {
|
Handlebars.registerPartial(
|
||||||
Handlebars.registerPartial(
|
partialName,
|
||||||
partialName,
|
Handlebars.compile(partial, { data: false })
|
||||||
Handlebars.compile(partial, { data: false })
|
);
|
||||||
);
|
}
|
||||||
});
|
);
|
||||||
|
|
||||||
handlebarsOut = handlebar(context, options);
|
handlebarsOut = handlebar(context, options);
|
||||||
bench('handlebars', function() {
|
bench('handlebars', function () {
|
||||||
handlebar(context, options);
|
handlebar(context, options);
|
||||||
});
|
});
|
||||||
|
|
||||||
compatOut = compat(context, options);
|
compatOut = compat(context, options);
|
||||||
bench('compat', function() {
|
bench('compat', function () {
|
||||||
compat(context, options);
|
compat(context, options);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -65,12 +65,12 @@ function makeSuite(bench, name, template, handlebarsOnly) {
|
|||||||
dustOut = false;
|
dustOut = false;
|
||||||
dust.loadSource(dust.compile(template.dust, templateName));
|
dust.loadSource(dust.compile(template.dust, templateName));
|
||||||
|
|
||||||
dust.render(templateName, context, function(err, out) {
|
dust.render(templateName, context, function (err, out) {
|
||||||
dustOut = out;
|
dustOut = out;
|
||||||
});
|
});
|
||||||
|
|
||||||
bench('dust', function() {
|
bench('dust', function () {
|
||||||
dust.render(templateName, context, function() {});
|
dust.render(templateName, context, function () {});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
bench('dust', error);
|
bench('dust', error);
|
||||||
@@ -84,7 +84,7 @@ function makeSuite(bench, name, template, handlebarsOnly) {
|
|||||||
if (mustacheSource) {
|
if (mustacheSource) {
|
||||||
mustacheOut = Mustache.to_html(mustacheSource, context, mustachePartials);
|
mustacheOut = Mustache.to_html(mustacheSource, context, mustachePartials);
|
||||||
|
|
||||||
bench('mustache', function() {
|
bench('mustache', function () {
|
||||||
Mustache.to_html(mustacheSource, context, mustachePartials);
|
Mustache.to_html(mustacheSource, context, mustachePartials);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -120,12 +120,12 @@ function makeSuite(bench, name, template, handlebarsOnly) {
|
|||||||
compare(mustacheOut, 'mustache');
|
compare(mustacheOut, 'mustache');
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function(grunt, callback) {
|
module.exports = function (grunt, callback) {
|
||||||
// Deferring load in case we are being run inline with the grunt build
|
// Deferring load in case we are being run inline with the grunt build
|
||||||
Handlebars = require('../../lib');
|
Handlebars = require('../../lib');
|
||||||
|
|
||||||
console.log('Execution Throughput');
|
console.log('Execution Throughput');
|
||||||
runner(grunt, makeSuite, function(times, scaled) {
|
runner(grunt, makeSuite, function (times, scaled) {
|
||||||
callback(scaled);
|
callback(scaled);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,21 +12,21 @@ function BenchWarmer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BenchWarmer.prototype = {
|
BenchWarmer.prototype = {
|
||||||
winners: function(benches) {
|
winners: function (benches) {
|
||||||
return Benchmark.filter(benches, 'fastest');
|
return Benchmark.filter(benches, 'fastest');
|
||||||
},
|
},
|
||||||
suite: function(suite, fn) {
|
suite: function (suite, fn) {
|
||||||
this.suiteName = suite;
|
this.suiteName = suite;
|
||||||
this.times[suite] = {};
|
this.times[suite] = {};
|
||||||
this.first = true;
|
this.first = true;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
fn(function(name, benchFn) {
|
fn(function (name, benchFn) {
|
||||||
self.push(name, benchFn);
|
self.push(name, benchFn);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
push: function(name, fn) {
|
push: function (name, fn) {
|
||||||
if (this.names.indexOf(name) === -1) {
|
if (this.names.indexOf(name) === -1) {
|
||||||
this.names.push(name);
|
this.names.push(name);
|
||||||
}
|
}
|
||||||
@@ -38,16 +38,16 @@ BenchWarmer.prototype = {
|
|||||||
|
|
||||||
var bench = new Benchmark(fn, {
|
var bench = new Benchmark(fn, {
|
||||||
name: this.suiteName + ': ' + name,
|
name: this.suiteName + ': ' + name,
|
||||||
onComplete: function() {
|
onComplete: function () {
|
||||||
if (first) {
|
if (first) {
|
||||||
self.startLine(suiteName);
|
self.startLine(suiteName);
|
||||||
}
|
}
|
||||||
self.writeBench(bench);
|
self.writeBench(bench);
|
||||||
self.currentBenches.push(bench);
|
self.currentBenches.push(bench);
|
||||||
},
|
},
|
||||||
onError: function() {
|
onError: function () {
|
||||||
self.errors[this.name] = this;
|
self.errors[this.name] = this;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
bench.suiteName = this.suiteName;
|
bench.suiteName = this.suiteName;
|
||||||
bench.benchName = name;
|
bench.benchName = name;
|
||||||
@@ -55,24 +55,24 @@ BenchWarmer.prototype = {
|
|||||||
this.benchmarks.push(bench);
|
this.benchmarks.push(bench);
|
||||||
},
|
},
|
||||||
|
|
||||||
bench: function(callback) {
|
bench: function (callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this.printHeader('ops/msec', true);
|
this.printHeader('ops/msec', true);
|
||||||
|
|
||||||
Benchmark.invoke(this.benchmarks, {
|
Benchmark.invoke(this.benchmarks, {
|
||||||
name: 'run',
|
name: 'run',
|
||||||
onComplete: function() {
|
onComplete: function () {
|
||||||
self.scaleTimes();
|
self.scaleTimes();
|
||||||
|
|
||||||
self.startLine('');
|
self.startLine('');
|
||||||
|
|
||||||
console.log('\n');
|
console.log('\n');
|
||||||
self.printHeader('scaled');
|
self.printHeader('scaled');
|
||||||
_.each(self.scaled, function(value, name) {
|
_.each(self.scaled, function (value, name) {
|
||||||
self.startLine(name);
|
self.startLine(name);
|
||||||
|
|
||||||
_.each(self.names, function(lang) {
|
_.each(self.names, function (lang) {
|
||||||
self.writeValue(value[lang] || '');
|
self.writeValue(value[lang] || '');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -93,7 +93,7 @@ BenchWarmer.prototype = {
|
|||||||
|
|
||||||
if (errors) {
|
if (errors) {
|
||||||
console.log('\n\nErrors:\n');
|
console.log('\n\nErrors:\n');
|
||||||
Object.keys(self.errors).forEach(function(prop) {
|
Object.keys(self.errors).forEach(function (prop) {
|
||||||
if (self.errors[prop].error.message !== 'EWOT') {
|
if (self.errors[prop].error.message !== 'EWOT') {
|
||||||
bench = self.errors[prop];
|
bench = self.errors[prop];
|
||||||
console.log('\n' + bench.name + ':\n');
|
console.log('\n' + bench.name + ':\n');
|
||||||
@@ -107,22 +107,22 @@ BenchWarmer.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('\n');
|
console.log('\n');
|
||||||
},
|
},
|
||||||
|
|
||||||
scaleTimes: function() {
|
scaleTimes: function () {
|
||||||
var scaled = (this.scaled = {});
|
var scaled = (this.scaled = {});
|
||||||
_.each(
|
_.each(
|
||||||
this.times,
|
this.times,
|
||||||
function(times, name) {
|
function (times, name) {
|
||||||
var output = (scaled[name] = {});
|
var output = (scaled[name] = {});
|
||||||
|
|
||||||
_.each(
|
_.each(
|
||||||
times,
|
times,
|
||||||
function(time, lang) {
|
function (time, lang) {
|
||||||
output[lang] = (
|
output[lang] = (
|
||||||
((time - this.minimum) / (this.maximum - this.minimum)) *
|
((time - this.minimum) / (this.maximum - this.minimum)) *
|
||||||
100
|
100
|
||||||
@@ -135,7 +135,7 @@ BenchWarmer.prototype = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
printHeader: function(title, winners) {
|
printHeader: function (title, winners) {
|
||||||
var benchSize = 0,
|
var benchSize = 0,
|
||||||
names = this.names,
|
names = this.names,
|
||||||
i,
|
i,
|
||||||
@@ -168,12 +168,13 @@ BenchWarmer.prototype = {
|
|||||||
console.log('\n' + new Array(horSize + 1).join('-'));
|
console.log('\n' + new Array(horSize + 1).join('-'));
|
||||||
},
|
},
|
||||||
|
|
||||||
startLine: function(name) {
|
startLine: function (name) {
|
||||||
var winners = Benchmark.map(this.winners(this.currentBenches), function(
|
var winners = Benchmark.map(
|
||||||
bench
|
this.winners(this.currentBenches),
|
||||||
) {
|
function (bench) {
|
||||||
return bench.name.split(': ')[1];
|
return bench.name.split(': ')[1];
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
this.currentBenches = [];
|
this.currentBenches = [];
|
||||||
|
|
||||||
@@ -184,7 +185,7 @@ BenchWarmer.prototype = {
|
|||||||
this.writeValue(name);
|
this.writeValue(name);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
writeBench: function(bench) {
|
writeBench: function (bench) {
|
||||||
var out;
|
var out;
|
||||||
|
|
||||||
if (!bench.error) {
|
if (!bench.error) {
|
||||||
@@ -211,11 +212,11 @@ BenchWarmer.prototype = {
|
|||||||
this.writeValue(out);
|
this.writeValue(out);
|
||||||
},
|
},
|
||||||
|
|
||||||
writeValue: function(out) {
|
writeValue: function (out) {
|
||||||
var padding = this.benchSize - out.length + 1;
|
var padding = this.benchSize - out.length + 1;
|
||||||
out = out + new Array(padding).join(' ');
|
out = out + new Array(padding).join(' ');
|
||||||
console.log(out);
|
console.log(out);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = BenchWarmer;
|
module.exports = BenchWarmer;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ var _ = require('underscore'),
|
|||||||
BenchWarmer = require('./benchwarmer'),
|
BenchWarmer = require('./benchwarmer'),
|
||||||
templates = require('../templates');
|
templates = require('../templates');
|
||||||
|
|
||||||
module.exports = function(grunt, makeSuite, callback) {
|
module.exports = function (grunt, makeSuite, callback) {
|
||||||
var warmer = new BenchWarmer();
|
var warmer = new BenchWarmer();
|
||||||
|
|
||||||
var handlebarsOnly = grunt.option('handlebars-only'),
|
var handlebarsOnly = grunt.option('handlebars-only'),
|
||||||
@@ -11,17 +11,17 @@ module.exports = function(grunt, makeSuite, callback) {
|
|||||||
grep = new RegExp(grep);
|
grep = new RegExp(grep);
|
||||||
}
|
}
|
||||||
|
|
||||||
_.each(templates, function(template, name) {
|
_.each(templates, function (template, name) {
|
||||||
if (!template.handlebars || (grep && !grep.test(name))) {
|
if (!template.handlebars || (grep && !grep.test(name))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
warmer.suite(name, function(bench) {
|
warmer.suite(name, function (bench) {
|
||||||
makeSuite(bench, name, template, handlebarsOnly);
|
makeSuite(bench, name, template, handlebarsOnly);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
warmer.bench(function() {
|
warmer.bench(function () {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(warmer.times, warmer.scaled);
|
callback(warmer.times, warmer.scaled);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
ecmaVersion: 2018
|
ecmaVersion: 2018,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,23 +5,23 @@ const config = {
|
|||||||
projects: [
|
projects: [
|
||||||
{
|
{
|
||||||
name: 'chromium',
|
name: 'chromium',
|
||||||
use: { ...devices['Desktop Chrome'] }
|
use: { ...devices['Desktop Chrome'] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'firefox',
|
name: 'firefox',
|
||||||
use: { ...devices['Desktop Firefox'] }
|
use: { ...devices['Desktop Firefox'] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'webkit',
|
name: 'webkit',
|
||||||
use: { ...devices['Desktop Safari'] }
|
use: { ...devices['Desktop Safari'] },
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
reporter: 'list',
|
reporter: 'list',
|
||||||
webServer: {
|
webServer: {
|
||||||
command: 'npm run test:serve',
|
command: 'npm run test:serve',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
reuseExistingServer: false
|
reuseExistingServer: false,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = config;
|
module.exports = config;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
rules: {
|
rules: {
|
||||||
'no-console': 'off',
|
'no-console': 'off',
|
||||||
'no-var': 'off'
|
'no-var': 'off',
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export default {
|
|||||||
input: 'src/index.js',
|
input: 'src/index.js',
|
||||||
output: {
|
output: {
|
||||||
file: 'dist/bundle.js',
|
file: 'dist/bundle.js',
|
||||||
format: 'es'
|
format: 'es',
|
||||||
},
|
},
|
||||||
plugins: [nodeResolve()]
|
plugins: [nodeResolve()],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ module.exports = {
|
|||||||
root: true,
|
root: true,
|
||||||
extends: ['eslint:recommended', 'prettier'],
|
extends: ['eslint:recommended', 'prettier'],
|
||||||
env: {
|
env: {
|
||||||
browser: true
|
browser: true,
|
||||||
},
|
},
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
ecmaVersion: 6
|
ecmaVersion: 6,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import * as Handlebars from 'handlebars/runtime';
|
|||||||
import hbs from 'handlebars-inline-precompile';
|
import hbs from 'handlebars-inline-precompile';
|
||||||
import { assertEquals } from '../../webpack-test/src/lib/assert';
|
import { assertEquals } from '../../webpack-test/src/lib/assert';
|
||||||
|
|
||||||
Handlebars.registerHelper('loud', function(text) {
|
Handlebars.registerHelper('loud', function (text) {
|
||||||
return text.toUpperCase();
|
return text.toUpperCase();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ const fs = require('fs');
|
|||||||
const testFiles = fs.readdirSync('src');
|
const testFiles = fs.readdirSync('src');
|
||||||
const entryPoints = {};
|
const entryPoints = {};
|
||||||
testFiles
|
testFiles
|
||||||
.filter(file => file.match(/-test.js$/))
|
.filter((file) => file.match(/-test.js$/))
|
||||||
.forEach(file => {
|
.forEach((file) => {
|
||||||
entryPoints[file] = `./src/${file}`;
|
entryPoints[file] = `./src/${file}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ module.exports = {
|
|||||||
mode: 'production',
|
mode: 'production',
|
||||||
output: {
|
output: {
|
||||||
filename: '[name]',
|
filename: '[name]',
|
||||||
path: __dirname + '/dist'
|
path: __dirname + '/dist',
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
@@ -22,12 +22,12 @@ module.exports = {
|
|||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
use: {
|
use: {
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
options: { cacheDirectory: false }
|
options: { cacheDirectory: false },
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
optimization: {
|
optimization: {
|
||||||
minimize: false
|
minimize: false,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ module.exports = {
|
|||||||
extends: ['eslint:recommended', 'prettier'],
|
extends: ['eslint:recommended', 'prettier'],
|
||||||
env: {
|
env: {
|
||||||
node: true,
|
node: true,
|
||||||
browser: true
|
browser: true,
|
||||||
},
|
},
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
ecmaVersion: 6
|
ecmaVersion: 6,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user