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:
Jakob Linskeseder
2022-10-19 22:26:53 +02:00
committed by Jay Linski
parent f6ff3bf52b
commit e534a911f3
104 changed files with 1869 additions and 1894 deletions
+5 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -2,6 +2,6 @@
module.exports = {
env: {
// Handlebars should run natively in the browser
node: false
}
node: false,
},
};
+3 -3
View File
@@ -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);
};
+1 -1
View File
@@ -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);
};
+8 -8
View File
@@ -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;
+5 -5
View File
@@ -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
+20 -20
View File
@@ -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;
+34 -34
View File
@@ -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,
};
}
}
+80 -80
View File
@@ -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;
+7 -4
View File
@@ -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;
+4 -4
View File
@@ -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.
+2 -2
View File
@@ -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;
+4 -4
View File
@@ -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,
});
});
}
+2 -2
View File
@@ -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++) {
+2 -2
View File
@@ -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;
+3 -3
View File
@@ -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);
+4 -4
View File
@@ -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];
});
}
+1 -1
View File
@@ -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);
+3 -3
View File
@@ -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;
+2 -2
View File
@@ -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
View File
@@ -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);
});
}
+1 -1
View File
@@ -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;
};
+2 -2
View File
@@ -5,7 +5,7 @@ const escape = {
'"': '&quot;',
"'": '&#x27;',
'`': '&#x60;',
'=': '&#x3D;'
'=': '&#x3D;',
};
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
View File
@@ -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
View File
@@ -5,5 +5,5 @@ module.exports = {
functions: 100,
statements: 100,
exclude: ['**/spec/**'],
reporter: 'html'
reporter: 'html',
};
+11 -8
View File
@@ -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
View File
@@ -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
View File
@@ -1,5 +1,5 @@
module.exports = {
tabWidth: 2,
semi: true,
singleQuote: true
singleQuote: true,
};
+4 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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, &lt;b&gt; looks like: &amp;lt;b&amp;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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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');
});
+3 -3
View File
@@ -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) {
+24 -24
View File
@@ -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;
+3 -3
View File
@@ -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) {
+9 -9
View File
@@ -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();
});
+8 -5
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+28 -26
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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&#x27;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&lt;&amp;&quot;&#x27;&gt;'
);
equals(Handlebars.Utils.escapeExpression('foo='), 'foo&#x3D;');
});
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
View File
@@ -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&lt;');
expectTemplate(' {{~foo~}} ').withInput(hash).toCompileTo('bar&lt;');
expectTemplate(' {{~foo}} ')
.withInput(hash)
.toCompileTo('bar&lt; ');
expectTemplate(' {{~foo}} ').withInput(hash).toCompileTo('bar&lt; ');
expectTemplate(' {{foo~}} ')
.withInput(hash)
.toCompileTo(' bar&lt;');
expectTemplate(' {{foo~}} ').withInput(hash).toCompileTo(' bar&lt;');
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
View File
@@ -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
View File
@@ -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();
});
+6 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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',
])
);
+2 -2
View File
@@ -1,5 +1,5 @@
module.exports = {
env: {
mocha: true
}
mocha: true,
},
};
+17 -17
View File
@@ -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 -2
View File
@@ -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());
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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,
+2 -2
View File
@@ -1,6 +1,6 @@
module.exports = {
rules: {
'no-console': 'off',
'no-var': 'off'
}
'no-var': 'off',
},
};
+4 -4
View File
@@ -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 -1
View File
@@ -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;
}
+3 -3
View File
@@ -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;
+4 -4
View File
@@ -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}}',
};
+3 -3
View File
@@ -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}}',
};
+3 -3
View File
@@ -4,8 +4,8 @@ module.exports = {
{ name: 'Moe' },
{ name: 'Larry' },
{ name: 'Curly' },
{ name: 'Shemp' }
]
{ name: 'Shemp' },
],
},
handlebars: '{{#names}}{{name}}{{/names}}'
handlebars: '{{#names}}{{name}}{{/names}}',
};
+4 -4
View File
@@ -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(),
};
+3 -3
View File
@@ -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}}',
};
+3 -3
View File
@@ -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}}',
};
+3 -3
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
module.exports = {
context: { person: { name: 'Larry', age: 45 } },
handlebars: '{{#person}}{{name}}{{age}}{{/person}}'
handlebars: '{{#person}}{{name}}{{age}}{{/person}}',
};
+1 -1
View File
@@ -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}}',
};
+3 -3
View File
@@ -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}}',
};
+5 -5
View File
@@ -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}}',
};
+1 -1
View File
@@ -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}}',
};
+1 -1
View File
@@ -2,5 +2,5 @@ module.exports = {
context: {},
handlebars: 'Hello world',
dust: 'Hello world',
mustache: 'Hello world'
mustache: 'Hello world',
};
+4 -4
View File
@@ -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;
+1 -1
View File
@@ -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
View File
@@ -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);
});
};
+26 -25
View File
@@ -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;
+4 -4
View File
@@ -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);
}
+2 -2
View File
@@ -1,5 +1,5 @@
module.exports = {
parserOptions: {
ecmaVersion: 2018
}
ecmaVersion: 2018,
},
};
+6 -6
View File
@@ -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