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 = {
|
||||
extends: ['eslint:recommended', 'plugin:compat/recommended', 'prettier'],
|
||||
globals: {
|
||||
self: false
|
||||
self: false,
|
||||
},
|
||||
env: {
|
||||
node: true,
|
||||
es2020: true
|
||||
es2020: true,
|
||||
},
|
||||
parserOptions: {
|
||||
sourceType: 'module'
|
||||
sourceType: 'module',
|
||||
},
|
||||
rules: {
|
||||
'no-console': 'warn',
|
||||
@@ -59,6 +59,6 @@ module.exports = {
|
||||
|
||||
// ECMAScript 6 //
|
||||
//--------------//
|
||||
'no-var': 'error'
|
||||
}
|
||||
'no-var': 'error',
|
||||
},
|
||||
};
|
||||
|
||||
+45
-40
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-process-env */
|
||||
module.exports = function(grunt) {
|
||||
module.exports = function (grunt) {
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
|
||||
@@ -8,7 +8,7 @@ module.exports = function(grunt) {
|
||||
copy: {
|
||||
dist: {
|
||||
options: {
|
||||
processContent: function(content) {
|
||||
processContent: function (content) {
|
||||
return (
|
||||
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'
|
||||
@@ -16,9 +16,9 @@ module.exports = function(grunt) {
|
||||
content +
|
||||
'\n// @license-end\n'
|
||||
);
|
||||
}
|
||||
},
|
||||
files: [{ expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/' }]
|
||||
},
|
||||
files: [{ expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/' }],
|
||||
},
|
||||
components: {
|
||||
files: [
|
||||
@@ -26,18 +26,23 @@ module.exports = function(grunt) {
|
||||
expand: true,
|
||||
cwd: 'components/',
|
||||
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: {
|
||||
options: {
|
||||
sourceMaps: 'inline',
|
||||
loose: ['es6.modules'],
|
||||
auxiliaryCommentBefore: 'istanbul ignore next'
|
||||
auxiliaryCommentBefore: 'istanbul ignore next',
|
||||
},
|
||||
cjs: {
|
||||
files: [
|
||||
@@ -45,10 +50,10 @@ module.exports = function(grunt) {
|
||||
cwd: 'lib/',
|
||||
expand: true,
|
||||
src: '**/!(index).js',
|
||||
dest: 'dist/cjs/'
|
||||
}
|
||||
]
|
||||
}
|
||||
dest: 'dist/cjs/',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
webpack: {
|
||||
options: {
|
||||
@@ -56,28 +61,28 @@ module.exports = function(grunt) {
|
||||
output: {
|
||||
path: 'dist/',
|
||||
library: 'Handlebars',
|
||||
libraryTarget: 'umd'
|
||||
}
|
||||
libraryTarget: 'umd',
|
||||
},
|
||||
},
|
||||
handlebars: {
|
||||
entry: './dist/cjs/handlebars.js',
|
||||
output: {
|
||||
filename: 'handlebars.js'
|
||||
}
|
||||
filename: 'handlebars.js',
|
||||
},
|
||||
},
|
||||
runtime: {
|
||||
entry: './dist/cjs/handlebars.runtime.js',
|
||||
output: {
|
||||
filename: 'handlebars.runtime.js'
|
||||
}
|
||||
}
|
||||
filename: 'handlebars.runtime.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
uglify: {
|
||||
options: {
|
||||
mangle: true,
|
||||
compress: true,
|
||||
preserveComments: /(?:^!|@(?:license|preserve|cc_on))/
|
||||
preserveComments: /(?:^!|@(?:license|preserve|cc_on))/,
|
||||
},
|
||||
dist: {
|
||||
files: [
|
||||
@@ -86,19 +91,19 @@ module.exports = function(grunt) {
|
||||
expand: true,
|
||||
src: ['handlebars*.js', '!*.min.js'],
|
||||
dest: 'dist/',
|
||||
rename: function(dest, src) {
|
||||
rename: function (dest, src) {
|
||||
return dest + src.replace(/\.js$/, '.min.js');
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
concat: {
|
||||
tests: {
|
||||
src: ['spec/!(require).js'],
|
||||
dest: 'tmp/tests.js'
|
||||
}
|
||||
dest: 'tmp/tests.js',
|
||||
},
|
||||
},
|
||||
|
||||
connect: {
|
||||
@@ -106,27 +111,27 @@ module.exports = function(grunt) {
|
||||
options: {
|
||||
base: '.',
|
||||
hostname: '*',
|
||||
port: 9999
|
||||
}
|
||||
}
|
||||
port: 9999,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
shell: {
|
||||
integrationTests: {
|
||||
command: './tests/integration/run-integration-tests.sh'
|
||||
}
|
||||
command: './tests/integration/run-integration-tests.sh',
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
scripts: {
|
||||
options: {
|
||||
atBegin: true
|
||||
atBegin: true,
|
||||
},
|
||||
|
||||
files: ['src/*', 'lib/**/*.js', 'spec/**/*.js'],
|
||||
tasks: ['on-file-change']
|
||||
}
|
||||
}
|
||||
tasks: ['on-file-change'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Load tasks from npm
|
||||
@@ -148,7 +153,7 @@ module.exports = function(grunt) {
|
||||
'uglify',
|
||||
'test:min',
|
||||
'copy:dist',
|
||||
'copy:components'
|
||||
'copy:components',
|
||||
]);
|
||||
|
||||
// Requires secret properties from .travis.yaml
|
||||
@@ -156,7 +161,7 @@ module.exports = function(grunt) {
|
||||
'default',
|
||||
'shell:integrationTests',
|
||||
'metrics',
|
||||
'publish-to-aws'
|
||||
'publish-to-aws',
|
||||
]);
|
||||
|
||||
grunt.registerTask('on-file-change', ['build', 'concat:tests', 'test']);
|
||||
@@ -174,6 +179,6 @@ module.exports = function(grunt) {
|
||||
);
|
||||
grunt.registerTask('integration-tests', [
|
||||
'default',
|
||||
'shell:integrationTests'
|
||||
'shell:integrationTests',
|
||||
]);
|
||||
};
|
||||
|
||||
+20
-20
@@ -5,103 +5,103 @@ const yargs = require('yargs')
|
||||
.option('f', {
|
||||
type: 'string',
|
||||
description: 'Output File',
|
||||
alias: 'output'
|
||||
alias: 'output',
|
||||
})
|
||||
.option('map', {
|
||||
type: 'string',
|
||||
description: 'Source Map File'
|
||||
description: 'Source Map File',
|
||||
})
|
||||
.option('a', {
|
||||
type: 'boolean',
|
||||
description: 'Exports amd style (require.js)',
|
||||
alias: 'amd'
|
||||
alias: 'amd',
|
||||
})
|
||||
.option('c', {
|
||||
type: 'string',
|
||||
description: 'Exports CommonJS style, path to Handlebars module',
|
||||
alias: 'commonjs',
|
||||
default: null
|
||||
default: null,
|
||||
})
|
||||
.option('h', {
|
||||
type: 'string',
|
||||
description: 'Path to handlebar.js (only valid for amd-style)',
|
||||
alias: 'handlebarPath',
|
||||
default: ''
|
||||
default: '',
|
||||
})
|
||||
.option('k', {
|
||||
type: 'string',
|
||||
description: 'Known helpers',
|
||||
alias: 'known'
|
||||
alias: 'known',
|
||||
})
|
||||
.option('o', {
|
||||
type: 'boolean',
|
||||
description: 'Known helpers only',
|
||||
alias: 'knownOnly'
|
||||
alias: 'knownOnly',
|
||||
})
|
||||
.option('m', {
|
||||
type: 'boolean',
|
||||
description: 'Minimize output',
|
||||
alias: 'min'
|
||||
alias: 'min',
|
||||
})
|
||||
.option('n', {
|
||||
type: 'string',
|
||||
description: 'Template namespace',
|
||||
alias: 'namespace',
|
||||
default: 'Handlebars.templates'
|
||||
default: 'Handlebars.templates',
|
||||
})
|
||||
.option('s', {
|
||||
type: 'boolean',
|
||||
description: 'Output template function only.',
|
||||
alias: 'simple'
|
||||
alias: 'simple',
|
||||
})
|
||||
.option('N', {
|
||||
type: 'string',
|
||||
description:
|
||||
'Name of passed string templates. Optional if running in a simple mode. Required when operating on multiple templates.',
|
||||
alias: 'name'
|
||||
alias: 'name',
|
||||
})
|
||||
.option('i', {
|
||||
type: 'string',
|
||||
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.',
|
||||
alias: 'string'
|
||||
alias: 'string',
|
||||
})
|
||||
.option('r', {
|
||||
type: 'string',
|
||||
description:
|
||||
'Template root. Base value that will be stripped from template names.',
|
||||
alias: 'root'
|
||||
alias: 'root',
|
||||
})
|
||||
.option('p', {
|
||||
type: 'boolean',
|
||||
description: 'Compiling a partial template',
|
||||
alias: 'partial'
|
||||
alias: 'partial',
|
||||
})
|
||||
.option('d', {
|
||||
type: 'boolean',
|
||||
description: 'Include data when compiling',
|
||||
alias: 'data'
|
||||
alias: 'data',
|
||||
})
|
||||
.option('e', {
|
||||
type: 'string',
|
||||
description: 'Template extension.',
|
||||
alias: 'extension',
|
||||
default: 'handlebars'
|
||||
default: 'handlebars',
|
||||
})
|
||||
.option('b', {
|
||||
type: 'boolean',
|
||||
description:
|
||||
'Removes the BOM (Byte Order Mark) from the beginning of the templates.',
|
||||
alias: 'bom'
|
||||
alias: 'bom',
|
||||
})
|
||||
.option('v', {
|
||||
type: 'boolean',
|
||||
description: 'Prints the current compiler version',
|
||||
alias: 'version'
|
||||
alias: 'version',
|
||||
})
|
||||
.option('help', {
|
||||
type: 'boolean',
|
||||
description: 'Outputs this message'
|
||||
description: 'Outputs this message',
|
||||
})
|
||||
.wrap(120);
|
||||
|
||||
@@ -110,7 +110,7 @@ argv.files = argv._;
|
||||
delete argv._;
|
||||
|
||||
const Precompiler = require('../dist/cjs/precompiler');
|
||||
Precompiler.loadTemplates(argv, function(err, opts) {
|
||||
Precompiler.loadTemplates(argv, function (err, opts) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
+2
-2
@@ -2,6 +2,6 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
// Handlebars should run natively in the browser
|
||||
node: false
|
||||
}
|
||||
node: false,
|
||||
},
|
||||
};
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@ import {
|
||||
parser as Parser,
|
||||
parse,
|
||||
parseWithoutProcessing,
|
||||
Visitor
|
||||
Visitor,
|
||||
} from '@handlebars/parser';
|
||||
|
||||
import runtime from './handlebars.runtime';
|
||||
@@ -18,10 +18,10 @@ let _create = runtime.create;
|
||||
function create() {
|
||||
let hb = _create();
|
||||
|
||||
hb.compile = function(input, options) {
|
||||
hb.compile = function (input, options) {
|
||||
return compile(input, options, hb);
|
||||
};
|
||||
hb.precompile = function(input, options) {
|
||||
hb.precompile = function (input, options) {
|
||||
return precompile(input, options, hb);
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ function create() {
|
||||
hb.escapeExpression = Utils.escapeExpression;
|
||||
|
||||
hb.VM = runtime;
|
||||
hb.template = function(spec) {
|
||||
hb.template = function (spec) {
|
||||
return runtime.template(spec, hb);
|
||||
};
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ export const REVISION_CHANGES = {
|
||||
5: '== 2.0.0-alpha.x',
|
||||
6: '>= 2.0.0-beta.1',
|
||||
7: '>= 4.0.0 <4.3.0',
|
||||
8: '>= 4.3.0'
|
||||
8: '>= 4.3.0',
|
||||
};
|
||||
|
||||
const objectType = '[object Object]';
|
||||
@@ -37,7 +37,7 @@ HandlebarsEnvironment.prototype = {
|
||||
logger: logger,
|
||||
log: logger.log,
|
||||
|
||||
registerHelper: function(name, fn) {
|
||||
registerHelper: function (name, fn) {
|
||||
if (toString.call(name) === objectType) {
|
||||
if (fn) {
|
||||
throw new Exception('Arg not supported with multiple helpers');
|
||||
@@ -47,11 +47,11 @@ HandlebarsEnvironment.prototype = {
|
||||
this.helpers[name] = fn;
|
||||
}
|
||||
},
|
||||
unregisterHelper: function(name) {
|
||||
unregisterHelper: function (name) {
|
||||
delete this.helpers[name];
|
||||
},
|
||||
|
||||
registerPartial: function(name, partial) {
|
||||
registerPartial: function (name, partial) {
|
||||
if (toString.call(name) === objectType) {
|
||||
extend(this.partials, name);
|
||||
} else {
|
||||
@@ -63,11 +63,11 @@ HandlebarsEnvironment.prototype = {
|
||||
this.partials[name] = partial;
|
||||
}
|
||||
},
|
||||
unregisterPartial: function(name) {
|
||||
unregisterPartial: function (name) {
|
||||
delete this.partials[name];
|
||||
},
|
||||
|
||||
registerDecorator: function(name, fn) {
|
||||
registerDecorator: function (name, fn) {
|
||||
if (toString.call(name) === objectType) {
|
||||
if (fn) {
|
||||
throw new Exception('Arg not supported with multiple decorators');
|
||||
@@ -77,7 +77,7 @@ HandlebarsEnvironment.prototype = {
|
||||
this.decorators[name] = fn;
|
||||
}
|
||||
},
|
||||
unregisterDecorator: function(name) {
|
||||
unregisterDecorator: function (name) {
|
||||
delete this.decorators[name];
|
||||
},
|
||||
/**
|
||||
@@ -86,7 +86,7 @@ HandlebarsEnvironment.prototype = {
|
||||
*/
|
||||
resetLoggedPropertyAccesses() {
|
||||
resetLoggedProperties();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export let log = logger.log;
|
||||
|
||||
@@ -4,7 +4,7 @@ let AST = {
|
||||
// a mustache is definitely a helper if:
|
||||
// * it is an eligible helper, and
|
||||
// * it has at least one parameter or hash segment
|
||||
helperExpression: function(node) {
|
||||
helperExpression: function (node) {
|
||||
return (
|
||||
node.type === 'SubExpression' ||
|
||||
((node.type === 'MustacheStatement' ||
|
||||
@@ -13,18 +13,18 @@ let AST = {
|
||||
);
|
||||
},
|
||||
|
||||
scopedId: function(path) {
|
||||
scopedId: function (path) {
|
||||
return /^\.|this\b/.test(path.original);
|
||||
},
|
||||
|
||||
// an ID is simple if it only has one part, and that part is not
|
||||
// `..` or `this`.
|
||||
simpleId: function(path) {
|
||||
simpleId: function (path) {
|
||||
return (
|
||||
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
|
||||
|
||||
@@ -17,7 +17,7 @@ try {
|
||||
|
||||
/* istanbul ignore if: tested but not covered in istanbul due to dist build */
|
||||
if (!SourceNode) {
|
||||
SourceNode = function(line, column, srcFile, chunks) {
|
||||
SourceNode = function (line, column, srcFile, chunks) {
|
||||
this.src = '';
|
||||
if (chunks) {
|
||||
this.add(chunks);
|
||||
@@ -25,24 +25,24 @@ if (!SourceNode) {
|
||||
};
|
||||
/* istanbul ignore next */
|
||||
SourceNode.prototype = {
|
||||
add: function(chunks) {
|
||||
add: function (chunks) {
|
||||
if (isArray(chunks)) {
|
||||
chunks = chunks.join('');
|
||||
}
|
||||
this.src += chunks;
|
||||
},
|
||||
prepend: function(chunks) {
|
||||
prepend: function (chunks) {
|
||||
if (isArray(chunks)) {
|
||||
chunks = chunks.join('');
|
||||
}
|
||||
this.src = chunks + this.src;
|
||||
},
|
||||
toStringWithSourceMap: function() {
|
||||
toStringWithSourceMap: function () {
|
||||
return { code: this.toString() };
|
||||
},
|
||||
toString: function() {
|
||||
toString: function () {
|
||||
return this.src;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -70,32 +70,32 @@ CodeGen.prototype = {
|
||||
isEmpty() {
|
||||
return !this.source.length;
|
||||
},
|
||||
prepend: function(source, loc) {
|
||||
prepend: function (source, loc) {
|
||||
this.source.unshift(this.wrap(source, loc));
|
||||
},
|
||||
push: function(source, loc) {
|
||||
push: function (source, loc) {
|
||||
this.source.push(this.wrap(source, loc));
|
||||
},
|
||||
|
||||
merge: function() {
|
||||
merge: function () {
|
||||
let source = this.empty();
|
||||
this.each(function(line) {
|
||||
this.each(function (line) {
|
||||
source.add([' ', line, '\n']);
|
||||
});
|
||||
return source;
|
||||
},
|
||||
|
||||
each: function(iter) {
|
||||
each: function (iter) {
|
||||
for (let i = 0, len = this.source.length; i < len; i++) {
|
||||
iter(this.source[i]);
|
||||
}
|
||||
},
|
||||
|
||||
empty: function() {
|
||||
empty: function () {
|
||||
let loc = this.currentLocation || { start: {} };
|
||||
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) {
|
||||
return chunk;
|
||||
}
|
||||
@@ -110,12 +110,12 @@ CodeGen.prototype = {
|
||||
);
|
||||
},
|
||||
|
||||
functionCall: function(fn, type, params) {
|
||||
functionCall: function (fn, type, params) {
|
||||
params = this.generateList(params);
|
||||
return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
|
||||
},
|
||||
|
||||
quotedString: function(str) {
|
||||
quotedString: function (str) {
|
||||
return (
|
||||
'"' +
|
||||
(str + '')
|
||||
@@ -129,10 +129,10 @@ CodeGen.prototype = {
|
||||
);
|
||||
},
|
||||
|
||||
objectLiteral: function(obj) {
|
||||
objectLiteral: function (obj) {
|
||||
let pairs = [];
|
||||
|
||||
Object.keys(obj).forEach(key => {
|
||||
Object.keys(obj).forEach((key) => {
|
||||
let value = castChunk(obj[key], this);
|
||||
if (value !== 'undefined') {
|
||||
pairs.push([this.quotedString(key), ':', value]);
|
||||
@@ -145,7 +145,7 @@ CodeGen.prototype = {
|
||||
return ret;
|
||||
},
|
||||
|
||||
generateList: function(entries) {
|
||||
generateList: function (entries) {
|
||||
let ret = this.empty();
|
||||
|
||||
for (let i = 0, len = entries.length; i < len; i++) {
|
||||
@@ -159,13 +159,13 @@ CodeGen.prototype = {
|
||||
return ret;
|
||||
},
|
||||
|
||||
generateArray: function(entries) {
|
||||
generateArray: function (entries) {
|
||||
let ret = this.generateList(entries);
|
||||
ret.prepend('[');
|
||||
ret.add(']');
|
||||
|
||||
return ret;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default CodeGen;
|
||||
|
||||
@@ -16,7 +16,7 @@ export function Compiler() {}
|
||||
Compiler.prototype = {
|
||||
compiler: Compiler,
|
||||
|
||||
equals: function(other) {
|
||||
equals: function (other) {
|
||||
let len = this.opcodes.length;
|
||||
if (other.opcodes.length !== len) {
|
||||
return false;
|
||||
@@ -47,7 +47,7 @@ Compiler.prototype = {
|
||||
|
||||
guid: 0,
|
||||
|
||||
compile: function(program, options) {
|
||||
compile: function (program, options) {
|
||||
this.sourceNode = [];
|
||||
this.opcodes = [];
|
||||
this.children = [];
|
||||
@@ -65,7 +65,7 @@ Compiler.prototype = {
|
||||
unless: true,
|
||||
with: true,
|
||||
log: true,
|
||||
lookup: true
|
||||
lookup: true,
|
||||
},
|
||||
options.knownHelpers
|
||||
);
|
||||
@@ -73,7 +73,7 @@ Compiler.prototype = {
|
||||
return this.accept(program);
|
||||
},
|
||||
|
||||
compileProgram: function(program) {
|
||||
compileProgram: function (program) {
|
||||
let childCompiler = new this.compiler(), // eslint-disable-line new-cap
|
||||
result = childCompiler.compile(program, this.options),
|
||||
guid = this.guid++;
|
||||
@@ -86,7 +86,7 @@ Compiler.prototype = {
|
||||
return guid;
|
||||
},
|
||||
|
||||
accept: function(node) {
|
||||
accept: function (node) {
|
||||
/* istanbul ignore next: Sanity code */
|
||||
if (!this[node.type]) {
|
||||
throw new Exception('Unknown type: ' + node.type, node);
|
||||
@@ -98,7 +98,7 @@ Compiler.prototype = {
|
||||
return ret;
|
||||
},
|
||||
|
||||
Program: function(program) {
|
||||
Program: function (program) {
|
||||
this.options.blockParams.unshift(program.blockParams);
|
||||
|
||||
let body = program.body,
|
||||
@@ -115,7 +115,7 @@ Compiler.prototype = {
|
||||
return this;
|
||||
},
|
||||
|
||||
BlockStatement: function(block) {
|
||||
BlockStatement: function (block) {
|
||||
transformLiteralToPath(block);
|
||||
|
||||
let program = block.program,
|
||||
@@ -160,7 +160,7 @@ Compiler.prototype = {
|
||||
this.opcode('registerDecorator', params.length, path.original);
|
||||
},
|
||||
|
||||
PartialStatement: function(partial) {
|
||||
PartialStatement: function (partial) {
|
||||
this.usePartial = true;
|
||||
|
||||
let program = partial.program;
|
||||
@@ -199,11 +199,11 @@ Compiler.prototype = {
|
||||
this.opcode('invokePartial', isDynamic, partialName, indent);
|
||||
this.opcode('append');
|
||||
},
|
||||
PartialBlockStatement: function(partialBlock) {
|
||||
PartialBlockStatement: function (partialBlock) {
|
||||
this.PartialStatement(partialBlock);
|
||||
},
|
||||
|
||||
MustacheStatement: function(mustache) {
|
||||
MustacheStatement: function (mustache) {
|
||||
this.SubExpression(mustache);
|
||||
|
||||
if (mustache.escaped && !this.options.noEscape) {
|
||||
@@ -216,15 +216,15 @@ Compiler.prototype = {
|
||||
this.DecoratorBlock(decorator);
|
||||
},
|
||||
|
||||
ContentStatement: function(content) {
|
||||
ContentStatement: function (content) {
|
||||
if (content.value) {
|
||||
this.opcode('appendContent', content.value);
|
||||
}
|
||||
},
|
||||
|
||||
CommentStatement: function() {},
|
||||
CommentStatement: function () {},
|
||||
|
||||
SubExpression: function(sexpr) {
|
||||
SubExpression: function (sexpr) {
|
||||
transformLiteralToPath(sexpr);
|
||||
let type = this.classifySexpr(sexpr);
|
||||
|
||||
@@ -236,7 +236,7 @@ Compiler.prototype = {
|
||||
this.ambiguousSexpr(sexpr);
|
||||
}
|
||||
},
|
||||
ambiguousSexpr: function(sexpr, program, inverse) {
|
||||
ambiguousSexpr: function (sexpr, program, inverse) {
|
||||
let path = sexpr.path,
|
||||
name = path.parts[0],
|
||||
isBlock = program != null || inverse != null;
|
||||
@@ -252,14 +252,14 @@ Compiler.prototype = {
|
||||
this.opcode('invokeAmbiguous', name, isBlock);
|
||||
},
|
||||
|
||||
simpleSexpr: function(sexpr) {
|
||||
simpleSexpr: function (sexpr) {
|
||||
let path = sexpr.path;
|
||||
path.strict = true;
|
||||
this.accept(path);
|
||||
this.opcode('resolvePossibleLambda');
|
||||
},
|
||||
|
||||
helperSexpr: function(sexpr, program, inverse) {
|
||||
helperSexpr: function (sexpr, program, inverse) {
|
||||
let params = this.setupFullMustacheParams(sexpr, program, inverse),
|
||||
path = sexpr.path,
|
||||
name = path.parts[0];
|
||||
@@ -285,7 +285,7 @@ Compiler.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
PathExpression: function(path) {
|
||||
PathExpression: function (path) {
|
||||
this.addDepth(path.depth);
|
||||
this.opcode('getContext', path.depth);
|
||||
|
||||
@@ -312,27 +312,27 @@ Compiler.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
StringLiteral: function(string) {
|
||||
StringLiteral: function (string) {
|
||||
this.opcode('pushString', string.value);
|
||||
},
|
||||
|
||||
NumberLiteral: function(number) {
|
||||
NumberLiteral: function (number) {
|
||||
this.opcode('pushLiteral', number.value);
|
||||
},
|
||||
|
||||
BooleanLiteral: function(bool) {
|
||||
BooleanLiteral: function (bool) {
|
||||
this.opcode('pushLiteral', bool.value);
|
||||
},
|
||||
|
||||
UndefinedLiteral: function() {
|
||||
UndefinedLiteral: function () {
|
||||
this.opcode('pushLiteral', 'undefined');
|
||||
},
|
||||
|
||||
NullLiteral: function() {
|
||||
NullLiteral: function () {
|
||||
this.opcode('pushLiteral', 'null');
|
||||
},
|
||||
|
||||
Hash: function(hash) {
|
||||
Hash: function (hash) {
|
||||
let pairs = hash.pairs,
|
||||
i = 0,
|
||||
l = pairs.length;
|
||||
@@ -349,15 +349,15 @@ Compiler.prototype = {
|
||||
},
|
||||
|
||||
// HELPERS
|
||||
opcode: function(name) {
|
||||
opcode: function (name) {
|
||||
this.opcodes.push({
|
||||
opcode: name,
|
||||
args: slice.call(arguments, 1),
|
||||
loc: this.sourceNode[0].loc
|
||||
loc: this.sourceNode[0].loc,
|
||||
});
|
||||
},
|
||||
|
||||
addDepth: function(depth) {
|
||||
addDepth: function (depth) {
|
||||
if (!depth) {
|
||||
return;
|
||||
}
|
||||
@@ -365,7 +365,7 @@ Compiler.prototype = {
|
||||
this.useDepths = true;
|
||||
},
|
||||
|
||||
classifySexpr: function(sexpr) {
|
||||
classifySexpr: function (sexpr) {
|
||||
let isSimple = AST.helpers.simpleId(sexpr.path);
|
||||
|
||||
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++) {
|
||||
this.pushParam(params[i]);
|
||||
}
|
||||
},
|
||||
|
||||
pushParam: function(val) {
|
||||
pushParam: function (val) {
|
||||
this.accept(val);
|
||||
},
|
||||
|
||||
setupFullMustacheParams: function(sexpr, program, inverse, omitEmpty) {
|
||||
setupFullMustacheParams: function (sexpr, program, inverse, omitEmpty) {
|
||||
let params = sexpr.params;
|
||||
this.pushParams(params);
|
||||
|
||||
@@ -426,7 +426,7 @@ Compiler.prototype = {
|
||||
return params;
|
||||
},
|
||||
|
||||
blockParamIndex: function(name) {
|
||||
blockParamIndex: function (name) {
|
||||
for (
|
||||
let depth = 0, len = this.options.blockParams.length;
|
||||
depth < len;
|
||||
@@ -438,7 +438,7 @@ Compiler.prototype = {
|
||||
return [depth, param];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
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.
|
||||
return function(context, execOptions) {
|
||||
return function (context, execOptions) {
|
||||
if (!compiled) {
|
||||
compiled = compileInput();
|
||||
}
|
||||
@@ -530,7 +530,7 @@ function transformLiteralToPath(sexpr) {
|
||||
depth: 0,
|
||||
parts: [literal.original + ''],
|
||||
original: literal.original + '',
|
||||
loc: literal.loc
|
||||
loc: literal.loc,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,25 +12,25 @@ function JavaScriptCompiler() {}
|
||||
JavaScriptCompiler.prototype = {
|
||||
// PUBLIC API: You can override these methods in a subclass to provide
|
||||
// alternative compiled forms for name lookup and buffering semantics
|
||||
nameLookup: function(parent, name /*, type */) {
|
||||
nameLookup: function (parent, name /*, type */) {
|
||||
return this.internalNameLookup(parent, name);
|
||||
},
|
||||
depthedLookup: function(name) {
|
||||
depthedLookup: function (name) {
|
||||
return [
|
||||
this.aliasable('container.lookup'),
|
||||
'(depths, ',
|
||||
JSON.stringify(name),
|
||||
')'
|
||||
')',
|
||||
];
|
||||
},
|
||||
|
||||
compilerInfo: function() {
|
||||
compilerInfo: function () {
|
||||
const revision = COMPILER_REVISION,
|
||||
versions = REVISION_CHANGES[revision];
|
||||
return [revision, versions];
|
||||
},
|
||||
|
||||
appendToBuffer: function(source, location, explicit) {
|
||||
appendToBuffer: function (source, location, explicit) {
|
||||
// Force a source as this simplifies the merge logic.
|
||||
if (!isArray(source)) {
|
||||
source = [source];
|
||||
@@ -50,18 +50,18 @@ JavaScriptCompiler.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
initializeBuffer: function() {
|
||||
initializeBuffer: function () {
|
||||
return this.quotedString('');
|
||||
},
|
||||
// END PUBLIC API
|
||||
internalNameLookup: function(parent, name) {
|
||||
internalNameLookup: function (parent, name) {
|
||||
this.lookupPropertyFunctionIsUsed = true;
|
||||
return ['lookupProperty(', parent, ',', JSON.stringify(name), ')'];
|
||||
},
|
||||
|
||||
lookupPropertyFunctionIsUsed: false,
|
||||
|
||||
compile: function(environment, options, context, asObject) {
|
||||
compile: function (environment, options, context, asObject) {
|
||||
this.environment = environment;
|
||||
this.options = options;
|
||||
this.precompile = !asObject;
|
||||
@@ -71,7 +71,7 @@ JavaScriptCompiler.prototype = {
|
||||
this.context = context || {
|
||||
decorators: [],
|
||||
programs: [],
|
||||
environments: []
|
||||
environments: [],
|
||||
};
|
||||
|
||||
this.preamble();
|
||||
@@ -123,7 +123,7 @@ JavaScriptCompiler.prototype = {
|
||||
this.decorators.prepend([
|
||||
'var decorators = container.decorators, ',
|
||||
this.lookupPropertyFunctionVarDeclaration(),
|
||||
';\n'
|
||||
';\n',
|
||||
]);
|
||||
this.decorators.push('return fn;');
|
||||
|
||||
@@ -137,7 +137,7 @@ JavaScriptCompiler.prototype = {
|
||||
'data',
|
||||
'blockParams',
|
||||
'depths',
|
||||
this.decorators.merge()
|
||||
this.decorators.merge(),
|
||||
]);
|
||||
} else {
|
||||
this.decorators.prepend(
|
||||
@@ -154,7 +154,7 @@ JavaScriptCompiler.prototype = {
|
||||
if (!this.isChild) {
|
||||
let ret = {
|
||||
compiler: this.compilerInfo(),
|
||||
main: fn
|
||||
main: fn,
|
||||
};
|
||||
|
||||
if (this.decorators) {
|
||||
@@ -211,7 +211,7 @@ JavaScriptCompiler.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
preamble: function() {
|
||||
preamble: function () {
|
||||
// track the last context pushed into place to allow skipping the
|
||||
// getContext opcode when it would be a noop
|
||||
this.lastContext = 0;
|
||||
@@ -219,7 +219,7 @@ JavaScriptCompiler.prototype = {
|
||||
this.decorators = new CodeGen(this.options.srcName);
|
||||
},
|
||||
|
||||
createFunctionContext: function(asObject) {
|
||||
createFunctionContext: function (asObject) {
|
||||
let varDeclarations = '';
|
||||
|
||||
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
|
||||
// we aren't concern about minimizing the template size.
|
||||
let aliasCount = 0;
|
||||
Object.keys(this.aliases).forEach(alias => {
|
||||
Object.keys(this.aliases).forEach((alias) => {
|
||||
let node = this.aliases[alias];
|
||||
if (node.children && node.referenceCount > 1) {
|
||||
varDeclarations += ', alias' + ++aliasCount + '=' + alias;
|
||||
@@ -268,18 +268,18 @@ JavaScriptCompiler.prototype = {
|
||||
params.join(','),
|
||||
') {\n ',
|
||||
source,
|
||||
'}'
|
||||
'}',
|
||||
]);
|
||||
}
|
||||
},
|
||||
mergeSource: function(varDeclarations) {
|
||||
mergeSource: function (varDeclarations) {
|
||||
let isSimple = this.environment.isSimple,
|
||||
appendOnly = !this.forceBuffer,
|
||||
appendFirst,
|
||||
sourceSeen,
|
||||
bufferStart,
|
||||
bufferEnd;
|
||||
this.source.each(line => {
|
||||
this.source.each((line) => {
|
||||
if (line.appendToBuffer) {
|
||||
if (bufferStart) {
|
||||
line.prepend(' + ');
|
||||
@@ -333,7 +333,7 @@ JavaScriptCompiler.prototype = {
|
||||
return this.source.merge();
|
||||
},
|
||||
|
||||
lookupPropertyFunctionVarDeclaration: function() {
|
||||
lookupPropertyFunctionVarDeclaration: function () {
|
||||
return `
|
||||
lookupProperty = container.lookupProperty || function(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
|
||||
// replace it on the stack with the result of properly
|
||||
// invoking blockHelperMissing.
|
||||
blockValue: function(name) {
|
||||
blockValue: function (name) {
|
||||
let blockHelperMissing = this.aliasable(
|
||||
'container.hooks.blockHelperMissing'
|
||||
),
|
||||
@@ -372,7 +372,7 @@ JavaScriptCompiler.prototype = {
|
||||
// Compiler value, before: lastHelper=value of last found helper, if any
|
||||
// On stack, after, if no lastHelper: same as [blockValue]
|
||||
// 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
|
||||
let blockHelperMissing = this.aliasable(
|
||||
'container.hooks.blockHelperMissing'
|
||||
@@ -392,7 +392,7 @@ JavaScriptCompiler.prototype = {
|
||||
current,
|
||||
' = ',
|
||||
this.source.functionCall(blockHelperMissing, 'call', params),
|
||||
'}'
|
||||
'}',
|
||||
]);
|
||||
},
|
||||
|
||||
@@ -402,7 +402,7 @@ JavaScriptCompiler.prototype = {
|
||||
// On stack, after: ...
|
||||
//
|
||||
// Appends the string value of `content` to the current buffer
|
||||
appendContent: function(content) {
|
||||
appendContent: function (content) {
|
||||
if (this.pendingContent) {
|
||||
content = this.pendingContent + content;
|
||||
} else {
|
||||
@@ -421,9 +421,9 @@ JavaScriptCompiler.prototype = {
|
||||
//
|
||||
// If `value` is truthy, or 0, it is coerced into a string and appended
|
||||
// Otherwise, the empty string is appended
|
||||
append: function() {
|
||||
append: function () {
|
||||
if (this.isInline()) {
|
||||
this.replaceStack(current => [' != null ? ', current, ' : ""']);
|
||||
this.replaceStack((current) => [' != null ? ', current, ' : ""']);
|
||||
|
||||
this.pushSource(this.appendToBuffer(this.popStack()));
|
||||
} else {
|
||||
@@ -433,13 +433,13 @@ JavaScriptCompiler.prototype = {
|
||||
local,
|
||||
' != null) { ',
|
||||
this.appendToBuffer(local, undefined, true),
|
||||
' }'
|
||||
' }',
|
||||
]);
|
||||
if (this.environment.isSimple) {
|
||||
this.pushSource([
|
||||
'else { ',
|
||||
this.appendToBuffer("''", undefined, true),
|
||||
' }'
|
||||
' }',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -451,13 +451,13 @@ JavaScriptCompiler.prototype = {
|
||||
// On stack, after: ...
|
||||
//
|
||||
// Escape `value` and append it to the buffer
|
||||
appendEscaped: function() {
|
||||
appendEscaped: function () {
|
||||
this.pushSource(
|
||||
this.appendToBuffer([
|
||||
this.aliasable('container.escapeExpression'),
|
||||
'(',
|
||||
this.popStack(),
|
||||
')'
|
||||
')',
|
||||
])
|
||||
);
|
||||
},
|
||||
@@ -469,7 +469,7 @@ JavaScriptCompiler.prototype = {
|
||||
// Compiler value, after: lastContext=depth
|
||||
//
|
||||
// Set the value of the `lastContext` compiler value to the depth
|
||||
getContext: function(depth) {
|
||||
getContext: function (depth) {
|
||||
this.lastContext = depth;
|
||||
},
|
||||
|
||||
@@ -479,7 +479,7 @@ JavaScriptCompiler.prototype = {
|
||||
// On stack, after: currentContext, ...
|
||||
//
|
||||
// Pushes the value of the current context onto the stack.
|
||||
pushContext: function() {
|
||||
pushContext: function () {
|
||||
this.pushStackLiteral(this.contextName(this.lastContext));
|
||||
},
|
||||
|
||||
@@ -490,7 +490,7 @@ JavaScriptCompiler.prototype = {
|
||||
//
|
||||
// Looks up the value of `name` on the current context and pushes
|
||||
// it onto the stack.
|
||||
lookupOnContext: function(parts, falsy, strict, scoped) {
|
||||
lookupOnContext: function (parts, falsy, strict, scoped) {
|
||||
let i = 0;
|
||||
|
||||
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
|
||||
// it onto the stack.
|
||||
lookupBlockParam: function(blockParamId, parts) {
|
||||
lookupBlockParam: function (blockParamId, parts) {
|
||||
this.useBlockParams = true;
|
||||
|
||||
this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
|
||||
@@ -524,7 +524,7 @@ JavaScriptCompiler.prototype = {
|
||||
// On stack, after: data, ...
|
||||
//
|
||||
// Push the data lookup operator
|
||||
lookupData: function(depth, parts, strict) {
|
||||
lookupData: function (depth, parts, strict) {
|
||||
if (!depth) {
|
||||
this.pushStackLiteral('data');
|
||||
} else {
|
||||
@@ -534,7 +534,7 @@ JavaScriptCompiler.prototype = {
|
||||
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) {
|
||||
this.push(
|
||||
strictLookup(this.options.strict && strict, this, parts, i, type)
|
||||
@@ -545,7 +545,7 @@ JavaScriptCompiler.prototype = {
|
||||
let len = parts.length;
|
||||
for (; i < len; i++) {
|
||||
/* eslint-disable no-loop-func */
|
||||
this.replaceStack(current => {
|
||||
this.replaceStack((current) => {
|
||||
let lookup = this.nameLookup(current, parts[i], type);
|
||||
// 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.
|
||||
@@ -567,27 +567,27 @@ JavaScriptCompiler.prototype = {
|
||||
//
|
||||
// If the `value` is a lambda, replace it on the stack by
|
||||
// the return value of the lambda
|
||||
resolvePossibleLambda: function() {
|
||||
resolvePossibleLambda: function () {
|
||||
this.push([
|
||||
this.aliasable('container.lambda'),
|
||||
'(',
|
||||
this.popStack(),
|
||||
', ',
|
||||
this.contextName(0),
|
||||
')'
|
||||
')',
|
||||
]);
|
||||
},
|
||||
|
||||
emptyHash: function(omitEmpty) {
|
||||
emptyHash: function (omitEmpty) {
|
||||
this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');
|
||||
},
|
||||
pushHash: function() {
|
||||
pushHash: function () {
|
||||
if (this.hash) {
|
||||
this.hashes.push(this.hash);
|
||||
}
|
||||
this.hash = { values: {} };
|
||||
},
|
||||
popHash: function() {
|
||||
popHash: function () {
|
||||
let hash = this.hash;
|
||||
this.hash = this.hashes.pop();
|
||||
|
||||
@@ -600,7 +600,7 @@ JavaScriptCompiler.prototype = {
|
||||
// On stack, after: quotedString(string), ...
|
||||
//
|
||||
// Push a quoted version of `string` onto the stack
|
||||
pushString: function(string) {
|
||||
pushString: function (string) {
|
||||
this.pushStackLiteral(this.quotedString(string));
|
||||
},
|
||||
|
||||
@@ -612,7 +612,7 @@ JavaScriptCompiler.prototype = {
|
||||
// Pushes a value onto the stack. This operation prevents
|
||||
// the compiler from creating a temporary variable to hold
|
||||
// it.
|
||||
pushLiteral: function(value) {
|
||||
pushLiteral: function (value) {
|
||||
this.pushStackLiteral(value);
|
||||
},
|
||||
|
||||
@@ -624,7 +624,7 @@ JavaScriptCompiler.prototype = {
|
||||
// Push a program expression onto the stack. This takes
|
||||
// a compile-time guid and converts it into a runtime-accessible
|
||||
// expression.
|
||||
pushProgram: function(guid) {
|
||||
pushProgram: function (guid) {
|
||||
if (guid != null) {
|
||||
this.pushStackLiteral(this.programExpression(guid));
|
||||
} else {
|
||||
@@ -649,9 +649,9 @@ JavaScriptCompiler.prototype = {
|
||||
'fn',
|
||||
'props',
|
||||
'container',
|
||||
options
|
||||
options,
|
||||
]),
|
||||
' || fn;'
|
||||
' || fn;',
|
||||
]);
|
||||
},
|
||||
|
||||
@@ -664,7 +664,7 @@ JavaScriptCompiler.prototype = {
|
||||
// and pushes the helper's return value onto the stack.
|
||||
//
|
||||
// If the helper is not found, `helperMissing` is called.
|
||||
invokeHelper: function(paramSize, name, isSimple) {
|
||||
invokeHelper: function (paramSize, name, isSimple) {
|
||||
let nonHelper = this.popStack(),
|
||||
helper = this.setupHelper(paramSize, name);
|
||||
|
||||
@@ -685,7 +685,7 @@ JavaScriptCompiler.prototype = {
|
||||
let functionLookupCode = [
|
||||
'(',
|
||||
this.itemsSeparatedBy(possibleFunctionCalls, '||'),
|
||||
')'
|
||||
')',
|
||||
];
|
||||
let functionCall = this.source.functionCall(
|
||||
functionLookupCode,
|
||||
@@ -695,7 +695,7 @@ JavaScriptCompiler.prototype = {
|
||||
this.push(functionCall);
|
||||
},
|
||||
|
||||
itemsSeparatedBy: function(items, separator) {
|
||||
itemsSeparatedBy: function (items, separator) {
|
||||
let result = [];
|
||||
result.push(items[0]);
|
||||
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,
|
||||
// so a `helperMissing` fallback is not required.
|
||||
invokeKnownHelper: function(paramSize, name) {
|
||||
invokeKnownHelper: function (paramSize, name) {
|
||||
let helper = this.setupHelper(paramSize, name);
|
||||
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,
|
||||
// and can be avoided by passing the `knownHelpers` and
|
||||
// `knownHelpersOnly` flags at compile-time.
|
||||
invokeAmbiguous: function(name, helperCall) {
|
||||
invokeAmbiguous: function (name, helperCall) {
|
||||
this.useRegister('helper');
|
||||
|
||||
let nonHelper = this.popStack();
|
||||
@@ -759,7 +759,7 @@ JavaScriptCompiler.prototype = {
|
||||
this.aliasable('"function"'),
|
||||
' ? ',
|
||||
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,
|
||||
// and pushes the result of the invocation back.
|
||||
invokePartial: function(isDynamic, name, indent) {
|
||||
invokePartial: function (isDynamic, name, indent) {
|
||||
let params = [],
|
||||
options = this.setupParams(name, 1, params);
|
||||
|
||||
@@ -807,7 +807,7 @@ JavaScriptCompiler.prototype = {
|
||||
// On stack, after: ..., 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();
|
||||
},
|
||||
|
||||
@@ -815,7 +815,7 @@ JavaScriptCompiler.prototype = {
|
||||
|
||||
compiler: JavaScriptCompiler,
|
||||
|
||||
compileChildren: function(environment, options) {
|
||||
compileChildren: function (environment, options) {
|
||||
let children = environment.children,
|
||||
child,
|
||||
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++) {
|
||||
let environment = this.context.environments[i];
|
||||
if (environment && environment.equals(child)) {
|
||||
@@ -862,7 +862,7 @@ JavaScriptCompiler.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
programExpression: function(guid) {
|
||||
programExpression: function (guid) {
|
||||
let child = this.environment.children[guid],
|
||||
programParams = [child.index, 'data', child.blockParams];
|
||||
|
||||
@@ -876,14 +876,14 @@ JavaScriptCompiler.prototype = {
|
||||
return 'container.program(' + programParams.join(', ') + ')';
|
||||
},
|
||||
|
||||
useRegister: function(name) {
|
||||
useRegister: function (name) {
|
||||
if (!this.registers[name]) {
|
||||
this.registers[name] = true;
|
||||
this.registers.list.push(name);
|
||||
}
|
||||
},
|
||||
|
||||
push: function(expr) {
|
||||
push: function (expr) {
|
||||
if (!(expr instanceof Literal)) {
|
||||
expr = this.source.wrap(expr);
|
||||
}
|
||||
@@ -892,11 +892,11 @@ JavaScriptCompiler.prototype = {
|
||||
return expr;
|
||||
},
|
||||
|
||||
pushStackLiteral: function(item) {
|
||||
pushStackLiteral: function (item) {
|
||||
this.push(new Literal(item));
|
||||
},
|
||||
|
||||
pushSource: function(source) {
|
||||
pushSource: function (source) {
|
||||
if (this.pendingContent) {
|
||||
this.source.push(
|
||||
this.appendToBuffer(
|
||||
@@ -912,7 +912,7 @@ JavaScriptCompiler.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
replaceStack: function(callback) {
|
||||
replaceStack: function (callback) {
|
||||
let prefix = ['('],
|
||||
stack,
|
||||
createdStack,
|
||||
@@ -951,17 +951,17 @@ JavaScriptCompiler.prototype = {
|
||||
this.push(prefix.concat(item, ')'));
|
||||
},
|
||||
|
||||
incrStack: function() {
|
||||
incrStack: function () {
|
||||
this.stackSlot++;
|
||||
if (this.stackSlot > this.stackVars.length) {
|
||||
this.stackVars.push('stack' + this.stackSlot);
|
||||
}
|
||||
return this.topStackName();
|
||||
},
|
||||
topStackName: function() {
|
||||
topStackName: function () {
|
||||
return 'stack' + this.stackSlot;
|
||||
},
|
||||
flushInline: function() {
|
||||
flushInline: function () {
|
||||
let inlineStack = this.inlineStack;
|
||||
this.inlineStack = [];
|
||||
for (let i = 0, len = inlineStack.length; i < len; i++) {
|
||||
@@ -976,11 +976,11 @@ JavaScriptCompiler.prototype = {
|
||||
}
|
||||
}
|
||||
},
|
||||
isInline: function() {
|
||||
isInline: function () {
|
||||
return this.inlineStack.length;
|
||||
},
|
||||
|
||||
popStack: function(wrapped) {
|
||||
popStack: function (wrapped) {
|
||||
let inline = this.isInline(),
|
||||
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,
|
||||
item = stack[stack.length - 1];
|
||||
|
||||
@@ -1010,7 +1010,7 @@ JavaScriptCompiler.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
contextName: function(context) {
|
||||
contextName: function (context) {
|
||||
if (this.useDepths && context) {
|
||||
return 'depths[' + context + ']';
|
||||
} else {
|
||||
@@ -1018,15 +1018,15 @@ JavaScriptCompiler.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
quotedString: function(str) {
|
||||
quotedString: function (str) {
|
||||
return this.source.quotedString(str);
|
||||
},
|
||||
|
||||
objectLiteral: function(obj) {
|
||||
objectLiteral: function (obj) {
|
||||
return this.source.objectLiteral(obj);
|
||||
},
|
||||
|
||||
aliasable: function(name) {
|
||||
aliasable: function (name) {
|
||||
let ret = this.aliases[name];
|
||||
if (ret) {
|
||||
ret.referenceCount++;
|
||||
@@ -1040,7 +1040,7 @@ JavaScriptCompiler.prototype = {
|
||||
return ret;
|
||||
},
|
||||
|
||||
setupHelper: function(paramSize, name, blockHelper) {
|
||||
setupHelper: function (paramSize, name, blockHelper) {
|
||||
let params = [],
|
||||
paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
|
||||
let foundHelper = this.nameLookup('helpers', name, 'helper'),
|
||||
@@ -1054,11 +1054,11 @@ JavaScriptCompiler.prototype = {
|
||||
params: params,
|
||||
paramsInit: paramsInit,
|
||||
name: foundHelper,
|
||||
callParams: [callContext].concat(params)
|
||||
callParams: [callContext].concat(params),
|
||||
};
|
||||
},
|
||||
|
||||
setupParams: function(helper, paramSize, params) {
|
||||
setupParams: function (helper, paramSize, params) {
|
||||
let options = {},
|
||||
objectArgs = !params,
|
||||
param;
|
||||
@@ -1101,7 +1101,7 @@ JavaScriptCompiler.prototype = {
|
||||
return options;
|
||||
},
|
||||
|
||||
setupHelperArgs: function(helper, paramSize, params, useRegister) {
|
||||
setupHelperArgs: function (helper, paramSize, params, useRegister) {
|
||||
let options = this.setupParams(helper, paramSize, params);
|
||||
options.loc = JSON.stringify(this.source.currentLocation);
|
||||
options = this.objectLiteral(options);
|
||||
@@ -1115,10 +1115,10 @@ JavaScriptCompiler.prototype = {
|
||||
} else {
|
||||
return options;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
(function() {
|
||||
(function () {
|
||||
const reservedWords = (
|
||||
'break else new var' +
|
||||
' case finally return void' +
|
||||
@@ -1148,7 +1148,7 @@ JavaScriptCompiler.prototype = {
|
||||
/**
|
||||
* @deprecated May be removed in the next major version
|
||||
*/
|
||||
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
|
||||
JavaScriptCompiler.isValidJavaScriptVariableName = function (name) {
|
||||
return (
|
||||
!JavaScriptCompiler.RESERVED_WORDS[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]),
|
||||
', ',
|
||||
JSON.stringify(compiler.source.currentLocation),
|
||||
' )'
|
||||
' )',
|
||||
];
|
||||
} else {
|
||||
return stack;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { extend } from '../utils';
|
||||
|
||||
export default function(instance) {
|
||||
instance.registerDecorator('inline', function(fn, props, container, options) {
|
||||
export default function (instance) {
|
||||
instance.registerDecorator(
|
||||
'inline',
|
||||
function (fn, props, container, options) {
|
||||
let ret = fn;
|
||||
if (!props.partials) {
|
||||
props.partials = {};
|
||||
ret = function(context, options) {
|
||||
ret = function (context, options) {
|
||||
// Create a new partials stack frame prior to exec.
|
||||
let original = container.partials;
|
||||
container.partials = extend({}, original, props.partials);
|
||||
@@ -18,5 +20,6 @@ export default function(instance) {
|
||||
props.partials[options.args[0]] = options.fn;
|
||||
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { isArray } from '../utils';
|
||||
|
||||
export default function(instance) {
|
||||
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||
export default function (instance) {
|
||||
instance.registerHelper('blockHelperMissing', function (context, options) {
|
||||
let inverse = options.inverse,
|
||||
fn = options.fn;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Exception } from '@handlebars/parser';
|
||||
import { createFrame, isArray, isFunction } from '../utils';
|
||||
|
||||
export default function(instance) {
|
||||
instance.registerHelper('each', function(context, options) {
|
||||
export default function (instance) {
|
||||
instance.registerHelper('each', function (context, options) {
|
||||
if (!options) {
|
||||
throw new Exception('Must pass iterator to #each');
|
||||
}
|
||||
@@ -33,7 +33,7 @@ export default function(instance) {
|
||||
ret +
|
||||
fn(context[field], {
|
||||
data: data,
|
||||
blockParams: [context[field], field]
|
||||
blockParams: [context[field], field],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ export default function(instance) {
|
||||
} else {
|
||||
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
|
||||
// the last iteration without have to scan the object twice and create
|
||||
// an intermediate keys array.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Exception } from '@handlebars/parser';
|
||||
|
||||
export default function(instance) {
|
||||
instance.registerHelper('helperMissing', function(/* [args, ]options */) {
|
||||
export default function (instance) {
|
||||
instance.registerHelper('helperMissing', function (/* [args, ]options */) {
|
||||
if (arguments.length === 1) {
|
||||
// A missing field in a {{foo}} construct.
|
||||
return undefined;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Exception } from '@handlebars/parser';
|
||||
import { isEmpty, isFunction } from '../utils';
|
||||
|
||||
export default function(instance) {
|
||||
instance.registerHelper('if', function(conditional, options) {
|
||||
export default function (instance) {
|
||||
instance.registerHelper('if', function (conditional, options) {
|
||||
if (arguments.length != 2) {
|
||||
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) {
|
||||
throw new Exception('#unless requires exactly one argument');
|
||||
}
|
||||
return instance.helpers['if'].call(this, conditional, {
|
||||
fn: options.inverse,
|
||||
inverse: options.fn,
|
||||
hash: options.hash
|
||||
hash: options.hash,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export default function(instance) {
|
||||
instance.registerHelper('log', function(/* message, options */) {
|
||||
export default function (instance) {
|
||||
instance.registerHelper('log', function (/* message, options */) {
|
||||
let args = [undefined],
|
||||
options = arguments[arguments.length - 1];
|
||||
for (let i = 0; i < arguments.length - 1; i++) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export default function(instance) {
|
||||
instance.registerHelper('lookup', function(obj, field, options) {
|
||||
export default function (instance) {
|
||||
instance.registerHelper('lookup', function (obj, field, options) {
|
||||
if (!obj) {
|
||||
// Note for 5.0: Change to "obj == null" in 5.0
|
||||
return obj;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Exception } from '@handlebars/parser';
|
||||
import { isEmpty, isFunction } from '../utils';
|
||||
|
||||
export default function(instance) {
|
||||
instance.registerHelper('with', function(context, options) {
|
||||
export default function (instance) {
|
||||
instance.registerHelper('with', function (context, options) {
|
||||
if (arguments.length != 2) {
|
||||
throw new Exception('#with requires exactly one argument');
|
||||
}
|
||||
@@ -17,7 +17,7 @@ export default function(instance) {
|
||||
|
||||
return fn(context, {
|
||||
data: data,
|
||||
blockParams: [context]
|
||||
blockParams: [context],
|
||||
});
|
||||
} else {
|
||||
return options.inverse(this);
|
||||
|
||||
@@ -20,15 +20,15 @@ export function createProtoAccessControl(runtimeOptions) {
|
||||
defaultPropertyWhiteList,
|
||||
runtimeOptions.allowedProtoProperties
|
||||
),
|
||||
defaultValue: runtimeOptions.allowProtoPropertiesByDefault
|
||||
defaultValue: runtimeOptions.allowProtoPropertiesByDefault,
|
||||
},
|
||||
methods: {
|
||||
whitelist: createNewLookupObject(
|
||||
defaultMethodWhiteList,
|
||||
runtimeOptions.allowedProtoMethods
|
||||
),
|
||||
defaultValue: runtimeOptions.allowProtoMethodsByDefault
|
||||
}
|
||||
defaultValue: runtimeOptions.allowProtoMethodsByDefault,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ function logUnexpectedPropertyAccessOnce(propertyName) {
|
||||
}
|
||||
|
||||
export function resetLoggedProperties() {
|
||||
Object.keys(loggedProperties).forEach(propertyName => {
|
||||
Object.keys(loggedProperties).forEach((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.
|
||||
return helper;
|
||||
}
|
||||
let wrapper = function(/* dynamic arguments */) {
|
||||
let wrapper = function (/* dynamic arguments */) {
|
||||
const options = arguments[arguments.length - 1];
|
||||
arguments[arguments.length - 1] = transformOptionsFn(options);
|
||||
return helper.apply(this, arguments);
|
||||
|
||||
@@ -5,7 +5,7 @@ let logger = {
|
||||
level: 'info',
|
||||
|
||||
// Maps a given level value to the `methodMap` indexes above.
|
||||
lookupLevel: function(level) {
|
||||
lookupLevel: function (level) {
|
||||
if (typeof level === 'string') {
|
||||
let levelMap = indexOf(logger.methodMap, level.toLowerCase());
|
||||
if (levelMap >= 0) {
|
||||
@@ -19,7 +19,7 @@ let logger = {
|
||||
},
|
||||
|
||||
// Can be overridden in the host environment
|
||||
log: function(level, ...message) {
|
||||
log: function (level, ...message) {
|
||||
level = logger.lookupLevel(level);
|
||||
|
||||
if (
|
||||
@@ -33,7 +33,7 @@ let logger = {
|
||||
}
|
||||
console[method](...message); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default logger;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
export default function(Handlebars) {
|
||||
export default function (Handlebars) {
|
||||
/* istanbul ignore next */
|
||||
let root = typeof global !== 'undefined' ? global : window, // eslint-disable-line no-undef
|
||||
$Handlebars = root.Handlebars;
|
||||
/* istanbul ignore next */
|
||||
Handlebars.noConflict = function() {
|
||||
Handlebars.noConflict = function () {
|
||||
if (root.Handlebars === Handlebars) {
|
||||
root.Handlebars = $Handlebars;
|
||||
}
|
||||
|
||||
+15
-15
@@ -4,13 +4,13 @@ import {
|
||||
COMPILER_REVISION,
|
||||
createFrame,
|
||||
LAST_COMPATIBLE_COMPILER_REVISION,
|
||||
REVISION_CHANGES
|
||||
REVISION_CHANGES,
|
||||
} from './base';
|
||||
import { moveHelperToHooks } from './helpers';
|
||||
import { wrapHelper } from './internal/wrapHelper';
|
||||
import {
|
||||
createProtoAccessControl,
|
||||
resultIsAllowed
|
||||
resultIsAllowed,
|
||||
} from './internal/proto-access';
|
||||
|
||||
export function checkRevision(compilerInfo) {
|
||||
@@ -73,7 +73,7 @@ export function template(templateSpec, env) {
|
||||
|
||||
let extendedOptions = Utils.extend({}, options, {
|
||||
hooks: this.hooks,
|
||||
protoAccessControl: this.protoAccessControl
|
||||
protoAccessControl: this.protoAccessControl,
|
||||
});
|
||||
|
||||
let result = env.VM.invokePartial.call(
|
||||
@@ -115,15 +115,15 @@ export function template(templateSpec, env) {
|
||||
|
||||
// Just add water
|
||||
let container = {
|
||||
strict: function(obj, name, loc) {
|
||||
strict: function (obj, name, loc) {
|
||||
if (!obj || !(name in obj)) {
|
||||
throw new Exception('"' + name + '" not defined in ' + obj, {
|
||||
loc: loc
|
||||
loc: loc,
|
||||
});
|
||||
}
|
||||
return container.lookupProperty(obj, name);
|
||||
},
|
||||
lookupProperty: function(parent, propertyName) {
|
||||
lookupProperty: function (parent, propertyName) {
|
||||
let result = parent[propertyName];
|
||||
if (result == null) {
|
||||
return result;
|
||||
@@ -137,7 +137,7 @@ export function template(templateSpec, env) {
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
lookup: function(depths, name) {
|
||||
lookup: function (depths, name) {
|
||||
const len = depths.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
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;
|
||||
},
|
||||
|
||||
escapeExpression: Utils.escapeExpression,
|
||||
invokePartial: invokePartialWrapper,
|
||||
|
||||
fn: function(i) {
|
||||
fn: function (i) {
|
||||
let ret = templateSpec[i];
|
||||
ret.decorator = templateSpec[i + '_d'];
|
||||
return ret;
|
||||
},
|
||||
|
||||
programs: [],
|
||||
program: function(i, data, declaredBlockParams, blockParams, depths) {
|
||||
program: function (i, data, declaredBlockParams, blockParams, depths) {
|
||||
let programWrapper = this.programs[i],
|
||||
fn = this.fn(i);
|
||||
if (data || depths || blockParams || declaredBlockParams) {
|
||||
@@ -179,13 +179,13 @@ export function template(templateSpec, env) {
|
||||
return programWrapper;
|
||||
},
|
||||
|
||||
data: function(value, depth) {
|
||||
data: function (value, depth) {
|
||||
while (value && depth--) {
|
||||
value = value._parent;
|
||||
}
|
||||
return value;
|
||||
},
|
||||
mergeIfNeeded: function(param, common) {
|
||||
mergeIfNeeded: function (param, common) {
|
||||
let obj = param || common;
|
||||
|
||||
if (param && common && param !== common) {
|
||||
@@ -198,7 +198,7 @@ export function template(templateSpec, env) {
|
||||
nullContext: Object.seal({}),
|
||||
|
||||
noop: env.VM.noop,
|
||||
compilerInfo: templateSpec.compiler
|
||||
compilerInfo: templateSpec.compiler,
|
||||
};
|
||||
|
||||
function ret(context, options = {}) {
|
||||
@@ -412,7 +412,7 @@ function executeDecorators(fn, prog, container, depths, data, blockParams) {
|
||||
}
|
||||
|
||||
function wrapHelpersToPassLookupProperty(mergedHelpers, container) {
|
||||
Object.keys(mergedHelpers).forEach(helperName => {
|
||||
Object.keys(mergedHelpers).forEach((helperName) => {
|
||||
let helper = mergedHelpers[helperName];
|
||||
mergedHelpers[helperName] = passLookupPropertyOption(helper, container);
|
||||
});
|
||||
@@ -420,7 +420,7 @@ function wrapHelpersToPassLookupProperty(mergedHelpers, container) {
|
||||
|
||||
function passLookupPropertyOption(helper, container) {
|
||||
const lookupProperty = container.lookupProperty;
|
||||
return wrapHelper(helper, options => {
|
||||
return wrapHelper(helper, (options) => {
|
||||
return Utils.extend({ lookupProperty }, options);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ function SafeString(string) {
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
SafeString.prototype.toString = SafeString.prototype.toHTML = function() {
|
||||
SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
|
||||
return '' + this.string;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ const escape = {
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
'`': '`',
|
||||
'=': '='
|
||||
'=': '=',
|
||||
};
|
||||
|
||||
const badChars = /[&<>"'`=]/g,
|
||||
@@ -38,7 +38,7 @@ export function isFunction(value) {
|
||||
/* istanbul ignore next */
|
||||
export const isArray =
|
||||
Array.isArray ||
|
||||
function(value) {
|
||||
function (value) {
|
||||
return value && typeof value === 'object'
|
||||
? toString.call(value) === '[object Array]'
|
||||
: false;
|
||||
|
||||
+26
-23
@@ -6,12 +6,12 @@ import * as Handlebars from './handlebars';
|
||||
import { basename } from 'path';
|
||||
import { SourceMapConsumer, SourceNode } from 'source-map';
|
||||
|
||||
module.exports.loadTemplates = function(opts, callback) {
|
||||
loadStrings(opts, function(err, strings) {
|
||||
module.exports.loadTemplates = function (opts, callback) {
|
||||
loadStrings(opts, function (err, strings) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
loadFiles(opts, function(err, files) {
|
||||
loadFiles(opts, function (err, files) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
@@ -37,7 +37,7 @@ function loadStrings(opts, callback) {
|
||||
|
||||
Async.map(
|
||||
strings,
|
||||
function(string, callback) {
|
||||
function (string, callback) {
|
||||
if (string !== '-') {
|
||||
callback(undefined, string);
|
||||
} else {
|
||||
@@ -45,19 +45,19 @@ function loadStrings(opts, callback) {
|
||||
let buffer = '';
|
||||
process.stdin.setEncoding('utf8');
|
||||
|
||||
process.stdin.on('data', function(chunk) {
|
||||
process.stdin.on('data', function (chunk) {
|
||||
buffer += chunk;
|
||||
});
|
||||
process.stdin.on('end', function() {
|
||||
process.stdin.on('end', function () {
|
||||
callback(undefined, buffer);
|
||||
});
|
||||
}
|
||||
},
|
||||
function(err, strings) {
|
||||
function (err, strings) {
|
||||
strings = strings.map((string, index) => ({
|
||||
name: names[index],
|
||||
path: names[index],
|
||||
source: string
|
||||
source: string,
|
||||
}));
|
||||
callback(err, strings);
|
||||
}
|
||||
@@ -68,20 +68,23 @@ function loadFiles(opts, callback) {
|
||||
// Build file extension pattern
|
||||
let extension = (opts.extension || 'handlebars').replace(
|
||||
/[\\^$*+?.():=!|{}\-[\]]/g,
|
||||
function(arg) {
|
||||
function (arg) {
|
||||
return '\\' + arg;
|
||||
}
|
||||
);
|
||||
extension = new RegExp('\\.' + extension + '$');
|
||||
|
||||
let ret = [],
|
||||
queue = (opts.files || []).map(template => ({ template, root: opts.root }));
|
||||
queue = (opts.files || []).map((template) => ({
|
||||
template,
|
||||
root: opts.root,
|
||||
}));
|
||||
Async.whilst(
|
||||
() => queue.length,
|
||||
function(callback) {
|
||||
function (callback) {
|
||||
let { template: path, root } = queue.shift();
|
||||
|
||||
fs.stat(path, function(err, stat) {
|
||||
fs.stat(path, function (err, stat) {
|
||||
if (err) {
|
||||
return callback(
|
||||
new Handlebars.Exception(`Unable to open template file "${path}"`)
|
||||
@@ -91,12 +94,12 @@ function loadFiles(opts, callback) {
|
||||
if (stat.isDirectory()) {
|
||||
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 */
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
children.forEach(function(file) {
|
||||
children.forEach(function (file) {
|
||||
let childPath = path + '/' + file;
|
||||
|
||||
if (
|
||||
@@ -110,7 +113,7 @@ function loadFiles(opts, callback) {
|
||||
callback();
|
||||
});
|
||||
} 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 */
|
||||
if (err) {
|
||||
return callback(err);
|
||||
@@ -132,7 +135,7 @@ function loadFiles(opts, callback) {
|
||||
ret.push({
|
||||
path: path,
|
||||
name: name,
|
||||
source: data
|
||||
source: data,
|
||||
});
|
||||
|
||||
callback();
|
||||
@@ -140,7 +143,7 @@ function loadFiles(opts, callback) {
|
||||
}
|
||||
});
|
||||
},
|
||||
function(err) {
|
||||
function (err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
@@ -150,7 +153,7 @@ function loadFiles(opts, callback) {
|
||||
);
|
||||
}
|
||||
|
||||
module.exports.cli = function(opts) {
|
||||
module.exports.cli = function (opts) {
|
||||
if (opts.version) {
|
||||
console.log(Handlebars.VERSION);
|
||||
return;
|
||||
@@ -219,10 +222,10 @@ module.exports.cli = function(opts) {
|
||||
output.add('{};\n');
|
||||
}
|
||||
|
||||
opts.templates.forEach(function(template) {
|
||||
opts.templates.forEach(function (template) {
|
||||
let options = {
|
||||
knownHelpers: known,
|
||||
knownHelpersOnly: opts.o
|
||||
knownHelpersOnly: opts.o,
|
||||
};
|
||||
|
||||
if (opts.map) {
|
||||
@@ -259,7 +262,7 @@ module.exports.cli = function(opts) {
|
||||
template.name,
|
||||
"'] = template(",
|
||||
precompiled,
|
||||
');\n'
|
||||
');\n',
|
||||
]);
|
||||
}
|
||||
});
|
||||
@@ -335,7 +338,7 @@ function minify(output, sourceMapFile) {
|
||||
return require('uglify-js').minify(output.code, {
|
||||
sourceMap: {
|
||||
content: output.map,
|
||||
url: sourceMapFile
|
||||
}
|
||||
url: sourceMapFile,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,5 +5,5 @@ module.exports = {
|
||||
functions: 100,
|
||||
statements: 100,
|
||||
exclude: ['**/spec/**'],
|
||||
reporter: 'html'
|
||||
reporter: 'html',
|
||||
};
|
||||
|
||||
Generated
+11
-8
@@ -51,7 +51,7 @@
|
||||
"mock-stdin": "^0.3.0",
|
||||
"mustache": "^2.1.3",
|
||||
"nyc": "^14.1.1",
|
||||
"prettier": "^1.19.1",
|
||||
"prettier": "^2.7.1",
|
||||
"semver": "^5.0.1",
|
||||
"sinon": "^7.5.0",
|
||||
"typescript": "^3.4.3",
|
||||
@@ -11268,15 +11268,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "1.19.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
|
||||
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-bytes": {
|
||||
@@ -23629,9 +23632,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"prettier": {
|
||||
"version": "1.19.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
|
||||
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"dev": true
|
||||
},
|
||||
"pretty-bytes": {
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@
|
||||
"mock-stdin": "^0.3.0",
|
||||
"mustache": "^2.1.3",
|
||||
"nyc": "^14.1.1",
|
||||
"prettier": "^1.19.1",
|
||||
"prettier": "^2.7.1",
|
||||
"semver": "^5.0.1",
|
||||
"sinon": "^7.5.0",
|
||||
"typescript": "^3.4.3",
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
tabWidth: 2,
|
||||
semi: true,
|
||||
singleQuote: true
|
||||
singleQuote: true,
|
||||
};
|
||||
|
||||
+4
-4
@@ -22,16 +22,16 @@ module.exports = {
|
||||
strictEqual: true,
|
||||
define: true,
|
||||
expect: true,
|
||||
chai: true
|
||||
chai: true,
|
||||
},
|
||||
env: {
|
||||
mocha: true
|
||||
mocha: true,
|
||||
},
|
||||
rules: {
|
||||
// Disabling for tests, for now.
|
||||
'no-path-concat': 'off',
|
||||
|
||||
'no-var': 'off',
|
||||
'dot-notation': 'off'
|
||||
}
|
||||
'dot-notation': 'off',
|
||||
},
|
||||
};
|
||||
|
||||
+25
-25
@@ -1,14 +1,14 @@
|
||||
describe('ast', function() {
|
||||
describe('ast', function () {
|
||||
if (!Handlebars.AST) {
|
||||
return;
|
||||
}
|
||||
|
||||
var AST = Handlebars.AST;
|
||||
|
||||
describe('BlockStatement', function() {
|
||||
it('should throw on mustache mismatch', function() {
|
||||
describe('BlockStatement', function () {
|
||||
it('should throw on mustache mismatch', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
handlebarsEnv.parse('\n {{#foo}}{{/bar}}');
|
||||
},
|
||||
Handlebars.Exception,
|
||||
@@ -17,14 +17,14 @@ describe('ast', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('helpers', function() {
|
||||
describe('#helperExpression', function() {
|
||||
it('should handle mustache statements', function() {
|
||||
describe('helpers', function () {
|
||||
describe('#helperExpression', function () {
|
||||
it('should handle mustache statements', function () {
|
||||
equals(
|
||||
AST.helpers.helperExpression({
|
||||
type: 'MustacheStatement',
|
||||
params: [],
|
||||
hash: undefined
|
||||
hash: undefined,
|
||||
}),
|
||||
false
|
||||
);
|
||||
@@ -32,7 +32,7 @@ describe('ast', function() {
|
||||
AST.helpers.helperExpression({
|
||||
type: 'MustacheStatement',
|
||||
params: [1],
|
||||
hash: undefined
|
||||
hash: undefined,
|
||||
}),
|
||||
true
|
||||
);
|
||||
@@ -40,17 +40,17 @@ describe('ast', function() {
|
||||
AST.helpers.helperExpression({
|
||||
type: 'MustacheStatement',
|
||||
params: [],
|
||||
hash: {}
|
||||
hash: {},
|
||||
}),
|
||||
true
|
||||
);
|
||||
});
|
||||
it('should handle block statements', function() {
|
||||
it('should handle block statements', function () {
|
||||
equals(
|
||||
AST.helpers.helperExpression({
|
||||
type: 'BlockStatement',
|
||||
params: [],
|
||||
hash: undefined
|
||||
hash: undefined,
|
||||
}),
|
||||
false
|
||||
);
|
||||
@@ -58,7 +58,7 @@ describe('ast', function() {
|
||||
AST.helpers.helperExpression({
|
||||
type: 'BlockStatement',
|
||||
params: [1],
|
||||
hash: undefined
|
||||
hash: undefined,
|
||||
}),
|
||||
true
|
||||
);
|
||||
@@ -66,15 +66,15 @@ describe('ast', function() {
|
||||
AST.helpers.helperExpression({
|
||||
type: 'BlockStatement',
|
||||
params: [],
|
||||
hash: {}
|
||||
hash: {},
|
||||
}),
|
||||
true
|
||||
);
|
||||
});
|
||||
it('should handle subexpressions', function() {
|
||||
it('should handle subexpressions', function () {
|
||||
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(
|
||||
@@ -107,7 +107,7 @@ describe('ast', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Line Numbers', function() {
|
||||
describe('Line Numbers', function () {
|
||||
var ast, body;
|
||||
|
||||
function testColumns(node, firstLine, lastLine, firstColumn, lastColumn) {
|
||||
@@ -134,45 +134,45 @@ describe('ast', function() {
|
||||
/* eslint-enable no-multi-spaces */
|
||||
body = ast.body;
|
||||
|
||||
it('gets ContentNode line numbers', function() {
|
||||
it('gets ContentNode line numbers', function () {
|
||||
var contentNode = body[0];
|
||||
testColumns(contentNode, 1, 1, 0, 7);
|
||||
});
|
||||
|
||||
it('gets MustacheStatement line numbers', function() {
|
||||
it('gets MustacheStatement line numbers', function () {
|
||||
var mustacheNode = body[1];
|
||||
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);
|
||||
});
|
||||
|
||||
it('gets MustacheStatement line numbers correct across newlines', function() {
|
||||
it('gets MustacheStatement line numbers correct across newlines', function () {
|
||||
var secondMustacheStatement = body[3];
|
||||
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];
|
||||
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],
|
||||
program = blockHelperNode.program;
|
||||
|
||||
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],
|
||||
inverse = blockHelperNode.inverse;
|
||||
|
||||
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];
|
||||
|
||||
testColumns(chainInverseNode.program, 8, 9, 9, 0);
|
||||
|
||||
+102
-124
@@ -1,17 +1,15 @@
|
||||
global.handlebarsEnv = null;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
global.handlebarsEnv = Handlebars.create();
|
||||
});
|
||||
|
||||
describe('basic context', function() {
|
||||
it('most basic', function() {
|
||||
expectTemplate('{{foo}}')
|
||||
.withInput({ foo: 'foo' })
|
||||
.toCompileTo('foo');
|
||||
describe('basic context', function () {
|
||||
it('most basic', function () {
|
||||
expectTemplate('{{foo}}').withInput({ foo: 'foo' }).toCompileTo('foo');
|
||||
});
|
||||
|
||||
it('escaping', function() {
|
||||
it('escaping', function () {
|
||||
expectTemplate('\\{{foo}}')
|
||||
.withInput({ foo: 'food' })
|
||||
.toCompileTo('{{foo}}');
|
||||
@@ -33,23 +31,21 @@ describe('basic context', function() {
|
||||
.toCompileTo('\\\\ food');
|
||||
});
|
||||
|
||||
it('compiling with a basic context', function() {
|
||||
it('compiling with a basic context', function () {
|
||||
expectTemplate('Goodbye\n{{cruel}}\n{{world}}!')
|
||||
.withInput({
|
||||
cruel: 'cruel',
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('It works if all the required keys are provided')
|
||||
.toCompileTo('Goodbye\ncruel\nworld!');
|
||||
});
|
||||
|
||||
it('compiling with a string context', function() {
|
||||
expectTemplate('{{.}}{{length}}')
|
||||
.withInput('bye')
|
||||
.toCompileTo('bye3');
|
||||
it('compiling with a string context', function () {
|
||||
expectTemplate('{{.}}{{length}}').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}}!')
|
||||
.withInput(undefined)
|
||||
.toCompileTo('Goodbye\n\n!');
|
||||
@@ -59,11 +55,11 @@ describe('basic context', function() {
|
||||
.toCompileTo('Goodbye');
|
||||
});
|
||||
|
||||
it('comments', function() {
|
||||
it('comments', function () {
|
||||
expectTemplate('{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!')
|
||||
.withInput({
|
||||
cruel: 'cruel',
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('comments are ignored')
|
||||
.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}}!';
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: true,
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('booleans show the contents when true')
|
||||
.toCompileTo('GOODBYE cruel world!');
|
||||
@@ -100,41 +96,37 @@ describe('basic context', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: false,
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('booleans do not show the contents when false')
|
||||
.toCompileTo('cruel world!');
|
||||
});
|
||||
|
||||
it('zeros', function() {
|
||||
it('zeros', function () {
|
||||
expectTemplate('num1: {{num1}}, num2: {{num2}}')
|
||||
.withInput({
|
||||
num1: 42,
|
||||
num2: 0
|
||||
num2: 0,
|
||||
})
|
||||
.toCompileTo('num1: 42, num2: 0');
|
||||
|
||||
expectTemplate('num: {{.}}')
|
||||
.withInput(0)
|
||||
.toCompileTo('num: 0');
|
||||
expectTemplate('num: {{.}}').withInput(0).toCompileTo('num: 0');
|
||||
|
||||
expectTemplate('num: {{num1/num2}}')
|
||||
.withInput({ num1: { num2: 0 } })
|
||||
.toCompileTo('num: 0');
|
||||
});
|
||||
|
||||
it('false', function() {
|
||||
it('false', function () {
|
||||
/* eslint-disable no-new-wrappers */
|
||||
expectTemplate('val1: {{val1}}, val2: {{val2}}')
|
||||
.withInput({
|
||||
val1: false,
|
||||
val2: new Boolean(false)
|
||||
val2: new Boolean(false),
|
||||
})
|
||||
.toCompileTo('val1: false, val2: false');
|
||||
|
||||
expectTemplate('val: {{.}}')
|
||||
.withInput(false)
|
||||
.toCompileTo('val: false');
|
||||
expectTemplate('val: {{.}}').withInput(false).toCompileTo('val: false');
|
||||
|
||||
expectTemplate('val: {{val1/val2}}')
|
||||
.withInput({ val1: { val2: false } })
|
||||
@@ -143,7 +135,7 @@ describe('basic context', function() {
|
||||
expectTemplate('val1: {{{val1}}}, val2: {{{val2}}}')
|
||||
.withInput({
|
||||
val1: false,
|
||||
val2: new Boolean(false)
|
||||
val2: new Boolean(false),
|
||||
})
|
||||
.toCompileTo('val1: false, val2: false');
|
||||
|
||||
@@ -153,10 +145,10 @@ describe('basic context', function() {
|
||||
/* eslint-enable */
|
||||
});
|
||||
|
||||
it('should handle undefined and null', function() {
|
||||
it('should handle undefined and null', function () {
|
||||
expectTemplate('{{awesome undefined null}}')
|
||||
.withInput({
|
||||
awesome: function(_undefined, _null, options) {
|
||||
awesome: function (_undefined, _null, options) {
|
||||
return (
|
||||
(_undefined === undefined) +
|
||||
' ' +
|
||||
@@ -164,34 +156,34 @@ describe('basic context', function() {
|
||||
' ' +
|
||||
typeof options
|
||||
);
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('true true object');
|
||||
|
||||
expectTemplate('{{undefined}}')
|
||||
.withInput({
|
||||
undefined: function() {
|
||||
undefined: function () {
|
||||
return 'undefined!';
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('undefined!');
|
||||
|
||||
expectTemplate('{{null}}')
|
||||
.withInput({
|
||||
null: function() {
|
||||
null: function () {
|
||||
return 'null!';
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('null!');
|
||||
});
|
||||
|
||||
it('newlines', function() {
|
||||
it('newlines', function () {
|
||||
expectTemplate("Alan's\nTest").toCompileTo("Alan's\nTest");
|
||||
|
||||
expectTemplate("Alan's\rTest").toCompileTo("Alan's\rTest");
|
||||
});
|
||||
|
||||
it('escaping text', function() {
|
||||
it('escaping text', function () {
|
||||
expectTemplate("Awesome's")
|
||||
.withMessage(
|
||||
"text is escaped so that it doesn't get caught on single quotes"
|
||||
@@ -216,7 +208,7 @@ describe('basic context', function() {
|
||||
.toCompileTo(" ' ' ");
|
||||
});
|
||||
|
||||
it('escaping expressions', function() {
|
||||
it('escaping expressions', function () {
|
||||
expectTemplate('{{{awesome}}}')
|
||||
.withInput({ awesome: "&'\\<>" })
|
||||
.withMessage("expressions with 3 handlebars aren't escaped")
|
||||
@@ -238,140 +230,140 @@ describe('basic context', function() {
|
||||
.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}}')
|
||||
.withInput({
|
||||
awesome: function() {
|
||||
awesome: function () {
|
||||
return new Handlebars.SafeString("&'\\<>");
|
||||
}
|
||||
},
|
||||
})
|
||||
.withMessage("functions returning safestrings aren't escaped")
|
||||
.toCompileTo("&'\\<>");
|
||||
});
|
||||
|
||||
it('functions', function() {
|
||||
it('functions', function () {
|
||||
expectTemplate('{{awesome}}')
|
||||
.withInput({
|
||||
awesome: function() {
|
||||
awesome: function () {
|
||||
return 'Awesome';
|
||||
}
|
||||
},
|
||||
})
|
||||
.withMessage('functions are called and render their output')
|
||||
.toCompileTo('Awesome');
|
||||
|
||||
expectTemplate('{{awesome}}')
|
||||
.withInput({
|
||||
awesome: function() {
|
||||
awesome: function () {
|
||||
return this.more;
|
||||
},
|
||||
more: 'More awesome'
|
||||
more: 'More awesome',
|
||||
})
|
||||
.withMessage('functions are bound to the context')
|
||||
.toCompileTo('More awesome');
|
||||
});
|
||||
|
||||
it('functions with context argument', function() {
|
||||
it('functions with context argument', function () {
|
||||
expectTemplate('{{awesome frank}}')
|
||||
.withInput({
|
||||
awesome: function(context) {
|
||||
awesome: function (context) {
|
||||
return context;
|
||||
},
|
||||
frank: 'Frank'
|
||||
frank: 'Frank',
|
||||
})
|
||||
.withMessage('functions are called with context arguments')
|
||||
.toCompileTo('Frank');
|
||||
});
|
||||
|
||||
it('pathed functions with context argument', function() {
|
||||
it('pathed functions with context argument', function () {
|
||||
expectTemplate('{{bar.awesome frank}}')
|
||||
.withInput({
|
||||
bar: {
|
||||
awesome: function(context) {
|
||||
awesome: function (context) {
|
||||
return context;
|
||||
}
|
||||
},
|
||||
frank: 'Frank'
|
||||
},
|
||||
frank: 'Frank',
|
||||
})
|
||||
.withMessage('functions are called with context arguments')
|
||||
.toCompileTo('Frank');
|
||||
});
|
||||
|
||||
it('depthed functions with context argument', function() {
|
||||
it('depthed functions with context argument', function () {
|
||||
expectTemplate('{{#with frank}}{{../awesome .}}{{/with}}')
|
||||
.withInput({
|
||||
awesome: function(context) {
|
||||
awesome: function (context) {
|
||||
return context;
|
||||
},
|
||||
frank: 'Frank'
|
||||
frank: 'Frank',
|
||||
})
|
||||
.withMessage('functions are called with context arguments')
|
||||
.toCompileTo('Frank');
|
||||
});
|
||||
|
||||
it('block functions with context argument', function() {
|
||||
it('block functions with context argument', function () {
|
||||
expectTemplate('{{#awesome 1}}inner {{.}}{{/awesome}}')
|
||||
.withInput({
|
||||
awesome: function(context, options) {
|
||||
awesome: function (context, options) {
|
||||
return options.fn(context);
|
||||
}
|
||||
},
|
||||
})
|
||||
.withMessage('block functions are called with context and options')
|
||||
.toCompileTo('inner 1');
|
||||
});
|
||||
|
||||
it('depthed block functions with context argument', function() {
|
||||
it('depthed block functions with context argument', function () {
|
||||
expectTemplate(
|
||||
'{{#with value}}{{#../awesome 1}}inner {{.}}{{/../awesome}}{{/with}}'
|
||||
)
|
||||
.withInput({
|
||||
value: true,
|
||||
awesome: function(context, options) {
|
||||
awesome: function (context, options) {
|
||||
return options.fn(context);
|
||||
}
|
||||
},
|
||||
})
|
||||
.withMessage('block functions are called with context and options')
|
||||
.toCompileTo('inner 1');
|
||||
});
|
||||
|
||||
it('block functions without context argument', function() {
|
||||
it('block functions without context argument', function () {
|
||||
expectTemplate('{{#awesome}}inner{{/awesome}}')
|
||||
.withInput({
|
||||
awesome: function(options) {
|
||||
awesome: function (options) {
|
||||
return options.fn(this);
|
||||
}
|
||||
},
|
||||
})
|
||||
.withMessage('block functions are called with options')
|
||||
.toCompileTo('inner');
|
||||
});
|
||||
|
||||
it('pathed block functions without context argument', function() {
|
||||
it('pathed block functions without context argument', function () {
|
||||
expectTemplate('{{#foo.awesome}}inner{{/foo.awesome}}')
|
||||
.withInput({
|
||||
foo: {
|
||||
awesome: function() {
|
||||
awesome: function () {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
.withMessage('block functions are called with options')
|
||||
.toCompileTo('inner');
|
||||
});
|
||||
|
||||
it('depthed block functions without context argument', function() {
|
||||
it('depthed block functions without context argument', function () {
|
||||
expectTemplate(
|
||||
'{{#with value}}{{#../awesome}}inner{{/../awesome}}{{/with}}'
|
||||
)
|
||||
.withInput({
|
||||
value: true,
|
||||
awesome: function() {
|
||||
awesome: function () {
|
||||
return this;
|
||||
}
|
||||
},
|
||||
})
|
||||
.withMessage('block functions are called with options')
|
||||
.toCompileTo('inner');
|
||||
});
|
||||
|
||||
it('paths with hyphens', function() {
|
||||
it('paths with hyphens', function () {
|
||||
expectTemplate('{{foo-bar}}')
|
||||
.withInput({ 'foo-bar': 'baz' })
|
||||
.withMessage('Paths can contain hyphens (-)')
|
||||
@@ -388,21 +380,21 @@ describe('basic context', function() {
|
||||
.toCompileTo('baz');
|
||||
});
|
||||
|
||||
it('nested paths', function() {
|
||||
it('nested paths', function () {
|
||||
expectTemplate('Goodbye {{alan/expression}} world!')
|
||||
.withInput({ alan: { expression: 'beautiful' } })
|
||||
.withMessage('Nested paths access nested objects')
|
||||
.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!')
|
||||
.withInput({ alan: { expression: '' } })
|
||||
.withMessage('Nested paths access nested objects with empty string')
|
||||
.toCompileTo('Goodbye world!');
|
||||
});
|
||||
|
||||
it('literal paths', function() {
|
||||
it('literal paths', function () {
|
||||
expectTemplate('Goodbye {{[@alan]/expression}} world!')
|
||||
.withInput({ '@alan': { expression: 'beautiful' } })
|
||||
.withMessage('Literal paths can be used')
|
||||
@@ -414,7 +406,7 @@ describe('basic context', function() {
|
||||
.toCompileTo('Goodbye beautiful world!');
|
||||
});
|
||||
|
||||
it('literal references', function() {
|
||||
it('literal references', function () {
|
||||
expectTemplate('Goodbye {{[foo bar]}} world!')
|
||||
.withInput({ 'foo bar': 'beautiful' })
|
||||
.toCompileTo('Goodbye beautiful world!');
|
||||
@@ -440,24 +432,22 @@ describe('basic context', function() {
|
||||
.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: {{.}}')
|
||||
.withInput(null)
|
||||
.withHelpers({ helper: 'awesome' })
|
||||
.toCompileTo('test: ');
|
||||
});
|
||||
|
||||
it('complex but empty paths', function() {
|
||||
it('complex but empty paths', function () {
|
||||
expectTemplate('{{person/name}}')
|
||||
.withInput({ person: { name: null } })
|
||||
.toCompileTo('');
|
||||
|
||||
expectTemplate('{{person/name}}')
|
||||
.withInput({ person: {} })
|
||||
.toCompileTo('');
|
||||
expectTemplate('{{person/name}}').withInput({ person: {} }).toCompileTo('');
|
||||
});
|
||||
|
||||
it('this keyword in paths', function() {
|
||||
it('this keyword in paths', function () {
|
||||
expectTemplate('{{#goodbyes}}{{this}}{{/goodbyes}}')
|
||||
.withInput({ goodbyes: ['goodbye', 'Goodbye', 'GOODBYE'] })
|
||||
.withMessage('This keyword in paths evaluates to current context')
|
||||
@@ -465,32 +455,30 @@ describe('basic context', function() {
|
||||
|
||||
expectTemplate('{{#hellos}}{{this/text}}{{/hellos}}')
|
||||
.withInput({
|
||||
hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }]
|
||||
hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }],
|
||||
})
|
||||
.withMessage('This keyword evaluates in more complex paths')
|
||||
.toCompileTo('helloHelloHELLO');
|
||||
});
|
||||
|
||||
it('this keyword nested inside path', function() {
|
||||
it('this keyword nested inside path', function () {
|
||||
expectTemplate('{{#hellos}}{{text/this/foo}}{{/hellos}}').toThrow(
|
||||
Error,
|
||||
'Invalid path: text/this - 1:13'
|
||||
);
|
||||
|
||||
expectTemplate('{{[this]}}')
|
||||
.withInput({ this: 'bar' })
|
||||
.toCompileTo('bar');
|
||||
expectTemplate('{{[this]}}').withInput({ this: 'bar' }).toCompileTo('bar');
|
||||
|
||||
expectTemplate('{{text/[this]}}')
|
||||
.withInput({ text: { this: 'bar' } })
|
||||
.toCompileTo('bar');
|
||||
});
|
||||
|
||||
it('this keyword in helpers', function() {
|
||||
it('this keyword in helpers', function () {
|
||||
var helpers = {
|
||||
foo: function(value) {
|
||||
foo: function (value) {
|
||||
return 'bar ' + value;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
expectTemplate('{{#goodbyes}}{{foo this}}{{/goodbyes}}')
|
||||
@@ -501,14 +489,14 @@ describe('basic context', function() {
|
||||
|
||||
expectTemplate('{{#hellos}}{{foo this/text}}{{/hellos}}')
|
||||
.withInput({
|
||||
hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }]
|
||||
hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }],
|
||||
})
|
||||
.withHelpers(helpers)
|
||||
.withMessage('This keyword evaluates in more complex paths')
|
||||
.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(
|
||||
Error,
|
||||
'Invalid path: text/this - 1:17'
|
||||
@@ -516,79 +504,69 @@ describe('basic context', function() {
|
||||
|
||||
expectTemplate('{{foo [this]}}')
|
||||
.withInput({
|
||||
foo: function(value) {
|
||||
foo: function (value) {
|
||||
return value;
|
||||
},
|
||||
this: 'bar'
|
||||
this: 'bar',
|
||||
})
|
||||
.toCompileTo('bar');
|
||||
|
||||
expectTemplate('{{foo text/[this]}}')
|
||||
.withInput({
|
||||
foo: function(value) {
|
||||
foo: function (value) {
|
||||
return value;
|
||||
},
|
||||
text: { this: 'bar' }
|
||||
text: { this: 'bar' },
|
||||
})
|
||||
.toCompileTo('bar');
|
||||
});
|
||||
|
||||
it('pass string literals', function() {
|
||||
it('pass string literals', function () {
|
||||
expectTemplate('{{"foo"}}').toCompileTo('');
|
||||
|
||||
expectTemplate('{{"foo"}}')
|
||||
.withInput({ foo: 'bar' })
|
||||
.toCompileTo('bar');
|
||||
expectTemplate('{{"foo"}}').withInput({ foo: 'bar' }).toCompileTo('bar');
|
||||
|
||||
expectTemplate('{{#"foo"}}{{.}}{{/"foo"}}')
|
||||
.withInput({
|
||||
foo: ['bar', 'baz']
|
||||
foo: ['bar', 'baz'],
|
||||
})
|
||||
.toCompileTo('barbaz');
|
||||
});
|
||||
|
||||
it('pass number literals', function() {
|
||||
it('pass number literals', function () {
|
||||
expectTemplate('{{12}}').toCompileTo('');
|
||||
|
||||
expectTemplate('{{12}}')
|
||||
.withInput({ '12': 'bar' })
|
||||
.toCompileTo('bar');
|
||||
expectTemplate('{{12}}').withInput({ 12: 'bar' }).toCompileTo('bar');
|
||||
|
||||
expectTemplate('{{12.34}}').toCompileTo('');
|
||||
|
||||
expectTemplate('{{12.34}}')
|
||||
.withInput({ '12.34': 'bar' })
|
||||
.toCompileTo('bar');
|
||||
expectTemplate('{{12.34}}').withInput({ 12.34: 'bar' }).toCompileTo('bar');
|
||||
|
||||
expectTemplate('{{12.34 1}}')
|
||||
.withInput({
|
||||
'12.34': function(arg) {
|
||||
12.34: function (arg) {
|
||||
return 'bar' + arg;
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('bar1');
|
||||
});
|
||||
|
||||
it('pass boolean literals', function() {
|
||||
it('pass boolean literals', function () {
|
||||
expectTemplate('{{true}}').toCompileTo('');
|
||||
|
||||
expectTemplate('{{true}}')
|
||||
.withInput({ '': 'foo' })
|
||||
.toCompileTo('');
|
||||
expectTemplate('{{true}}').withInput({ '': 'foo' }).toCompileTo('');
|
||||
|
||||
expectTemplate('{{false}}')
|
||||
.withInput({ false: 'foo' })
|
||||
.toCompileTo('foo');
|
||||
expectTemplate('{{false}}').withInput({ false: 'foo' }).toCompileTo('foo');
|
||||
});
|
||||
|
||||
it('should handle literals in subexpression', function() {
|
||||
it('should handle literals in subexpression', function () {
|
||||
expectTemplate('{{foo (false)}}')
|
||||
.withInput({
|
||||
false: function() {
|
||||
false: function () {
|
||||
return 'bar';
|
||||
}
|
||||
},
|
||||
})
|
||||
.withHelper('foo', function(arg) {
|
||||
.withHelper('foo', function (arg) {
|
||||
return arg;
|
||||
})
|
||||
.toCompileTo('bar');
|
||||
|
||||
+84
-84
@@ -1,5 +1,5 @@
|
||||
describe('blocks', function() {
|
||||
it('array', function() {
|
||||
describe('blocks', function () {
|
||||
it('array', function () {
|
||||
var string = '{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!';
|
||||
|
||||
expectTemplate(string)
|
||||
@@ -7,9 +7,9 @@ describe('blocks', function() {
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('Arrays iterate over the contents when not empty')
|
||||
.toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!');
|
||||
@@ -17,13 +17,13 @@ describe('blocks', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbyes: [],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('Arrays ignore the contents when empty')
|
||||
.toCompileTo('cruel world!');
|
||||
});
|
||||
|
||||
it('array without data', function() {
|
||||
it('array without data', function () {
|
||||
expectTemplate(
|
||||
'{{#goodbyes}}{{text}}{{/goodbyes}} {{#goodbyes}}{{text}}{{/goodbyes}}'
|
||||
)
|
||||
@@ -31,15 +31,15 @@ describe('blocks', function() {
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withCompileOptions({ compat: false })
|
||||
.toCompileTo('goodbyeGoodbyeGOODBYE goodbyeGoodbyeGOODBYE');
|
||||
});
|
||||
|
||||
it('array with @index', function() {
|
||||
it('array with @index', function () {
|
||||
expectTemplate(
|
||||
'{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!'
|
||||
)
|
||||
@@ -47,15 +47,15 @@ describe('blocks', function() {
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('The @index variable is used')
|
||||
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
||||
});
|
||||
|
||||
it('empty block', function() {
|
||||
it('empty block', function () {
|
||||
var string = '{{#goodbyes}}{{/goodbyes}}cruel {{world}}!';
|
||||
|
||||
expectTemplate(string)
|
||||
@@ -63,9 +63,9 @@ describe('blocks', function() {
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('Arrays iterate over the contents when not empty')
|
||||
.toCompileTo('cruel world!');
|
||||
@@ -73,21 +73,21 @@ describe('blocks', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbyes: [],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('Arrays ignore the contents when empty')
|
||||
.toCompileTo('cruel world!');
|
||||
});
|
||||
|
||||
it('block with complex lookup', function() {
|
||||
it('block with complex lookup', function () {
|
||||
expectTemplate('{{#goodbyes}}{{text}} cruel {{../name}}! {{/goodbyes}}')
|
||||
.withInput({
|
||||
name: 'Alan',
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
]
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
})
|
||||
.withMessage(
|
||||
'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}}')
|
||||
.withInput({
|
||||
name: 'Alan',
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
]
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
})
|
||||
.toCompileTo('AlanAlanAlanAlanAlanAlan');
|
||||
});
|
||||
|
||||
it('block with complex lookup using nested context', function() {
|
||||
it('block with complex lookup using nested context', function () {
|
||||
expectTemplate(
|
||||
'{{#goodbyes}}{{text}} cruel {{foo/../name}}! {{/goodbyes}}'
|
||||
).toThrow(Error);
|
||||
});
|
||||
|
||||
it('block with deep nested complex lookup', function() {
|
||||
it('block with deep nested complex lookup', function () {
|
||||
expectTemplate(
|
||||
'{{#outer}}Goodbye {{#inner}}cruel {{../sibling}} {{../../omg}}{{/inner}}{{/outer}}'
|
||||
)
|
||||
.withInput({
|
||||
omg: 'OMG!',
|
||||
outer: [{ sibling: 'sad', inner: [{ text: 'goodbye' }] }]
|
||||
outer: [{ sibling: 'sad', inner: [{ text: 'goodbye' }] }],
|
||||
})
|
||||
.toCompileTo('Goodbye cruel sad OMG!');
|
||||
});
|
||||
|
||||
it('works with cached blocks', function() {
|
||||
it('works with cached blocks', function () {
|
||||
expectTemplate(
|
||||
'{{#each person}}{{#with .}}{{first}} {{last}}{{/with}}{{/each}}'
|
||||
)
|
||||
@@ -135,14 +135,14 @@ describe('blocks', function() {
|
||||
.withInput({
|
||||
person: [
|
||||
{ first: 'Alan', last: 'Johnson' },
|
||||
{ first: 'Alan', last: 'Johnson' }
|
||||
]
|
||||
{ first: 'Alan', last: 'Johnson' },
|
||||
],
|
||||
})
|
||||
.toCompileTo('Alan JohnsonAlan Johnson');
|
||||
});
|
||||
|
||||
describe('inverted sections', function() {
|
||||
it('inverted sections with unset value', function() {
|
||||
describe('inverted sections', function () {
|
||||
it('inverted sections with unset value', function () {
|
||||
expectTemplate(
|
||||
'{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
|
||||
)
|
||||
@@ -150,7 +150,7 @@ describe('blocks', function() {
|
||||
.toCompileTo('Right On!');
|
||||
});
|
||||
|
||||
it('inverted section with false value', function() {
|
||||
it('inverted section with false value', function () {
|
||||
expectTemplate(
|
||||
'{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
|
||||
)
|
||||
@@ -159,7 +159,7 @@ describe('blocks', function() {
|
||||
.toCompileTo('Right On!');
|
||||
});
|
||||
|
||||
it('inverted section with empty set', function() {
|
||||
it('inverted section with empty set', function () {
|
||||
expectTemplate(
|
||||
'{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
|
||||
)
|
||||
@@ -168,13 +168,13 @@ describe('blocks', function() {
|
||||
.toCompileTo('Right On!');
|
||||
});
|
||||
|
||||
it('block inverted sections', function() {
|
||||
it('block inverted sections', function () {
|
||||
expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}')
|
||||
.withInput({ none: 'No people' })
|
||||
.toCompileTo('No people');
|
||||
});
|
||||
|
||||
it('chained inverted sections', function() {
|
||||
it('chained inverted sections', function () {
|
||||
expectTemplate('{{#people}}{{name}}{{else if none}}{{none}}{{/people}}')
|
||||
.withInput({ none: 'No people' })
|
||||
.toCompileTo('No people');
|
||||
@@ -192,24 +192,24 @@ describe('blocks', function() {
|
||||
.toCompileTo('No people');
|
||||
});
|
||||
|
||||
it('chained inverted sections with mismatch', function() {
|
||||
it('chained inverted sections with mismatch', function () {
|
||||
expectTemplate(
|
||||
'{{#people}}{{name}}{{else if none}}{{none}}{{/if}}'
|
||||
).toThrow(Error);
|
||||
});
|
||||
|
||||
it('block inverted sections with empty arrays', function() {
|
||||
it('block inverted sections with empty arrays', function () {
|
||||
expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}')
|
||||
.withInput({
|
||||
none: 'No people',
|
||||
people: []
|
||||
people: [],
|
||||
})
|
||||
.toCompileTo('No people');
|
||||
});
|
||||
});
|
||||
|
||||
describe('standalone sections', function() {
|
||||
it('block standalone else sections', function() {
|
||||
describe('standalone sections', function () {
|
||||
it('block standalone else sections', function () {
|
||||
expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n')
|
||||
.withInput({ none: 'No people' })
|
||||
.toCompileTo('No people\n');
|
||||
@@ -223,7 +223,7 @@ describe('blocks', function() {
|
||||
.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')
|
||||
.withInput({ none: 'No people' })
|
||||
.withCompileOptions({ ignoreStandalone: true })
|
||||
@@ -235,7 +235,7 @@ describe('blocks', function() {
|
||||
.toCompileTo('\nNo people\n\n');
|
||||
});
|
||||
|
||||
it('block standalone chained else sections', function() {
|
||||
it('block standalone chained else sections', function () {
|
||||
expectTemplate(
|
||||
'{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n'
|
||||
)
|
||||
@@ -249,17 +249,17 @@ describe('blocks', function() {
|
||||
.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.')
|
||||
.withInput({
|
||||
data: [1, 3, 5]
|
||||
data: [1, 3, 5],
|
||||
})
|
||||
.toCompileTo('1\n3\n5\nOK.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('compat mode', function() {
|
||||
it('block with deep recursive lookup lookup', function() {
|
||||
describe('compat mode', function () {
|
||||
it('block with deep recursive lookup lookup', function () {
|
||||
expectTemplate(
|
||||
'{{#outer}}Goodbye {{#inner}}cruel {{omg}}{{/inner}}{{/outer}}'
|
||||
)
|
||||
@@ -268,108 +268,108 @@ describe('blocks', function() {
|
||||
.toCompileTo('Goodbye cruel OMG!');
|
||||
});
|
||||
|
||||
it('block with deep recursive pathed lookup', function() {
|
||||
it('block with deep recursive pathed lookup', function () {
|
||||
expectTemplate(
|
||||
'{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}'
|
||||
)
|
||||
.withInput({
|
||||
omg: { yes: 'OMG!' },
|
||||
outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }]
|
||||
outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }],
|
||||
})
|
||||
.withCompileOptions({ compat: true })
|
||||
.toCompileTo('Goodbye cruel OMG!');
|
||||
});
|
||||
|
||||
it('block with missed recursive lookup', function() {
|
||||
it('block with missed recursive lookup', function () {
|
||||
expectTemplate(
|
||||
'{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}'
|
||||
)
|
||||
.withInput({
|
||||
omg: { no: 'OMG!' },
|
||||
outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }]
|
||||
outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }],
|
||||
})
|
||||
.withCompileOptions({ compat: true })
|
||||
.toCompileTo('Goodbye cruel ');
|
||||
});
|
||||
});
|
||||
|
||||
describe('decorators', function() {
|
||||
it('should apply mustache decorators', function() {
|
||||
describe('decorators', function () {
|
||||
it('should apply mustache decorators', function () {
|
||||
expectTemplate('{{#helper}}{{*decorator}}{{/helper}}')
|
||||
.withHelper('helper', function(options) {
|
||||
.withHelper('helper', function (options) {
|
||||
return options.fn.run;
|
||||
})
|
||||
.withDecorator('decorator', function(fn) {
|
||||
.withDecorator('decorator', function (fn) {
|
||||
fn.run = 'success';
|
||||
return fn;
|
||||
})
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should apply allow undefined return', function() {
|
||||
it('should apply allow undefined return', function () {
|
||||
expectTemplate('{{#helper}}{{*decorator}}suc{{/helper}}')
|
||||
.withHelper('helper', function(options) {
|
||||
.withHelper('helper', function (options) {
|
||||
return options.fn() + options.fn.run;
|
||||
})
|
||||
.withDecorator('decorator', function(fn) {
|
||||
.withDecorator('decorator', function (fn) {
|
||||
fn.run = 'cess';
|
||||
})
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should apply block decorators', function() {
|
||||
it('should apply block decorators', function () {
|
||||
expectTemplate(
|
||||
'{{#helper}}{{#*decorator}}success{{/decorator}}{{/helper}}'
|
||||
)
|
||||
.withHelper('helper', function(options) {
|
||||
.withHelper('helper', function (options) {
|
||||
return options.fn.run;
|
||||
})
|
||||
.withDecorator('decorator', function(fn, props, container, options) {
|
||||
.withDecorator('decorator', function (fn, props, container, options) {
|
||||
fn.run = options.fn();
|
||||
return fn;
|
||||
})
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should support nested decorators', function() {
|
||||
it('should support nested decorators', function () {
|
||||
expectTemplate(
|
||||
'{{#helper}}{{#*decorator}}{{#*nested}}suc{{/nested}}cess{{/decorator}}{{/helper}}'
|
||||
)
|
||||
.withHelper('helper', function(options) {
|
||||
.withHelper('helper', function (options) {
|
||||
return options.fn.run;
|
||||
})
|
||||
.withDecorators({
|
||||
decorator: function(fn, props, container, options) {
|
||||
decorator: function (fn, props, container, options) {
|
||||
fn.run = options.fn.nested + options.fn();
|
||||
return fn;
|
||||
},
|
||||
nested: function(fn, props, container, options) {
|
||||
nested: function (fn, props, container, options) {
|
||||
props.nested = options.fn();
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should apply multiple decorators', function() {
|
||||
it('should apply multiple decorators', function () {
|
||||
expectTemplate(
|
||||
'{{#helper}}{{#*decorator}}suc{{/decorator}}{{#*decorator}}cess{{/decorator}}{{/helper}}'
|
||||
)
|
||||
.withHelper('helper', function(options) {
|
||||
.withHelper('helper', function (options) {
|
||||
return options.fn.run;
|
||||
})
|
||||
.withDecorator('decorator', function(fn, props, container, options) {
|
||||
.withDecorator('decorator', function (fn, props, container, options) {
|
||||
fn.run = (fn.run || '') + options.fn();
|
||||
return fn;
|
||||
})
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should access parent variables', function() {
|
||||
it('should access parent variables', function () {
|
||||
expectTemplate('{{#helper}}{{*decorator foo}}{{/helper}}')
|
||||
.withHelper('helper', function(options) {
|
||||
.withHelper('helper', function (options) {
|
||||
return options.fn.run;
|
||||
})
|
||||
.withDecorator('decorator', function(fn, props, container, options) {
|
||||
.withDecorator('decorator', function (fn, props, container, options) {
|
||||
fn.run = options.args;
|
||||
return fn;
|
||||
})
|
||||
@@ -377,10 +377,10 @@ describe('blocks', function() {
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should work with root program', function() {
|
||||
it('should work with root program', function () {
|
||||
var run;
|
||||
expectTemplate('{{*decorator "success"}}')
|
||||
.withDecorator('decorator', function(fn, props, container, options) {
|
||||
.withDecorator('decorator', function (fn, props, container, options) {
|
||||
equals(options.args[0], 'success');
|
||||
run = true;
|
||||
return fn;
|
||||
@@ -390,10 +390,10 @@ describe('blocks', function() {
|
||||
equals(run, true);
|
||||
});
|
||||
|
||||
it('should fail when accessing variables from root', function() {
|
||||
it('should fail when accessing variables from root', function () {
|
||||
var run;
|
||||
expectTemplate('{{*decorator foo}}')
|
||||
.withDecorator('decorator', function(fn, props, container, options) {
|
||||
.withDecorator('decorator', function (fn, props, container, options) {
|
||||
equals(options.args[0], undefined);
|
||||
run = true;
|
||||
return fn;
|
||||
@@ -403,11 +403,11 @@ describe('blocks', function() {
|
||||
equals(run, true);
|
||||
});
|
||||
|
||||
describe('registration', function() {
|
||||
it('unregisters', function() {
|
||||
describe('registration', function () {
|
||||
it('unregisters', function () {
|
||||
handlebarsEnv.decorators = {};
|
||||
|
||||
handlebarsEnv.registerDecorator('foo', function() {
|
||||
handlebarsEnv.registerDecorator('foo', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
@@ -416,12 +416,12 @@ describe('blocks', function() {
|
||||
equals(handlebarsEnv.decorators.foo, undefined);
|
||||
});
|
||||
|
||||
it('allows multiple globals', function() {
|
||||
it('allows multiple globals', function () {
|
||||
handlebarsEnv.decorators = {};
|
||||
|
||||
handlebarsEnv.registerDecorator({
|
||||
foo: function() {},
|
||||
bar: function() {}
|
||||
foo: function () {},
|
||||
bar: function () {},
|
||||
});
|
||||
|
||||
equals(!!handlebarsEnv.decorators.foo, true);
|
||||
@@ -432,17 +432,17 @@ describe('blocks', function() {
|
||||
equals(handlebarsEnv.decorators.bar, undefined);
|
||||
});
|
||||
|
||||
it('fails with multiple and args', function() {
|
||||
it('fails with multiple and args', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
handlebarsEnv.registerDecorator(
|
||||
{
|
||||
world: function() {
|
||||
world: function () {
|
||||
return 'world!';
|
||||
},
|
||||
testHelper: function() {
|
||||
testHelper: function () {
|
||||
return 'found it!';
|
||||
}
|
||||
},
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
+125
-123
@@ -1,12 +1,12 @@
|
||||
describe('builtin helpers', function() {
|
||||
describe('#if', function() {
|
||||
it('if', function() {
|
||||
describe('builtin helpers', function () {
|
||||
describe('#if', function () {
|
||||
it('if', function () {
|
||||
var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
|
||||
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: true,
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('if with boolean argument shows the contents when true')
|
||||
.toCompileTo('GOODBYE cruel world!');
|
||||
@@ -14,7 +14,7 @@ describe('builtin helpers', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: 'dummy',
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('if with string argument shows the contents')
|
||||
.toCompileTo('GOODBYE cruel world!');
|
||||
@@ -22,7 +22,7 @@ describe('builtin helpers', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: false,
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage(
|
||||
'if with boolean argument does not show the contents when false'
|
||||
@@ -37,7 +37,7 @@ describe('builtin helpers', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: ['foo'],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('if with non-empty array shows the contents')
|
||||
.toCompileTo('GOODBYE cruel world!');
|
||||
@@ -45,7 +45,7 @@ describe('builtin helpers', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: [],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('if with empty array does not show the contents')
|
||||
.toCompileTo('cruel world!');
|
||||
@@ -53,7 +53,7 @@ describe('builtin helpers', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: 0,
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('if with zero does not show the contents')
|
||||
.toCompileTo('cruel world!');
|
||||
@@ -63,21 +63,21 @@ describe('builtin helpers', function() {
|
||||
)
|
||||
.withInput({
|
||||
goodbye: 0,
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('if with zero does not show the contents')
|
||||
.toCompileTo('GOODBYE cruel world!');
|
||||
});
|
||||
|
||||
it('if with function argument', function() {
|
||||
it('if with function argument', function () {
|
||||
var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
|
||||
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: function() {
|
||||
goodbye: function () {
|
||||
return true;
|
||||
},
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage(
|
||||
'if with function shows the contents when function returns true'
|
||||
@@ -86,10 +86,10 @@ describe('builtin helpers', function() {
|
||||
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: function() {
|
||||
goodbye: function () {
|
||||
return this.world;
|
||||
},
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage(
|
||||
'if with function shows the contents when function returns string'
|
||||
@@ -98,10 +98,10 @@ describe('builtin helpers', function() {
|
||||
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: function() {
|
||||
goodbye: function () {
|
||||
return false;
|
||||
},
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage(
|
||||
'if with function does not show the contents when returns false'
|
||||
@@ -110,10 +110,10 @@ describe('builtin helpers', function() {
|
||||
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbye: function() {
|
||||
goodbye: function () {
|
||||
return this.foo;
|
||||
},
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage(
|
||||
'if with function does not show the contents when returns undefined'
|
||||
@@ -121,61 +121,61 @@ describe('builtin helpers', function() {
|
||||
.toCompileTo('cruel world!');
|
||||
});
|
||||
|
||||
it('should not change the depth list', function() {
|
||||
it('should not change the depth list', function () {
|
||||
expectTemplate(
|
||||
'{{#with foo}}{{#if goodbye}}GOODBYE cruel {{../world}}!{{/if}}{{/with}}'
|
||||
)
|
||||
.withInput({
|
||||
foo: { goodbye: true },
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.toCompileTo('GOODBYE cruel world!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#with', function() {
|
||||
it('with', function() {
|
||||
describe('#with', function () {
|
||||
it('with', function () {
|
||||
expectTemplate('{{#with person}}{{first}} {{last}}{{/with}}')
|
||||
.withInput({
|
||||
person: {
|
||||
first: 'Alan',
|
||||
last: 'Johnson'
|
||||
}
|
||||
last: 'Johnson',
|
||||
},
|
||||
})
|
||||
.toCompileTo('Alan Johnson');
|
||||
});
|
||||
|
||||
it('with with function argument', function() {
|
||||
it('with with function argument', function () {
|
||||
expectTemplate('{{#with person}}{{first}} {{last}}{{/with}}')
|
||||
.withInput({
|
||||
person: function() {
|
||||
person: function () {
|
||||
return {
|
||||
first: 'Alan',
|
||||
last: 'Johnson'
|
||||
last: 'Johnson',
|
||||
};
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('Alan Johnson');
|
||||
});
|
||||
|
||||
it('with with else', function() {
|
||||
it('with with else', function () {
|
||||
expectTemplate(
|
||||
'{{#with person}}Person is present{{else}}Person is not present{{/with}}'
|
||||
).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}}')
|
||||
.withInput({
|
||||
person: {
|
||||
first: 'Alan',
|
||||
last: 'Johnson'
|
||||
}
|
||||
last: '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}}')
|
||||
.withInput({ person: { first: 'Alan', last: 'Johnson' } })
|
||||
.withCompileOptions({ data: false })
|
||||
@@ -183,14 +183,14 @@ describe('builtin helpers', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#each', function() {
|
||||
beforeEach(function() {
|
||||
handlebarsEnv.registerHelper('detectDataInsideEach', function(options) {
|
||||
describe('#each', function () {
|
||||
beforeEach(function () {
|
||||
handlebarsEnv.registerHelper('detectDataInsideEach', function (options) {
|
||||
return options.data && options.data.exclaim;
|
||||
});
|
||||
});
|
||||
|
||||
it('each', function() {
|
||||
it('each', function () {
|
||||
var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
|
||||
|
||||
expectTemplate(string)
|
||||
@@ -198,9 +198,9 @@ describe('builtin helpers', function() {
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage(
|
||||
'each with array argument iterates over the contents when not empty'
|
||||
@@ -210,21 +210,21 @@ describe('builtin helpers', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbyes: [],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('each with array argument ignores the contents when empty')
|
||||
.toCompileTo('cruel world!');
|
||||
});
|
||||
|
||||
it('each without data', function() {
|
||||
it('each without data', function () {
|
||||
expectTemplate('{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!')
|
||||
.withInput({
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withRuntimeOptions({ data: false })
|
||||
.withCompileOptions({ data: false })
|
||||
@@ -237,13 +237,13 @@ describe('builtin helpers', function() {
|
||||
.toCompileTo('cruelworld');
|
||||
});
|
||||
|
||||
it('each without context', function() {
|
||||
it('each without context', function () {
|
||||
expectTemplate('{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!')
|
||||
.withInput(undefined)
|
||||
.toCompileTo('cruel !');
|
||||
});
|
||||
|
||||
it('each with an object and @key', function() {
|
||||
it('each with an object and @key', function () {
|
||||
var string =
|
||||
'{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!';
|
||||
|
||||
@@ -272,12 +272,12 @@ describe('builtin helpers', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbyes: {},
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.toCompileTo('cruel world!');
|
||||
});
|
||||
|
||||
it('each with @index', function() {
|
||||
it('each with @index', function () {
|
||||
expectTemplate(
|
||||
'{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
|
||||
)
|
||||
@@ -285,15 +285,15 @@ describe('builtin helpers', function() {
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('The @index variable is used')
|
||||
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
||||
});
|
||||
|
||||
it('each with nested @index', function() {
|
||||
it('each with nested @index', function () {
|
||||
expectTemplate(
|
||||
'{{#each goodbyes}}{{@index}}. {{text}}! {{#each ../goodbyes}}{{@index}} {{/each}}After {{@index}} {{/each}}{{@index}}cruel {{world}}!'
|
||||
)
|
||||
@@ -301,9 +301,9 @@ describe('builtin helpers', function() {
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('The @index variable is used')
|
||||
.toCompileTo(
|
||||
@@ -311,20 +311,20 @@ describe('builtin helpers', function() {
|
||||
);
|
||||
});
|
||||
|
||||
it('each with block params', function() {
|
||||
it('each with block params', function () {
|
||||
expectTemplate(
|
||||
'{{#each goodbyes as |value index|}}{{index}}. {{value.text}}! {{#each ../goodbyes as |childValue childIndex|}} {{index}} {{childIndex}}{{/each}} After {{index}} {{/each}}{{index}}cruel {{world}}!'
|
||||
)
|
||||
.withInput({
|
||||
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.toCompileTo(
|
||||
'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(
|
||||
'{{#each goodbyes as |value index|}}{{index}}. {{value.text}}!{{/each}}'
|
||||
)
|
||||
@@ -333,7 +333,7 @@ describe('builtin helpers', function() {
|
||||
.toCompileTo('0. goodbye!1. Goodbye!');
|
||||
});
|
||||
|
||||
it('each object with @index', function() {
|
||||
it('each object with @index', function () {
|
||||
expectTemplate(
|
||||
'{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
|
||||
)
|
||||
@@ -341,15 +341,15 @@ describe('builtin helpers', function() {
|
||||
goodbyes: {
|
||||
a: { text: 'goodbye' },
|
||||
b: { text: 'Goodbye' },
|
||||
c: { text: 'GOODBYE' }
|
||||
c: { text: 'GOODBYE' },
|
||||
},
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('The @index variable is used')
|
||||
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
||||
});
|
||||
|
||||
it('each with @first', function() {
|
||||
it('each with @first', function () {
|
||||
expectTemplate(
|
||||
'{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
||||
)
|
||||
@@ -357,15 +357,15 @@ describe('builtin helpers', function() {
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('The @first variable is used')
|
||||
.toCompileTo('goodbye! cruel world!');
|
||||
});
|
||||
|
||||
it('each with nested @first', function() {
|
||||
it('each with nested @first', function () {
|
||||
expectTemplate(
|
||||
'{{#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: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('The @first variable is used')
|
||||
.toCompileTo(
|
||||
@@ -383,19 +383,19 @@ describe('builtin helpers', function() {
|
||||
);
|
||||
});
|
||||
|
||||
it('each object with @first', function() {
|
||||
it('each object with @first', function () {
|
||||
expectTemplate(
|
||||
'{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
||||
)
|
||||
.withInput({
|
||||
goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } },
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('The @first variable is used')
|
||||
.toCompileTo('goodbye! cruel world!');
|
||||
});
|
||||
|
||||
it('each with @last', function() {
|
||||
it('each with @last', function () {
|
||||
expectTemplate(
|
||||
'{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
||||
)
|
||||
@@ -403,27 +403,27 @@ describe('builtin helpers', function() {
|
||||
goodbyes: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('The @last variable is used')
|
||||
.toCompileTo('GOODBYE! cruel world!');
|
||||
});
|
||||
|
||||
it('each object with @last', function() {
|
||||
it('each object with @last', function () {
|
||||
expectTemplate(
|
||||
'{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
|
||||
)
|
||||
.withInput({
|
||||
goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } },
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('The @last variable is used')
|
||||
.toCompileTo('Goodbye! cruel world!');
|
||||
});
|
||||
|
||||
it('each with nested @last', function() {
|
||||
it('each with nested @last', function () {
|
||||
expectTemplate(
|
||||
'{{#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: [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('The @last variable is used')
|
||||
.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}}!';
|
||||
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbyes: function() {
|
||||
goodbyes: function () {
|
||||
return [
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
];
|
||||
},
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage(
|
||||
'each with array function argument iterates over the contents when not empty'
|
||||
@@ -463,7 +463,7 @@ describe('builtin helpers', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbyes: [],
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage(
|
||||
'each with array function argument ignores the contents when empty'
|
||||
@@ -471,7 +471,7 @@ describe('builtin helpers', function() {
|
||||
.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(
|
||||
'{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
|
||||
)
|
||||
@@ -479,15 +479,15 @@ describe('builtin helpers', function() {
|
||||
goodbyes: {
|
||||
a: { text: 'goodbye' },
|
||||
b: { text: 'Goodbye' },
|
||||
'': { text: 'GOODBYE' }
|
||||
'': { text: 'GOODBYE' },
|
||||
},
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage('Empty string key is not skipped')
|
||||
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
|
||||
});
|
||||
|
||||
it('data passed to helpers', function() {
|
||||
it('data passed to helpers', function () {
|
||||
expectTemplate(
|
||||
'{{#each letters}}{{this}}{{detectDataInsideEach}}{{/each}}'
|
||||
)
|
||||
@@ -495,13 +495,13 @@ describe('builtin helpers', function() {
|
||||
.withMessage('should output data')
|
||||
.withRuntimeOptions({
|
||||
data: {
|
||||
exclaim: '!'
|
||||
}
|
||||
exclaim: '!',
|
||||
},
|
||||
})
|
||||
.toCompileTo('a!b!c!');
|
||||
});
|
||||
|
||||
it('each on implicit context', function() {
|
||||
it('each on implicit context', function () {
|
||||
expectTemplate('{{#each}}{{text}}! {{/each}}cruel world!').toThrow(
|
||||
handlebarsEnv.Exception,
|
||||
'Must pass iterator to #each'
|
||||
@@ -509,12 +509,12 @@ describe('builtin helpers', function() {
|
||||
});
|
||||
|
||||
if (global.Symbol && global.Symbol.iterator) {
|
||||
it('each on iterable', function() {
|
||||
it('each on iterable', function () {
|
||||
function Iterator(arr) {
|
||||
this.arr = arr;
|
||||
this.index = 0;
|
||||
}
|
||||
Iterator.prototype.next = function() {
|
||||
Iterator.prototype.next = function () {
|
||||
var value = this.arr[this.index];
|
||||
var done = this.index === this.arr.length;
|
||||
if (!done) {
|
||||
@@ -525,7 +525,7 @@ describe('builtin helpers', function() {
|
||||
function Iterable(arr) {
|
||||
this.arr = arr;
|
||||
}
|
||||
Iterable.prototype[global.Symbol.iterator] = function() {
|
||||
Iterable.prototype[global.Symbol.iterator] = function () {
|
||||
return new Iterator(this.arr);
|
||||
};
|
||||
var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
|
||||
@@ -535,9 +535,9 @@ describe('builtin helpers', function() {
|
||||
goodbyes: new Iterable([
|
||||
{ text: 'goodbye' },
|
||||
{ text: 'Goodbye' },
|
||||
{ text: 'GOODBYE' }
|
||||
{ text: 'GOODBYE' },
|
||||
]),
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage(
|
||||
'each with array argument iterates over the contents when not empty'
|
||||
@@ -547,7 +547,7 @@ describe('builtin helpers', function() {
|
||||
expectTemplate(string)
|
||||
.withInput({
|
||||
goodbyes: new Iterable([]),
|
||||
world: 'world'
|
||||
world: 'world',
|
||||
})
|
||||
.withMessage(
|
||||
'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 */
|
||||
if (typeof console === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
var $log, $info, $error;
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
$log = console.log;
|
||||
$info = console.info;
|
||||
$error = console.error;
|
||||
});
|
||||
afterEach(function() {
|
||||
afterEach(function () {
|
||||
console.log = $log;
|
||||
console.info = $info;
|
||||
console.error = $error;
|
||||
});
|
||||
|
||||
it('should call logger at default level', function() {
|
||||
it('should call logger at default level', function () {
|
||||
var levelArg, logArg;
|
||||
handlebarsEnv.log = function(level, arg) {
|
||||
handlebarsEnv.log = function (level, arg) {
|
||||
levelArg = level;
|
||||
logArg = arg;
|
||||
};
|
||||
@@ -590,9 +590,9 @@ describe('builtin helpers', function() {
|
||||
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;
|
||||
handlebarsEnv.log = function(level, arg) {
|
||||
handlebarsEnv.log = function (level, arg) {
|
||||
levelArg = level;
|
||||
logArg = arg;
|
||||
};
|
||||
@@ -606,16 +606,16 @@ describe('builtin helpers', function() {
|
||||
equals('whee', logArg);
|
||||
});
|
||||
|
||||
it('should output to info', function() {
|
||||
it('should output to info', function () {
|
||||
var called;
|
||||
|
||||
console.info = function(info) {
|
||||
console.info = function (info) {
|
||||
equals('whee', info);
|
||||
called = true;
|
||||
console.info = $info;
|
||||
console.log = $log;
|
||||
};
|
||||
console.log = function(log) {
|
||||
console.log = function (log) {
|
||||
equals('whee', log);
|
||||
called = true;
|
||||
console.info = $info;
|
||||
@@ -628,10 +628,10 @@ describe('builtin helpers', function() {
|
||||
equals(true, called);
|
||||
});
|
||||
|
||||
it('should log at data level', function() {
|
||||
it('should log at data level', function () {
|
||||
var called;
|
||||
|
||||
console.error = function(log) {
|
||||
console.error = function (log) {
|
||||
equals('whee', log);
|
||||
called = true;
|
||||
console.error = $error;
|
||||
@@ -645,11 +645,11 @@ describe('builtin helpers', function() {
|
||||
equals(true, called);
|
||||
});
|
||||
|
||||
it('should handle missing logger', function() {
|
||||
it('should handle missing logger', function () {
|
||||
var called = false;
|
||||
|
||||
console.error = undefined;
|
||||
console.log = function(log) {
|
||||
console.log = function (log) {
|
||||
equals('whee', log);
|
||||
called = true;
|
||||
console.log = $log;
|
||||
@@ -663,10 +663,10 @@ describe('builtin helpers', function() {
|
||||
equals(true, called);
|
||||
});
|
||||
|
||||
it('should handle string log levels', function() {
|
||||
it('should handle string log levels', function () {
|
||||
var called;
|
||||
|
||||
console.error = function(log) {
|
||||
console.error = function (log) {
|
||||
equals('whee', log);
|
||||
called = true;
|
||||
};
|
||||
@@ -688,10 +688,10 @@ describe('builtin helpers', function() {
|
||||
equals(true, called);
|
||||
});
|
||||
|
||||
it('should handle hash log levels', function() {
|
||||
it('should handle hash log levels', function () {
|
||||
var called;
|
||||
|
||||
console.error = function(log) {
|
||||
console.error = function (log) {
|
||||
equals('whee', log);
|
||||
called = true;
|
||||
};
|
||||
@@ -702,10 +702,14 @@ describe('builtin helpers', function() {
|
||||
equals(true, called);
|
||||
});
|
||||
|
||||
it('should handle hash log levels', function() {
|
||||
it('should handle hash log levels', function () {
|
||||
var called = false;
|
||||
|
||||
console.info = console.log = console.error = console.debug = function() {
|
||||
console.info =
|
||||
console.log =
|
||||
console.error =
|
||||
console.debug =
|
||||
function () {
|
||||
called = true;
|
||||
console.info = console.log = console.error = console.debug = $log;
|
||||
};
|
||||
@@ -716,10 +720,10 @@ describe('builtin helpers', function() {
|
||||
equals(false, called);
|
||||
});
|
||||
|
||||
it('should pass multiple log arguments', function() {
|
||||
it('should pass multiple log arguments', function () {
|
||||
var called;
|
||||
|
||||
console.info = console.log = function(log1, log2, log3) {
|
||||
console.info = console.log = function (log1, log2, log3) {
|
||||
equals('whee', log1);
|
||||
equals('foo', log2);
|
||||
equals(1, log3);
|
||||
@@ -733,31 +737,29 @@ describe('builtin helpers', function() {
|
||||
equals(true, called);
|
||||
});
|
||||
|
||||
it('should pass zero log arguments', function() {
|
||||
it('should pass zero log arguments', function () {
|
||||
var called;
|
||||
|
||||
console.info = console.log = function() {
|
||||
console.info = console.log = function () {
|
||||
expect(arguments.length).to.equal(0);
|
||||
called = true;
|
||||
console.log = $log;
|
||||
};
|
||||
|
||||
expectTemplate('{{log}}')
|
||||
.withInput({ blah: 'whee' })
|
||||
.toCompileTo('');
|
||||
expectTemplate('{{log}}').withInput({ blah: 'whee' }).toCompileTo('');
|
||||
expect(called).to.be.true();
|
||||
});
|
||||
/* eslint-enable no-console */
|
||||
});
|
||||
|
||||
describe('#lookup', function() {
|
||||
it('should lookup arbitrary content', function() {
|
||||
describe('#lookup', function () {
|
||||
it('should lookup arbitrary content', function () {
|
||||
expectTemplate('{{#each goodbyes}}{{lookup ../data .}}{{/each}}')
|
||||
.withInput({ goodbyes: [0, 1], data: ['foo', 'bar'] })
|
||||
.toCompileTo('foobar');
|
||||
});
|
||||
|
||||
it('should not fail on undefined value', function() {
|
||||
it('should not fail on undefined value', function () {
|
||||
expectTemplate('{{#each goodbyes}}{{lookup ../bar .}}{{/each}}')
|
||||
.withInput({ goodbyes: [0, 1], data: ['foo', 'bar'] })
|
||||
.toCompileTo('');
|
||||
|
||||
+25
-25
@@ -1,15 +1,15 @@
|
||||
describe('compiler', function() {
|
||||
describe('compiler', function () {
|
||||
if (!Handlebars.compile) {
|
||||
return;
|
||||
}
|
||||
|
||||
describe('#equals', function() {
|
||||
describe('#equals', function () {
|
||||
function compile(string) {
|
||||
var ast = Handlebars.parse(string);
|
||||
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.bar}}').equals(compile('{{foo.bar}}')), true);
|
||||
@@ -30,7 +30,7 @@ describe('compiler', function() {
|
||||
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.bar}}').equals(compile('{{bar.bar}}')), false);
|
||||
@@ -59,17 +59,17 @@ describe('compiler', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#compile', function() {
|
||||
it('should fail with invalid input', function() {
|
||||
describe('#compile', function () {
|
||||
it('should fail with invalid input', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.compile(null);
|
||||
},
|
||||
Error,
|
||||
'You must pass a string or Handlebars AST to Handlebars.compile. You passed null'
|
||||
);
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.compile({});
|
||||
},
|
||||
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 {
|
||||
Handlebars.compile(' \n {{#if}}\n{{/def}}')();
|
||||
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 {
|
||||
Handlebars.compile(' \n {{#if}}\n{{/def}}')();
|
||||
equal(
|
||||
@@ -118,30 +118,30 @@ describe('compiler', function() {
|
||||
}
|
||||
});
|
||||
|
||||
it('can utilize AST instance', function() {
|
||||
it('can utilize AST instance', function () {
|
||||
equal(
|
||||
Handlebars.compile({
|
||||
type: 'Program',
|
||||
body: [{ type: 'ContentStatement', value: 'Hello' }]
|
||||
body: [{ type: 'ContentStatement', value: 'Hello' }],
|
||||
})(),
|
||||
'Hello'
|
||||
);
|
||||
});
|
||||
|
||||
it('can pass through an empty string', function() {
|
||||
it('can pass through an empty string', function () {
|
||||
equal(Handlebars.compile('')(), '');
|
||||
});
|
||||
|
||||
it('throws on desupported options', function() {
|
||||
it('throws on desupported options', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.compile('Dudes', { trackIds: true });
|
||||
},
|
||||
Error,
|
||||
'TrackIds and stringParams are no longer supported. See Github #1145'
|
||||
);
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.compile('Dudes', { stringParams: true });
|
||||
},
|
||||
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' }] };
|
||||
Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
|
||||
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: {} };
|
||||
Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
|
||||
equal(
|
||||
@@ -168,17 +168,17 @@ describe('compiler', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#precompile', function() {
|
||||
it('should fail with invalid input', function() {
|
||||
describe('#precompile', function () {
|
||||
it('should fail with invalid input', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.precompile(null);
|
||||
},
|
||||
Error,
|
||||
'You must pass a string or Handlebars AST to Handlebars.compile. You passed null'
|
||||
);
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.precompile({});
|
||||
},
|
||||
Error,
|
||||
@@ -186,19 +186,19 @@ describe('compiler', function() {
|
||||
);
|
||||
});
|
||||
|
||||
it('can utilize AST instance', function() {
|
||||
it('can utilize AST instance', function () {
|
||||
equal(
|
||||
/return "Hello"/.test(
|
||||
Handlebars.precompile({
|
||||
type: 'Program',
|
||||
body: [{ type: 'ContentStatement', value: 'Hello' }]
|
||||
body: [{ type: 'ContentStatement', value: 'Hello' }],
|
||||
})
|
||||
),
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it('can pass through an empty string', function() {
|
||||
it('can pass through an empty string', function () {
|
||||
equal(/return ""/.test(Handlebars.precompile('')), true);
|
||||
});
|
||||
});
|
||||
|
||||
+53
-53
@@ -1,8 +1,8 @@
|
||||
describe('data', function() {
|
||||
it('passing in data to a compiled function that expects data - works with helpers', function() {
|
||||
describe('data', function () {
|
||||
it('passing in data to a compiled function that expects data - works with helpers', function () {
|
||||
expectTemplate('{{hello}}')
|
||||
.withCompileOptions({ data: true })
|
||||
.withHelper('hello', function(options) {
|
||||
.withHelper('hello', function (options) {
|
||||
return options.data.adjective + ' ' + this.noun;
|
||||
})
|
||||
.withRuntimeOptions({ data: { adjective: 'happy' } })
|
||||
@@ -11,17 +11,17 @@ describe('data', function() {
|
||||
.toCompileTo('happy cat');
|
||||
});
|
||||
|
||||
it('data can be looked up via @foo', function() {
|
||||
it('data can be looked up via @foo', function () {
|
||||
expectTemplate('{{@hello}}')
|
||||
.withRuntimeOptions({ data: { hello: 'hello' } })
|
||||
.withMessage('@foo retrieves template data')
|
||||
.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);
|
||||
|
||||
helpers.let = function(options) {
|
||||
helpers.let = function (options) {
|
||||
var frame = Handlebars.createFrame(options.data);
|
||||
|
||||
for (var prop in options.hash) {
|
||||
@@ -41,83 +41,83 @@ describe('data', function() {
|
||||
.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}}')
|
||||
.withRuntimeOptions({ data: { world: 'world' } })
|
||||
.withHelper('hello', function(noun) {
|
||||
.withHelper('hello', function (noun) {
|
||||
return 'Hello ' + noun;
|
||||
})
|
||||
.withMessage('@foo as a parameter retrieves template data')
|
||||
.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}}')
|
||||
.withRuntimeOptions({ data: { world: 'world' } })
|
||||
.withHelper('hello', function(options) {
|
||||
.withHelper('hello', function (options) {
|
||||
return 'Hello ' + options.hash.noun;
|
||||
})
|
||||
.withMessage('@foo as a parameter retrieves template data')
|
||||
.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}}')
|
||||
.withRuntimeOptions({ data: { world: { bar: 'world' } } })
|
||||
.withHelper('hello', function(noun) {
|
||||
.withHelper('hello', function (noun) {
|
||||
return 'Hello ' + noun;
|
||||
})
|
||||
.withMessage('@foo as a parameter retrieves template data')
|
||||
.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}}')
|
||||
.withRuntimeOptions({ data: { foo: { bar: 'world' } } })
|
||||
.withHelper('hello', function(noun) {
|
||||
.withHelper('hello', function (noun) {
|
||||
return 'Hello ' + noun;
|
||||
})
|
||||
.withMessage('@foo as a parameter retrieves template data')
|
||||
.toCompileTo('Hello undefined');
|
||||
});
|
||||
|
||||
it('parameter data throws when using complex scope references', function() {
|
||||
it('parameter data throws when using complex scope references', function () {
|
||||
expectTemplate(
|
||||
'{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}'
|
||||
).toThrow(Error);
|
||||
});
|
||||
|
||||
it('data can be functions', function() {
|
||||
it('data can be functions', function () {
|
||||
expectTemplate('{{@hello}}')
|
||||
.withRuntimeOptions({
|
||||
data: {
|
||||
hello: function() {
|
||||
hello: function () {
|
||||
return 'hello';
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
.toCompileTo('hello');
|
||||
});
|
||||
|
||||
it('data can be functions with params', function() {
|
||||
it('data can be functions with params', function () {
|
||||
expectTemplate('{{@hello "hello"}}')
|
||||
.withRuntimeOptions({
|
||||
data: {
|
||||
hello: function(arg) {
|
||||
hello: function (arg) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
.toCompileTo('hello');
|
||||
});
|
||||
|
||||
it('data is inherited downstream', function() {
|
||||
it('data is inherited downstream', function () {
|
||||
expectTemplate(
|
||||
'{{#let foo=1 bar=2}}{{#let foo=bar.baz}}{{@bar}}{{@foo}}{{/let}}{{@foo}}{{/let}}'
|
||||
)
|
||||
.withInput({ bar: { baz: 'hello world' } })
|
||||
.withCompileOptions({ data: true })
|
||||
.withHelper('let', function(options) {
|
||||
.withHelper('let', function (options) {
|
||||
var frame = Handlebars.createFrame(options.data);
|
||||
for (var prop in options.hash) {
|
||||
if (prop in options.hash) {
|
||||
@@ -131,11 +131,11 @@ describe('data', function() {
|
||||
.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}}')
|
||||
.withCompileOptions({ data: true })
|
||||
.withPartial('myPartial', '{{hello}}')
|
||||
.withHelper('hello', function(options) {
|
||||
.withHelper('hello', function (options) {
|
||||
return options.data.adjective + ' ' + this.noun;
|
||||
})
|
||||
.withInput({ noun: 'cat' })
|
||||
@@ -144,10 +144,10 @@ describe('data', function() {
|
||||
.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}}')
|
||||
.withCompileOptions({ data: true })
|
||||
.withHelper('hello', function(noun, options) {
|
||||
.withHelper('hello', function (noun, options) {
|
||||
return options.data.adjective + ' ' + noun + (this.exclaim ? '!' : '');
|
||||
})
|
||||
.withInput({ exclaim: true, world: 'world' })
|
||||
@@ -156,15 +156,15 @@ describe('data', function() {
|
||||
.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}}')
|
||||
.withCompileOptions({
|
||||
data: true
|
||||
data: true,
|
||||
})
|
||||
.withHelper('hello', function(options) {
|
||||
.withHelper('hello', function (options) {
|
||||
return options.fn(this);
|
||||
})
|
||||
.withHelper('world', function(options) {
|
||||
.withHelper('world', function (options) {
|
||||
return options.data.adjective + ' world' + (this.exclaim ? '!' : '');
|
||||
})
|
||||
.withInput({ exclaim: true })
|
||||
@@ -173,13 +173,13 @@ describe('data', function() {
|
||||
.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}}')
|
||||
.withCompileOptions({ data: true })
|
||||
.withHelper('hello', function(options) {
|
||||
.withHelper('hello', function (options) {
|
||||
return options.fn({ exclaim: '?' });
|
||||
})
|
||||
.withHelper('world', function(thing, options) {
|
||||
.withHelper('world', function (thing, options) {
|
||||
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
||||
})
|
||||
.withInput({ exclaim: true, zomg: 'world' })
|
||||
@@ -188,13 +188,13 @@ describe('data', function() {
|
||||
.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}}')
|
||||
.withCompileOptions({ data: true })
|
||||
.withHelper('hello', function(options) {
|
||||
.withHelper('hello', function (options) {
|
||||
return options.data.accessData + ' ' + options.fn({ exclaim: '?' });
|
||||
})
|
||||
.withHelper('world', function(thing, options) {
|
||||
.withHelper('world', function (thing, options) {
|
||||
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
||||
})
|
||||
.withInput({ exclaim: true, zomg: 'world' })
|
||||
@@ -203,16 +203,16 @@ describe('data', function() {
|
||||
.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}}')
|
||||
.withCompileOptions({ data: true })
|
||||
.withHelper('hello', function(options) {
|
||||
.withHelper('hello', function (options) {
|
||||
return options.fn(
|
||||
{ exclaim: '?', zomg: 'world' },
|
||||
{ data: { adjective: 'sad' } }
|
||||
);
|
||||
})
|
||||
.withHelper('world', function(thing, options) {
|
||||
.withHelper('world', function (thing, options) {
|
||||
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
||||
})
|
||||
.withInput({ exclaim: true, zomg: 'planet' })
|
||||
@@ -221,13 +221,13 @@ describe('data', function() {
|
||||
.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}}')
|
||||
.withCompileOptions({ data: true })
|
||||
.withHelper('hello', function(options) {
|
||||
.withHelper('hello', function (options) {
|
||||
return options.fn({ exclaim: '?' }, { data: { adjective: 'sad' } });
|
||||
})
|
||||
.withHelper('world', function(thing, options) {
|
||||
.withHelper('world', function (thing, options) {
|
||||
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
||||
})
|
||||
.withInput({ exclaim: true, zomg: 'world' })
|
||||
@@ -236,8 +236,8 @@ describe('data', function() {
|
||||
.toCompileTo('sad world?');
|
||||
});
|
||||
|
||||
describe('@root', function() {
|
||||
it('the root context can be looked up via @root', function() {
|
||||
describe('@root', function () {
|
||||
it('the root context can be looked up via @root', function () {
|
||||
expectTemplate('{{@root.foo}}')
|
||||
.withInput({ foo: 'hello' })
|
||||
.withRuntimeOptions({ data: {} })
|
||||
@@ -248,7 +248,7 @@ describe('data', function() {
|
||||
.toCompileTo('hello');
|
||||
});
|
||||
|
||||
it('passed root values take priority', function() {
|
||||
it('passed root values take priority', function () {
|
||||
expectTemplate('{{@root.foo}}')
|
||||
.withInput({ foo: 'should not be used' })
|
||||
.withRuntimeOptions({ data: { root: { foo: 'hello' } } })
|
||||
@@ -256,21 +256,21 @@ describe('data', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('nesting', function() {
|
||||
it('the root context can be looked up via @root', function() {
|
||||
describe('nesting', function () {
|
||||
it('the root context can be looked up via @root', function () {
|
||||
expectTemplate(
|
||||
'{{#helper}}{{#helper}}{{@./depth}} {{@../depth}} {{@../../depth}}{{/helper}}{{/helper}}'
|
||||
)
|
||||
.withInput({ foo: 'hello' })
|
||||
.withHelper('helper', function(options) {
|
||||
.withHelper('helper', function (options) {
|
||||
var frame = Handlebars.createFrame(options.data);
|
||||
frame.depth = options.data.depth + 1;
|
||||
return options.fn(this, { data: frame });
|
||||
})
|
||||
.withRuntimeOptions({
|
||||
data: {
|
||||
depth: 0
|
||||
}
|
||||
depth: 0,
|
||||
},
|
||||
})
|
||||
.toCompileTo('2 1 0');
|
||||
});
|
||||
|
||||
Vendored
+3
-3
@@ -26,13 +26,13 @@ vm.runInThisContext(distHandlebars, filename);
|
||||
global.CompilerContext = {
|
||||
browser: true,
|
||||
|
||||
compile: function(template, options) {
|
||||
compile: function (template, options) {
|
||||
var templateSpec = handlebarsEnv.precompile(template, options);
|
||||
return handlebarsEnv.template(safeEval(templateSpec));
|
||||
},
|
||||
compileWithPartial: function(template, options) {
|
||||
compileWithPartial: function (template, options) {
|
||||
return handlebarsEnv.compile(template, options);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function safeEval(templateSpec) {
|
||||
|
||||
Vendored
+24
-24
@@ -1,4 +1,4 @@
|
||||
var global = (function() {
|
||||
var global = (function () {
|
||||
return this;
|
||||
})();
|
||||
|
||||
@@ -21,7 +21,7 @@ if (Error.captureStackTrace) {
|
||||
/**
|
||||
* @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);
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ global.shouldCompileToWithPartials = function shouldCompileToWithPartials(
|
||||
/**
|
||||
* @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
|
||||
*/
|
||||
global.compileWithPartials = function(string, hashOrArray, partials) {
|
||||
global.compileWithPartials = function (string, hashOrArray, partials) {
|
||||
var template, ary, options;
|
||||
if (hashOrArray && hashOrArray.hash) {
|
||||
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)`)
|
||||
* @see https://www.chaijs.com/api/bdd/#method_throw
|
||||
*/
|
||||
global.shouldThrow = function(callback, type, msg) {
|
||||
global.shouldThrow = function (callback, type, msg) {
|
||||
var failed;
|
||||
try {
|
||||
callback();
|
||||
@@ -121,7 +121,7 @@ global.shouldThrow = function(callback, type, msg) {
|
||||
}
|
||||
};
|
||||
|
||||
global.expectTemplate = function(templateAsString) {
|
||||
global.expectTemplate = function (templateAsString) {
|
||||
return new HandlebarsTestBench(templateAsString);
|
||||
};
|
||||
|
||||
@@ -137,38 +137,38 @@ function HandlebarsTestBench(templateAsString) {
|
||||
this.runtimeOptions = {};
|
||||
}
|
||||
|
||||
HandlebarsTestBench.prototype.withInput = function(input) {
|
||||
HandlebarsTestBench.prototype.withInput = function (input) {
|
||||
this.input = input;
|
||||
return this;
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype.withHelper = function(name, helperFunction) {
|
||||
HandlebarsTestBench.prototype.withHelper = function (name, helperFunction) {
|
||||
this.helpers[name] = helperFunction;
|
||||
return this;
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype.withHelpers = function(helperFunctions) {
|
||||
HandlebarsTestBench.prototype.withHelpers = function (helperFunctions) {
|
||||
var self = this;
|
||||
Object.keys(helperFunctions).forEach(function(name) {
|
||||
Object.keys(helperFunctions).forEach(function (name) {
|
||||
self.withHelper(name, helperFunctions[name]);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype.withPartial = function(name, partialAsString) {
|
||||
HandlebarsTestBench.prototype.withPartial = function (name, partialAsString) {
|
||||
this.partials[name] = partialAsString;
|
||||
return this;
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype.withPartials = function(partials) {
|
||||
HandlebarsTestBench.prototype.withPartials = function (partials) {
|
||||
var self = this;
|
||||
Object.keys(partials).forEach(function(name) {
|
||||
Object.keys(partials).forEach(function (name) {
|
||||
self.withPartial(name, partials[name]);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype.withDecorator = function(
|
||||
HandlebarsTestBench.prototype.withDecorator = function (
|
||||
name,
|
||||
decoratorFunction
|
||||
) {
|
||||
@@ -176,30 +176,30 @@ HandlebarsTestBench.prototype.withDecorator = function(
|
||||
return this;
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype.withDecorators = function(decorators) {
|
||||
HandlebarsTestBench.prototype.withDecorators = function (decorators) {
|
||||
var self = this;
|
||||
Object.keys(decorators).forEach(function(name) {
|
||||
Object.keys(decorators).forEach(function (name) {
|
||||
self.withDecorator(name, decorators[name]);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype.withCompileOptions = function(compileOptions) {
|
||||
HandlebarsTestBench.prototype.withCompileOptions = function (compileOptions) {
|
||||
this.compileOptions = compileOptions;
|
||||
return this;
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype.withRuntimeOptions = function(runtimeOptions) {
|
||||
HandlebarsTestBench.prototype.withRuntimeOptions = function (runtimeOptions) {
|
||||
this.runtimeOptions = runtimeOptions;
|
||||
return this;
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype.withMessage = function(message) {
|
||||
HandlebarsTestBench.prototype.withMessage = function (message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype.toCompileTo = function(expectedOutputAsString) {
|
||||
HandlebarsTestBench.prototype.toCompileTo = function (expectedOutputAsString) {
|
||||
expect(this._compileAndExecute()).to.equal(
|
||||
expectedOutputAsString,
|
||||
this.message
|
||||
@@ -207,14 +207,14 @@ HandlebarsTestBench.prototype.toCompileTo = function(expectedOutputAsString) {
|
||||
};
|
||||
|
||||
// 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;
|
||||
expect(function() {
|
||||
expect(function () {
|
||||
self._compileAndExecute();
|
||||
}).to.throw(errorLike, errMsgMatcher, this.message);
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype._compileAndExecute = function() {
|
||||
HandlebarsTestBench.prototype._compileAndExecute = function () {
|
||||
var compile =
|
||||
Object.keys(this.partials).length > 0
|
||||
? CompilerContext.compileWithPartial
|
||||
@@ -226,10 +226,10 @@ HandlebarsTestBench.prototype._compileAndExecute = function() {
|
||||
return template(this.input, combinedRuntimeOptions);
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype._combineRuntimeOptions = function() {
|
||||
HandlebarsTestBench.prototype._combineRuntimeOptions = function () {
|
||||
var self = this;
|
||||
var combinedRuntimeOptions = {};
|
||||
Object.keys(this.runtimeOptions).forEach(function(key) {
|
||||
Object.keys(this.runtimeOptions).forEach(function (key) {
|
||||
combinedRuntimeOptions[key] = self.runtimeOptions[key];
|
||||
});
|
||||
combinedRuntimeOptions.helpers = this.helpers;
|
||||
|
||||
Vendored
+3
-3
@@ -11,13 +11,13 @@ global.sinon = require('sinon');
|
||||
global.Handlebars = require('../../lib');
|
||||
|
||||
global.CompilerContext = {
|
||||
compile: function(template, options) {
|
||||
compile: function (template, options) {
|
||||
var templateSpec = handlebarsEnv.precompile(template, options);
|
||||
return handlebarsEnv.template(safeEval(templateSpec));
|
||||
},
|
||||
compileWithPartial: function(template, options) {
|
||||
compileWithPartial: function (template, options) {
|
||||
return handlebarsEnv.compile(template, options);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function safeEval(templateSpec) {
|
||||
|
||||
Vendored
+9
-9
@@ -15,25 +15,25 @@ if (grep === '--min') {
|
||||
|
||||
var files = fs
|
||||
.readdirSync(testDir)
|
||||
.filter(function(name) {
|
||||
.filter(function (name) {
|
||||
return /.*\.js$/.test(name);
|
||||
})
|
||||
.map(function(name) {
|
||||
.map(function (name) {
|
||||
return testDir + path.sep + name;
|
||||
});
|
||||
|
||||
if (global.minimizedTest) {
|
||||
run('./runtime', function() {
|
||||
run('./browser', function() {
|
||||
run('./runtime', function () {
|
||||
run('./browser', function () {
|
||||
/* eslint-disable no-process-exit */
|
||||
process.exit(errors);
|
||||
/* eslint-enable no-process-exit */
|
||||
});
|
||||
});
|
||||
} else {
|
||||
run('./runtime', function() {
|
||||
run('./browser', function() {
|
||||
run('./node', function() {
|
||||
run('./runtime', function () {
|
||||
run('./browser', function () {
|
||||
run('./node', function () {
|
||||
/* eslint-disable no-process-exit */
|
||||
process.exit(errors);
|
||||
/* eslint-enable no-process-exit */
|
||||
@@ -50,13 +50,13 @@ function run(env, callback) {
|
||||
mocha.grep(grep);
|
||||
}
|
||||
|
||||
files.forEach(function(name) {
|
||||
files.forEach(function (name) {
|
||||
delete require.cache[name];
|
||||
});
|
||||
|
||||
console.log('Running env: ' + env);
|
||||
require(env);
|
||||
mocha.run(function(errorCount) {
|
||||
mocha.run(function (errorCount) {
|
||||
errors += errorCount;
|
||||
callback();
|
||||
});
|
||||
|
||||
Vendored
+8
-5
@@ -29,9 +29,12 @@ var JavaScriptCompiler = require('../../dist/cjs/handlebars/compiler/javascript-
|
||||
global.CompilerContext = {
|
||||
browser: true,
|
||||
|
||||
compile: function(template, options) {
|
||||
compile: function (template, options) {
|
||||
// Hack the compiler on to the environment for these specific tests
|
||||
handlebarsEnv.precompile = function(precompileTemplate, precompileOptions) {
|
||||
handlebarsEnv.precompile = function (
|
||||
precompileTemplate,
|
||||
precompileOptions
|
||||
) {
|
||||
return compiler.precompile(
|
||||
precompileTemplate,
|
||||
precompileOptions,
|
||||
@@ -45,9 +48,9 @@ global.CompilerContext = {
|
||||
var templateSpec = handlebarsEnv.precompile(template, options);
|
||||
return handlebarsEnv.template(safeEval(templateSpec));
|
||||
},
|
||||
compileWithPartial: function(template, options) {
|
||||
compileWithPartial: function (template, options) {
|
||||
// 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);
|
||||
};
|
||||
handlebarsEnv.parse = parse;
|
||||
@@ -55,7 +58,7 @@ global.CompilerContext = {
|
||||
handlebarsEnv.JavaScriptCompiler = JavaScriptCompiler;
|
||||
|
||||
return handlebarsEnv.compile(template, options);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function safeEval(templateSpec) {
|
||||
|
||||
+200
-200
File diff suppressed because it is too large
Load Diff
+28
-26
@@ -1,19 +1,19 @@
|
||||
describe('javascript-compiler api', function() {
|
||||
describe('javascript-compiler api', function () {
|
||||
if (!Handlebars.JavaScriptCompiler) {
|
||||
return;
|
||||
}
|
||||
|
||||
describe('#nameLookup', function() {
|
||||
describe('#nameLookup', function () {
|
||||
var $superName;
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
$superName = handlebarsEnv.JavaScriptCompiler.prototype.nameLookup;
|
||||
});
|
||||
afterEach(function() {
|
||||
afterEach(function () {
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = $superName;
|
||||
});
|
||||
|
||||
it('should allow override', function() {
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = function(
|
||||
it('should allow override', function () {
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = function (
|
||||
parent,
|
||||
name
|
||||
) {
|
||||
@@ -28,27 +28,27 @@ describe('javascript-compiler api', function() {
|
||||
|
||||
// Tests nameLookup dot vs. bracket behavior. Bracket is required in certain cases
|
||||
// to avoid errors in older browsers.
|
||||
it('should handle reserved words', function() {
|
||||
it('should handle reserved words', function () {
|
||||
expectTemplate('{{foo}} {{~null~}}')
|
||||
.withInput({ foo: 'food' })
|
||||
.toCompileTo('food');
|
||||
});
|
||||
});
|
||||
describe('#compilerInfo', function() {
|
||||
describe('#compilerInfo', function () {
|
||||
var $superCheck, $superInfo;
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
$superCheck = handlebarsEnv.VM.checkRevision;
|
||||
$superInfo = handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo;
|
||||
});
|
||||
afterEach(function() {
|
||||
afterEach(function () {
|
||||
handlebarsEnv.VM.checkRevision = $superCheck;
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = $superInfo;
|
||||
});
|
||||
it('should allow compilerInfo override', function() {
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = function() {
|
||||
it('should allow compilerInfo override', function () {
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = function () {
|
||||
return 'crazy';
|
||||
};
|
||||
handlebarsEnv.VM.checkRevision = function(compilerInfo) {
|
||||
handlebarsEnv.VM.checkRevision = function (compilerInfo) {
|
||||
if (compilerInfo !== 'crazy') {
|
||||
throw new Error("It didn't work");
|
||||
}
|
||||
@@ -58,30 +58,32 @@ describe('javascript-compiler api', function() {
|
||||
.toCompileTo('food ');
|
||||
});
|
||||
});
|
||||
describe('buffer', function() {
|
||||
describe('buffer', function () {
|
||||
var $superAppend, $superCreate;
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.forceBuffer = true;
|
||||
$superAppend = handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer;
|
||||
$superCreate =
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer;
|
||||
});
|
||||
afterEach(function() {
|
||||
afterEach(function () {
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.forceBuffer = false;
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = $superAppend;
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer = $superCreate;
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer =
|
||||
$superCreate;
|
||||
});
|
||||
|
||||
it('should allow init buffer override', function() {
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer = function() {
|
||||
it('should allow init buffer override', function () {
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer =
|
||||
function () {
|
||||
return this.quotedString('foo_');
|
||||
};
|
||||
expectTemplate('{{foo}} ')
|
||||
.withInput({ foo: 'food' })
|
||||
.toCompileTo('foo_food ');
|
||||
});
|
||||
it('should allow append buffer override', function() {
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = function(
|
||||
it('should allow append buffer override', function () {
|
||||
handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = function (
|
||||
string
|
||||
) {
|
||||
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 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
|
||||
// and might be removed in 5.0
|
||||
['test', 'abc123', 'abc_123'].forEach(function(validVariableName) {
|
||||
it("should return true for '" + validVariableName + "'", function() {
|
||||
['test', 'abc123', 'abc_123'].forEach(function (validVariableName) {
|
||||
it("should return true for '" + validVariableName + "'", function () {
|
||||
expect(
|
||||
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
||||
validVariableName
|
||||
@@ -106,8 +108,8 @@ describe('javascript-compiler api', function() {
|
||||
).to.be.true();
|
||||
});
|
||||
});
|
||||
[('123test', 'abc()', 'abc.cde')].forEach(function(invalidVariableName) {
|
||||
it("should return true for '" + invalidVariableName + "'", function() {
|
||||
[('123test', 'abc()', 'abc.cde')].forEach(function (invalidVariableName) {
|
||||
it("should return true for '" + invalidVariableName + "'", function () {
|
||||
expect(
|
||||
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
||||
invalidVariableName
|
||||
|
||||
+118
-121
@@ -1,12 +1,12 @@
|
||||
describe('partials', function() {
|
||||
it('basic partials', function() {
|
||||
describe('partials', function () {
|
||||
it('basic partials', function () {
|
||||
var string = 'Dudes: {{#dudes}}{{> dude}}{{/dudes}}';
|
||||
var partial = '{{name}} ({{url}}) ';
|
||||
var hash = {
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
};
|
||||
|
||||
expectTemplate(string)
|
||||
@@ -22,19 +22,19 @@ describe('partials', function() {
|
||||
.toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
|
||||
});
|
||||
|
||||
it('dynamic partials', function() {
|
||||
it('dynamic partials', function () {
|
||||
var string = 'Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}';
|
||||
var partial = '{{name}} ({{url}}) ';
|
||||
var hash = {
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
};
|
||||
var helpers = {
|
||||
partial: function() {
|
||||
partial: function () {
|
||||
return 'dude';
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
expectTemplate(string)
|
||||
@@ -52,41 +52,41 @@ describe('partials', function() {
|
||||
.toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
|
||||
});
|
||||
|
||||
it('failing dynamic partials', function() {
|
||||
it('failing dynamic partials', function () {
|
||||
expectTemplate('Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}')
|
||||
.withInput({
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withHelper('partial', function() {
|
||||
.withHelper('partial', function () {
|
||||
return 'missing';
|
||||
})
|
||||
.withPartial('dude', '{{name}} ({{url}}) ')
|
||||
.toThrow(Handlebars.Exception, 'The partial missing could not be found');
|
||||
});
|
||||
|
||||
it('partials with context', function() {
|
||||
it('partials with context', function () {
|
||||
expectTemplate('Dudes: {{>dude dudes}}')
|
||||
.withInput({
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartial('dude', '{{#this}}{{name}} ({{url}}) {{/this}}')
|
||||
.withMessage('Partials can be passed a context')
|
||||
.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 hash = {
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
};
|
||||
|
||||
expectTemplate('Dudes: {{#dudes}}{{>dude}}{{/dudes}}')
|
||||
@@ -102,50 +102,50 @@ describe('partials', function() {
|
||||
.toCompileTo('Dudes: foo () foo () ');
|
||||
});
|
||||
|
||||
it('partials with string context', function() {
|
||||
it('partials with string context', function () {
|
||||
expectTemplate('Dudes: {{>dude "dudes"}}')
|
||||
.withPartial('dude', '{{.}}')
|
||||
.toCompileTo('Dudes: dudes');
|
||||
});
|
||||
|
||||
it('partials with undefined context', function() {
|
||||
it('partials with undefined context', function () {
|
||||
expectTemplate('Dudes: {{>dude dudes}}')
|
||||
.withPartial('dude', '{{foo}} Empty')
|
||||
.toCompileTo('Dudes: Empty');
|
||||
});
|
||||
|
||||
it('partials with duplicate parameters', function() {
|
||||
it('partials with duplicate parameters', function () {
|
||||
expectTemplate('Dudes: {{>dude dudes foo bar=baz}}').toThrow(
|
||||
Error,
|
||||
'Unsupported number of partial arguments: 2 - 1:7'
|
||||
);
|
||||
});
|
||||
|
||||
it('partials with parameters', function() {
|
||||
it('partials with parameters', function () {
|
||||
expectTemplate('Dudes: {{#dudes}}{{> dude others=..}}{{/dudes}}')
|
||||
.withInput({
|
||||
foo: 'bar',
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartial('dude', '{{others.foo}}{{name}} ({{url}}) ')
|
||||
.withMessage('Basic partials output based on current context.')
|
||||
.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}}')
|
||||
.withInput({
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartials({
|
||||
dude: '{{name}} {{> url}} ',
|
||||
url: '<a href="{{url}}">{{url}}</a>'
|
||||
url: '<a href="{{url}}">{{url}}</a>',
|
||||
})
|
||||
.withMessage('Partials are rendered inside of other partials')
|
||||
.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(
|
||||
Handlebars.Exception,
|
||||
'The partial whatever could not be found'
|
||||
);
|
||||
});
|
||||
|
||||
it('registering undefined partial throws an exception', function() {
|
||||
it('registering undefined partial throws an exception', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
var 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(
|
||||
Handlebars.Exception,
|
||||
'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) {
|
||||
return context.name + ' (' + context.url + ') ';
|
||||
}
|
||||
@@ -186,15 +186,15 @@ describe('partials', function() {
|
||||
.withInput({
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartial('dude', partial)
|
||||
.withMessage('Function partials output based in VM.')
|
||||
.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}}')
|
||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||
.withPartial('dude', '{{name}}')
|
||||
@@ -202,7 +202,7 @@ describe('partials', function() {
|
||||
.toCompileTo('Dudes: Jeepers Creepers');
|
||||
});
|
||||
|
||||
it('Partials with slash paths', function() {
|
||||
it('Partials with slash paths', function () {
|
||||
expectTemplate('Dudes: {{> shared/dude}}')
|
||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||
.withPartial('shared/dude', '{{name}}')
|
||||
@@ -210,7 +210,7 @@ describe('partials', function() {
|
||||
.toCompileTo('Dudes: Jeepers');
|
||||
});
|
||||
|
||||
it('Partials with slash and point paths', function() {
|
||||
it('Partials with slash and point paths', function () {
|
||||
expectTemplate('Dudes: {{> shared/dude.thing}}')
|
||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||
.withPartial('shared/dude.thing', '{{name}}')
|
||||
@@ -218,7 +218,7 @@ describe('partials', function() {
|
||||
.toCompileTo('Dudes: Jeepers');
|
||||
});
|
||||
|
||||
it('Global Partials', function() {
|
||||
it('Global Partials', function () {
|
||||
handlebarsEnv.registerPartial('globalTest', '{{anotherDude}}');
|
||||
|
||||
expectTemplate('Dudes: {{> shared/dude}} {{> globalTest}}')
|
||||
@@ -231,10 +231,10 @@ describe('partials', function() {
|
||||
equals(handlebarsEnv.partials.globalTest, undefined);
|
||||
});
|
||||
|
||||
it('Multiple partial registration', function() {
|
||||
it('Multiple partial registration', function () {
|
||||
handlebarsEnv.registerPartial({
|
||||
'shared/dude': '{{name}}',
|
||||
globalTest: '{{anotherDude}}'
|
||||
globalTest: '{{anotherDude}}',
|
||||
});
|
||||
|
||||
expectTemplate('Dudes: {{> shared/dude}} {{> globalTest}}')
|
||||
@@ -244,7 +244,7 @@ describe('partials', function() {
|
||||
.toCompileTo('Dudes: Jeepers Creepers');
|
||||
});
|
||||
|
||||
it('Partials with integer path', function() {
|
||||
it('Partials with integer path', function () {
|
||||
expectTemplate('Dudes: {{> 404}}')
|
||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||
.withPartial(404, '{{name}}')
|
||||
@@ -252,7 +252,7 @@ describe('partials', function() {
|
||||
.toCompileTo('Dudes: Jeepers');
|
||||
});
|
||||
|
||||
it('Partials with complex path', function() {
|
||||
it('Partials with complex path', function () {
|
||||
expectTemplate('Dudes: {{> 404/asdf?.bar}}')
|
||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||
.withPartial('404/asdf?.bar', '{{name}}')
|
||||
@@ -260,7 +260,7 @@ describe('partials', function() {
|
||||
.toCompileTo('Dudes: Jeepers');
|
||||
});
|
||||
|
||||
it('Partials with escaped', function() {
|
||||
it('Partials with escaped', function () {
|
||||
expectTemplate('Dudes: {{> [+404/asdf?.bar]}}')
|
||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||
.withPartial('+404/asdf?.bar', '{{name}}')
|
||||
@@ -268,7 +268,7 @@ describe('partials', function() {
|
||||
.toCompileTo('Dudes: Jeepers');
|
||||
});
|
||||
|
||||
it('Partials with string', function() {
|
||||
it('Partials with string', function () {
|
||||
expectTemplate("Dudes: {{> '+404/asdf?.bar'}}")
|
||||
.withInput({ name: 'Jeepers', anotherDude: 'Creepers' })
|
||||
.withPartial('+404/asdf?.bar', '{{name}}')
|
||||
@@ -276,19 +276,19 @@ describe('partials', function() {
|
||||
.toCompileTo('Dudes: Jeepers');
|
||||
});
|
||||
|
||||
it('should handle empty partial', function() {
|
||||
it('should handle empty partial', function () {
|
||||
expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}')
|
||||
.withInput({
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartial('dude', '')
|
||||
.toCompileTo('Dudes: ');
|
||||
});
|
||||
|
||||
it('throw on missing partial', function() {
|
||||
it('throw on missing partial', function () {
|
||||
var compile = handlebarsEnv.compile;
|
||||
var compileWithPartial = CompilerContext.compileWithPartial;
|
||||
handlebarsEnv.compile = undefined;
|
||||
@@ -300,18 +300,18 @@ describe('partials', function() {
|
||||
CompilerContext.compileWithPartial = compileWithPartial;
|
||||
});
|
||||
|
||||
describe('partial blocks', function() {
|
||||
it('should render partial block as default', function() {
|
||||
describe('partial blocks', function () {
|
||||
it('should render partial block as default', function () {
|
||||
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}}')
|
||||
.withInput({ context: { value: 'success' } })
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should propagate block parameters to default block', function() {
|
||||
it('should propagate block parameters to default block', function () {
|
||||
expectTemplate(
|
||||
'{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}'
|
||||
)
|
||||
@@ -319,79 +319,76 @@ describe('partials', function() {
|
||||
.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}}')
|
||||
.withPartials({ dude: 'success' })
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should render block from partial', function() {
|
||||
it('should render block from partial', function () {
|
||||
expectTemplate('{{#> dude}}success{{/dude}}')
|
||||
.withPartials({ dude: '{{> @partial-block }}' })
|
||||
.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}}')
|
||||
.withPartials({ dude: '{{> @partial-block }} {{> @partial-block }}' })
|
||||
.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}}')
|
||||
.withInput({ context: { value: 'success' } })
|
||||
.withPartials({
|
||||
dude: '{{#with context}}{{> @partial-block }}{{/with}}'
|
||||
dude: '{{#with context}}{{> @partial-block }}{{/with}}',
|
||||
})
|
||||
.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}}')
|
||||
.withInput({ value: 'success' })
|
||||
.withPartials({
|
||||
dude:
|
||||
'<code>before-block: {{@root/value}} {{> @partial-block }}</code>'
|
||||
dude: '<code>before-block: {{@root/value}} {{> @partial-block }}</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(
|
||||
'<template>{{#> list value}}value = {{.}}{{/list}}</template>'
|
||||
)
|
||||
.withInput({
|
||||
value: ['a', 'b', 'c']
|
||||
value: ['a', 'b', 'c'],
|
||||
})
|
||||
.withPartials({
|
||||
list:
|
||||
'<list>{{#each .}}<item>{{> @partial-block}}</item>{{/each}}</list>'
|
||||
list: '<list>{{#each .}}<item>{{> @partial-block}}</item>{{/each}}</list>',
|
||||
})
|
||||
.toCompileTo(
|
||||
'<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}}')
|
||||
.withInput({ context: { value: 'success' } })
|
||||
.withPartials({
|
||||
dude:
|
||||
'{{#with context}}{{> @partial-block }} {{> @partial-block }}{{/with}}'
|
||||
dude: '{{#with context}}{{> @partial-block }} {{> @partial-block }}{{/with}}',
|
||||
})
|
||||
.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}}')
|
||||
.withInput({ context: { value: 'success' } })
|
||||
.withPartials({
|
||||
dude: '{{#with context}}{{> @partial-block }}{{/with}}'
|
||||
dude: '{{#with context}}{{> @partial-block }}{{/with}}',
|
||||
})
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should render block from partial with block params', function() {
|
||||
it('should render block from partial with block params', function () {
|
||||
expectTemplate(
|
||||
'{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}'
|
||||
)
|
||||
@@ -400,52 +397,52 @@ describe('partials', function() {
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should render nested partial blocks', function() {
|
||||
it('should render nested partial blocks', function () {
|
||||
expectTemplate('<template>{{#> outer}}{{value}}{{/outer}}</template>')
|
||||
.withInput({ value: 'success' })
|
||||
.withPartials({
|
||||
outer:
|
||||
'<outer>{{#> nested}}<outer-block>{{> @partial-block}}</outer-block>{{/nested}}</outer>',
|
||||
nested: '<nested>{{> @partial-block}}</nested>'
|
||||
nested: '<nested>{{> @partial-block}}</nested>',
|
||||
})
|
||||
.toCompileTo(
|
||||
'<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>')
|
||||
.withInput({ value: 'success' })
|
||||
.withPartials({
|
||||
outer:
|
||||
'<outer>{{#> nested}}<outer-block>{{> @partial-block}}</outer-block>{{/nested}}{{> @partial-block}}</outer>',
|
||||
nested: '<nested>{{> @partial-block}}</nested>'
|
||||
nested: '<nested>{{> @partial-block}}</nested>',
|
||||
})
|
||||
.toCompileTo(
|
||||
'<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>')
|
||||
.withInput({ value: 'success' })
|
||||
.withPartials({
|
||||
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(
|
||||
'<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>')
|
||||
.withInput({ value: 'success' })
|
||||
.withPartials({
|
||||
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(
|
||||
'<template><outer>' +
|
||||
@@ -455,20 +452,20 @@ describe('partials', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('inline partials', function() {
|
||||
it('should define inline partials for template', function() {
|
||||
describe('inline partials', function () {
|
||||
it('should define inline partials for template', function () {
|
||||
expectTemplate(
|
||||
'{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}'
|
||||
).toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should overwrite multiple partials in the same template', function() {
|
||||
it('should overwrite multiple partials in the same template', function () {
|
||||
expectTemplate(
|
||||
'{{#*inline "myPartial"}}fail{{/inline}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}'
|
||||
).toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should define inline partials for block', function() {
|
||||
it('should define inline partials for block', function () {
|
||||
expectTemplate(
|
||||
'{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}'
|
||||
).toCompileTo('success');
|
||||
@@ -478,37 +475,37 @@ describe('partials', function() {
|
||||
).toThrow(Error, /myPartial could not/);
|
||||
});
|
||||
|
||||
it('should override global partials', function() {
|
||||
it('should override global partials', function () {
|
||||
expectTemplate(
|
||||
'{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}'
|
||||
)
|
||||
.withPartials({
|
||||
myPartial: function() {
|
||||
myPartial: function () {
|
||||
return 'fail';
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should override template partials', function() {
|
||||
it('should override template partials', function () {
|
||||
expectTemplate(
|
||||
'{{#*inline "myPartial"}}fail{{/inline}}{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}'
|
||||
).toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should override partials down the entire stack', function() {
|
||||
it('should override partials down the entire stack', function () {
|
||||
expectTemplate(
|
||||
'{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{#with .}}{{#with .}}{{> myPartial}}{{/with}}{{/with}}{{/with}}'
|
||||
).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}}')
|
||||
.withPartials({ dude: '{{> myPartial }}' })
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should define inline partials in partial block call', function() {
|
||||
it('should define inline partials in partial block call', function () {
|
||||
expectTemplate(
|
||||
'{{#> dude}}{{#*inline "myPartial"}}success{{/inline}}{{/dude}}'
|
||||
)
|
||||
@@ -516,7 +513,7 @@ describe('partials', function() {
|
||||
.toCompileTo('success');
|
||||
});
|
||||
|
||||
it('should render nested inline partials', function() {
|
||||
it('should render nested inline partials', function () {
|
||||
expectTemplate(
|
||||
'{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}}</outer-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>');
|
||||
});
|
||||
|
||||
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(
|
||||
'{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}}</outer-block>{{/inner}}{{>@partial-block}}{{/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(
|
||||
'{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}} {{>@partial-block}}</outer-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) {
|
||||
var env = Handlebars.create();
|
||||
env.registerPartial('partial', '{{foo}}');
|
||||
@@ -560,47 +557,47 @@ describe('partials', function() {
|
||||
}
|
||||
});
|
||||
|
||||
describe('standalone partials', function() {
|
||||
it('indented partials', function() {
|
||||
describe('standalone partials', function () {
|
||||
it('indented partials', function () {
|
||||
expectTemplate('Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}')
|
||||
.withInput({
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartial('dude', '{{name}}\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}}')
|
||||
.withInput({
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartials({
|
||||
dude: '{{name}}\n {{> url}}',
|
||||
url: '{{url}}!\n'
|
||||
url: '{{url}}!\n',
|
||||
})
|
||||
.toCompileTo(
|
||||
'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}}')
|
||||
.withInput({
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartials({
|
||||
dude: '{{name}}\n {{> url}}',
|
||||
url: '{{url}}!\n'
|
||||
url: '{{url}}!\n',
|
||||
})
|
||||
.withCompileOptions({ preventIndent: true })
|
||||
.toCompileTo(
|
||||
@@ -609,15 +606,15 @@ describe('partials', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('compat mode', function() {
|
||||
it('partials can access parents', function() {
|
||||
describe('compat mode', function () {
|
||||
it('partials can access parents', function () {
|
||||
expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}')
|
||||
.withInput({
|
||||
root: 'yes',
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartials({ dude: '{{name}} ({{url}}) {{root}} ' })
|
||||
.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}}')
|
||||
.withInput({
|
||||
root: 'yes',
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartials({ dude: '{{name}} ({{url}}) {{root}} ' })
|
||||
.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}}')
|
||||
.withInput({
|
||||
root: 'yes',
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartials({ dude: '{{name}} ({{url}}) {{root}} ' })
|
||||
.withRuntimeOptions({ data: false })
|
||||
@@ -659,17 +656,17 @@ describe('partials', function() {
|
||||
);
|
||||
});
|
||||
|
||||
it('partials inherit compat', function() {
|
||||
it('partials inherit compat', function () {
|
||||
expectTemplate('Dudes: {{> dude}}')
|
||||
.withInput({
|
||||
root: 'yes',
|
||||
dudes: [
|
||||
{ name: 'Yehuda', url: 'http://yehuda' },
|
||||
{ name: 'Alan', url: 'http://alan' }
|
||||
]
|
||||
{ name: 'Alan', url: 'http://alan' },
|
||||
],
|
||||
})
|
||||
.withPartials({
|
||||
dude: '{{#dudes}}{{name}} ({{url}}) {{root}} {{/dudes}}'
|
||||
dude: '{{#dudes}}{{name}} ({{url}}) {{root}} {{/dudes}}',
|
||||
})
|
||||
.withCompileOptions({ compat: true })
|
||||
.toCompileTo(
|
||||
|
||||
+83
-83
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-console */
|
||||
describe('precompiler', function() {
|
||||
describe('precompiler', function () {
|
||||
// NOP Under non-node environments
|
||||
if (typeof process === 'undefined') {
|
||||
return;
|
||||
@@ -19,7 +19,7 @@ describe('precompiler', function() {
|
||||
emptyTemplate = {
|
||||
path: __dirname + '/artifacts/empty.handlebars',
|
||||
name: 'empty',
|
||||
source: ''
|
||||
source: '',
|
||||
},
|
||||
file,
|
||||
content,
|
||||
@@ -38,7 +38,7 @@ describe('precompiler', function() {
|
||||
var _resolveFilename = Module._resolveFilename;
|
||||
delete require.cache[require.resolve('uglify-js')];
|
||||
delete require.cache[require.resolve('../dist/cjs/precompiler')];
|
||||
Module._resolveFilename = function(request, mod) {
|
||||
Module._resolveFilename = function (request, mod) {
|
||||
if (request === 'uglify-js') {
|
||||
throw loadError;
|
||||
}
|
||||
@@ -53,7 +53,7 @@ describe('precompiler', function() {
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
precompile = Handlebars.precompile;
|
||||
minify = uglify.minify;
|
||||
writeFileSync = fs.writeFileSync;
|
||||
@@ -61,21 +61,21 @@ describe('precompiler', function() {
|
||||
// Mock stdout and stderr
|
||||
logFunction = console.log;
|
||||
log = '';
|
||||
console.log = function() {
|
||||
console.log = function () {
|
||||
log += Array.prototype.join.call(arguments, '');
|
||||
};
|
||||
errorLogFunction = console.error;
|
||||
errorLog = '';
|
||||
console.error = function() {
|
||||
console.error = function () {
|
||||
errorLog += Array.prototype.join.call(arguments, '');
|
||||
};
|
||||
|
||||
fs.writeFileSync = function(_file, _content) {
|
||||
fs.writeFileSync = function (_file, _content) {
|
||||
file = _file;
|
||||
content = _content;
|
||||
};
|
||||
});
|
||||
afterEach(function() {
|
||||
afterEach(function () {
|
||||
Handlebars.precompile = precompile;
|
||||
uglify.minify = minify;
|
||||
fs.writeFileSync = writeFileSync;
|
||||
@@ -83,59 +83,59 @@ describe('precompiler', function() {
|
||||
console.error = errorLogFunction;
|
||||
});
|
||||
|
||||
it('should output version', function() {
|
||||
it('should output version', function () {
|
||||
Precompiler.cli({ templates: [], version: true });
|
||||
equals(log, Handlebars.VERSION);
|
||||
});
|
||||
it('should throw if lacking templates', function() {
|
||||
it('should throw if lacking templates', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Precompiler.cli({ templates: [] });
|
||||
},
|
||||
Handlebars.Exception,
|
||||
'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: [] });
|
||||
// Success is not throwing
|
||||
});
|
||||
it('should throw when combining simple and minimized', function() {
|
||||
it('should throw when combining simple and minimized', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Precompiler.cli({ templates: [__dirname], simple: true, min: true });
|
||||
},
|
||||
Handlebars.Exception,
|
||||
'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(
|
||||
function() {
|
||||
function () {
|
||||
Precompiler.cli({
|
||||
templates: [
|
||||
__dirname + '/artifacts/empty.handlebars',
|
||||
__dirname + '/artifacts/empty.handlebars'
|
||||
__dirname + '/artifacts/empty.handlebars',
|
||||
],
|
||||
simple: true
|
||||
simple: true,
|
||||
});
|
||||
},
|
||||
Handlebars.Exception,
|
||||
'Unable to output multiple templates in simple mode'
|
||||
);
|
||||
});
|
||||
it('should throw when missing name', function() {
|
||||
it('should throw when missing name', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Precompiler.cli({ templates: [{ source: '' }], amd: true });
|
||||
},
|
||||
Handlebars.Exception,
|
||||
'Name missing for template'
|
||||
);
|
||||
});
|
||||
it('should throw when combining simple and directories', function() {
|
||||
it('should throw when combining simple and directories', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Precompiler.cli({ hasDirectory: true, templates: [1], simple: true });
|
||||
},
|
||||
Handlebars.Exception,
|
||||
@@ -143,70 +143,70 @@ describe('precompiler', function() {
|
||||
);
|
||||
});
|
||||
|
||||
it('should output simple templates', function() {
|
||||
Handlebars.precompile = function() {
|
||||
it('should output simple templates', function () {
|
||||
Handlebars.precompile = function () {
|
||||
return 'simple';
|
||||
};
|
||||
Precompiler.cli({ templates: [emptyTemplate], simple: true });
|
||||
equal(log, 'simple\n');
|
||||
});
|
||||
it('should default to simple templates', function() {
|
||||
Handlebars.precompile = function() {
|
||||
it('should default to simple templates', function () {
|
||||
Handlebars.precompile = function () {
|
||||
return 'simple';
|
||||
};
|
||||
Precompiler.cli({ templates: [{ source: '' }] });
|
||||
equal(log, 'simple\n');
|
||||
});
|
||||
it('should output amd templates', function() {
|
||||
Handlebars.precompile = function() {
|
||||
it('should output amd templates', function () {
|
||||
Handlebars.precompile = function () {
|
||||
return 'amd';
|
||||
};
|
||||
Precompiler.cli({ templates: [emptyTemplate], amd: true });
|
||||
equal(/template\(amd\)/.test(log), true);
|
||||
});
|
||||
it('should output multiple amd', function() {
|
||||
Handlebars.precompile = function() {
|
||||
it('should output multiple amd', function () {
|
||||
Handlebars.precompile = function () {
|
||||
return 'amd';
|
||||
};
|
||||
Precompiler.cli({
|
||||
templates: [emptyTemplate, emptyTemplate],
|
||||
amd: true,
|
||||
namespace: 'foo'
|
||||
namespace: 'foo',
|
||||
});
|
||||
equal(/templates = foo = foo \|\|/.test(log), true);
|
||||
equal(/return templates/.test(log), true);
|
||||
equal(/template\(amd\)/.test(log), true);
|
||||
});
|
||||
it('should output amd partials', function() {
|
||||
Handlebars.precompile = function() {
|
||||
it('should output amd partials', function () {
|
||||
Handlebars.precompile = function () {
|
||||
return 'amd';
|
||||
};
|
||||
Precompiler.cli({ templates: [emptyTemplate], amd: true, partial: true });
|
||||
equal(/return Handlebars\.partials\['empty'\]/.test(log), true);
|
||||
equal(/template\(amd\)/.test(log), true);
|
||||
});
|
||||
it('should output multiple amd partials', function() {
|
||||
Handlebars.precompile = function() {
|
||||
it('should output multiple amd partials', function () {
|
||||
Handlebars.precompile = function () {
|
||||
return 'amd';
|
||||
};
|
||||
Precompiler.cli({
|
||||
templates: [emptyTemplate, emptyTemplate],
|
||||
amd: true,
|
||||
partial: true
|
||||
partial: true,
|
||||
});
|
||||
equal(/return Handlebars\.partials\[/.test(log), false);
|
||||
equal(/template\(amd\)/.test(log), true);
|
||||
});
|
||||
it('should output commonjs templates', function() {
|
||||
Handlebars.precompile = function() {
|
||||
it('should output commonjs templates', function () {
|
||||
Handlebars.precompile = function () {
|
||||
return 'commonjs';
|
||||
};
|
||||
Precompiler.cli({ templates: [emptyTemplate], commonjs: true });
|
||||
equal(/template\(commonjs\)/.test(log), true);
|
||||
});
|
||||
|
||||
it('should set data flag', function() {
|
||||
Handlebars.precompile = function(data, options) {
|
||||
it('should set data flag', function () {
|
||||
Handlebars.precompile = function (data, options) {
|
||||
equal(options.data, true);
|
||||
return 'simple';
|
||||
};
|
||||
@@ -214,45 +214,45 @@ describe('precompiler', function() {
|
||||
equal(log, 'simple\n');
|
||||
});
|
||||
|
||||
it('should set known helpers', function() {
|
||||
Handlebars.precompile = function(data, options) {
|
||||
it('should set known helpers', function () {
|
||||
Handlebars.precompile = function (data, options) {
|
||||
equal(options.knownHelpers.foo, true);
|
||||
return 'simple';
|
||||
};
|
||||
Precompiler.cli({ templates: [emptyTemplate], simple: true, known: 'foo' });
|
||||
equal(log, 'simple\n');
|
||||
});
|
||||
it('should output to file system', function() {
|
||||
Handlebars.precompile = function() {
|
||||
it('should output to file system', function () {
|
||||
Handlebars.precompile = function () {
|
||||
return 'simple';
|
||||
};
|
||||
Precompiler.cli({
|
||||
templates: [emptyTemplate],
|
||||
simple: true,
|
||||
output: 'file!'
|
||||
output: 'file!',
|
||||
});
|
||||
equal(file, 'file!');
|
||||
equal(content, 'simple\n');
|
||||
equal(log, '');
|
||||
});
|
||||
|
||||
it('should output minimized templates', function() {
|
||||
Handlebars.precompile = function() {
|
||||
it('should output minimized templates', function () {
|
||||
Handlebars.precompile = function () {
|
||||
return 'amd';
|
||||
};
|
||||
uglify.minify = function() {
|
||||
uglify.minify = function () {
|
||||
return { code: 'min' };
|
||||
};
|
||||
Precompiler.cli({ templates: [emptyTemplate], min: true });
|
||||
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'");
|
||||
error.code = 'MODULE_NOT_FOUND';
|
||||
mockRequireUglify(error, function() {
|
||||
mockRequireUglify(error, function () {
|
||||
var Precompiler = require('../dist/cjs/precompiler');
|
||||
Handlebars.precompile = function() {
|
||||
Handlebars.precompile = function () {
|
||||
return 'amd';
|
||||
};
|
||||
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() {
|
||||
mockRequireUglify(new Error('Mock Error'), function() {
|
||||
it('should fail on errors (other than missing module) while loading uglify-js', function () {
|
||||
mockRequireUglify(new Error('Mock Error'), function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
var Precompiler = require('../dist/cjs/precompiler');
|
||||
Handlebars.precompile = function() {
|
||||
Handlebars.precompile = function () {
|
||||
return 'amd';
|
||||
};
|
||||
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' });
|
||||
|
||||
equal(file, 'foo.js.map');
|
||||
equal(log.match(/sourceMappingURL=/g).length, 1);
|
||||
});
|
||||
|
||||
it('should output map', function() {
|
||||
it('should output map', function () {
|
||||
Precompiler.cli({
|
||||
templates: [emptyTemplate],
|
||||
min: true,
|
||||
map: 'foo.js.map'
|
||||
map: 'foo.js.map',
|
||||
});
|
||||
|
||||
equal(file, 'foo.js.map');
|
||||
equal(log.match(/sourceMappingURL=/g).length, 1);
|
||||
});
|
||||
|
||||
describe('#loadTemplates', function() {
|
||||
it('should throw on missing template', function(done) {
|
||||
Precompiler.loadTemplates({ files: ['foo'] }, function(err) {
|
||||
describe('#loadTemplates', function () {
|
||||
it('should throw on missing template', function (done) {
|
||||
Precompiler.loadTemplates({ files: ['foo'] }, function (err) {
|
||||
equal(err.message, 'Unable to open template file "foo"');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should enumerate directories by extension', function(done) {
|
||||
it('should enumerate directories by extension', function (done) {
|
||||
Precompiler.loadTemplates(
|
||||
{ files: [__dirname + '/artifacts'], extension: 'hbs' },
|
||||
function(err, opts) {
|
||||
function (err, opts) {
|
||||
equal(opts.templates.length, 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(
|
||||
{ files: [__dirname + '/artifacts'], extension: 'handlebars' },
|
||||
function(err, opts) {
|
||||
function (err, opts) {
|
||||
equal(opts.templates.length, 5);
|
||||
equal(opts.templates[0].name, 'bom');
|
||||
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(
|
||||
{ files: [__dirname + '/artifacts'], extension: 'hb(s' },
|
||||
function(err) {
|
||||
function (err) {
|
||||
// Success is not throwing
|
||||
done(err);
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should handle BOM', function(done) {
|
||||
it('should handle BOM', function (done) {
|
||||
var opts = {
|
||||
files: [__dirname + '/artifacts/bom.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');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle different root', function(done) {
|
||||
it('should handle different root', function (done) {
|
||||
var opts = {
|
||||
files: [__dirname + '/artifacts/empty.handlebars'],
|
||||
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');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('should accept string inputs', function(done) {
|
||||
it('should accept string inputs', function (done) {
|
||||
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].source, '');
|
||||
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'] };
|
||||
Precompiler.loadTemplates(opts, function(err, opts) {
|
||||
Precompiler.loadTemplates(opts, function (err, opts) {
|
||||
equal(opts.templates[0].name, 'beep');
|
||||
equal(opts.templates[0].source, '');
|
||||
equal(opts.templates[1].name, 'boop');
|
||||
@@ -377,9 +377,9 @@ describe('precompiler', function() {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
it('should accept stdin input', function(done) {
|
||||
it('should accept stdin input', function (done) {
|
||||
var stdin = require('mock-stdin').stdin();
|
||||
Precompiler.loadTemplates({ string: '-' }, function(err, opts) {
|
||||
Precompiler.loadTemplates({ string: '-' }, function (err, opts) {
|
||||
equal(opts.templates[0].source, 'foo');
|
||||
done(err);
|
||||
});
|
||||
@@ -387,9 +387,9 @@ describe('precompiler', function() {
|
||||
stdin.send('o');
|
||||
stdin.end();
|
||||
});
|
||||
it('error on name missing', function(done) {
|
||||
it('error on name missing', function (done) {
|
||||
var opts = { string: ['', 'bar'] };
|
||||
Precompiler.loadTemplates(opts, function(err) {
|
||||
Precompiler.loadTemplates(opts, function (err) {
|
||||
equal(
|
||||
err.message,
|
||||
'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) {
|
||||
Precompiler.loadTemplates({}, function(err, opts) {
|
||||
it('should complete when no args are passed', function (done) {
|
||||
Precompiler.loadTemplates({}, function (err, opts) {
|
||||
equal(opts.templates.length, 0);
|
||||
done(err);
|
||||
});
|
||||
|
||||
+91
-99
@@ -1,24 +1,24 @@
|
||||
describe('Regressions', function() {
|
||||
it('GH-94: Cannot read property of undefined', function() {
|
||||
describe('Regressions', function () {
|
||||
it('GH-94: Cannot read property of undefined', function () {
|
||||
expectTemplate('{{#books}}{{title}}{{author.name}}{{/books}}')
|
||||
.withInput({
|
||||
books: [
|
||||
{
|
||||
title: 'The origin of species',
|
||||
author: {
|
||||
name: 'Charles Darwin'
|
||||
}
|
||||
name: 'Charles Darwin',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Lazarillo de Tormes'
|
||||
}
|
||||
]
|
||||
title: 'Lazarillo de Tormes',
|
||||
},
|
||||
],
|
||||
})
|
||||
.withMessage('Renders without an undefined property error')
|
||||
.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}}';
|
||||
|
||||
expectTemplate(string)
|
||||
@@ -43,14 +43,14 @@ describe('Regressions', function() {
|
||||
.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]}}')
|
||||
.withInput({ arr: [1, 2] })
|
||||
.withMessage('it works as expected')
|
||||
.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 =
|
||||
'<strong>This is a slightly more complicated {{thing}}.</strong>.\n' +
|
||||
'{{! Just ignore this business. }}\n' +
|
||||
@@ -67,17 +67,17 @@ describe('Regressions', function() {
|
||||
'{{/hasThings}}';
|
||||
|
||||
var data = {
|
||||
thing: function() {
|
||||
thing: function () {
|
||||
return 'blah';
|
||||
},
|
||||
things: [
|
||||
{ className: 'one', word: '@fat' },
|
||||
{ className: 'two', word: '@dhg' },
|
||||
{ className: 'three', word: '@sayrer' }
|
||||
{ className: 'three', word: '@sayrer' },
|
||||
],
|
||||
hasThings: function() {
|
||||
hasThings: function () {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var output =
|
||||
@@ -89,36 +89,34 @@ describe('Regressions', function() {
|
||||
'<li class=three>@sayrer</li>\n' +
|
||||
'</ul>.\n';
|
||||
|
||||
expectTemplate(string)
|
||||
.withInput(data)
|
||||
.toCompileTo(output);
|
||||
expectTemplate(string).withInput(data).toCompileTo(output);
|
||||
});
|
||||
|
||||
it('GH-408: Multiple loops fail', function() {
|
||||
it('GH-408: Multiple loops fail', function () {
|
||||
expectTemplate(
|
||||
'{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}'
|
||||
)
|
||||
.withInput([
|
||||
{ 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')
|
||||
.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 =
|
||||
'{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}';
|
||||
var failingTemplate =
|
||||
'{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}';
|
||||
|
||||
var helpers = {
|
||||
blk: function(block) {
|
||||
blk: function (block) {
|
||||
return block.fn('');
|
||||
},
|
||||
inverse: function(block) {
|
||||
inverse: function (block) {
|
||||
return block.inverse('');
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
expectTemplate(succeedingTemplate)
|
||||
@@ -130,34 +128,30 @@ describe('Regressions', function() {
|
||||
.toCompileTo(' Expected ');
|
||||
});
|
||||
|
||||
it('GH-458: Scoped this identifier', function() {
|
||||
expectTemplate('{{./foo}}')
|
||||
.withInput({ foo: 'bar' })
|
||||
.toCompileTo('bar');
|
||||
it('GH-458: Scoped this identifier', function () {
|
||||
expectTemplate('{{./foo}}').withInput({ foo: 'bar' }).toCompileTo('bar');
|
||||
});
|
||||
|
||||
it('GH-375: Unicode line terminators', function() {
|
||||
it('GH-375: Unicode line terminators', function () {
|
||||
expectTemplate('\u2028').toCompileTo('\u2028');
|
||||
});
|
||||
|
||||
it('GH-534: Object prototype aliases', function() {
|
||||
it('GH-534: Object prototype aliases', function () {
|
||||
/* eslint-disable no-extend-native */
|
||||
Object.prototype[0xd834] = true;
|
||||
|
||||
expectTemplate('{{foo}}')
|
||||
.withInput({ foo: 'bar' })
|
||||
.toCompileTo('bar');
|
||||
expectTemplate('{{foo}}').withInput({ foo: 'bar' }).toCompileTo('bar');
|
||||
|
||||
delete Object.prototype[0xd834];
|
||||
/* 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/);
|
||||
});
|
||||
|
||||
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] };
|
||||
|
||||
expectTemplate('{{arr}}')
|
||||
@@ -166,7 +160,7 @@ describe('Regressions', function() {
|
||||
.toCompileTo(data.arr.toString());
|
||||
});
|
||||
|
||||
it('Mustache man page', function() {
|
||||
it('Mustache man page', function () {
|
||||
expectTemplate(
|
||||
'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',
|
||||
value: 10000,
|
||||
taxed_value: 10000 - 10000 * 0.4,
|
||||
in_ca: true
|
||||
in_ca: true,
|
||||
})
|
||||
.withMessage('the hello world mustache example works')
|
||||
.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}}')
|
||||
.withInput({
|
||||
foo: 0,
|
||||
bar: 'OK'
|
||||
bar: 'OK',
|
||||
})
|
||||
.toCompileTo(' This is ~ ');
|
||||
});
|
||||
|
||||
it('GH-820: zero pathed rendering', function() {
|
||||
expectTemplate('{{foo.bar}}')
|
||||
.withInput({ foo: 0 })
|
||||
.toCompileTo('');
|
||||
it('GH-820: zero pathed rendering', function () {
|
||||
expectTemplate('{{foo.bar}}').withInput({ foo: 0 }).toCompileTo('');
|
||||
});
|
||||
|
||||
it('GH-837: undefined values for helpers', function() {
|
||||
it('GH-837: undefined values for helpers', function () {
|
||||
expectTemplate('{{str bar.baz}}')
|
||||
.withHelpers({
|
||||
str: function(value) {
|
||||
str: function (value) {
|
||||
return value + '';
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('undefined');
|
||||
});
|
||||
|
||||
it('GH-926: Depths and de-dupe', function() {
|
||||
it('GH-926: Depths and de-dupe', function () {
|
||||
expectTemplate(
|
||||
'{{#if dater}}{{#each data}}{{../name}}{{/each}}{{else}}{{#each notData}}{{../name}}{{/each}}{{/if}}'
|
||||
)
|
||||
.withInput({
|
||||
name: 'foo',
|
||||
data: [1],
|
||||
notData: [1]
|
||||
notData: [1],
|
||||
})
|
||||
.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}}')
|
||||
.withInput({
|
||||
data: {
|
||||
'': 'foo',
|
||||
name: 'Chris',
|
||||
value: 10000
|
||||
}
|
||||
value: 10000,
|
||||
},
|
||||
})
|
||||
.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}}')
|
||||
.withHelpers({
|
||||
wrap: function(options) {
|
||||
wrap: function (options) {
|
||||
return new Handlebars.SafeString(options.fn());
|
||||
}
|
||||
},
|
||||
})
|
||||
.withPartials({
|
||||
partial: '{{#wrap}}<partial>{{/wrap}}'
|
||||
partial: '{{#wrap}}<partial>{{/wrap}}',
|
||||
})
|
||||
.toCompileTo('<partial>');
|
||||
});
|
||||
|
||||
it('GH-1065: Sparse arrays', function() {
|
||||
it('GH-1065: Sparse arrays', function () {
|
||||
var array = [];
|
||||
array[1] = 'foo';
|
||||
array[3] = 'bar';
|
||||
@@ -253,11 +245,11 @@ describe('Regressions', function() {
|
||||
.toCompileTo('1foo3bar');
|
||||
});
|
||||
|
||||
it('GH-1093: Undefined helper context', function() {
|
||||
it('GH-1093: Undefined helper context', function () {
|
||||
expectTemplate('{{#each obj}}{{{helper}}}{{.}}{{/each}}')
|
||||
.withInput({ obj: { foo: undefined, bar: 'bat' } })
|
||||
.withHelpers({
|
||||
helper: function() {
|
||||
helper: function () {
|
||||
// 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;
|
||||
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.
|
||||
return this === 'bat' ? 'found' : 'not';
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('notfoundbat');
|
||||
});
|
||||
|
||||
it('should support multiple levels of inline partials', function() {
|
||||
it('should support multiple levels of inline partials', function () {
|
||||
expectTemplate(
|
||||
'{{#> layout}}{{#*inline "subcontent"}}subcontent{{/inline}}{{/layout}}'
|
||||
)
|
||||
.withPartials({
|
||||
doctype: 'doctype{{> content}}',
|
||||
layout:
|
||||
'{{#> doctype}}{{#*inline "content"}}layout{{> subcontent}}{{/inline}}{{/doctype}}'
|
||||
'{{#> doctype}}{{#*inline "content"}}layout{{> subcontent}}{{/inline}}{{/doctype}}',
|
||||
})
|
||||
.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}}')
|
||||
.withPartials({
|
||||
doctype: 'doctype{{> content}}',
|
||||
layout:
|
||||
'{{#> doctype}}{{#*inline "content"}}layout{{#> subcontent}}subcontent{{/subcontent}}{{/inline}}{{/doctype}}'
|
||||
'{{#> doctype}}{{#*inline "content"}}layout{{#> subcontent}}subcontent{{/subcontent}}{{/inline}}{{/doctype}}',
|
||||
})
|
||||
.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}}')
|
||||
.withPartials({
|
||||
layout: '{{#> inner}}Inner{{/inner}}{{> @partial-block }}',
|
||||
inner: ''
|
||||
inner: '',
|
||||
})
|
||||
.toCompileTo('Outer');
|
||||
});
|
||||
|
||||
it('GH-1135 : Context handling within each iteration', function() {
|
||||
it('GH-1135 : Context handling within each iteration', function () {
|
||||
expectTemplate(
|
||||
'{{#each array}}\n' +
|
||||
' 1. IF: {{#if true}}{{../name}}-{{../../name}}-{{../../../name}}{{/if}}\n' +
|
||||
@@ -312,18 +304,18 @@ describe('Regressions', function() {
|
||||
)
|
||||
.withInput({ array: [1], name: 'John' })
|
||||
.withHelpers({
|
||||
myif: function(conditional, options) {
|
||||
myif: function (conditional, options) {
|
||||
if (conditional) {
|
||||
return options.fn(this);
|
||||
} else {
|
||||
return options.inverse(this);
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
.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(
|
||||
'{{#*inline "test"}}{{> @partial-block }}{{/inline}}' +
|
||||
'{{#>test }}{{#each listOne as |item|}}{{ item }}{{/each}}{{/test}}' +
|
||||
@@ -331,64 +323,64 @@ describe('Regressions', function() {
|
||||
)
|
||||
.withInput({
|
||||
listOne: ['a'],
|
||||
listTwo: ['b']
|
||||
listTwo: ['b'],
|
||||
})
|
||||
.withMessage('')
|
||||
.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 helpers = {
|
||||
helpa: function(options) {
|
||||
helpa: function (options) {
|
||||
return options.hash.length;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
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(
|
||||
'{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}'
|
||||
)
|
||||
.withInput({
|
||||
value: 'parent',
|
||||
list: [null, 'a']
|
||||
list: [null, 'a'],
|
||||
})
|
||||
.withMessage('')
|
||||
.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')
|
||||
.withPartials({
|
||||
partialWithBlock:
|
||||
'{{#if @partial-block}} block {{> @partial-block}} block {{/if}}',
|
||||
partial: '{{#> partialWithBlock}} partial {{/partialWithBlock}}'
|
||||
partial: '{{#> partialWithBlock}} partial {{/partialWithBlock}}',
|
||||
})
|
||||
.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() {
|
||||
it('should compile and execute templates', 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 () {
|
||||
var newHandlebarsInstance = Handlebars.create();
|
||||
|
||||
registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
|
||||
newHandlebarsInstance.registerHelper('loud', function(value) {
|
||||
newHandlebarsInstance.registerHelper('loud', function (value) {
|
||||
return value.toUpperCase();
|
||||
});
|
||||
var result = newHandlebarsInstance.templates['test.hbs']({
|
||||
name: 'yehuda'
|
||||
name: '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();
|
||||
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
|
||||
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();
|
||||
registerTemplate(
|
||||
newHandlebarsInstance,
|
||||
@@ -409,7 +401,7 @@ describe('Regressions', function() {
|
||||
expect(
|
||||
newHandlebarsInstance.templates['test.hbs']({
|
||||
property: 'a',
|
||||
test: { a: 'b' }
|
||||
test: { a: 'b' },
|
||||
})
|
||||
).to.equal('b');
|
||||
});
|
||||
@@ -423,7 +415,7 @@ describe('Regressions', function() {
|
||||
function compiledTemplateVersion7() {
|
||||
return {
|
||||
compiler: [7, '>= 4.0.0'],
|
||||
main: function(container, depth0, helpers, partials, data) {
|
||||
main: function (container, depth0, helpers, partials, data) {
|
||||
return (
|
||||
container.escapeExpression(
|
||||
(
|
||||
@@ -438,7 +430,7 @@ describe('Regressions', function() {
|
||||
) + '\n\n'
|
||||
);
|
||||
},
|
||||
useData: true
|
||||
useData: true,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -446,7 +438,7 @@ describe('Regressions', function() {
|
||||
// This is the compiled version of "{{lookup test property}}"
|
||||
return {
|
||||
compiler: [7, '>= 4.0.0'],
|
||||
main: function(container, depth0, helpers, partials, data) {
|
||||
main: function (container, depth0, helpers, partials, data) {
|
||||
return container.escapeExpression(
|
||||
helpers.lookup.call(
|
||||
depth0 != null ? depth0 : container.nullContext || {},
|
||||
@@ -455,45 +447,45 @@ describe('Regressions', function() {
|
||||
{
|
||||
name: 'lookup',
|
||||
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"}}')
|
||||
.withInput({ array: [1], name: 'John' })
|
||||
.withHelpers({
|
||||
helpa: function(options) {
|
||||
helpa: function (options) {
|
||||
return options.hash.length;
|
||||
}
|
||||
},
|
||||
})
|
||||
.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
|
||||
if (!Handlebars.compile) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newHandlebarsInstance;
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
newHandlebarsInstance = Handlebars.create();
|
||||
});
|
||||
afterEach(function() {
|
||||
afterEach(function () {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
it('should only compile global partials once', function() {
|
||||
it('should only compile global partials once', function () {
|
||||
var templateSpy = sinon.spy(newHandlebarsInstance, 'template');
|
||||
newHandlebarsInstance.registerPartial({
|
||||
dude: 'I am a partial'
|
||||
dude: 'I am a partial',
|
||||
});
|
||||
var string = 'Dudes: {{> dude}} {{> dude}}';
|
||||
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() {
|
||||
it('should treat undefined helpers like non-existing helpers', 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 () {
|
||||
expectTemplate('{{foo}}')
|
||||
.withHelper('foo', undefined)
|
||||
.withInput({ foo: 'bar' })
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
if (typeof require !== 'undefined' && require.extensions['.handlebars']) {
|
||||
describe('Require', function() {
|
||||
it('Load .handlebars files with require()', function() {
|
||||
describe('Require', function () {
|
||||
it('Load .handlebars files with require()', function () {
|
||||
var template = require('./artifacts/example_1');
|
||||
equal(template, require('./artifacts/example_1.handlebars'));
|
||||
|
||||
@@ -10,7 +10,7 @@ if (typeof require !== 'undefined' && require.extensions['.handlebars']) {
|
||||
equal(result, expected);
|
||||
});
|
||||
|
||||
it('Load .hbs files with require()', function() {
|
||||
it('Load .hbs files with require()', function () {
|
||||
var template = require('./artifacts/example_2');
|
||||
equal(template, require('./artifacts/example_2.hbs'));
|
||||
|
||||
|
||||
+15
-15
@@ -1,53 +1,53 @@
|
||||
describe('runtime', function() {
|
||||
describe('#template', function() {
|
||||
it('should throw on invalid templates', function() {
|
||||
describe('runtime', function () {
|
||||
describe('#template', function () {
|
||||
it('should throw on invalid templates', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.template({});
|
||||
},
|
||||
Error,
|
||||
'Unknown template object: object'
|
||||
);
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.template();
|
||||
},
|
||||
Error,
|
||||
'Unknown template object: undefined'
|
||||
);
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.template('');
|
||||
},
|
||||
Error,
|
||||
'Unknown template object: string'
|
||||
);
|
||||
});
|
||||
it('should throw on version mismatch', function() {
|
||||
it('should throw on version mismatch', function () {
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.template({
|
||||
main: {},
|
||||
compiler: [Handlebars.COMPILER_REVISION + 1]
|
||||
compiler: [Handlebars.COMPILER_REVISION + 1],
|
||||
});
|
||||
},
|
||||
Error,
|
||||
/Template was precompiled with a newer version of Handlebars than the current runtime/
|
||||
);
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.template({
|
||||
main: {},
|
||||
compiler: [Handlebars.LAST_COMPATIBLE_COMPILER_REVISION - 1]
|
||||
compiler: [Handlebars.LAST_COMPATIBLE_COMPILER_REVISION - 1],
|
||||
});
|
||||
},
|
||||
Error,
|
||||
/Template was precompiled with an older version of Handlebars than the current runtime/
|
||||
);
|
||||
shouldThrow(
|
||||
function() {
|
||||
function () {
|
||||
Handlebars.template({
|
||||
main: {}
|
||||
main: {},
|
||||
});
|
||||
},
|
||||
Error,
|
||||
@@ -56,12 +56,12 @@ describe('runtime', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#noConflict', function() {
|
||||
describe('#noConflict', function () {
|
||||
if (!CompilerContext.browser) {
|
||||
return;
|
||||
}
|
||||
|
||||
it('should reset on no conflict', function() {
|
||||
it('should reset on no conflict', function () {
|
||||
var reset = Handlebars;
|
||||
Handlebars.noConflict();
|
||||
equal(Handlebars, 'no-conflict');
|
||||
|
||||
+81
-85
@@ -1,25 +1,23 @@
|
||||
describe('security issues', function() {
|
||||
describe('GH-1495: Prevent Remote Code Execution via constructor', function() {
|
||||
it('should not allow constructors to be accessed', function() {
|
||||
describe('security issues', function () {
|
||||
describe('GH-1495: Prevent Remote Code Execution via constructor', function () {
|
||||
it('should not allow constructors to be accessed', function () {
|
||||
expectTemplate('{{lookup (lookup this "constructor") "name"}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
|
||||
expectTemplate('{{constructor.name}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
expectTemplate('{{constructor.name}}').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"}}')
|
||||
.withInput({})
|
||||
.withHelper('list', function(element) {
|
||||
.withHelper('list', function (element) {
|
||||
return [element];
|
||||
})
|
||||
.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}}')
|
||||
.withInput({ constructor: { name: 'here we go' } })
|
||||
.toCompileTo('here we go');
|
||||
@@ -29,79 +27,79 @@ describe('security issues', function() {
|
||||
.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"}}')
|
||||
.withInput({ constructor: { name: '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) {
|
||||
return;
|
||||
}
|
||||
|
||||
describe('without the option "allowExplicitCallOfHelperMissing"', function() {
|
||||
it('should throw an exception when calling "{{helperMissing}}" ', function() {
|
||||
describe('without the option "allowExplicitCallOfHelperMissing"', function () {
|
||||
it('should throw an exception when calling "{{helperMissing}}" ', function () {
|
||||
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);
|
||||
});
|
||||
|
||||
it('should throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function() {
|
||||
it('should throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function () {
|
||||
var functionCalls = [];
|
||||
expect(function() {
|
||||
expect(function () {
|
||||
var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
|
||||
template({
|
||||
fn: function() {
|
||||
fn: function () {
|
||||
functionCalls.push('called');
|
||||
}
|
||||
},
|
||||
});
|
||||
}).to.throw(Error);
|
||||
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}}')
|
||||
.withInput({
|
||||
fn: function() {
|
||||
fn: function () {
|
||||
return 'functionInData';
|
||||
}
|
||||
},
|
||||
})
|
||||
.toThrow(Error);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with the option "allowCallsToHelperMissing" set to true', function() {
|
||||
it('should not throw an exception when calling "{{helperMissing}}" ', function() {
|
||||
describe('with the option "allowCallsToHelperMissing" set to true', function () {
|
||||
it('should not throw an exception when calling "{{helperMissing}}" ', function () {
|
||||
var template = Handlebars.compile('{{helperMissing}}');
|
||||
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(
|
||||
'{{#helperMissing}}{{/helperMissing}}'
|
||||
);
|
||||
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 template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
|
||||
template(
|
||||
{
|
||||
fn: function() {
|
||||
fn: function () {
|
||||
functionCalls.push('called');
|
||||
}
|
||||
},
|
||||
},
|
||||
{ allowCallsToHelperMissing: true }
|
||||
);
|
||||
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(
|
||||
'{{#blockHelperMissing true}}sdads{{/blockHelperMissing}}'
|
||||
);
|
||||
@@ -110,8 +108,8 @@ describe('security issues', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GH-1563', function() {
|
||||
it('should not allow to access constructor after overriding via __defineGetter__', function() {
|
||||
describe('GH-1563', function () {
|
||||
it('should not allow to access constructor after overriding via __defineGetter__', function () {
|
||||
if ({}.__defineGetter__ == null || {}.__lookupGetter__ == null) {
|
||||
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 = [
|
||||
'{{constructor}}',
|
||||
'{{__defineGetter__}}',
|
||||
@@ -138,53 +136,51 @@ describe('security issues', function() {
|
||||
'{{lookup this "__defineGetter__"}}',
|
||||
'{{lookup this "__defineSetter__"}}',
|
||||
'{{lookup this "__lookupGetter__"}}',
|
||||
'{{lookup this "__proto__"}}'
|
||||
'{{lookup this "__proto__"}}',
|
||||
];
|
||||
|
||||
templates.forEach(function(template) {
|
||||
describe('access should be denied to ' + template, function() {
|
||||
it('by default', function() {
|
||||
expectTemplate(template)
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
templates.forEach(function (template) {
|
||||
describe('access should be denied to ' + template, function () {
|
||||
it('by default', function () {
|
||||
expectTemplate(template).withInput({}).toCompileTo('');
|
||||
});
|
||||
it(' with proto-access enabled', function() {
|
||||
it(' with proto-access enabled', function () {
|
||||
expectTemplate(template)
|
||||
.withInput({})
|
||||
.withRuntimeOptions({
|
||||
allowProtoPropertiesByDefault: true,
|
||||
allowProtoMethodsByDefault: true
|
||||
allowProtoMethodsByDefault: true,
|
||||
})
|
||||
.toCompileTo('');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('GH-1631: disallow access to prototype functions', function() {
|
||||
describe('GH-1631: disallow access to prototype functions', function () {
|
||||
function TestClass() {}
|
||||
|
||||
TestClass.prototype.aProperty = 'propertyValue';
|
||||
TestClass.prototype.aMethod = function() {
|
||||
TestClass.prototype.aMethod = function () {
|
||||
return 'returnValue';
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
handlebarsEnv.resetLoggedPropertyAccesses();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
afterEach(function () {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
describe('control access to prototype methods via "allowedProtoMethods"', function() {
|
||||
describe('control access to prototype methods via "allowedProtoMethods"', function () {
|
||||
checkProtoMethodAccess({});
|
||||
|
||||
describe('in compat mode', function() {
|
||||
describe('in compat mode', function () {
|
||||
checkProtoMethodAccess({ compat: true });
|
||||
});
|
||||
|
||||
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');
|
||||
|
||||
expectTemplate('{{aMethod}}')
|
||||
@@ -196,7 +192,7 @@ describe('security issues', function() {
|
||||
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');
|
||||
|
||||
expectTemplate('{{aMethod}}')
|
||||
@@ -213,7 +209,7 @@ describe('security issues', function() {
|
||||
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');
|
||||
|
||||
expectTemplate('{{aMethod}}')
|
||||
@@ -221,89 +217,89 @@ describe('security issues', function() {
|
||||
.withCompileOptions(compileOptions)
|
||||
.withRuntimeOptions({
|
||||
allowedProtoMethods: {
|
||||
aMethod: true
|
||||
}
|
||||
aMethod: true,
|
||||
},
|
||||
})
|
||||
.toCompileTo('returnValue');
|
||||
|
||||
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');
|
||||
|
||||
expectTemplate('{{aMethod}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
.withRuntimeOptions({
|
||||
allowProtoMethodsByDefault: true
|
||||
allowProtoMethodsByDefault: true,
|
||||
})
|
||||
.toCompileTo('returnValue');
|
||||
|
||||
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');
|
||||
|
||||
expectTemplate('{{aMethod}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
.withRuntimeOptions({
|
||||
allowProtoMethodsByDefault: false
|
||||
allowProtoMethodsByDefault: false,
|
||||
})
|
||||
.toCompileTo('');
|
||||
|
||||
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}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
.withRuntimeOptions({
|
||||
allowProtoMethodsByDefault: true,
|
||||
allowedProtoMethods: {
|
||||
aMethod: false
|
||||
}
|
||||
aMethod: false,
|
||||
},
|
||||
})
|
||||
.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}}')
|
||||
.withInput({ aString: ' abc ', trim: 'trim' })
|
||||
.withCompileOptions({ compat: true })
|
||||
.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}}')
|
||||
.withInput({ aString: ' abc ', trim: 'trim' })
|
||||
.withCompileOptions({ compat: true })
|
||||
.withRuntimeOptions({
|
||||
allowedProtoMethods: {
|
||||
trim: true
|
||||
}
|
||||
trim: true,
|
||||
},
|
||||
})
|
||||
.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({});
|
||||
|
||||
describe('in compat-mode', function() {
|
||||
describe('in compat-mode', function () {
|
||||
checkProtoPropertyAccess({ compat: true });
|
||||
});
|
||||
|
||||
describe('in strict-mode', function() {
|
||||
describe('in strict-mode', function () {
|
||||
checkProtoPropertyAccess({ strict: true });
|
||||
});
|
||||
|
||||
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');
|
||||
|
||||
expectTemplate('{{aProperty}}')
|
||||
@@ -315,21 +311,21 @@ describe('security issues', function() {
|
||||
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');
|
||||
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
.withRuntimeOptions({
|
||||
allowProtoPropertiesByDefault: false
|
||||
allowProtoPropertiesByDefault: false,
|
||||
})
|
||||
.toCompileTo('');
|
||||
|
||||
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');
|
||||
|
||||
expectTemplate('{{aProperty}}')
|
||||
@@ -337,63 +333,63 @@ describe('security issues', function() {
|
||||
.withCompileOptions(compileOptions)
|
||||
.withRuntimeOptions({
|
||||
allowedProtoProperties: {
|
||||
aProperty: true
|
||||
}
|
||||
aProperty: true,
|
||||
},
|
||||
})
|
||||
.toCompileTo('propertyValue');
|
||||
|
||||
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');
|
||||
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
.withRuntimeOptions({
|
||||
allowProtoPropertiesByDefault: true
|
||||
allowProtoPropertiesByDefault: true,
|
||||
})
|
||||
.toCompileTo('propertyValue');
|
||||
|
||||
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}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
.withRuntimeOptions({
|
||||
allowProtoPropertiesByDefault: true,
|
||||
allowedProtoProperties: {
|
||||
aProperty: false
|
||||
}
|
||||
aProperty: false,
|
||||
},
|
||||
})
|
||||
.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() {
|
||||
var oldTemplateMethod = handlebarsEnv.template;
|
||||
sinon.replace(handlebarsEnv, 'template', function(templateSpec) {
|
||||
sinon.replace(handlebarsEnv, 'template', function (templateSpec) {
|
||||
templateSpec.main = wrapToAdjustContainer(templateSpec.main);
|
||||
return oldTemplateMethod.call(this, templateSpec);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
afterEach(function () {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
it('should work with simple properties', function() {
|
||||
it('should work with simple properties', function () {
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput({ aProperty: 'propertyValue' })
|
||||
.toCompileTo('propertyValue');
|
||||
});
|
||||
|
||||
it('should work with Array.prototype.length', function() {
|
||||
it('should work with Array.prototype.length', function () {
|
||||
expectTemplate('{{anArray.length}}')
|
||||
.withInput({ anArray: ['a', 'b', 'c'] })
|
||||
.toCompileTo('3');
|
||||
@@ -401,21 +397,21 @@ describe('security issues', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('escapes template variables', function() {
|
||||
it('in compat mode', function() {
|
||||
describe('escapes template variables', function () {
|
||||
it('in compat mode', function () {
|
||||
expectTemplate("{{'a\\b'}}")
|
||||
.withCompileOptions({ compat: true })
|
||||
.withInput({ 'a\\b': 'c' })
|
||||
.toCompileTo('c');
|
||||
});
|
||||
|
||||
it('in default mode', function() {
|
||||
it('in default mode', function () {
|
||||
expectTemplate("{{'a\\b'}}")
|
||||
.withCompileOptions()
|
||||
.withInput({ 'a\\b': 'c' })
|
||||
.toCompileTo('c');
|
||||
});
|
||||
it('in default mode', function() {
|
||||
it('in default mode', function () {
|
||||
expectTemplate("{{'a\\b'}}")
|
||||
.withCompileOptions({ strict: true })
|
||||
.withInput({ 'a\\b': 'c' })
|
||||
|
||||
+6
-6
@@ -7,26 +7,26 @@ try {
|
||||
/* NOP for in browser */
|
||||
}
|
||||
|
||||
describe('source-map', function() {
|
||||
describe('source-map', function () {
|
||||
if (!Handlebars.precompile || !SourceMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
it('should safely include source map info', function() {
|
||||
it('should safely include source map info', function () {
|
||||
var template = Handlebars.precompile('{{hello}}', {
|
||||
destName: 'dest.js',
|
||||
srcName: 'src.hbs'
|
||||
srcName: 'src.hbs',
|
||||
});
|
||||
|
||||
equal(!!template.code, true);
|
||||
equal(!!template.map, !CompilerContext.browser);
|
||||
});
|
||||
it('should map source properly', function() {
|
||||
it('should map source properly', function () {
|
||||
var templateSource =
|
||||
' b{{hello}} \n {{bar}}a {{#block arg hash=(subex 1 subval)}}{{/block}}',
|
||||
template = Handlebars.precompile(templateSource, {
|
||||
destName: 'dest.js',
|
||||
srcName: 'src.hbs'
|
||||
srcName: 'src.hbs',
|
||||
});
|
||||
|
||||
if (template.map) {
|
||||
@@ -49,7 +49,7 @@ function grepLine(token, lines) {
|
||||
if (column >= 0) {
|
||||
return {
|
||||
line: i + 1,
|
||||
column: column
|
||||
column: column,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
describe('spec', function() {
|
||||
describe('spec', function () {
|
||||
// NOP Under non-node environments
|
||||
if (typeof process === 'undefined') {
|
||||
return;
|
||||
@@ -7,11 +7,11 @@ describe('spec', function() {
|
||||
var fs = require('fs');
|
||||
|
||||
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);
|
||||
spec.tests.forEach(function(test) {
|
||||
spec.tests.forEach(function (test) {
|
||||
// Our lambda implementation knowingly deviates from the optional Mustache lambda spec
|
||||
// We also do not support alternative delimiters
|
||||
if (
|
||||
@@ -21,7 +21,7 @@ describe('spec', function() {
|
||||
// We nest the entire response from partials, not just the literals
|
||||
(name === 'partials.json' && test.name === 'Standalone Indentation') ||
|
||||
/\{\{=/.test(test.template) ||
|
||||
Object.values(test.partials || {}).some(value => /\{\{=/.test(value))
|
||||
Object.values(test.partials || {}).some((value) => /\{\{=/.test(value))
|
||||
) {
|
||||
it.skip(name + ' - ' + test.name);
|
||||
return;
|
||||
@@ -33,7 +33,7 @@ describe('spec', function() {
|
||||
/* eslint-disable-next-line no-eval */
|
||||
data.lambda = eval('(' + data.lambda.js + ')');
|
||||
}
|
||||
it(name + ' - ' + test.name, function() {
|
||||
it(name + ' - ' + test.name, function () {
|
||||
expectTemplate(test.template)
|
||||
.withInput(data)
|
||||
.withPartials(test.partials || {})
|
||||
|
||||
+27
-27
@@ -1,14 +1,14 @@
|
||||
var Exception = Handlebars.Exception;
|
||||
|
||||
describe('strict', function() {
|
||||
describe('strict mode', function() {
|
||||
it('should error on missing property lookup', function() {
|
||||
describe('strict', function () {
|
||||
describe('strict mode', function () {
|
||||
it('should error on missing property lookup', function () {
|
||||
expectTemplate('{{hello}}')
|
||||
.withCompileOptions({ strict: true })
|
||||
.toThrow(Exception, /"hello" not defined in/);
|
||||
});
|
||||
|
||||
it('should error on missing child', function() {
|
||||
it('should error on missing child', function () {
|
||||
expectTemplate('{{hello.bar}}')
|
||||
.withCompileOptions({ strict: true })
|
||||
.withInput({ hello: { bar: 'foo' } })
|
||||
@@ -20,31 +20,31 @@ describe('strict', function() {
|
||||
.toThrow(Exception, /"bar" not defined in/);
|
||||
});
|
||||
|
||||
it('should handle explicit undefined', function() {
|
||||
it('should handle explicit undefined', function () {
|
||||
expectTemplate('{{hello.bar}}')
|
||||
.withCompileOptions({ strict: true })
|
||||
.withInput({ hello: { bar: undefined } })
|
||||
.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}}')
|
||||
.withCompileOptions({
|
||||
strict: true,
|
||||
knownHelpersOnly: true
|
||||
knownHelpersOnly: true,
|
||||
})
|
||||
.toThrow(Exception, /"hello" not defined in/);
|
||||
});
|
||||
|
||||
it('should error on missing context', function() {
|
||||
it('should error on missing context', function () {
|
||||
expectTemplate('{{hello}}')
|
||||
.withCompileOptions({ strict: true })
|
||||
.toThrow(Error);
|
||||
});
|
||||
|
||||
it('should error on missing data lookup', function() {
|
||||
it('should error on missing data lookup', function () {
|
||||
var xt = expectTemplate('{{@hello}}').withCompileOptions({
|
||||
strict: true
|
||||
strict: true,
|
||||
});
|
||||
|
||||
xt.toThrow(Error);
|
||||
@@ -52,7 +52,7 @@ describe('strict', function() {
|
||||
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}}')
|
||||
.withCompileOptions({ strict: true })
|
||||
.withInput({ foo: true })
|
||||
@@ -64,7 +64,7 @@ describe('strict', function() {
|
||||
.toThrow(Exception, /"hello" not defined in/);
|
||||
});
|
||||
|
||||
it('should throw on ambiguous blocks', function() {
|
||||
it('should throw on ambiguous blocks', function () {
|
||||
expectTemplate('{{#hello}}{{/hello}}')
|
||||
.withCompileOptions({ strict: true })
|
||||
.toThrow(Exception, /"hello" not defined in/);
|
||||
@@ -79,37 +79,37 @@ describe('strict', function() {
|
||||
.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}}')
|
||||
.withCompileOptions({ strict: true })
|
||||
.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}}')
|
||||
.withCompileOptions({
|
||||
strict: true
|
||||
strict: true,
|
||||
})
|
||||
.withHelpers({
|
||||
helper: function(options) {
|
||||
helper: function (options) {
|
||||
equals('value' in options.hash, true);
|
||||
equals(options.hash.value, undefined);
|
||||
return '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}}')
|
||||
.withCompileOptions({ strict: true })
|
||||
.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 {
|
||||
var template = CompilerContext.compile('\n\n\n {{hello}}', {
|
||||
strict: true
|
||||
strict: true,
|
||||
});
|
||||
template({});
|
||||
} catch (error) {
|
||||
@@ -121,41 +121,41 @@ describe('strict', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('assume objects', function() {
|
||||
it('should ignore missing property', function() {
|
||||
describe('assume objects', function () {
|
||||
it('should ignore missing property', function () {
|
||||
expectTemplate('{{hello}}')
|
||||
.withCompileOptions({ assumeObjects: true })
|
||||
.toCompileTo('');
|
||||
});
|
||||
|
||||
it('should ignore missing child', function() {
|
||||
it('should ignore missing child', function () {
|
||||
expectTemplate('{{hello.bar}}')
|
||||
.withCompileOptions({ assumeObjects: true })
|
||||
.withInput({ hello: {} })
|
||||
.toCompileTo('');
|
||||
});
|
||||
|
||||
it('should error on missing object', function() {
|
||||
it('should error on missing object', function () {
|
||||
expectTemplate('{{hello.bar}}')
|
||||
.withCompileOptions({ assumeObjects: true })
|
||||
.toThrow(Error);
|
||||
});
|
||||
|
||||
it('should error on missing context', function() {
|
||||
it('should error on missing context', function () {
|
||||
expectTemplate('{{hello}}')
|
||||
.withCompileOptions({ assumeObjects: true })
|
||||
.withInput(undefined)
|
||||
.toThrow(Error);
|
||||
});
|
||||
|
||||
it('should error on missing data lookup', function() {
|
||||
it('should error on missing data lookup', function () {
|
||||
expectTemplate('{{@hello.bar}}')
|
||||
.withCompileOptions({ assumeObjects: true })
|
||||
.withInput(undefined)
|
||||
.toThrow(Error);
|
||||
});
|
||||
|
||||
it('should execute blockHelperMissing', function() {
|
||||
it('should execute blockHelperMissing', function () {
|
||||
expectTemplate('{{^hello}}foo{{/hello}}')
|
||||
.withCompileOptions({ assumeObjects: true })
|
||||
.toCompileTo('foo');
|
||||
|
||||
+51
-51
@@ -1,68 +1,68 @@
|
||||
describe('subexpressions', function() {
|
||||
it('arg-less helper', function() {
|
||||
describe('subexpressions', function () {
|
||||
it('arg-less helper', function () {
|
||||
expectTemplate('{{foo (bar)}}!')
|
||||
.withHelpers({
|
||||
foo: function(val) {
|
||||
foo: function (val) {
|
||||
return val + val;
|
||||
},
|
||||
bar: function() {
|
||||
bar: function () {
|
||||
return 'LOL';
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('LOLLOL!');
|
||||
});
|
||||
|
||||
it('helper w args', function() {
|
||||
it('helper w args', function () {
|
||||
expectTemplate('{{blog (equal a b)}}')
|
||||
.withInput({ bar: 'LOL' })
|
||||
.withHelpers({
|
||||
blog: function(val) {
|
||||
blog: function (val) {
|
||||
return 'val is ' + val;
|
||||
},
|
||||
equal: function(x, y) {
|
||||
equal: function (x, y) {
|
||||
return x === y;
|
||||
}
|
||||
},
|
||||
})
|
||||
.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}}')
|
||||
.withInput({ bar: 'LOL', baz: { bat: 'foo!', bar: 'bar!' } })
|
||||
.withHelpers({
|
||||
blog: function(val, that, theOther) {
|
||||
blog: function (val, that, theOther) {
|
||||
return 'val is ' + val + ', ' + that + ' and ' + theOther;
|
||||
},
|
||||
equal: function(x, y) {
|
||||
equal: function (x, y) {
|
||||
return x === y;
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('val is foo!, true and bar!');
|
||||
});
|
||||
|
||||
it('supports much nesting', function() {
|
||||
it('supports much nesting', function () {
|
||||
expectTemplate('{{blog (equal (equal true true) true)}}')
|
||||
.withInput({ bar: 'LOL' })
|
||||
.withHelpers({
|
||||
blog: function(val) {
|
||||
blog: function (val) {
|
||||
return 'val is ' + val;
|
||||
},
|
||||
equal: function(x, y) {
|
||||
equal: function (x, y) {
|
||||
return x === y;
|
||||
}
|
||||
},
|
||||
})
|
||||
.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 helpers = {
|
||||
dash: function(a, b) {
|
||||
dash: function (a, b) {
|
||||
return a + '-' + b;
|
||||
},
|
||||
concat: function(a, b) {
|
||||
concat: function (a, b) {
|
||||
return a + b;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
expectTemplate("{{dash 'abc' (concat a b)}}")
|
||||
@@ -91,55 +91,55 @@ describe('subexpressions', function() {
|
||||
.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 helpers = {
|
||||
equal: function(x, y, options) {
|
||||
equal: function (x, y, options) {
|
||||
if (!options || options === lastOptions) {
|
||||
throw new Error('options hash was reused');
|
||||
}
|
||||
lastOptions = options;
|
||||
return x === y;
|
||||
}
|
||||
},
|
||||
};
|
||||
expectTemplate('{{equal (equal true true) true}}')
|
||||
.withHelpers(helpers)
|
||||
.toCompileTo('true');
|
||||
});
|
||||
|
||||
it('with hashes', function() {
|
||||
it('with hashes', function () {
|
||||
expectTemplate("{{blog (equal (equal true true) true fun='yes')}}")
|
||||
.withInput({ bar: 'LOL' })
|
||||
.withHelpers({
|
||||
blog: function(val) {
|
||||
blog: function (val) {
|
||||
return 'val is ' + val;
|
||||
},
|
||||
equal: function(x, y) {
|
||||
equal: function (x, y) {
|
||||
return x === y;
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('val is true');
|
||||
});
|
||||
|
||||
it('as hashes', function() {
|
||||
it('as hashes', function () {
|
||||
expectTemplate("{{blog fun=(equal (blog fun=1) 'val is 1')}}")
|
||||
.withHelpers({
|
||||
blog: function(options) {
|
||||
blog: function (options) {
|
||||
return 'val is ' + options.hash.fun;
|
||||
},
|
||||
equal: function(x, y) {
|
||||
equal: function (x, y) {
|
||||
return x === y;
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('val is true');
|
||||
});
|
||||
|
||||
it('multiple subexpressions in a hash', function() {
|
||||
it('multiple subexpressions in a hash', function () {
|
||||
expectTemplate(
|
||||
'{{input aria-label=(t "Name") placeholder=(t "Example User")}}'
|
||||
)
|
||||
.withHelpers({
|
||||
input: function(options) {
|
||||
input: function (options) {
|
||||
var hash = options.hash;
|
||||
var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
|
||||
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);
|
||||
}
|
||||
},
|
||||
})
|
||||
.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(
|
||||
'{{input aria-label=(t item.field) placeholder=(t item.placeholder)}}'
|
||||
)
|
||||
.withInput({
|
||||
item: {
|
||||
field: 'Name',
|
||||
placeholder: 'Example User'
|
||||
}
|
||||
placeholder: 'Example User',
|
||||
},
|
||||
})
|
||||
.withHelpers({
|
||||
input: function(options) {
|
||||
input: function (options) {
|
||||
var hash = options.hash;
|
||||
var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
|
||||
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);
|
||||
}
|
||||
},
|
||||
})
|
||||
.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)}}!')
|
||||
.withInput({
|
||||
bar: function() {
|
||||
bar: function () {
|
||||
return 'LOL';
|
||||
}
|
||||
},
|
||||
})
|
||||
.withHelpers({
|
||||
foo: function(val) {
|
||||
foo: function (val) {
|
||||
return val + val;
|
||||
}
|
||||
},
|
||||
})
|
||||
.toCompileTo('LOLLOL!');
|
||||
});
|
||||
|
||||
it("subexpressions can't just be property lookups", function() {
|
||||
it("subexpressions can't just be property lookups", function () {
|
||||
expectTemplate('{{foo (bar)}}!')
|
||||
.withInput({
|
||||
bar: 'LOL'
|
||||
bar: 'LOL',
|
||||
})
|
||||
.withHelpers({
|
||||
foo: function(val) {
|
||||
foo: function (val) {
|
||||
return val + val;
|
||||
}
|
||||
},
|
||||
})
|
||||
.toThrow();
|
||||
});
|
||||
|
||||
+93
-93
@@ -8,7 +8,7 @@ function shouldBeToken(result, name, text) {
|
||||
equals(result.text, text);
|
||||
}
|
||||
|
||||
describe('Tokenizer', function() {
|
||||
describe('Tokenizer', function () {
|
||||
if (!Handlebars.Parser) {
|
||||
return;
|
||||
}
|
||||
@@ -32,13 +32,13 @@ describe('Tokenizer', function() {
|
||||
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}}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']);
|
||||
shouldBeToken(result[1], 'ID', 'foo');
|
||||
});
|
||||
|
||||
it('supports unescaping with &', function() {
|
||||
it('supports unescaping with &', function () {
|
||||
var result = tokenize('{{&bar}}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']);
|
||||
|
||||
@@ -46,14 +46,14 @@ describe('Tokenizer', function() {
|
||||
shouldBeToken(result[1], 'ID', 'bar');
|
||||
});
|
||||
|
||||
it('supports unescaping with {{{', function() {
|
||||
it('supports unescaping with {{{', function () {
|
||||
var result = tokenize('{{{bar}}}');
|
||||
shouldMatchTokens(result, ['OPEN_UNESCAPED', 'ID', 'CLOSE_UNESCAPED']);
|
||||
|
||||
shouldBeToken(result[1], 'ID', 'bar');
|
||||
});
|
||||
|
||||
it('supports escaping delimiters', function() {
|
||||
it('supports escaping delimiters', function () {
|
||||
var result = tokenize('{{foo}} \\{{bar}} {{baz}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -63,14 +63,14 @@ describe('Tokenizer', function() {
|
||||
'CONTENT',
|
||||
'OPEN',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
shouldBeToken(result[3], 'CONTENT', ' ');
|
||||
shouldBeToken(result[4], 'CONTENT', '{{bar}} ');
|
||||
});
|
||||
|
||||
it('supports escaping multiple delimiters', function() {
|
||||
it('supports escaping multiple delimiters', function () {
|
||||
var result = tokenize('{{foo}} \\{{bar}} \\{{baz}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -78,7 +78,7 @@ describe('Tokenizer', function() {
|
||||
'CLOSE',
|
||||
'CONTENT',
|
||||
'CONTENT',
|
||||
'CONTENT'
|
||||
'CONTENT',
|
||||
]);
|
||||
|
||||
shouldBeToken(result[3], 'CONTENT', ' ');
|
||||
@@ -86,7 +86,7 @@ describe('Tokenizer', function() {
|
||||
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}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -96,13 +96,13 @@ describe('Tokenizer', function() {
|
||||
'CONTENT',
|
||||
'OPEN',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
shouldBeToken(result[4], 'CONTENT', '{{{bar}}} ');
|
||||
});
|
||||
|
||||
it('supports escaping escape character', function() {
|
||||
it('supports escaping escape character', function () {
|
||||
var result = tokenize('{{foo}} \\\\{{bar}} {{baz}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -115,14 +115,14 @@ describe('Tokenizer', function() {
|
||||
'CONTENT',
|
||||
'OPEN',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
shouldBeToken(result[3], 'CONTENT', ' \\');
|
||||
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}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -135,7 +135,7 @@ describe('Tokenizer', function() {
|
||||
'CONTENT',
|
||||
'OPEN',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
shouldBeToken(result[3], 'CONTENT', ' \\');
|
||||
@@ -144,7 +144,7 @@ describe('Tokenizer', function() {
|
||||
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}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -156,7 +156,7 @@ describe('Tokenizer', function() {
|
||||
'CLOSE',
|
||||
'CONTENT',
|
||||
'CONTENT',
|
||||
'CONTENT'
|
||||
'CONTENT',
|
||||
]);
|
||||
|
||||
shouldBeToken(result[3], 'CONTENT', ' \\');
|
||||
@@ -166,7 +166,7 @@ describe('Tokenizer', function() {
|
||||
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}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -177,7 +177,7 @@ describe('Tokenizer', function() {
|
||||
'CONTENT',
|
||||
'OPEN',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
shouldBeToken(result[4], 'CONTENT', '{{bar}} ');
|
||||
@@ -186,7 +186,7 @@ describe('Tokenizer', function() {
|
||||
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}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -199,19 +199,19 @@ describe('Tokenizer', function() {
|
||||
'CONTENT',
|
||||
'OPEN',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
shouldBeToken(result[3], 'CONTENT', ' \\');
|
||||
shouldBeToken(result[5], 'ID', 'bar');
|
||||
});
|
||||
|
||||
it('tokenizes a simple path', function() {
|
||||
it('tokenizes a simple path', function () {
|
||||
var result = tokenize('{{foo/bar}}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
||||
});
|
||||
|
||||
it('allows dot notation', function() {
|
||||
it('allows dot notation', function () {
|
||||
var result = tokenize('{{foo.bar}}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
||||
|
||||
@@ -222,16 +222,16 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'SEP',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
});
|
||||
|
||||
it('allows path literals with []', function() {
|
||||
it('allows path literals with []', function () {
|
||||
var result = tokenize('{{foo.[bar]}}');
|
||||
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]}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -243,21 +243,21 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'SEP',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
});
|
||||
|
||||
it('allows escaped literals in []', function() {
|
||||
it('allows escaped literals in []', function () {
|
||||
var result = tokenize('{{foo.[bar\\]]}}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
||||
});
|
||||
|
||||
it('tokenizes {{.}} as OPEN ID CLOSE', function() {
|
||||
it('tokenizes {{.}} as OPEN ID CLOSE', function () {
|
||||
var result = tokenize('{{.}}');
|
||||
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}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -266,12 +266,12 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'SEP',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
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}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -280,58 +280,58 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'SEP',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
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}}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
|
||||
shouldBeToken(result[1], 'ID', 'this');
|
||||
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 }}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']);
|
||||
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 }}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'CLOSE']);
|
||||
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');
|
||||
shouldMatchTokens(result, ['CONTENT', 'OPEN', 'ID', 'CLOSE', 'CONTENT']);
|
||||
shouldBeToken(result[0], 'CONTENT', 'foo ');
|
||||
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}}');
|
||||
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 }}');
|
||||
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}}');
|
||||
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 }}');
|
||||
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 }}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN_PARTIAL',
|
||||
@@ -340,15 +340,15 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'SEP',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
});
|
||||
|
||||
it('tokenizes partial block declarations', function() {
|
||||
it('tokenizes partial block declarations', function () {
|
||||
var result = tokenize('{{#> foo}}');
|
||||
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 }}');
|
||||
shouldMatchTokens(result, [
|
||||
'CONTENT',
|
||||
@@ -356,12 +356,12 @@ describe('Tokenizer', function() {
|
||||
'CONTENT',
|
||||
'OPEN',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
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 }}');
|
||||
shouldMatchTokens(result, [
|
||||
'CONTENT',
|
||||
@@ -369,12 +369,12 @@ describe('Tokenizer', function() {
|
||||
'CONTENT',
|
||||
'OPEN',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
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(
|
||||
'foo {{!-- this is a\n{{comment}}\n--}} bar {{ baz }}'
|
||||
);
|
||||
@@ -384,12 +384,12 @@ describe('Tokenizer', function() {
|
||||
'CONTENT',
|
||||
'OPEN',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
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}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN_BLOCK',
|
||||
@@ -398,11 +398,11 @@ describe('Tokenizer', function() {
|
||||
'CONTENT',
|
||||
'OPEN_ENDBLOCK',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
});
|
||||
|
||||
it('tokenizes directives', function() {
|
||||
it('tokenizes directives', function () {
|
||||
shouldMatchTokens(tokenize('{{#*foo}}content{{/foo}}'), [
|
||||
'OPEN_BLOCK',
|
||||
'ID',
|
||||
@@ -410,30 +410,30 @@ describe('Tokenizer', function() {
|
||||
'CONTENT',
|
||||
'OPEN_ENDBLOCK',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'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('{{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}}');
|
||||
shouldMatchTokens(result, ['OPEN_INVERSE', 'ID', 'CLOSE']);
|
||||
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 }}');
|
||||
shouldMatchTokens(result, ['OPEN_INVERSE', 'ID', 'CLOSE']);
|
||||
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 }}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'CLOSE']);
|
||||
shouldBeToken(result[1], 'ID', 'foo');
|
||||
@@ -441,37 +441,37 @@ describe('Tokenizer', function() {
|
||||
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" }}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']);
|
||||
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' }}");
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']);
|
||||
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" }}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']);
|
||||
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" }}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'STRING', 'CLOSE']);
|
||||
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' }}");
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'STRING', 'CLOSE']);
|
||||
shouldBeToken(result[2], 'STRING', "bar'baz");
|
||||
});
|
||||
|
||||
it('tokenizes numbers', function() {
|
||||
it('tokenizes numbers', function () {
|
||||
var result = tokenize('{{ foo 1 }}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'NUMBER', 'CLOSE']);
|
||||
shouldBeToken(result[2], 'NUMBER', '1');
|
||||
@@ -489,7 +489,7 @@ describe('Tokenizer', function() {
|
||||
shouldBeToken(result[2], 'NUMBER', '-1.1');
|
||||
});
|
||||
|
||||
it('tokenizes booleans', function() {
|
||||
it('tokenizes booleans', function () {
|
||||
var result = tokenize('{{ foo true }}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'BOOLEAN', 'CLOSE']);
|
||||
shouldBeToken(result[2], 'BOOLEAN', 'true');
|
||||
@@ -499,14 +499,14 @@ describe('Tokenizer', function() {
|
||||
shouldBeToken(result[2], 'BOOLEAN', 'false');
|
||||
});
|
||||
|
||||
it('tokenizes undefined and null', function() {
|
||||
it('tokenizes undefined and null', function () {
|
||||
var result = tokenize('{{ foo undefined null }}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'UNDEFINED', 'NULL', 'CLOSE']);
|
||||
shouldBeToken(result[2], 'UNDEFINED', 'undefined');
|
||||
shouldBeToken(result[3], 'NULL', 'null');
|
||||
});
|
||||
|
||||
it('tokenizes hash arguments', function() {
|
||||
it('tokenizes hash arguments', function () {
|
||||
var result = tokenize('{{ foo bar=baz }}');
|
||||
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'EQUALS', 'ID', 'CLOSE']);
|
||||
|
||||
@@ -518,7 +518,7 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'EQUALS',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
result = tokenize('{{ foo bar baz=1 }}');
|
||||
@@ -529,7 +529,7 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'EQUALS',
|
||||
'NUMBER',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
result = tokenize('{{ foo bar baz=true }}');
|
||||
@@ -540,7 +540,7 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'EQUALS',
|
||||
'BOOLEAN',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
result = tokenize('{{ foo bar baz=false }}');
|
||||
@@ -551,7 +551,7 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'EQUALS',
|
||||
'BOOLEAN',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
result = tokenize('{{ foo bar\n baz=bat }}');
|
||||
@@ -562,7 +562,7 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'EQUALS',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
result = tokenize('{{ foo bar baz="bat" }}');
|
||||
@@ -573,7 +573,7 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'EQUALS',
|
||||
'STRING',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
result = tokenize('{{ foo bar baz="bat" bam=wot }}');
|
||||
@@ -587,7 +587,7 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'EQUALS',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
result = tokenize('{{foo omg bar=baz bat="bam"}}');
|
||||
@@ -601,12 +601,12 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'EQUALS',
|
||||
'STRING',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
shouldBeToken(result[2], 'ID', 'omg');
|
||||
});
|
||||
|
||||
it('tokenizes special @ identifiers', function() {
|
||||
it('tokenizes special @ identifiers', function () {
|
||||
var result = tokenize('{{ @foo }}');
|
||||
shouldMatchTokens(result, ['OPEN', 'DATA', 'ID', 'CLOSE']);
|
||||
shouldBeToken(result[2], 'ID', 'foo');
|
||||
@@ -623,20 +623,20 @@ describe('Tokenizer', function() {
|
||||
'EQUALS',
|
||||
'DATA',
|
||||
'ID',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
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']);
|
||||
});
|
||||
|
||||
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']);
|
||||
});
|
||||
|
||||
it('tokenizes subexpressions', function() {
|
||||
it('tokenizes subexpressions', function () {
|
||||
var result = tokenize('{{foo (bar)}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -644,7 +644,7 @@ describe('Tokenizer', function() {
|
||||
'OPEN_SEXPR',
|
||||
'ID',
|
||||
'CLOSE_SEXPR',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
shouldBeToken(result[1], 'ID', 'foo');
|
||||
shouldBeToken(result[3], 'ID', 'bar');
|
||||
@@ -657,14 +657,14 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'ID',
|
||||
'CLOSE_SEXPR',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
shouldBeToken(result[1], 'ID', 'foo');
|
||||
shouldBeToken(result[3], 'ID', 'a-x');
|
||||
shouldBeToken(result[4], 'ID', 'b-y');
|
||||
});
|
||||
|
||||
it('tokenizes nested subexpressions', function() {
|
||||
it('tokenizes nested subexpressions', function () {
|
||||
var result = tokenize('{{foo (bar (lol rofl)) (baz)}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN',
|
||||
@@ -679,7 +679,7 @@ describe('Tokenizer', function() {
|
||||
'OPEN_SEXPR',
|
||||
'ID',
|
||||
'CLOSE_SEXPR',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
shouldBeToken(result[3], 'ID', 'bar');
|
||||
shouldBeToken(result[5], 'ID', 'lol');
|
||||
@@ -687,7 +687,7 @@ describe('Tokenizer', function() {
|
||||
shouldBeToken(result[10], 'ID', 'baz');
|
||||
});
|
||||
|
||||
it('tokenizes nested subexpressions: literals', function() {
|
||||
it('tokenizes nested subexpressions: literals', function () {
|
||||
var result = tokenize(
|
||||
'{{foo (bar (lol true) false) (baz 1) (blah \'b\') (blorg "c")}}'
|
||||
);
|
||||
@@ -714,11 +714,11 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'STRING',
|
||||
'CLOSE_SEXPR',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
});
|
||||
|
||||
it('tokenizes block params', function() {
|
||||
it('tokenizes block params', function () {
|
||||
var result = tokenize('{{#foo as |bar|}}');
|
||||
shouldMatchTokens(result, [
|
||||
'OPEN_BLOCK',
|
||||
@@ -726,7 +726,7 @@ describe('Tokenizer', function() {
|
||||
'OPEN_BLOCK_PARAMS',
|
||||
'ID',
|
||||
'CLOSE_BLOCK_PARAMS',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
result = tokenize('{{#foo as |bar baz|}}');
|
||||
@@ -737,7 +737,7 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'ID',
|
||||
'CLOSE_BLOCK_PARAMS',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
result = tokenize('{{#foo as | bar baz |}}');
|
||||
@@ -748,7 +748,7 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'ID',
|
||||
'CLOSE_BLOCK_PARAMS',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
result = tokenize('{{#foo as as | bar baz |}}');
|
||||
@@ -760,7 +760,7 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'ID',
|
||||
'CLOSE_BLOCK_PARAMS',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
|
||||
result = tokenize('{{else foo as |bar baz|}}');
|
||||
@@ -771,11 +771,11 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'ID',
|
||||
'CLOSE_BLOCK_PARAMS',
|
||||
'CLOSE'
|
||||
'CLOSE',
|
||||
]);
|
||||
});
|
||||
|
||||
it('tokenizes raw blocks', function() {
|
||||
it('tokenizes raw blocks', function () {
|
||||
var result = tokenize(
|
||||
'{{{{a}}}} abc {{{{/a}}}} aaa {{{{a}}}} abc {{{{/a}}}}'
|
||||
);
|
||||
@@ -790,7 +790,7 @@ describe('Tokenizer', function() {
|
||||
'ID',
|
||||
'CLOSE_RAW_BLOCK',
|
||||
'CONTENT',
|
||||
'END_RAW_BLOCK'
|
||||
'END_RAW_BLOCK',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
+16
-16
@@ -1,6 +1,6 @@
|
||||
describe('utils', function() {
|
||||
describe('#SafeString', function() {
|
||||
it('constructing a safestring from a string and checking its type', function() {
|
||||
describe('utils', function () {
|
||||
describe('#SafeString', function () {
|
||||
it('constructing a safestring from a string and checking its type', function () {
|
||||
var safe = new Handlebars.SafeString('testing 1, 2, 3');
|
||||
if (!(safe instanceof Handlebars.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>');
|
||||
|
||||
expectTemplate('{{name}}')
|
||||
@@ -21,26 +21,26 @@ describe('utils', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#escapeExpression', function() {
|
||||
it('should escape html', function() {
|
||||
describe('#escapeExpression', function () {
|
||||
it('should escape html', function () {
|
||||
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<&"\'>');
|
||||
equals(Handlebars.Utils.escapeExpression(string), 'foo<&"\'>');
|
||||
|
||||
var obj = {
|
||||
toHTML: function() {
|
||||
toHTML: function () {
|
||||
return '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(undefined), '');
|
||||
equals(Handlebars.Utils.escapeExpression(null), '');
|
||||
@@ -48,14 +48,14 @@ describe('utils', function() {
|
||||
equals(Handlebars.Utils.escapeExpression(false), 'false');
|
||||
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());
|
||||
});
|
||||
});
|
||||
|
||||
describe('#isEmpty', function() {
|
||||
it('should not be empty', function() {
|
||||
describe('#isEmpty', function () {
|
||||
it('should not be empty', function () {
|
||||
equals(Handlebars.Utils.isEmpty(undefined), true);
|
||||
equals(Handlebars.Utils.isEmpty(null), true);
|
||||
equals(Handlebars.Utils.isEmpty(false), true);
|
||||
@@ -63,7 +63,7 @@ describe('utils', function() {
|
||||
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([1]), false);
|
||||
equals(Handlebars.Utils.isEmpty('foo'), false);
|
||||
@@ -71,8 +71,8 @@ describe('utils', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#extend', function() {
|
||||
it('should ignore prototype values', function() {
|
||||
describe('#extend', function () {
|
||||
it('should ignore prototype values', function () {
|
||||
function A() {
|
||||
this.a = 1;
|
||||
}
|
||||
|
||||
+13
-23
@@ -1,32 +1,22 @@
|
||||
describe('whitespace control', function() {
|
||||
it('should strip whitespace around mustache calls', function() {
|
||||
describe('whitespace control', function () {
|
||||
it('should strip whitespace around mustache calls', function () {
|
||||
var hash = { foo: 'bar<' };
|
||||
|
||||
expectTemplate(' {{~foo~}} ')
|
||||
.withInput(hash)
|
||||
.toCompileTo('bar<');
|
||||
expectTemplate(' {{~foo~}} ').withInput(hash).toCompileTo('bar<');
|
||||
|
||||
expectTemplate(' {{~foo}} ')
|
||||
.withInput(hash)
|
||||
.toCompileTo('bar< ');
|
||||
expectTemplate(' {{~foo}} ').withInput(hash).toCompileTo('bar< ');
|
||||
|
||||
expectTemplate(' {{foo~}} ')
|
||||
.withInput(hash)
|
||||
.toCompileTo(' bar<');
|
||||
expectTemplate(' {{foo~}} ').withInput(hash).toCompileTo(' bar<');
|
||||
|
||||
expectTemplate(' {{~&foo~}} ')
|
||||
.withInput(hash)
|
||||
.toCompileTo('bar<');
|
||||
expectTemplate(' {{~&foo~}} ').withInput(hash).toCompileTo('bar<');
|
||||
|
||||
expectTemplate(' {{~{foo}~}} ')
|
||||
.withInput(hash)
|
||||
.toCompileTo('bar<');
|
||||
expectTemplate(' {{~{foo}~}} ').withInput(hash).toCompileTo('bar<');
|
||||
|
||||
expectTemplate('1\n{{foo~}} \n\n 23\n{{bar}}4').toCompileTo('1\n23\n4');
|
||||
});
|
||||
|
||||
describe('blocks', function() {
|
||||
it('should strip whitespace around simple block calls', function() {
|
||||
describe('blocks', function () {
|
||||
it('should strip whitespace around simple block calls', function () {
|
||||
var hash = { foo: 'bar<' };
|
||||
|
||||
expectTemplate(' {{~#if foo~}} bar {{~/if~}} ')
|
||||
@@ -54,7 +44,7 @@ describe('whitespace control', function() {
|
||||
.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 ');
|
||||
@@ -68,7 +58,7 @@ describe('whitespace control', function() {
|
||||
).toCompileTo('bar');
|
||||
});
|
||||
|
||||
it('should strip whitespace around complex block calls', function() {
|
||||
it('should strip whitespace around complex block calls', function () {
|
||||
var hash = { foo: 'bar<' };
|
||||
|
||||
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~}} ')
|
||||
.withPartials({ dude: 'bar' })
|
||||
.toCompileTo('foobar');
|
||||
@@ -149,7 +139,7 @@ describe('whitespace control', function() {
|
||||
.toCompileTo('foo\n bar');
|
||||
});
|
||||
|
||||
it('should only strip whitespace once', function() {
|
||||
it('should only strip whitespace once', function () {
|
||||
expectTemplate(' {{~foo~}} {{foo}} {{foo}} ')
|
||||
.withInput({ foo: 'bar' })
|
||||
.toCompileTo('barbar bar ');
|
||||
|
||||
+2
-2
@@ -3,6 +3,6 @@ module.exports = {
|
||||
'no-process-env': 'off',
|
||||
'prefer-const': 'warn',
|
||||
'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 { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
||||
|
||||
module.exports = function(grunt) {
|
||||
module.exports = function (grunt) {
|
||||
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
||||
|
||||
registerAsyncTask('metrics', function() {
|
||||
registerAsyncTask('metrics', function () {
|
||||
const onlyExecuteName = grunt.option('name');
|
||||
const events = {};
|
||||
|
||||
const promises = Object.keys(metrics).map(async name => {
|
||||
const promises = Object.keys(metrics).map(async (name) => {
|
||||
if (/^_/.test(name)) {
|
||||
return;
|
||||
}
|
||||
@@ -16,8 +16,8 @@ module.exports = function(grunt) {
|
||||
return;
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
metrics[name](grunt, function(data) {
|
||||
return new Promise((resolve) => {
|
||||
metrics[name](grunt, function (data) {
|
||||
events[name] = data;
|
||||
resolve();
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ const git = require('./util/git');
|
||||
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
||||
const semver = require('semver');
|
||||
|
||||
module.exports = function(grunt) {
|
||||
module.exports = function (grunt) {
|
||||
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
||||
|
||||
registerAsyncTask('publish-to-aws', async () => {
|
||||
@@ -48,7 +48,7 @@ module.exports = function(grunt) {
|
||||
}
|
||||
|
||||
async function publish(suffixes) {
|
||||
const publishPromises = suffixes.map(suffix => publishSuffix(suffix));
|
||||
const publishPromises = suffixes.map((suffix) => publishSuffix(suffix));
|
||||
return Promise.all(publishPromises);
|
||||
}
|
||||
|
||||
@@ -57,9 +57,9 @@ module.exports = function(grunt) {
|
||||
'handlebars.js',
|
||||
'handlebars.min.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 localFile = getLocalFile(filename);
|
||||
await uploadToBucket(localFile, nameInBucket);
|
||||
@@ -75,7 +75,7 @@ module.exports = function(grunt) {
|
||||
const uploadParams = {
|
||||
Bucket: bucket,
|
||||
Key: nameInBucket,
|
||||
Body: grunt.file.read(localFile)
|
||||
Body: grunt.file.read(localFile),
|
||||
};
|
||||
return s3PutObject(uploadParams);
|
||||
}
|
||||
@@ -84,7 +84,7 @@ module.exports = function(grunt) {
|
||||
function s3PutObject(uploadParams) {
|
||||
const s3 = new AWS.S3();
|
||||
return new Promise((resolve, reject) => {
|
||||
s3.putObject(uploadParams, err => {
|
||||
s3.putObject(uploadParams, (err) => {
|
||||
if (err != null) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
+36
-36
@@ -11,47 +11,47 @@ const testCases = [
|
||||
{
|
||||
binInputParameters: ['-a', 'spec/artifacts/empty.handlebars'],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/empty.amd.js'
|
||||
expectedOutputSpec: './spec/expected/empty.amd.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: [
|
||||
'-a',
|
||||
'-f',
|
||||
'TEST_OUTPUT',
|
||||
'spec/artifacts/empty.handlebars'
|
||||
'spec/artifacts/empty.handlebars',
|
||||
],
|
||||
outputLocation: 'TEST_OUTPUT',
|
||||
expectedOutputSpec: './spec/expected/empty.amd.js'
|
||||
expectedOutputSpec: './spec/expected/empty.amd.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: [
|
||||
'-a',
|
||||
'-n',
|
||||
'CustomNamespace.templates',
|
||||
'spec/artifacts/empty.handlebars'
|
||||
'spec/artifacts/empty.handlebars',
|
||||
],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/empty.amd.namespace.js'
|
||||
expectedOutputSpec: './spec/expected/empty.amd.namespace.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: [
|
||||
'-a',
|
||||
'--namespace',
|
||||
'CustomNamespace.templates',
|
||||
'spec/artifacts/empty.handlebars'
|
||||
'spec/artifacts/empty.handlebars',
|
||||
],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/empty.amd.namespace.js'
|
||||
expectedOutputSpec: './spec/expected/empty.amd.namespace.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: ['-a', '-s', 'spec/artifacts/empty.handlebars'],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/empty.amd.simple.js'
|
||||
expectedOutputSpec: './spec/expected/empty.amd.simple.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: ['-a', '-m', 'spec/artifacts/empty.handlebars'],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/empty.amd.min.js'
|
||||
expectedOutputSpec: './spec/expected/empty.amd.min.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: [
|
||||
@@ -61,44 +61,44 @@ const testCases = [
|
||||
'someHelper',
|
||||
'-k',
|
||||
'anotherHelper',
|
||||
'-o'
|
||||
'-o',
|
||||
],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/non.empty.amd.known.helper.js'
|
||||
expectedOutputSpec: './spec/expected/non.empty.amd.known.helper.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: ['--help'],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/help.menu.txt'
|
||||
expectedOutputSpec: './spec/expected/help.menu.txt',
|
||||
},
|
||||
{
|
||||
binInputParameters: ['-v'],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutput: require('../package.json').version
|
||||
expectedOutput: require('../package.json').version,
|
||||
},
|
||||
{
|
||||
binInputParameters: [
|
||||
'-a',
|
||||
'-e',
|
||||
'hbs',
|
||||
'./spec/artifacts/non.default.extension.hbs'
|
||||
'./spec/artifacts/non.default.extension.hbs',
|
||||
],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/non.default.extension.amd.js'
|
||||
expectedOutputSpec: './spec/expected/non.default.extension.amd.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: [
|
||||
'-a',
|
||||
'-p',
|
||||
'./spec/artifacts/partial.template.handlebars'
|
||||
'./spec/artifacts/partial.template.handlebars',
|
||||
],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/partial.template.js'
|
||||
expectedOutputSpec: './spec/expected/partial.template.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: ['spec/artifacts/empty.handlebars', '-c'],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/empty.common.js'
|
||||
expectedOutputSpec: './spec/expected/empty.common.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: [
|
||||
@@ -106,30 +106,30 @@ const testCases = [
|
||||
'spec/artifacts/empty.handlebars',
|
||||
'-a',
|
||||
'-n',
|
||||
'someNameSpace'
|
||||
'someNameSpace',
|
||||
],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/namespace.amd.js'
|
||||
expectedOutputSpec: './spec/expected/namespace.amd.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: [
|
||||
'spec/artifacts/empty.handlebars',
|
||||
'-h',
|
||||
'some-path/',
|
||||
'-a'
|
||||
'-a',
|
||||
],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/handlebar.path.amd.js'
|
||||
expectedOutputSpec: './spec/expected/handlebar.path.amd.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: [
|
||||
'spec/artifacts/partial.template.handlebars',
|
||||
'-r',
|
||||
'spec',
|
||||
'-a'
|
||||
'-a',
|
||||
],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/empty.root.amd.js'
|
||||
expectedOutputSpec: './spec/expected/empty.root.amd.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: [
|
||||
@@ -141,10 +141,10 @@ const testCases = [
|
||||
'firstTemplate',
|
||||
'-N',
|
||||
'secondTemplate',
|
||||
'-a'
|
||||
'-a',
|
||||
],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/empty.name.amd.js'
|
||||
expectedOutputSpec: './spec/expected/empty.name.amd.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: [
|
||||
@@ -155,36 +155,36 @@ const testCases = [
|
||||
'-N',
|
||||
'test',
|
||||
'--map',
|
||||
'./spec/tmp/source.map.amd.txt'
|
||||
'./spec/tmp/source.map.amd.txt',
|
||||
],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/source.map.amd.js'
|
||||
expectedOutputSpec: './spec/expected/source.map.amd.js',
|
||||
},
|
||||
{
|
||||
binInputParameters: ['./spec/artifacts/bom.handlebars', '-b', '-a'],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/bom.amd.js'
|
||||
expectedOutputSpec: './spec/expected/bom.amd.js',
|
||||
},
|
||||
// Issue #1673
|
||||
{
|
||||
binInputParameters: [
|
||||
'--amd',
|
||||
'--no-amd',
|
||||
'spec/artifacts/empty.handlebars'
|
||||
'spec/artifacts/empty.handlebars',
|
||||
],
|
||||
outputLocation: 'stdout',
|
||||
expectedOutputSpec: './spec/expected/empty.common.js'
|
||||
}
|
||||
expectedOutputSpec: './spec/expected/empty.common.js',
|
||||
},
|
||||
];
|
||||
|
||||
module.exports = function(grunt) {
|
||||
grunt.registerTask('test:bin', function() {
|
||||
module.exports = function (grunt) {
|
||||
grunt.registerTask('test:bin', function () {
|
||||
testCases.forEach(
|
||||
({
|
||||
binInputParameters,
|
||||
outputLocation,
|
||||
expectedOutputSpec,
|
||||
expectedOutput
|
||||
expectedOutput,
|
||||
}) => {
|
||||
const stdout = executeBinHandlebars(...binInputParameters);
|
||||
|
||||
@@ -205,7 +205,7 @@ module.exports = function(grunt) {
|
||||
expect(normalizedOutput).not.to.be.differentFrom(
|
||||
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 nodeJs = process.argv0;
|
||||
|
||||
module.exports = function(grunt) {
|
||||
module.exports = function (grunt) {
|
||||
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
||||
|
||||
registerAsyncTask('test:mocha', async () =>
|
||||
@@ -12,7 +12,7 @@ module.exports = function(grunt) {
|
||||
registerAsyncTask('test:cov', async () =>
|
||||
execNodeJsScriptWithInheritedOutput('node_modules/nyc/bin/nyc', [
|
||||
nodeJs,
|
||||
'./spec/env/runner.js'
|
||||
'./spec/env/runner.js',
|
||||
])
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
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 oldCwd = process.cwd();
|
||||
|
||||
describe('utils/git', function() {
|
||||
beforeEach(async function() {
|
||||
describe('utils/git', function () {
|
||||
beforeEach(async function () {
|
||||
await fs.remove(tmpDir);
|
||||
await createRepositoryThatActsAsRemote();
|
||||
process.chdir(tmpDir);
|
||||
@@ -33,12 +33,12 @@ describe('utils/git', function() {
|
||||
await git.commit('commit message');
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
afterEach(function () {
|
||||
process.chdir(oldCwd);
|
||||
});
|
||||
|
||||
describe('the "remotes"-function', function() {
|
||||
it('should list all remotes', async function() {
|
||||
describe('the "remotes"-function', function () {
|
||||
it('should list all remotes', async function () {
|
||||
await git.git('remote', 'set-url', 'origin', 'https://test.org/test');
|
||||
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 (push)',
|
||||
'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() {
|
||||
it('should list all branches', async function() {
|
||||
describe('the "branches"-function', function () {
|
||||
it('should list all branches', async function () {
|
||||
await git.git('branch', 'test');
|
||||
await git.git('branch', 'test2');
|
||||
|
||||
@@ -64,32 +64,32 @@ describe('utils/git', function() {
|
||||
' test',
|
||||
' test2',
|
||||
' remotes/origin/HEAD -> origin/master',
|
||||
' remotes/origin/master'
|
||||
' remotes/origin/master',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('the "commitInfo"-function', function() {
|
||||
it('should list head and master sha', async function() {
|
||||
describe('the "commitInfo"-function', function () {
|
||||
it('should list head and master sha', async function () {
|
||||
const result = await git.commitInfo();
|
||||
expect(result.masterSha).to.equal(result.headSha);
|
||||
expect(result.masterSha).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();
|
||||
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');
|
||||
|
||||
const result = await git.commitInfo();
|
||||
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');
|
||||
fs.writeFile('new-file.txt', 'new-file');
|
||||
await git.add('new-file.txt');
|
||||
@@ -99,13 +99,13 @@ describe('utils/git', function() {
|
||||
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');
|
||||
const result = await git.commitInfo();
|
||||
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', 'v1.2');
|
||||
await git.git('tag', 'test-tag2');
|
||||
@@ -113,7 +113,7 @@ describe('utils/git', function() {
|
||||
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();
|
||||
expect(result.tagName).to.be.null();
|
||||
});
|
||||
|
||||
@@ -2,9 +2,9 @@ module.exports = { createRegisterAsyncTaskFn };
|
||||
|
||||
function createRegisterAsyncTaskFn(grunt) {
|
||||
return function registerAsyncTask(name, asyncFunction) {
|
||||
grunt.registerTask(name, function() {
|
||||
grunt.registerTask(name, function () {
|
||||
asyncFunction()
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
grunt.fatal(error);
|
||||
})
|
||||
.finally(this.async());
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
const childProcess = require('child_process');
|
||||
|
||||
module.exports = {
|
||||
execNodeJsScriptWithInheritedOutput
|
||||
execNodeJsScriptWithInheritedOutput,
|
||||
};
|
||||
|
||||
async function execNodeJsScriptWithInheritedOutput(command, args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = childProcess.fork(command, args, { stdio: 'inherit' });
|
||||
child.on('close', code => {
|
||||
child.on('close', (code) => {
|
||||
if (code !== 0) {
|
||||
reject(new Error(`Child process failed with exit-code ${code}`));
|
||||
}
|
||||
|
||||
+3
-3
@@ -14,7 +14,7 @@ module.exports = {
|
||||
headSha,
|
||||
masterSha,
|
||||
tagName: await getTagName(),
|
||||
isMaster: headSha === masterSha
|
||||
isMaster: headSha === masterSha,
|
||||
};
|
||||
},
|
||||
async add(path) {
|
||||
@@ -23,7 +23,7 @@ module.exports = {
|
||||
async commit(message) {
|
||||
return git('commit', '--message', message);
|
||||
},
|
||||
git // visible for testing
|
||||
git, // visible for testing
|
||||
};
|
||||
|
||||
async function getHeadSha() {
|
||||
@@ -52,7 +52,7 @@ async function getTagName() {
|
||||
}
|
||||
|
||||
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) {
|
||||
return versionTags[0];
|
||||
}
|
||||
|
||||
+7
-7
@@ -2,7 +2,7 @@ const git = require('./util/git');
|
||||
const semver = require('semver');
|
||||
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
||||
|
||||
module.exports = function(grunt) {
|
||||
module.exports = function (grunt) {
|
||||
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
||||
|
||||
registerAsyncTask('version', async () => {
|
||||
@@ -22,27 +22,27 @@ module.exports = function(grunt) {
|
||||
{
|
||||
path: 'lib/handlebars/base.js',
|
||||
regex: /const VERSION = ['"](.*)['"];/,
|
||||
replacement: `const VERSION = '${version}';`
|
||||
replacement: `const VERSION = '${version}';`,
|
||||
},
|
||||
{
|
||||
path: 'components/bower.json',
|
||||
regex: /"version":.*/,
|
||||
replacement: `"version": "${version}",`
|
||||
replacement: `"version": "${version}",`,
|
||||
},
|
||||
{
|
||||
path: 'components/package.json',
|
||||
regex: /"version":.*/,
|
||||
replacement: `"version": "${version}",`
|
||||
replacement: `"version": "${version}",`,
|
||||
},
|
||||
{
|
||||
path: 'components/handlebars.js.nuspec',
|
||||
regex: /<version>.*<\/version>/,
|
||||
replacement: `<version>${version}</version>`
|
||||
}
|
||||
replacement: `<version>${version}</version>`,
|
||||
},
|
||||
];
|
||||
|
||||
await Promise.all(
|
||||
replaceSpec.map(replaceSpec =>
|
||||
replaceSpec.map((replaceSpec) =>
|
||||
replaceAndAdd(
|
||||
replaceSpec.path,
|
||||
replaceSpec.regex,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module.exports = {
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
'no-var': 'off'
|
||||
}
|
||||
'no-var': 'off',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2,13 +2,13 @@ var async = require('neo-async'),
|
||||
fs = require('fs'),
|
||||
zlib = require('zlib');
|
||||
|
||||
module.exports = function(grunt, callback) {
|
||||
module.exports = function (grunt, callback) {
|
||||
var distFiles = fs.readdirSync('dist'),
|
||||
distSizes = {};
|
||||
|
||||
async.each(
|
||||
distFiles,
|
||||
function(file, callback) {
|
||||
function (file, callback) {
|
||||
var content;
|
||||
try {
|
||||
content = fs.readFileSync('dist/' + file);
|
||||
@@ -24,7 +24,7 @@ module.exports = function(grunt, callback) {
|
||||
file = file.replace(/\.js/, '').replace(/\./g, '_');
|
||||
distSizes[file] = content.length;
|
||||
|
||||
zlib.gzip(content, function(err, data) {
|
||||
zlib.gzip(content, function (err, data) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
@@ -33,7 +33,7 @@ module.exports = function(grunt, callback) {
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function() {
|
||||
function () {
|
||||
grunt.log.writeln(
|
||||
'Distribution sizes: ' + JSON.stringify(distSizes, undefined, 2)
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
var fs = require('fs');
|
||||
|
||||
var metrics = fs.readdirSync(__dirname);
|
||||
metrics.forEach(function(metric) {
|
||||
metrics.forEach(function (metric) {
|
||||
if (metric === 'index.js' || !/(.*)\.js$/.test(metric)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
var _ = require('underscore'),
|
||||
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
|
||||
var Handlebars = require('../../lib');
|
||||
|
||||
var templateSizes = {};
|
||||
_.each(templates, function(info, template) {
|
||||
_.each(templates, function (info, template) {
|
||||
var src = info.handlebars,
|
||||
compiled = Handlebars.precompile(src, {}),
|
||||
knownHelpers = Handlebars.precompile(src, {
|
||||
knownHelpersOnly: true,
|
||||
knownHelpers: info.helpers
|
||||
knownHelpers: info.helpers,
|
||||
});
|
||||
|
||||
templateSizes[template] = compiled.length;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
module.exports = {
|
||||
helpers: {
|
||||
foo: function() {
|
||||
foo: function () {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
},
|
||||
context: {
|
||||
bar: true
|
||||
bar: true,
|
||||
},
|
||||
|
||||
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: 'Larry' },
|
||||
{ name: 'Curly' },
|
||||
{ name: 'Shemp' }
|
||||
]
|
||||
{ name: 'Shemp' },
|
||||
],
|
||||
},
|
||||
handlebars: '{{#each names}}{{name}}{{/each}}',
|
||||
dust: '{#names}{name}{/names}',
|
||||
mustache: '{{#names}}{{name}}{{/names}}'
|
||||
mustache: '{{#names}}{{name}}{{/names}}',
|
||||
};
|
||||
|
||||
@@ -4,8 +4,8 @@ module.exports = {
|
||||
{ name: 'Moe' },
|
||||
{ name: 'Larry' },
|
||||
{ name: 'Curly' },
|
||||
{ name: 'Shemp' }
|
||||
]
|
||||
{ name: 'Shemp' },
|
||||
],
|
||||
},
|
||||
handlebars: '{{#names}}{{name}}{{/names}}'
|
||||
handlebars: '{{#names}}{{name}}{{/names}}',
|
||||
};
|
||||
|
||||
@@ -2,18 +2,18 @@ var fs = require('fs');
|
||||
|
||||
module.exports = {
|
||||
context: {
|
||||
header: function() {
|
||||
header: function () {
|
||||
return 'Colors';
|
||||
},
|
||||
hasItems: true, // To make things fairer in mustache land due to no `{{if}}` construct on arrays
|
||||
items: [
|
||||
{ name: 'red', current: true, url: '#Red' },
|
||||
{ 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(),
|
||||
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: 'Larry' },
|
||||
{ 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: 'Larry' },
|
||||
{ name: 'Curly' },
|
||||
{ name: 'Shemp' }
|
||||
{ name: 'Shemp' },
|
||||
],
|
||||
foo: 'bar'
|
||||
foo: 'bar',
|
||||
},
|
||||
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: ['Larry'] },
|
||||
{ bat: 'foo', name: ['Curly'] },
|
||||
{ bat: 'foo', name: ['Shemp'] }
|
||||
{ bat: 'foo', name: ['Shemp'] },
|
||||
],
|
||||
foo: 'bar'
|
||||
foo: 'bar',
|
||||
},
|
||||
handlebars:
|
||||
'{{#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 templates = fs.readdirSync(__dirname);
|
||||
templates.forEach(function(template) {
|
||||
templates.forEach(function (template) {
|
||||
if (template === 'index.js' || !/(.*)\.js$/.test(template)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module.exports = {
|
||||
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 } },
|
||||
handlebars: '{{#with person}}{{name}}{{age}}{{/with}}',
|
||||
dust: '{#person}{name}{age}{/person}',
|
||||
mustache: '{{#person}}{{name}}{{age}}{{/person}}'
|
||||
mustache: '{{#person}}{{name}}{{age}}{{/person}}',
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
module.exports = {
|
||||
context: {
|
||||
name: '1',
|
||||
kids: [{ name: '1.1', kids: [{ name: '1.1.1', kids: [] }] }]
|
||||
kids: [{ name: '1.1', kids: [{ name: '1.1.1', kids: [] }] }],
|
||||
},
|
||||
partials: {
|
||||
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}}',
|
||||
dust: '{name}{#kids}{>recursion:./}{/kids}',
|
||||
mustache: '{{name}}{{#kids}}{{>recursion}}{{/kids}}'
|
||||
mustache: '{{name}}{{#kids}}{{>recursion}}{{/kids}}',
|
||||
};
|
||||
|
||||
@@ -3,17 +3,17 @@ module.exports = {
|
||||
peeps: [
|
||||
{ name: 'Moe', count: 15 },
|
||||
{ name: 'Larry', count: 5 },
|
||||
{ name: 'Curly', count: 1 }
|
||||
]
|
||||
{ name: 'Curly', count: 1 },
|
||||
],
|
||||
},
|
||||
partials: {
|
||||
mustache: { variables: 'Hello {{name}}! You have {{count}} new messages.' },
|
||||
handlebars: {
|
||||
variables: 'Hello {{name}}! You have {{count}} new messages.'
|
||||
}
|
||||
variables: 'Hello {{name}}! You have {{count}} new messages.',
|
||||
},
|
||||
},
|
||||
|
||||
handlebars: '{{#each peeps}}{{>variables}}{{/each}}',
|
||||
dust: '{#peeps}{>variables/}{/peeps}',
|
||||
mustache: '{{#peeps}}{{>variables}}{{/peeps}}'
|
||||
mustache: '{{#peeps}}{{>variables}}{{/peeps}}',
|
||||
};
|
||||
|
||||
@@ -3,5 +3,5 @@ module.exports = {
|
||||
handlebars:
|
||||
'{{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: {},
|
||||
handlebars: 'Hello world',
|
||||
dust: 'Hello world',
|
||||
mustache: 'Hello world'
|
||||
mustache: 'Hello world',
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
module.exports = {
|
||||
helpers: {
|
||||
echo: function(value) {
|
||||
echo: function (value) {
|
||||
return 'foo ' + value;
|
||||
},
|
||||
header: function() {
|
||||
header: function () {
|
||||
return 'Colors';
|
||||
}
|
||||
},
|
||||
handlebars: '{{echo (header)}}'
|
||||
},
|
||||
handlebars: '{{echo (header)}}',
|
||||
};
|
||||
|
||||
module.exports.context = module.exports.helpers;
|
||||
|
||||
@@ -2,5 +2,5 @@ module.exports = {
|
||||
context: { name: 'Mick', count: 30 },
|
||||
handlebars: '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.',
|
||||
};
|
||||
|
||||
+14
-14
@@ -33,26 +33,26 @@ function makeSuite(bench, name, template, handlebarsOnly) {
|
||||
var handlebar = Handlebars.compile(template.handlebars, { data: false }),
|
||||
compat = Handlebars.compile(template.handlebars, {
|
||||
data: false,
|
||||
compat: true
|
||||
compat: true,
|
||||
}),
|
||||
options = { helpers: template.helpers };
|
||||
_.each(template.partials && template.partials.handlebars, function(
|
||||
partial,
|
||||
partialName
|
||||
) {
|
||||
_.each(
|
||||
template.partials && template.partials.handlebars,
|
||||
function (partial, partialName) {
|
||||
Handlebars.registerPartial(
|
||||
partialName,
|
||||
Handlebars.compile(partial, { data: false })
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
handlebarsOut = handlebar(context, options);
|
||||
bench('handlebars', function() {
|
||||
bench('handlebars', function () {
|
||||
handlebar(context, options);
|
||||
});
|
||||
|
||||
compatOut = compat(context, options);
|
||||
bench('compat', function() {
|
||||
bench('compat', function () {
|
||||
compat(context, options);
|
||||
});
|
||||
|
||||
@@ -65,12 +65,12 @@ function makeSuite(bench, name, template, handlebarsOnly) {
|
||||
dustOut = false;
|
||||
dust.loadSource(dust.compile(template.dust, templateName));
|
||||
|
||||
dust.render(templateName, context, function(err, out) {
|
||||
dust.render(templateName, context, function (err, out) {
|
||||
dustOut = out;
|
||||
});
|
||||
|
||||
bench('dust', function() {
|
||||
dust.render(templateName, context, function() {});
|
||||
bench('dust', function () {
|
||||
dust.render(templateName, context, function () {});
|
||||
});
|
||||
} else {
|
||||
bench('dust', error);
|
||||
@@ -84,7 +84,7 @@ function makeSuite(bench, name, template, handlebarsOnly) {
|
||||
if (mustacheSource) {
|
||||
mustacheOut = Mustache.to_html(mustacheSource, context, mustachePartials);
|
||||
|
||||
bench('mustache', function() {
|
||||
bench('mustache', function () {
|
||||
Mustache.to_html(mustacheSource, context, mustachePartials);
|
||||
});
|
||||
} else {
|
||||
@@ -120,12 +120,12 @@ function makeSuite(bench, name, template, handlebarsOnly) {
|
||||
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
|
||||
Handlebars = require('../../lib');
|
||||
|
||||
console.log('Execution Throughput');
|
||||
runner(grunt, makeSuite, function(times, scaled) {
|
||||
runner(grunt, makeSuite, function (times, scaled) {
|
||||
callback(scaled);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -12,21 +12,21 @@ function BenchWarmer() {
|
||||
}
|
||||
|
||||
BenchWarmer.prototype = {
|
||||
winners: function(benches) {
|
||||
winners: function (benches) {
|
||||
return Benchmark.filter(benches, 'fastest');
|
||||
},
|
||||
suite: function(suite, fn) {
|
||||
suite: function (suite, fn) {
|
||||
this.suiteName = suite;
|
||||
this.times[suite] = {};
|
||||
this.first = true;
|
||||
|
||||
var self = this;
|
||||
|
||||
fn(function(name, benchFn) {
|
||||
fn(function (name, benchFn) {
|
||||
self.push(name, benchFn);
|
||||
});
|
||||
},
|
||||
push: function(name, fn) {
|
||||
push: function (name, fn) {
|
||||
if (this.names.indexOf(name) === -1) {
|
||||
this.names.push(name);
|
||||
}
|
||||
@@ -38,16 +38,16 @@ BenchWarmer.prototype = {
|
||||
|
||||
var bench = new Benchmark(fn, {
|
||||
name: this.suiteName + ': ' + name,
|
||||
onComplete: function() {
|
||||
onComplete: function () {
|
||||
if (first) {
|
||||
self.startLine(suiteName);
|
||||
}
|
||||
self.writeBench(bench);
|
||||
self.currentBenches.push(bench);
|
||||
},
|
||||
onError: function() {
|
||||
onError: function () {
|
||||
self.errors[this.name] = this;
|
||||
}
|
||||
},
|
||||
});
|
||||
bench.suiteName = this.suiteName;
|
||||
bench.benchName = name;
|
||||
@@ -55,24 +55,24 @@ BenchWarmer.prototype = {
|
||||
this.benchmarks.push(bench);
|
||||
},
|
||||
|
||||
bench: function(callback) {
|
||||
bench: function (callback) {
|
||||
var self = this;
|
||||
|
||||
this.printHeader('ops/msec', true);
|
||||
|
||||
Benchmark.invoke(this.benchmarks, {
|
||||
name: 'run',
|
||||
onComplete: function() {
|
||||
onComplete: function () {
|
||||
self.scaleTimes();
|
||||
|
||||
self.startLine('');
|
||||
|
||||
console.log('\n');
|
||||
self.printHeader('scaled');
|
||||
_.each(self.scaled, function(value, name) {
|
||||
_.each(self.scaled, function (value, name) {
|
||||
self.startLine(name);
|
||||
|
||||
_.each(self.names, function(lang) {
|
||||
_.each(self.names, function (lang) {
|
||||
self.writeValue(value[lang] || '');
|
||||
});
|
||||
});
|
||||
@@ -93,7 +93,7 @@ BenchWarmer.prototype = {
|
||||
|
||||
if (errors) {
|
||||
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') {
|
||||
bench = self.errors[prop];
|
||||
console.log('\n' + bench.name + ':\n');
|
||||
@@ -107,22 +107,22 @@ BenchWarmer.prototype = {
|
||||
}
|
||||
|
||||
callback();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
console.log('\n');
|
||||
},
|
||||
|
||||
scaleTimes: function() {
|
||||
scaleTimes: function () {
|
||||
var scaled = (this.scaled = {});
|
||||
_.each(
|
||||
this.times,
|
||||
function(times, name) {
|
||||
function (times, name) {
|
||||
var output = (scaled[name] = {});
|
||||
|
||||
_.each(
|
||||
times,
|
||||
function(time, lang) {
|
||||
function (time, lang) {
|
||||
output[lang] = (
|
||||
((time - this.minimum) / (this.maximum - this.minimum)) *
|
||||
100
|
||||
@@ -135,7 +135,7 @@ BenchWarmer.prototype = {
|
||||
);
|
||||
},
|
||||
|
||||
printHeader: function(title, winners) {
|
||||
printHeader: function (title, winners) {
|
||||
var benchSize = 0,
|
||||
names = this.names,
|
||||
i,
|
||||
@@ -168,12 +168,13 @@ BenchWarmer.prototype = {
|
||||
console.log('\n' + new Array(horSize + 1).join('-'));
|
||||
},
|
||||
|
||||
startLine: function(name) {
|
||||
var winners = Benchmark.map(this.winners(this.currentBenches), function(
|
||||
bench
|
||||
) {
|
||||
startLine: function (name) {
|
||||
var winners = Benchmark.map(
|
||||
this.winners(this.currentBenches),
|
||||
function (bench) {
|
||||
return bench.name.split(': ')[1];
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
this.currentBenches = [];
|
||||
|
||||
@@ -184,7 +185,7 @@ BenchWarmer.prototype = {
|
||||
this.writeValue(name);
|
||||
}
|
||||
},
|
||||
writeBench: function(bench) {
|
||||
writeBench: function (bench) {
|
||||
var out;
|
||||
|
||||
if (!bench.error) {
|
||||
@@ -211,11 +212,11 @@ BenchWarmer.prototype = {
|
||||
this.writeValue(out);
|
||||
},
|
||||
|
||||
writeValue: function(out) {
|
||||
writeValue: function (out) {
|
||||
var padding = this.benchSize - out.length + 1;
|
||||
out = out + new Array(padding).join(' ');
|
||||
console.log(out);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = BenchWarmer;
|
||||
|
||||
@@ -2,7 +2,7 @@ var _ = require('underscore'),
|
||||
BenchWarmer = require('./benchwarmer'),
|
||||
templates = require('../templates');
|
||||
|
||||
module.exports = function(grunt, makeSuite, callback) {
|
||||
module.exports = function (grunt, makeSuite, callback) {
|
||||
var warmer = new BenchWarmer();
|
||||
|
||||
var handlebarsOnly = grunt.option('handlebars-only'),
|
||||
@@ -11,17 +11,17 @@ module.exports = function(grunt, makeSuite, callback) {
|
||||
grep = new RegExp(grep);
|
||||
}
|
||||
|
||||
_.each(templates, function(template, name) {
|
||||
_.each(templates, function (template, name) {
|
||||
if (!template.handlebars || (grep && !grep.test(name))) {
|
||||
return;
|
||||
}
|
||||
|
||||
warmer.suite(name, function(bench) {
|
||||
warmer.suite(name, function (bench) {
|
||||
makeSuite(bench, name, template, handlebarsOnly);
|
||||
});
|
||||
});
|
||||
|
||||
warmer.bench(function() {
|
||||
warmer.bench(function () {
|
||||
if (callback) {
|
||||
callback(warmer.times, warmer.scaled);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018
|
||||
}
|
||||
ecmaVersion: 2018,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -5,23 +5,23 @@ const config = {
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] }
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
{
|
||||
name: 'firefox',
|
||||
use: { ...devices['Desktop Firefox'] }
|
||||
use: { ...devices['Desktop Firefox'] },
|
||||
},
|
||||
{
|
||||
name: 'webkit',
|
||||
use: { ...devices['Desktop Safari'] }
|
||||
}
|
||||
use: { ...devices['Desktop Safari'] },
|
||||
},
|
||||
],
|
||||
reporter: 'list',
|
||||
webServer: {
|
||||
command: 'npm run test:serve',
|
||||
port: 9999,
|
||||
reuseExistingServer: false
|
||||
}
|
||||
reuseExistingServer: false,
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module.exports = {
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
'no-var': 'off'
|
||||
}
|
||||
'no-var': 'off',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ export default {
|
||||
input: 'src/index.js',
|
||||
output: {
|
||||
file: 'dist/bundle.js',
|
||||
format: 'es'
|
||||
format: 'es',
|
||||
},
|
||||
plugins: [nodeResolve()]
|
||||
plugins: [nodeResolve()],
|
||||
};
|
||||
|
||||
@@ -3,10 +3,10 @@ module.exports = {
|
||||
root: true,
|
||||
extends: ['eslint:recommended', 'prettier'],
|
||||
env: {
|
||||
browser: true
|
||||
browser: true,
|
||||
},
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 6
|
||||
}
|
||||
ecmaVersion: 6,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as Handlebars from 'handlebars/runtime';
|
||||
import hbs from 'handlebars-inline-precompile';
|
||||
import { assertEquals } from '../../webpack-test/src/lib/assert';
|
||||
|
||||
Handlebars.registerHelper('loud', function(text) {
|
||||
Handlebars.registerHelper('loud', function (text) {
|
||||
return text.toUpperCase();
|
||||
});
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ const fs = require('fs');
|
||||
const testFiles = fs.readdirSync('src');
|
||||
const entryPoints = {};
|
||||
testFiles
|
||||
.filter(file => file.match(/-test.js$/))
|
||||
.forEach(file => {
|
||||
.filter((file) => file.match(/-test.js$/))
|
||||
.forEach((file) => {
|
||||
entryPoints[file] = `./src/${file}`;
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ module.exports = {
|
||||
mode: 'production',
|
||||
output: {
|
||||
filename: '[name]',
|
||||
path: __dirname + '/dist'
|
||||
path: __dirname + '/dist',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
@@ -22,12 +22,12 @@ module.exports = {
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: { cacheDirectory: false }
|
||||
}
|
||||
}
|
||||
]
|
||||
options: { cacheDirectory: false },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
minimize: false
|
||||
}
|
||||
minimize: false,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,10 +3,10 @@ module.exports = {
|
||||
extends: ['eslint:recommended', 'prettier'],
|
||||
env: {
|
||||
node: true,
|
||||
browser: true
|
||||
browser: true,
|
||||
},
|
||||
parserOptions: {
|
||||
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