Convert tests to vitest (#2127)
* Convert tests to vitest * fix git tests * Cleanup * Convert ignore comments * address code review comments
This commit is contained in:
@@ -85,4 +85,6 @@ jobs:
|
|||||||
run: npx grunt prepare
|
run: npx grunt prepare
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: npm run test:browser
|
run: |
|
||||||
|
npm run test:browser-smoke
|
||||||
|
npm run test:browser
|
||||||
|
|||||||
+2
-4
@@ -151,17 +151,15 @@ module.exports = function (grunt) {
|
|||||||
grunt.registerTask('globals', ['webpack']);
|
grunt.registerTask('globals', ['webpack']);
|
||||||
grunt.registerTask('release', 'Build final packages', [
|
grunt.registerTask('release', 'Build final packages', [
|
||||||
'uglify',
|
'uglify',
|
||||||
'test:min',
|
|
||||||
'copy:dist',
|
'copy:dist',
|
||||||
'copy:components',
|
'copy:components',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
grunt.registerTask('on-file-change', ['build', 'concat:tests', 'test']);
|
grunt.registerTask('on-file-change', ['build', 'concat:tests']);
|
||||||
|
|
||||||
// === Primary tasks ===
|
// === Primary tasks ===
|
||||||
grunt.registerTask('dev', ['clean', 'connect', 'watch']);
|
grunt.registerTask('dev', ['clean', 'connect', 'watch']);
|
||||||
grunt.registerTask('default', ['clean', 'build', 'test', 'release']);
|
grunt.registerTask('default', ['clean', 'build', 'release']);
|
||||||
grunt.registerTask('test', ['test:bin', 'test:cov']);
|
|
||||||
grunt.registerTask('bench', ['metrics']);
|
grunt.registerTask('bench', ['metrics']);
|
||||||
grunt.registerTask('prepare', ['build', 'concat:tests']);
|
grunt.registerTask('prepare', ['build', 'concat:tests']);
|
||||||
grunt.registerTask(
|
grunt.registerTask(
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { isArray } from '../utils';
|
|||||||
let SourceNode;
|
let SourceNode;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/* istanbul ignore next */
|
/* v8 ignore next */
|
||||||
if (typeof define !== 'function' || !define.amd) {
|
if (typeof define !== 'function' || !define.amd) {
|
||||||
// We don't support this in AMD environments. For these environments, we assume that
|
// We don't support this in AMD environments. For these environments, we assume that
|
||||||
// they are running on the browser and thus have no need for the source-map library.
|
// they are running on the browser and thus have no need for the source-map library.
|
||||||
@@ -15,7 +15,7 @@ try {
|
|||||||
/* NOP */
|
/* NOP */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* istanbul ignore if: tested but not covered in istanbul due to dist build */
|
/* v8 ignore next -- tested but not covered due to dist build */
|
||||||
if (!SourceNode) {
|
if (!SourceNode) {
|
||||||
SourceNode = function (line, column, srcFile, chunks) {
|
SourceNode = function (line, column, srcFile, chunks) {
|
||||||
this.src = '';
|
this.src = '';
|
||||||
@@ -23,7 +23,7 @@ if (!SourceNode) {
|
|||||||
this.add(chunks);
|
this.add(chunks);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/* istanbul ignore next */
|
/* v8 ignore next */
|
||||||
SourceNode.prototype = {
|
SourceNode.prototype = {
|
||||||
add: function (chunks) {
|
add: function (chunks) {
|
||||||
if (isArray(chunks)) {
|
if (isArray(chunks)) {
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ Compiler.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
accept: function (node) {
|
accept: function (node) {
|
||||||
/* istanbul ignore next: Sanity code */
|
/* v8 ignore next -- Sanity code */
|
||||||
if (!this[node.type]) {
|
if (!this[node.type]) {
|
||||||
throw new Exception('Unknown type: ' + node.type, node);
|
throw new Exception('Unknown type: ' + node.type, node);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
this.source.currentLocation = firstLoc;
|
this.source.currentLocation = firstLoc;
|
||||||
this.pushSource('');
|
this.pushSource('');
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* v8 ignore next */
|
||||||
if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
|
if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
|
||||||
throw new Exception('Compile completed with content left on stack');
|
throw new Exception('Compile completed with content left on stack');
|
||||||
}
|
}
|
||||||
@@ -924,7 +924,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
createdStack,
|
createdStack,
|
||||||
usedLiteral;
|
usedLiteral;
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* v8 ignore next */
|
||||||
if (!this.isInline()) {
|
if (!this.isInline()) {
|
||||||
throw new Exception('replaceStack on non-inline');
|
throw new Exception('replaceStack on non-inline');
|
||||||
}
|
}
|
||||||
@@ -972,7 +972,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
this.inlineStack = [];
|
this.inlineStack = [];
|
||||||
for (let i = 0, len = inlineStack.length; i < len; i++) {
|
for (let i = 0, len = inlineStack.length; i < len; i++) {
|
||||||
let entry = inlineStack[i];
|
let entry = inlineStack[i];
|
||||||
/* istanbul ignore if */
|
/* v8 ignore next */
|
||||||
if (entry instanceof Literal) {
|
if (entry instanceof Literal) {
|
||||||
this.compileStack.push(entry);
|
this.compileStack.push(entry);
|
||||||
} else {
|
} else {
|
||||||
@@ -994,7 +994,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
return item.value;
|
return item.value;
|
||||||
} else {
|
} else {
|
||||||
if (!inline) {
|
if (!inline) {
|
||||||
/* istanbul ignore next */
|
/* v8 ignore next */
|
||||||
if (!this.stackSlot) {
|
if (!this.stackSlot) {
|
||||||
throw new Exception('Invalid stack pop');
|
throw new Exception('Invalid stack pop');
|
||||||
}
|
}
|
||||||
@@ -1008,7 +1008,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
let stack = this.isInline() ? this.inlineStack : this.compileStack,
|
let stack = this.isInline() ? this.inlineStack : this.compileStack,
|
||||||
item = stack[stack.length - 1];
|
item = stack[stack.length - 1];
|
||||||
|
|
||||||
/* istanbul ignore if */
|
/* v8 ignore next */
|
||||||
if (item instanceof Literal) {
|
if (item instanceof Literal) {
|
||||||
return item.value;
|
return item.value;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export default function (Handlebars) {
|
export default function (Handlebars) {
|
||||||
let $Handlebars = globalThis.Handlebars;
|
let $Handlebars = globalThis.Handlebars;
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* v8 ignore next */
|
||||||
Handlebars.noConflict = function () {
|
Handlebars.noConflict = function () {
|
||||||
if (globalThis.Handlebars === Handlebars) {
|
if (globalThis.Handlebars === Handlebars) {
|
||||||
globalThis.Handlebars = $Handlebars;
|
globalThis.Handlebars = $Handlebars;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export function checkRevision(compilerInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function template(templateSpec, env) {
|
export function template(templateSpec, env) {
|
||||||
/* istanbul ignore next */
|
/* v8 ignore next */
|
||||||
if (!env) {
|
if (!env) {
|
||||||
throw new Exception('No environment passed to template');
|
throw new Exception('No environment passed to template');
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ function extension(module, filename) {
|
|||||||
var templateString = fs.readFileSync(filename, 'utf8');
|
var templateString = fs.readFileSync(filename, 'utf8');
|
||||||
module.exports = handlebars.compile(templateString);
|
module.exports = handlebars.compile(templateString);
|
||||||
}
|
}
|
||||||
/* istanbul ignore else */
|
/* v8 ignore next 4 */
|
||||||
if (typeof require !== 'undefined' && require.extensions) {
|
if (typeof require !== 'undefined' && require.extensions) {
|
||||||
require.extensions['.handlebars'] = extension;
|
require.extensions['.handlebars'] = extension;
|
||||||
require.extensions['.hbs'] = extension;
|
require.extensions['.hbs'] = extension;
|
||||||
|
|||||||
+2
-2
@@ -95,7 +95,7 @@ function loadFiles(opts, callback) {
|
|||||||
opts.hasDirectory = true;
|
opts.hasDirectory = true;
|
||||||
|
|
||||||
fs.readdir(path, function (err, children) {
|
fs.readdir(path, function (err, children) {
|
||||||
/* istanbul ignore next : Race condition that being too lazy to test */
|
/* v8 ignore next -- Race condition that being too lazy to test */
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ function loadFiles(opts, callback) {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
fs.readFile(path, 'utf8', function (err, data) {
|
fs.readFile(path, 'utf8', function (err, data) {
|
||||||
/* istanbul ignore next : Race condition that being too lazy to test */
|
/* v8 ignore next -- Race condition that being too lazy to test */
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
'check-coverage': true,
|
|
||||||
branches: 100,
|
|
||||||
lines: 100,
|
|
||||||
functions: 100,
|
|
||||||
statements: 100,
|
|
||||||
exclude: ['**/spec/**'],
|
|
||||||
reporter: 'html',
|
|
||||||
};
|
|
||||||
Generated
+2929
-2393
File diff suppressed because it is too large
Load Diff
+9
-10
@@ -29,14 +29,14 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.58.2",
|
"@playwright/test": "^1.58.2",
|
||||||
|
"@vitest/browser": "^4.0.18",
|
||||||
|
"@vitest/browser-playwright": "^4.0.18",
|
||||||
|
"@vitest/coverage-v8": "^4.0.18",
|
||||||
"aws-sdk": "^2.1.49",
|
"aws-sdk": "^2.1.49",
|
||||||
"babel-loader": "^5.0.0",
|
"babel-loader": "^5.0.0",
|
||||||
"babel-runtime": "^5.1.10",
|
"babel-runtime": "^5.1.10",
|
||||||
"benchmark": "~1.0",
|
"benchmark": "~1.0",
|
||||||
"chai": "^4.2.0",
|
|
||||||
"chai-diff": "^1.0.1",
|
|
||||||
"concurrently": "^5.0.0",
|
"concurrently": "^5.0.0",
|
||||||
"dirty-chai": "^2.0.1",
|
|
||||||
"dustjs-linkedin": "^2.0.2",
|
"dustjs-linkedin": "^2.0.2",
|
||||||
"eslint": "^8.25.0",
|
"eslint": "^8.25.0",
|
||||||
"eslint-config-prettier": "^8.9.0",
|
"eslint-config-prettier": "^8.9.0",
|
||||||
@@ -56,16 +56,14 @@
|
|||||||
"grunt-webpack": "^1.0.8",
|
"grunt-webpack": "^1.0.8",
|
||||||
"husky": "^3.1.0",
|
"husky": "^3.1.0",
|
||||||
"lint-staged": "^9.5.0",
|
"lint-staged": "^9.5.0",
|
||||||
"mocha": "^5",
|
|
||||||
"mock-stdin": "^0.3.0",
|
"mock-stdin": "^0.3.0",
|
||||||
"mustache": "^2.1.3",
|
"mustache": "^2.1.3",
|
||||||
"nyc": "^14.1.1",
|
|
||||||
"prettier": "^3.0.0",
|
"prettier": "^3.0.0",
|
||||||
"semver": "^5.0.1",
|
"semver": "^5.0.1",
|
||||||
"sinon": "^7.5.0",
|
|
||||||
"typescript": "^3.4.3",
|
"typescript": "^3.4.3",
|
||||||
"uglify-js": "^3.1.4",
|
"uglify-js": "^3.1.4",
|
||||||
"underscore": "^1.5.1",
|
"underscore": "^1.5.1",
|
||||||
|
"vitest": "^4.0.18",
|
||||||
"webpack": "^1.12.6",
|
"webpack": "^1.12.6",
|
||||||
"webpack-dev-server": "^1.12.1"
|
"webpack-dev-server": "^1.12.1"
|
||||||
},
|
},
|
||||||
@@ -84,10 +82,11 @@
|
|||||||
"lint:eslint": "eslint --max-warnings 0 .",
|
"lint:eslint": "eslint --max-warnings 0 .",
|
||||||
"lint:prettier": "prettier --check '**/*.js'",
|
"lint:prettier": "prettier --check '**/*.js'",
|
||||||
"lint:types": "tsc --noEmit --project types",
|
"lint:types": "tsc --noEmit --project types",
|
||||||
"test": "npm run test:mocha",
|
"test": "grunt build && vitest run --project node --project tasks --coverage",
|
||||||
"test:mocha": "grunt build && grunt test",
|
"test:browser": "vitest run --project browser",
|
||||||
"test:tasks": "mocha tasks/tests/",
|
"test:unit": "vitest run --project node",
|
||||||
"test:browser": "playwright test --config tests/browser/playwright.config.js",
|
"test:tasks": "vitest run --project tasks",
|
||||||
|
"test:browser-smoke": "playwright test --config tests/browser/playwright.config.js",
|
||||||
"test:integration": "grunt integration-tests",
|
"test:integration": "grunt integration-tests",
|
||||||
"test:serve": "grunt connect:server:keepalive",
|
"test:serve": "grunt connect:server:keepalive",
|
||||||
"--- combined tasks ---": "",
|
"--- combined tasks ---": "",
|
||||||
|
|||||||
+5
-5
@@ -18,14 +18,14 @@ module.exports = {
|
|||||||
start: true,
|
start: true,
|
||||||
stop: true,
|
stop: true,
|
||||||
ok: true,
|
ok: true,
|
||||||
sinon: true,
|
vi: true,
|
||||||
strictEqual: true,
|
strictEqual: true,
|
||||||
define: true,
|
define: true,
|
||||||
expect: true,
|
expect: true,
|
||||||
chai: true,
|
beforeEach: true,
|
||||||
},
|
afterEach: true,
|
||||||
env: {
|
describe: true,
|
||||||
mocha: true,
|
it: true,
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
// Disabling for tests, for now.
|
// Disabling for tests, for now.
|
||||||
|
|||||||
@@ -1,9 +1,3 @@
|
|||||||
global.handlebarsEnv = null;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
global.handlebarsEnv = Handlebars.create();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('basic context', function () {
|
describe('basic context', function () {
|
||||||
it('most basic', function () {
|
it('most basic', function () {
|
||||||
expectTemplate('{{foo}}').withInput({ foo: 'foo' }).toCompileTo('foo');
|
expectTemplate('{{foo}}').withInput({ foo: 'foo' }).toCompileTo('foo');
|
||||||
|
|||||||
+2
-2
@@ -785,13 +785,13 @@ describe('builtin helpers', function () {
|
|||||||
var called;
|
var called;
|
||||||
|
|
||||||
console.info = console.log = function () {
|
console.info = console.log = function () {
|
||||||
expect(arguments.length).to.equal(0);
|
expect(arguments.length).toBe(0);
|
||||||
called = true;
|
called = true;
|
||||||
console.log = $log;
|
console.log = $log;
|
||||||
};
|
};
|
||||||
|
|
||||||
expectTemplate('{{log}}').withInput({ blah: 'whee' }).toCompileTo('');
|
expectTemplate('{{log}}').withInput({ blah: 'whee' }).toCompileTo('');
|
||||||
expect(called).to.be.true();
|
expect(called).toBe(true);
|
||||||
});
|
});
|
||||||
/* eslint-enable no-console */
|
/* eslint-enable no-console */
|
||||||
});
|
});
|
||||||
|
|||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// Pre-setup for browser tests. Must run before the main setup file
|
||||||
|
// imports the Handlebars library, so that noConflict() captures this value.
|
||||||
|
globalThis.Handlebars = 'no-conflict';
|
||||||
|
|
||||||
|
// Polyfill Node.js 'global' for specs that reference it at module level
|
||||||
|
globalThis.global = globalThis;
|
||||||
Vendored
+27
@@ -0,0 +1,27 @@
|
|||||||
|
import './common.js';
|
||||||
|
import Handlebars from '../../lib/handlebars.js';
|
||||||
|
|
||||||
|
globalThis.Handlebars = Handlebars;
|
||||||
|
|
||||||
|
globalThis.CompilerContext = {
|
||||||
|
browser: true,
|
||||||
|
|
||||||
|
compile: function (template, options) {
|
||||||
|
var templateSpec = handlebarsEnv.precompile(template, options);
|
||||||
|
return handlebarsEnv.template(safeEval(templateSpec));
|
||||||
|
},
|
||||||
|
compileWithPartial: function (template, options) {
|
||||||
|
return handlebarsEnv.compile(template, options);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function safeEval(templateSpec) {
|
||||||
|
/* eslint-disable no-eval, no-console */
|
||||||
|
try {
|
||||||
|
return eval('(' + templateSpec + ')');
|
||||||
|
} catch (err) {
|
||||||
|
console.error(templateSpec);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
/* eslint-enable no-eval, no-console */
|
||||||
|
}
|
||||||
Vendored
-11
@@ -3,20 +3,9 @@ require('./common');
|
|||||||
var fs = require('fs'),
|
var fs = require('fs'),
|
||||||
vm = require('vm');
|
vm = require('vm');
|
||||||
|
|
||||||
var chai = require('chai');
|
|
||||||
var dirtyChai = require('dirty-chai');
|
|
||||||
|
|
||||||
chai.use(dirtyChai);
|
|
||||||
global.expect = chai.expect;
|
|
||||||
|
|
||||||
global.sinon = require('sinon');
|
|
||||||
|
|
||||||
global.Handlebars = 'no-conflict';
|
global.Handlebars = 'no-conflict';
|
||||||
|
|
||||||
var filename = 'dist/handlebars.js';
|
var filename = 'dist/handlebars.js';
|
||||||
if (global.minimizedTest) {
|
|
||||||
filename = 'dist/handlebars.min.js';
|
|
||||||
}
|
|
||||||
var distHandlebars = fs.readFileSync(
|
var distHandlebars = fs.readFileSync(
|
||||||
require.resolve('../../' + filename),
|
require.resolve('../../' + filename),
|
||||||
'utf-8'
|
'utf-8'
|
||||||
|
|||||||
Vendored
+33
-48
@@ -1,22 +1,4 @@
|
|||||||
var global = (function () {
|
var global = globalThis;
|
||||||
return this;
|
|
||||||
})();
|
|
||||||
|
|
||||||
var AssertError;
|
|
||||||
if (Error.captureStackTrace) {
|
|
||||||
AssertError = function AssertError(message, caller) {
|
|
||||||
Error.prototype.constructor.call(this, message);
|
|
||||||
this.message = message;
|
|
||||||
|
|
||||||
if (Error.captureStackTrace) {
|
|
||||||
Error.captureStackTrace(this, caller || AssertError);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
AssertError.prototype = new Error();
|
|
||||||
} else {
|
|
||||||
AssertError = Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
|
* @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
|
||||||
@@ -33,15 +15,10 @@ global.shouldCompileToWithPartials = function shouldCompileToWithPartials(
|
|||||||
hashOrArray,
|
hashOrArray,
|
||||||
partials,
|
partials,
|
||||||
expected,
|
expected,
|
||||||
message
|
message // eslint-disable-line no-unused-vars
|
||||||
) {
|
) {
|
||||||
var result = compileWithPartials(string, hashOrArray, partials);
|
var result = compileWithPartials(string, hashOrArray, partials);
|
||||||
if (result !== expected) {
|
expect(result).toBe(expected);
|
||||||
throw new AssertError(
|
|
||||||
"'" + result + "' should === '" + expected + "': " + message,
|
|
||||||
shouldCompileToWithPartials
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,21 +53,15 @@ global.compileWithPartials = function (string, hashOrArray, partials) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use chai's expect-style API instead (`expect(actualValue).to.equal(expectedValue)`)
|
* @deprecated Use vitest's expect API instead
|
||||||
* @see https://www.chaijs.com/api/bdd/
|
|
||||||
*/
|
*/
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
global.equals = global.equal = function equals(a, b, msg) {
|
global.equals = global.equal = function equals(a, b, msg) {
|
||||||
if (a !== b) {
|
expect(a).toBe(b);
|
||||||
throw new AssertError(
|
|
||||||
"'" + a + "' should === '" + b + "'" + (msg ? ': ' + msg : ''),
|
|
||||||
equals
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use chai's expect-style API instead (`expect(actualValue).to.equal(expectedValue)`)
|
* @deprecated Use vitest's expect API instead
|
||||||
* @see https://www.chaijs.com/api/bdd/#method_throw
|
|
||||||
*/
|
*/
|
||||||
global.shouldThrow = function (callback, type, msg) {
|
global.shouldThrow = function (callback, type, msg) {
|
||||||
var failed;
|
var failed;
|
||||||
@@ -99,25 +70,24 @@ global.shouldThrow = function (callback, type, msg) {
|
|||||||
failed = true;
|
failed = true;
|
||||||
} catch (caught) {
|
} catch (caught) {
|
||||||
if (type && !(caught instanceof type)) {
|
if (type && !(caught instanceof type)) {
|
||||||
throw new AssertError('Type failure: ' + caught);
|
throw new Error('Type failure: ' + caught);
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
msg &&
|
msg &&
|
||||||
!(msg.test ? msg.test(caught.message) : msg === caught.message)
|
!(msg.test ? msg.test(caught.message) : msg === caught.message)
|
||||||
) {
|
) {
|
||||||
throw new AssertError(
|
throw new Error(
|
||||||
'Throw mismatch: Expected ' +
|
'Throw mismatch: Expected ' +
|
||||||
caught.message +
|
caught.message +
|
||||||
' to match ' +
|
' to match ' +
|
||||||
msg +
|
msg +
|
||||||
'\n\n' +
|
'\n\n' +
|
||||||
caught.stack,
|
caught.stack
|
||||||
shouldThrow
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (failed) {
|
if (failed) {
|
||||||
throw new AssertError('It failed to throw', shouldThrow);
|
throw new Error('It failed to throw');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -200,18 +170,29 @@ HandlebarsTestBench.prototype.withMessage = function (message) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype.toCompileTo = function (expectedOutputAsString) {
|
HandlebarsTestBench.prototype.toCompileTo = function (expectedOutputAsString) {
|
||||||
expect(this._compileAndExecute()).to.equal(
|
expect(this._compileAndExecute()).toBe(expectedOutputAsString);
|
||||||
expectedOutputAsString,
|
|
||||||
this.message
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// see chai "to.throw" (https://www.chaijs.com/api/bdd/#method_throw)
|
|
||||||
HandlebarsTestBench.prototype.toThrow = function (errorLike, errMsgMatcher) {
|
HandlebarsTestBench.prototype.toThrow = function (errorLike, errMsgMatcher) {
|
||||||
var self = this;
|
var self = this;
|
||||||
expect(function () {
|
var caught;
|
||||||
|
try {
|
||||||
self._compileAndExecute();
|
self._compileAndExecute();
|
||||||
}).to.throw(errorLike, errMsgMatcher, this.message);
|
} catch (e) {
|
||||||
|
caught = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(caught).toBeDefined();
|
||||||
|
|
||||||
|
if (typeof errorLike === 'function') {
|
||||||
|
expect(caught).toBeInstanceOf(errorLike);
|
||||||
|
if (errMsgMatcher) {
|
||||||
|
expect(caught.message).toMatch(errMsgMatcher);
|
||||||
|
}
|
||||||
|
} else if (errorLike) {
|
||||||
|
// errorLike is a string or regex message matcher (single-argument form)
|
||||||
|
expect(caught.message).toMatch(errorLike);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
HandlebarsTestBench.prototype._compileAndExecute = function () {
|
HandlebarsTestBench.prototype._compileAndExecute = function () {
|
||||||
@@ -237,3 +218,7 @@ HandlebarsTestBench.prototype._combineRuntimeOptions = function () {
|
|||||||
combinedRuntimeOptions.decorators = this.decorators;
|
combinedRuntimeOptions.decorators = this.decorators;
|
||||||
return combinedRuntimeOptions;
|
return combinedRuntimeOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
global.handlebarsEnv = Handlebars.create();
|
||||||
|
});
|
||||||
|
|||||||
Vendored
-8
@@ -1,13 +1,5 @@
|
|||||||
require('./common');
|
require('./common');
|
||||||
|
|
||||||
var chai = require('chai');
|
|
||||||
var dirtyChai = require('dirty-chai');
|
|
||||||
|
|
||||||
chai.use(dirtyChai);
|
|
||||||
global.expect = chai.expect;
|
|
||||||
|
|
||||||
global.sinon = require('sinon');
|
|
||||||
|
|
||||||
global.Handlebars = require('../../lib');
|
global.Handlebars = require('../../lib');
|
||||||
|
|
||||||
global.CompilerContext = {
|
global.CompilerContext = {
|
||||||
|
|||||||
Vendored
-63
@@ -1,63 +0,0 @@
|
|||||||
/* eslint-disable no-console */
|
|
||||||
var fs = require('fs'),
|
|
||||||
Mocha = require('mocha'),
|
|
||||||
path = require('path');
|
|
||||||
|
|
||||||
var errors = 0,
|
|
||||||
testDir = path.dirname(__dirname),
|
|
||||||
grep = process.argv[2];
|
|
||||||
|
|
||||||
// Lazy hack, but whatever
|
|
||||||
if (grep === '--min') {
|
|
||||||
global.minimizedTest = true;
|
|
||||||
grep = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
var files = fs
|
|
||||||
.readdirSync(testDir)
|
|
||||||
.filter(function (name) {
|
|
||||||
return /.*\.js$/.test(name);
|
|
||||||
})
|
|
||||||
.map(function (name) {
|
|
||||||
return testDir + path.sep + name;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (global.minimizedTest) {
|
|
||||||
run('./runtime', function () {
|
|
||||||
run('./browser', function () {
|
|
||||||
/* eslint-disable no-process-exit */
|
|
||||||
process.exit(errors);
|
|
||||||
/* eslint-enable no-process-exit */
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
run('./runtime', function () {
|
|
||||||
run('./browser', function () {
|
|
||||||
run('./node', function () {
|
|
||||||
/* eslint-disable no-process-exit */
|
|
||||||
process.exit(errors);
|
|
||||||
/* eslint-enable no-process-exit */
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function run(env, callback) {
|
|
||||||
var mocha = new Mocha();
|
|
||||||
mocha.ui('bdd');
|
|
||||||
mocha.files = files.slice();
|
|
||||||
if (grep) {
|
|
||||||
mocha.grep(grep);
|
|
||||||
}
|
|
||||||
|
|
||||||
files.forEach(function (name) {
|
|
||||||
delete require.cache[name];
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('Running env: ' + env);
|
|
||||||
require(env);
|
|
||||||
mocha.run(function (errorCount) {
|
|
||||||
errors += errorCount;
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Vendored
-73
@@ -1,73 +0,0 @@
|
|||||||
require('./common');
|
|
||||||
|
|
||||||
var fs = require('fs'),
|
|
||||||
vm = require('vm');
|
|
||||||
|
|
||||||
var chai = require('chai');
|
|
||||||
var dirtyChai = require('dirty-chai');
|
|
||||||
|
|
||||||
chai.use(dirtyChai);
|
|
||||||
global.expect = chai.expect;
|
|
||||||
|
|
||||||
global.sinon = require('sinon');
|
|
||||||
|
|
||||||
global.Handlebars = 'no-conflict';
|
|
||||||
|
|
||||||
var filename = 'dist/handlebars.runtime.js';
|
|
||||||
if (global.minimizedTest) {
|
|
||||||
filename = 'dist/handlebars.runtime.min.js';
|
|
||||||
}
|
|
||||||
vm.runInThisContext(
|
|
||||||
fs.readFileSync(__dirname + '/../../' + filename),
|
|
||||||
filename
|
|
||||||
);
|
|
||||||
|
|
||||||
var parse = require('@handlebars/parser').parse;
|
|
||||||
var compiler = require('../../dist/cjs/handlebars/compiler/compiler');
|
|
||||||
var JavaScriptCompiler = require('../../dist/cjs/handlebars/compiler/javascript-compiler');
|
|
||||||
|
|
||||||
global.CompilerContext = {
|
|
||||||
browser: true,
|
|
||||||
|
|
||||||
compile: function (template, options) {
|
|
||||||
// Hack the compiler on to the environment for these specific tests
|
|
||||||
handlebarsEnv.precompile = function (
|
|
||||||
precompileTemplate,
|
|
||||||
precompileOptions
|
|
||||||
) {
|
|
||||||
return compiler.precompile(
|
|
||||||
precompileTemplate,
|
|
||||||
precompileOptions,
|
|
||||||
handlebarsEnv
|
|
||||||
);
|
|
||||||
};
|
|
||||||
handlebarsEnv.parse = parse;
|
|
||||||
handlebarsEnv.Compiler = compiler.Compiler;
|
|
||||||
handlebarsEnv.JavaScriptCompiler = JavaScriptCompiler;
|
|
||||||
|
|
||||||
var templateSpec = handlebarsEnv.precompile(template, options);
|
|
||||||
return handlebarsEnv.template(safeEval(templateSpec));
|
|
||||||
},
|
|
||||||
compileWithPartial: function (template, options) {
|
|
||||||
// Hack the compiler on to the environment for these specific tests
|
|
||||||
handlebarsEnv.compile = function (compileTemplate, compileOptions) {
|
|
||||||
return compiler.compile(compileTemplate, compileOptions, handlebarsEnv);
|
|
||||||
};
|
|
||||||
handlebarsEnv.parse = parse;
|
|
||||||
handlebarsEnv.Compiler = compiler.Compiler;
|
|
||||||
handlebarsEnv.JavaScriptCompiler = JavaScriptCompiler;
|
|
||||||
|
|
||||||
return handlebarsEnv.compile(template, options);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function safeEval(templateSpec) {
|
|
||||||
/* eslint-disable no-eval, no-console */
|
|
||||||
try {
|
|
||||||
return eval('(' + templateSpec + ')');
|
|
||||||
} catch (err) {
|
|
||||||
console.error(templateSpec);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
/* eslint-enable no-eval, no-console */
|
|
||||||
}
|
|
||||||
+1
-1
@@ -53,7 +53,7 @@ describe('helpers', function () {
|
|||||||
runWithIdentityHelper('{{{{identity}}}}{{{{/identity}}}}', '');
|
runWithIdentityHelper('{{{{identity}}}}{{{{/identity}}}}', '');
|
||||||
});
|
});
|
||||||
|
|
||||||
xit('helper for nested raw block works if nested raw blocks are broken', function () {
|
it.skip('helper for nested raw block works if nested raw blocks are broken', function () {
|
||||||
// This test was introduced in 4.4.4, but it was not the actual problem that lead to the patch release
|
// This test was introduced in 4.4.4, but it was not the actual problem that lead to the patch release
|
||||||
// The test is deactivated, because in 3.x this template cases an exception and it also does not work in 4.4.3
|
// The test is deactivated, because in 3.x this template cases an exception and it also does not work in 4.4.3
|
||||||
// If anyone can make this template work without breaking everything else, then go for it,
|
// If anyone can make this template work without breaking everything else, then go for it,
|
||||||
|
|||||||
+36
-89
@@ -1,98 +1,45 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Mocha</title>
|
<title>Handlebars UMD Smoke Test</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/node_modules/mocha/mocha.css" />
|
|
||||||
<style>
|
|
||||||
.headless .suite > h1,
|
|
||||||
.headless .test.pass {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Show only errors in "headless", non-interactive mode.
|
|
||||||
if (/headless=true/.test(location.href)) {
|
|
||||||
document.documentElement.className = 'headless';
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script src="/node_modules/sinon/pkg/sinon.js"></script>
|
|
||||||
<script src="/node_modules/chai/chai.js"></script>
|
|
||||||
<script src="/node_modules/dirty-chai/lib/dirty-chai.js"></script>
|
|
||||||
<script src="/node_modules/mocha/mocha.js"></script>
|
|
||||||
<script>
|
|
||||||
window.expect = chai.expect;
|
|
||||||
mocha.setup('bdd');
|
|
||||||
</script>
|
|
||||||
<script src="/dist/handlebars.js"></script>
|
|
||||||
<script src="/spec/env/common.js"></script>
|
|
||||||
<script>
|
|
||||||
var CompilerContext = {
|
|
||||||
compile: function(template, options) {
|
|
||||||
var templateSpec = handlebarsEnv.precompile(template, options);
|
|
||||||
return handlebarsEnv.template(safeEval(templateSpec));
|
|
||||||
},
|
|
||||||
compileWithPartial: function(template, options) {
|
|
||||||
return handlebarsEnv.compile(template, options);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function safeEval(templateSpec) {
|
|
||||||
try {
|
|
||||||
var ret;
|
|
||||||
eval('ret = ' + templateSpec);
|
|
||||||
return ret;
|
|
||||||
} catch (err) {
|
|
||||||
console.error(templateSpec);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script src="/tmp/tests.js"></script>
|
|
||||||
<script>
|
|
||||||
onload = function(){
|
|
||||||
mocha.globals(['mochaResults'])
|
|
||||||
// The test harness leaks under FF. We should have decent global leak coverage from other tests
|
|
||||||
if (!navigator.userAgent.match(/Firefox\/([\d.]+)/)) {
|
|
||||||
mocha.checkLeaks();
|
|
||||||
}
|
|
||||||
var runner = mocha.run();
|
|
||||||
|
|
||||||
// Reporting to test-runner
|
|
||||||
var failedTests = [];
|
|
||||||
runner.on('end', function(){
|
|
||||||
window.mochaResults = runner.stats;
|
|
||||||
window.mochaResults.reports = failedTests;
|
|
||||||
});
|
|
||||||
|
|
||||||
runner.on('fail', logFailure);
|
|
||||||
|
|
||||||
function logFailure(test, err){
|
|
||||||
|
|
||||||
var flattenTitles = function(test){
|
|
||||||
var titles = [];
|
|
||||||
while (test.parent.title){
|
|
||||||
titles.push(test.parent.title);
|
|
||||||
test = test.parent;
|
|
||||||
}
|
|
||||||
return titles.reverse();
|
|
||||||
};
|
|
||||||
|
|
||||||
failedTests.push({
|
|
||||||
name: test.title,
|
|
||||||
result: false,
|
|
||||||
message: err.message,
|
|
||||||
stack: err.stack,
|
|
||||||
titles: flattenTitles(test)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="mocha"></div>
|
<h1>Handlebars UMD Smoke Test</h1>
|
||||||
|
<pre id="results"></pre>
|
||||||
|
<script src="/dist/handlebars.js"></script>
|
||||||
|
<script>
|
||||||
|
var results = document.getElementById('results');
|
||||||
|
var failures = 0;
|
||||||
|
var tests = 0;
|
||||||
|
|
||||||
|
function assert(condition, message) {
|
||||||
|
tests++;
|
||||||
|
if (!condition) {
|
||||||
|
failures++;
|
||||||
|
results.textContent += 'FAIL: ' + message + '\n';
|
||||||
|
} else {
|
||||||
|
results.textContent += 'PASS: ' + message + '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
assert(typeof Handlebars !== 'undefined', 'Handlebars is defined');
|
||||||
|
assert(typeof Handlebars.compile === 'function', 'Handlebars.compile exists');
|
||||||
|
assert(typeof Handlebars.template === 'function', 'Handlebars.template exists');
|
||||||
|
assert(typeof Handlebars.VERSION === 'string', 'Handlebars.VERSION exists');
|
||||||
|
|
||||||
|
var template = Handlebars.compile('Hello {{name}}!');
|
||||||
|
var output = template({ name: 'World' });
|
||||||
|
assert(output === 'Hello World!', 'Basic compilation works: ' + output);
|
||||||
|
} catch (e) {
|
||||||
|
failures++;
|
||||||
|
results.textContent += 'ERROR: ' + e.message + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
results.textContent += '\n' + tests + ' tests, ' + failures + ' failures\n';
|
||||||
|
window.mochaResults = { passes: tests - failures, failures: failures };
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+31
-26
@@ -34,30 +34,35 @@ describe('javascript-compiler api', function () {
|
|||||||
.toCompileTo('food');
|
.toCompileTo('food');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#compilerInfo', function () {
|
// Monkey-patching VM.checkRevision is not possible when VM is an ESM
|
||||||
var $superCheck, $superInfo;
|
// namespace object (browser mode), so skip these tests in that context.
|
||||||
beforeEach(function () {
|
(CompilerContext.browser ? describe.skip : describe)(
|
||||||
$superCheck = handlebarsEnv.VM.checkRevision;
|
'#compilerInfo',
|
||||||
$superInfo = handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo;
|
function () {
|
||||||
});
|
var $superCheck, $superInfo;
|
||||||
afterEach(function () {
|
beforeEach(function () {
|
||||||
handlebarsEnv.VM.checkRevision = $superCheck;
|
$superCheck = handlebarsEnv.VM.checkRevision;
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = $superInfo;
|
$superInfo = handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo;
|
||||||
});
|
});
|
||||||
it('should allow compilerInfo override', function () {
|
afterEach(function () {
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = function () {
|
handlebarsEnv.VM.checkRevision = $superCheck;
|
||||||
return 'crazy';
|
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = $superInfo;
|
||||||
};
|
});
|
||||||
handlebarsEnv.VM.checkRevision = function (compilerInfo) {
|
it('should allow compilerInfo override', function () {
|
||||||
if (compilerInfo !== 'crazy') {
|
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = function () {
|
||||||
throw new Error("It didn't work");
|
return 'crazy';
|
||||||
}
|
};
|
||||||
};
|
handlebarsEnv.VM.checkRevision = function (compilerInfo) {
|
||||||
expectTemplate('{{foo}} ')
|
if (compilerInfo !== 'crazy') {
|
||||||
.withInput({ foo: 'food' })
|
throw new Error("It didn't work");
|
||||||
.toCompileTo('food ');
|
}
|
||||||
});
|
};
|
||||||
});
|
expectTemplate('{{foo}} ')
|
||||||
|
.withInput({ foo: 'food' })
|
||||||
|
.toCompileTo('food ');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
describe('buffer', function () {
|
describe('buffer', function () {
|
||||||
var $superAppend, $superCreate;
|
var $superAppend, $superCreate;
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
@@ -105,7 +110,7 @@ describe('javascript-compiler api', function () {
|
|||||||
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
||||||
validVariableName
|
validVariableName
|
||||||
)
|
)
|
||||||
).to.be.true();
|
).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
[('123test', 'abc()', 'abc.cde')].forEach(function (invalidVariableName) {
|
[('123test', 'abc()', 'abc.cde')].forEach(function (invalidVariableName) {
|
||||||
@@ -114,7 +119,7 @@ describe('javascript-compiler api', function () {
|
|||||||
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
||||||
invalidVariableName
|
invalidVariableName
|
||||||
)
|
)
|
||||||
).to.be.false();
|
).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+72
-75
@@ -297,112 +297,109 @@ describe('precompiler', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#loadTemplates', function () {
|
describe('#loadTemplates', function () {
|
||||||
it('should throw on missing template', function (done) {
|
function loadTemplatesAsync(inputOpts) {
|
||||||
Precompiler.loadTemplates({ files: ['foo'] }, function (err) {
|
// eslint-disable-next-line compat/compat
|
||||||
equal(err.message, 'Unable to open template file "foo"');
|
return new Promise(function (resolve, reject) {
|
||||||
done();
|
Precompiler.loadTemplates(inputOpts, function (err, opts) {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(opts);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
it('should enumerate directories by extension', function (done) {
|
|
||||||
Precompiler.loadTemplates(
|
|
||||||
{ files: [__dirname + '/artifacts'], extension: 'hbs' },
|
|
||||||
function (err, opts) {
|
|
||||||
equal(opts.templates.length, 2);
|
|
||||||
equal(opts.templates[0].name, 'example_2');
|
|
||||||
|
|
||||||
done(err);
|
it('should throw on missing template', async function () {
|
||||||
}
|
try {
|
||||||
);
|
await loadTemplatesAsync({ files: ['foo'] });
|
||||||
|
throw new Error('should have thrown');
|
||||||
|
} catch (err) {
|
||||||
|
equal(err.message, 'Unable to open template file "foo"');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
it('should enumerate all templates by extension', function (done) {
|
it('should enumerate directories by extension', async function () {
|
||||||
Precompiler.loadTemplates(
|
var opts = await loadTemplatesAsync({
|
||||||
{ files: [__dirname + '/artifacts'], extension: 'handlebars' },
|
files: [__dirname + '/artifacts'],
|
||||||
function (err, opts) {
|
extension: 'hbs',
|
||||||
equal(opts.templates.length, 5);
|
});
|
||||||
equal(opts.templates[0].name, 'bom');
|
equal(opts.templates.length, 2);
|
||||||
equal(opts.templates[1].name, 'empty');
|
equal(opts.templates[0].name, 'example_2');
|
||||||
equal(opts.templates[2].name, 'example_1');
|
|
||||||
done(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it('should handle regular expression characters in extensions', function (done) {
|
it('should enumerate all templates by extension', async function () {
|
||||||
Precompiler.loadTemplates(
|
var opts = await loadTemplatesAsync({
|
||||||
{ files: [__dirname + '/artifacts'], extension: 'hb(s' },
|
files: [__dirname + '/artifacts'],
|
||||||
function (err) {
|
extension: 'handlebars',
|
||||||
// Success is not throwing
|
});
|
||||||
done(err);
|
equal(opts.templates.length, 5);
|
||||||
}
|
equal(opts.templates[0].name, 'bom');
|
||||||
);
|
equal(opts.templates[1].name, 'empty');
|
||||||
|
equal(opts.templates[2].name, 'example_1');
|
||||||
});
|
});
|
||||||
it('should handle BOM', function (done) {
|
it('should handle regular expression characters in extensions', async function () {
|
||||||
var opts = {
|
await loadTemplatesAsync({
|
||||||
|
files: [__dirname + '/artifacts'],
|
||||||
|
extension: 'hb(s',
|
||||||
|
});
|
||||||
|
// Success is not throwing
|
||||||
|
});
|
||||||
|
it('should handle BOM', async function () {
|
||||||
|
var opts = await loadTemplatesAsync({
|
||||||
files: [__dirname + '/artifacts/bom.handlebars'],
|
files: [__dirname + '/artifacts/bom.handlebars'],
|
||||||
extension: 'handlebars',
|
extension: 'handlebars',
|
||||||
bom: true,
|
bom: true,
|
||||||
};
|
|
||||||
Precompiler.loadTemplates(opts, function (err, opts) {
|
|
||||||
equal(opts.templates[0].source, 'a');
|
|
||||||
done(err);
|
|
||||||
});
|
});
|
||||||
|
equal(opts.templates[0].source, 'a');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle different root', function (done) {
|
it('should handle different root', async function () {
|
||||||
var opts = {
|
var opts = await loadTemplatesAsync({
|
||||||
files: [__dirname + '/artifacts/empty.handlebars'],
|
files: [__dirname + '/artifacts/empty.handlebars'],
|
||||||
simple: true,
|
simple: true,
|
||||||
root: 'foo/',
|
root: 'foo/',
|
||||||
};
|
|
||||||
Precompiler.loadTemplates(opts, function (err, opts) {
|
|
||||||
equal(opts.templates[0].name, __dirname + '/artifacts/empty');
|
|
||||||
done(err);
|
|
||||||
});
|
});
|
||||||
|
equal(opts.templates[0].name, __dirname + '/artifacts/empty');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept string inputs', function (done) {
|
it('should accept string inputs', async function () {
|
||||||
var opts = { string: '' };
|
var opts = await loadTemplatesAsync({ string: '' });
|
||||||
Precompiler.loadTemplates(opts, function (err, opts) {
|
equal(opts.templates[0].name, undefined);
|
||||||
equal(opts.templates[0].name, undefined);
|
equal(opts.templates[0].source, '');
|
||||||
equal(opts.templates[0].source, '');
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
it('should accept string array inputs', function (done) {
|
it('should accept string array inputs', async function () {
|
||||||
var opts = { string: ['', 'bar'], name: ['beep', 'boop'] };
|
var opts = await loadTemplatesAsync({
|
||||||
Precompiler.loadTemplates(opts, function (err, opts) {
|
string: ['', 'bar'],
|
||||||
equal(opts.templates[0].name, 'beep');
|
name: ['beep', 'boop'],
|
||||||
equal(opts.templates[0].source, '');
|
|
||||||
equal(opts.templates[1].name, 'boop');
|
|
||||||
equal(opts.templates[1].source, 'bar');
|
|
||||||
done(err);
|
|
||||||
});
|
});
|
||||||
|
equal(opts.templates[0].name, 'beep');
|
||||||
|
equal(opts.templates[0].source, '');
|
||||||
|
equal(opts.templates[1].name, 'boop');
|
||||||
|
equal(opts.templates[1].source, 'bar');
|
||||||
});
|
});
|
||||||
it('should accept stdin input', function (done) {
|
it('should accept stdin input', async function () {
|
||||||
var stdin = require('mock-stdin').stdin();
|
var stdin = require('mock-stdin').stdin();
|
||||||
Precompiler.loadTemplates({ string: '-' }, function (err, opts) {
|
var promise = loadTemplatesAsync({ string: '-' });
|
||||||
equal(opts.templates[0].source, 'foo');
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
stdin.send('fo');
|
stdin.send('fo');
|
||||||
stdin.send('o');
|
stdin.send('o');
|
||||||
stdin.end();
|
stdin.end();
|
||||||
|
var opts = await promise;
|
||||||
|
equal(opts.templates[0].source, 'foo');
|
||||||
});
|
});
|
||||||
it('error on name missing', function (done) {
|
it('error on name missing', async function () {
|
||||||
var opts = { string: ['', 'bar'] };
|
try {
|
||||||
Precompiler.loadTemplates(opts, function (err) {
|
await loadTemplatesAsync({ string: ['', 'bar'] });
|
||||||
|
throw new Error('should have thrown');
|
||||||
|
} catch (err) {
|
||||||
equal(
|
equal(
|
||||||
err.message,
|
err.message,
|
||||||
'Number of names did not match the number of string inputs'
|
'Number of names did not match the number of string inputs'
|
||||||
);
|
);
|
||||||
done();
|
}
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should complete when no args are passed', function (done) {
|
it('should complete when no args are passed', async function () {
|
||||||
Precompiler.loadTemplates({}, function (err, opts) {
|
var opts = await loadTemplatesAsync({});
|
||||||
equal(opts.templates.length, 0);
|
equal(opts.templates.length, 0);
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+5
-5
@@ -403,7 +403,7 @@ describe('Regressions', function () {
|
|||||||
property: 'a',
|
property: 'a',
|
||||||
test: { a: 'b' },
|
test: { a: 'b' },
|
||||||
})
|
})
|
||||||
).to.equal('b');
|
).toBe('b');
|
||||||
});
|
});
|
||||||
|
|
||||||
function registerTemplate(Handlebars, compileTemplate) {
|
function registerTemplate(Handlebars, compileTemplate) {
|
||||||
@@ -479,19 +479,19 @@ describe('Regressions', function () {
|
|||||||
newHandlebarsInstance = Handlebars.create();
|
newHandlebarsInstance = Handlebars.create();
|
||||||
});
|
});
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
sinon.restore();
|
vi.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should only compile global partials once', function () {
|
it('should only compile global partials once', function () {
|
||||||
var templateSpy = sinon.spy(newHandlebarsInstance, 'template');
|
var templateSpy = vi.spyOn(newHandlebarsInstance, 'template');
|
||||||
newHandlebarsInstance.registerPartial({
|
newHandlebarsInstance.registerPartial({
|
||||||
dude: 'I am a partial',
|
dude: 'I am a partial',
|
||||||
});
|
});
|
||||||
var string = 'Dudes: {{> dude}} {{> dude}}';
|
var string = 'Dudes: {{> dude}} {{> dude}}';
|
||||||
newHandlebarsInstance.compile(string)(); // This should compile template + partial once
|
newHandlebarsInstance.compile(string)(); // This should compile template + partial once
|
||||||
newHandlebarsInstance.compile(string)(); // This should only compile template
|
newHandlebarsInstance.compile(string)(); // This should only compile template
|
||||||
equal(templateSpy.callCount, 3);
|
expect(templateSpy).toHaveBeenCalledTimes(3);
|
||||||
sinon.restore();
|
vi.restoreAllMocks();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+3
-4
@@ -57,11 +57,10 @@ 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 () {
|
||||||
|
if (!CompilerContext.browser) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
var reset = Handlebars;
|
var reset = Handlebars;
|
||||||
Handlebars.noConflict();
|
Handlebars.noConflict();
|
||||||
equal(Handlebars, 'no-conflict');
|
equal(Handlebars, 'no-conflict');
|
||||||
|
|||||||
+71
-42
@@ -57,8 +57,8 @@ describe('security issues', function () {
|
|||||||
functionCalls.push('called');
|
functionCalls.push('called');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}).to.throw(Error);
|
}).toThrow();
|
||||||
expect(functionCalls.length).to.equal(0);
|
expect(functionCalls.length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function () {
|
it('should throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function () {
|
||||||
@@ -109,20 +109,23 @@ describe('security issues', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('GH-1563', function () {
|
describe('GH-1563', function () {
|
||||||
it('should not allow to access constructor after overriding via __defineGetter__', function () {
|
var browserSupportsExploit =
|
||||||
if ({}.__defineGetter__ == null || {}.__lookupGetter__ == null) {
|
{}.__defineGetter__ != null && {}.__lookupGetter__ != null;
|
||||||
return this.skip(); // Browser does not support this exploit anyway
|
|
||||||
|
it.skipIf(!browserSupportsExploit)(
|
||||||
|
'should not allow to access constructor after overriding via __defineGetter__',
|
||||||
|
function () {
|
||||||
|
expectTemplate(
|
||||||
|
'{{__defineGetter__ "undefined" valueOf }}' +
|
||||||
|
'{{#with __lookupGetter__ }}' +
|
||||||
|
'{{__defineGetter__ "propertyIsEnumerable" (this.bind (this.bind 1)) }}' +
|
||||||
|
'{{constructor.name}}' +
|
||||||
|
'{{/with}}'
|
||||||
|
)
|
||||||
|
.withInput({})
|
||||||
|
.toThrow(/Missing helper: "__defineGetter__"/);
|
||||||
}
|
}
|
||||||
expectTemplate(
|
);
|
||||||
'{{__defineGetter__ "undefined" valueOf }}' +
|
|
||||||
'{{#with __lookupGetter__ }}' +
|
|
||||||
'{{__defineGetter__ "propertyIsEnumerable" (this.bind (this.bind 1)) }}' +
|
|
||||||
'{{constructor.name}}' +
|
|
||||||
'{{/with}}'
|
|
||||||
)
|
|
||||||
.withInput({})
|
|
||||||
.toThrow(/Missing helper: "__defineGetter__"/);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GH-1595: dangerous properties', function () {
|
describe('GH-1595: dangerous properties', function () {
|
||||||
@@ -169,7 +172,7 @@ describe('security issues', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
sinon.restore();
|
vi.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('control access to prototype methods via "allowedProtoMethods"', function () {
|
describe('control access to prototype methods via "allowedProtoMethods"', function () {
|
||||||
@@ -181,19 +184,25 @@ describe('security issues', function () {
|
|||||||
|
|
||||||
function checkProtoMethodAccess(compileOptions) {
|
function checkProtoMethodAccess(compileOptions) {
|
||||||
it('should be prohibited by default and log a warning', function () {
|
it('should be prohibited by default and log a warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = vi
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(function () {});
|
||||||
|
|
||||||
expectTemplate('{{aMethod}}')
|
expectTemplate('{{aMethod}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
.withCompileOptions(compileOptions)
|
.withCompileOptions(compileOptions)
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
|
|
||||||
expect(spy.calledOnce).to.be.true();
|
expect(spy).toHaveBeenCalledTimes(1);
|
||||||
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
expect(spy.mock.calls[0][0]).toMatch(
|
||||||
|
/Handlebars: Access has been denied/
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should only log the warning once', function () {
|
it('should only log the warning once', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = vi
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(function () {});
|
||||||
|
|
||||||
expectTemplate('{{aMethod}}')
|
expectTemplate('{{aMethod}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
@@ -205,12 +214,16 @@ describe('security issues', function () {
|
|||||||
.withCompileOptions(compileOptions)
|
.withCompileOptions(compileOptions)
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
|
|
||||||
expect(spy.calledOnce).to.be.true();
|
expect(spy).toHaveBeenCalledTimes(1);
|
||||||
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
expect(spy.mock.calls[0][0]).toMatch(
|
||||||
|
/Handlebars: Access has been denied/
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be allowed, which disables the warning', function () {
|
it('can be allowed, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = vi
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(function () {});
|
||||||
|
|
||||||
expectTemplate('{{aMethod}}')
|
expectTemplate('{{aMethod}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
@@ -222,11 +235,13 @@ describe('security issues', function () {
|
|||||||
})
|
})
|
||||||
.toCompileTo('returnValue');
|
.toCompileTo('returnValue');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned on by default, which disables the warning', function () {
|
it('can be turned on by default, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = vi
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(function () {});
|
||||||
|
|
||||||
expectTemplate('{{aMethod}}')
|
expectTemplate('{{aMethod}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
@@ -236,11 +251,13 @@ describe('security issues', function () {
|
|||||||
})
|
})
|
||||||
.toCompileTo('returnValue');
|
.toCompileTo('returnValue');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned off by default, which disables the warning', function () {
|
it('can be turned off by default, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = vi
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(function () {});
|
||||||
|
|
||||||
expectTemplate('{{aMethod}}')
|
expectTemplate('{{aMethod}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
@@ -250,7 +267,7 @@ describe('security issues', function () {
|
|||||||
})
|
})
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned off, if turned on by default', function () {
|
it('can be turned off, if turned on by default', function () {
|
||||||
@@ -300,19 +317,25 @@ describe('security issues', function () {
|
|||||||
|
|
||||||
function checkProtoPropertyAccess(compileOptions) {
|
function checkProtoPropertyAccess(compileOptions) {
|
||||||
it('should be prohibited by default and log a warning', function () {
|
it('should be prohibited by default and log a warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = vi
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(function () {});
|
||||||
|
|
||||||
expectTemplate('{{aProperty}}')
|
expectTemplate('{{aProperty}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
.withCompileOptions(compileOptions)
|
.withCompileOptions(compileOptions)
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
|
|
||||||
expect(spy.calledOnce).to.be.true();
|
expect(spy).toHaveBeenCalledTimes(1);
|
||||||
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
expect(spy.mock.calls[0][0]).toMatch(
|
||||||
|
/Handlebars: Access has been denied/
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be explicitly prohibited by default, which disables the warning', function () {
|
it('can be explicitly prohibited by default, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = vi
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(function () {});
|
||||||
|
|
||||||
expectTemplate('{{aProperty}}')
|
expectTemplate('{{aProperty}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
@@ -322,11 +345,13 @@ describe('security issues', function () {
|
|||||||
})
|
})
|
||||||
.toCompileTo('');
|
.toCompileTo('');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned on, which disables the warning', function () {
|
it('can be turned on, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = vi
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(function () {});
|
||||||
|
|
||||||
expectTemplate('{{aProperty}}')
|
expectTemplate('{{aProperty}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
@@ -338,11 +363,13 @@ describe('security issues', function () {
|
|||||||
})
|
})
|
||||||
.toCompileTo('propertyValue');
|
.toCompileTo('propertyValue');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned on by default, which disables the warning', function () {
|
it('can be turned on by default, which disables the warning', function () {
|
||||||
var spy = sinon.spy(console, 'error');
|
var spy = vi
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(function () {});
|
||||||
|
|
||||||
expectTemplate('{{aProperty}}')
|
expectTemplate('{{aProperty}}')
|
||||||
.withInput(new TestClass())
|
.withInput(new TestClass())
|
||||||
@@ -352,7 +379,7 @@ describe('security issues', function () {
|
|||||||
})
|
})
|
||||||
.toCompileTo('propertyValue');
|
.toCompileTo('propertyValue');
|
||||||
|
|
||||||
expect(spy.callCount).to.equal(0);
|
expect(spy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be turned off, if turned on by default', function () {
|
it('can be turned off, if turned on by default', function () {
|
||||||
@@ -373,14 +400,16 @@ describe('security issues', function () {
|
|||||||
describe('compatibility with old runtimes, that do not provide the function "container.lookupProperty"', function () {
|
describe('compatibility with old runtimes, that do not provide the function "container.lookupProperty"', function () {
|
||||||
beforeEach(function simulateRuntimeWithoutLookupProperty() {
|
beforeEach(function simulateRuntimeWithoutLookupProperty() {
|
||||||
var oldTemplateMethod = handlebarsEnv.template;
|
var oldTemplateMethod = handlebarsEnv.template;
|
||||||
sinon.replace(handlebarsEnv, 'template', function (templateSpec) {
|
vi.spyOn(handlebarsEnv, 'template').mockImplementation(
|
||||||
templateSpec.main = wrapToAdjustContainer(templateSpec.main);
|
function (templateSpec) {
|
||||||
return oldTemplateMethod.call(this, templateSpec);
|
templateSpec.main = wrapToAdjustContainer(templateSpec.main);
|
||||||
});
|
return oldTemplateMethod.call(this, templateSpec);
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
sinon.restore();
|
vi.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with simple properties', function () {
|
it('should work with simple properties', function () {
|
||||||
|
|||||||
+34
-77
@@ -1,91 +1,48 @@
|
|||||||
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Mocha</title>
|
<title>Handlebars Runtime UMD Smoke Test</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
</head>
|
||||||
<link rel="stylesheet" href="/node_modules/mocha/mocha.css" />
|
<body>
|
||||||
<style>
|
<h1>Handlebars Runtime UMD Smoke Test</h1>
|
||||||
.headless .suite > h1,
|
<pre id="results"></pre>
|
||||||
.headless .test.pass {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Show only errors in "headless", non-interactive mode.
|
|
||||||
if (/headless=true/.test(location.href)) {
|
|
||||||
document.documentElement.className = 'headless';
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script src="/node_modules/sinon/pkg/sinon.js"></script>
|
|
||||||
<script src="/node_modules/chai/chai.js"></script>
|
|
||||||
<script src="/node_modules/dirty-chai/lib/dirty-chai.js"></script>
|
|
||||||
<script src="/node_modules/mocha/mocha.js"></script>
|
|
||||||
<script>
|
|
||||||
window.expect = chai.expect;
|
|
||||||
mocha.setup('bdd');
|
|
||||||
</script>
|
|
||||||
<script src="/spec/vendor/require.js"></script>
|
<script src="/spec/vendor/require.js"></script>
|
||||||
|
|
||||||
<script src="/spec/env/common.js"></script>
|
|
||||||
<script>
|
<script>
|
||||||
|
var results = document.getElementById('results');
|
||||||
|
var failures = 0;
|
||||||
|
var tests = 0;
|
||||||
|
|
||||||
|
function assert(condition, message) {
|
||||||
|
tests++;
|
||||||
|
if (!condition) {
|
||||||
|
failures++;
|
||||||
|
results.textContent += 'FAIL: ' + message + '\n';
|
||||||
|
} else {
|
||||||
|
results.textContent += 'PASS: ' + message + '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
requirejs.config({
|
requirejs.config({
|
||||||
paths: {
|
paths: {
|
||||||
'handlebars.runtime': '/dist/handlebars.runtime'
|
'handlebars.runtime': '/dist/handlebars.runtime'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
require(['handlebars.runtime'], function(Handlebars) {
|
||||||
|
try {
|
||||||
|
assert(typeof Handlebars !== 'undefined', 'Handlebars runtime loaded via RequireJS');
|
||||||
|
assert(typeof Handlebars.template === 'function', 'Handlebars.template exists');
|
||||||
|
assert(typeof Handlebars.VERSION === 'string', 'Handlebars.VERSION exists');
|
||||||
|
} catch (e) {
|
||||||
|
failures++;
|
||||||
|
results.textContent += 'ERROR: ' + e.message + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
results.textContent += '\n' + tests + ' tests, ' + failures + ' failures\n';
|
||||||
|
window.mochaResults = { passes: tests - failures, failures: failures };
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<script>
|
|
||||||
onload = function(){
|
|
||||||
require(['handlebars.runtime'], function(Handlebars) {
|
|
||||||
describe('runtime', function() {
|
|
||||||
it('should load', function() {
|
|
||||||
equal(!!Handlebars.template, true);
|
|
||||||
equal(!!Handlebars.VERSION, true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
mocha.globals(['mochaResults'])
|
|
||||||
// The test harness leaks under FF. We should have decent global leak coverage from other tests
|
|
||||||
if (!navigator.userAgent.match(/Firefox\/([\d.]+)/)) {
|
|
||||||
mocha.checkLeaks();
|
|
||||||
}
|
|
||||||
var runner = mocha.run();
|
|
||||||
|
|
||||||
// Reporting to test-runner
|
|
||||||
var failedTests = [];
|
|
||||||
runner.on('end', function(){
|
|
||||||
window.mochaResults = runner.stats;
|
|
||||||
window.mochaResults.reports = failedTests;
|
|
||||||
});
|
|
||||||
|
|
||||||
runner.on('fail', logFailure);
|
|
||||||
|
|
||||||
function logFailure(test, err){
|
|
||||||
|
|
||||||
var flattenTitles = function(test){
|
|
||||||
var titles = [];
|
|
||||||
while (test.parent.title){
|
|
||||||
titles.push(test.parent.title);
|
|
||||||
test = test.parent;
|
|
||||||
}
|
|
||||||
return titles.reverse();
|
|
||||||
};
|
|
||||||
|
|
||||||
failedTests.push({
|
|
||||||
name: test.title,
|
|
||||||
result: false,
|
|
||||||
message: err.message,
|
|
||||||
stack: err.stack,
|
|
||||||
titles: flattenTitles(test)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="mocha"></div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+37
-96
@@ -1,112 +1,53 @@
|
|||||||
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Mocha</title>
|
<title>Handlebars UMD Module Smoke Test</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
</head>
|
||||||
<link rel="stylesheet" href="/node_modules/mocha/mocha.css" />
|
<body>
|
||||||
<style>
|
<h1>Handlebars UMD Module Smoke Test</h1>
|
||||||
.headless .suite > h1,
|
<pre id="results"></pre>
|
||||||
.headless .test.pass {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Show only errors in "headless", non-interactive mode.
|
|
||||||
if (/headless=true/.test(location.href)) {
|
|
||||||
document.documentElement.className = 'headless';
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="/node_modules/sinon/pkg/sinon.js"></script>
|
|
||||||
<script src="/node_modules/chai/chai.js"></script>
|
|
||||||
<script src="/node_modules/dirty-chai/lib/dirty-chai.js"></script>
|
|
||||||
<script src="/node_modules/mocha/mocha.js"></script>
|
|
||||||
<script>
|
|
||||||
window.expect = chai.expect;
|
|
||||||
mocha.setup('bdd');
|
|
||||||
</script>
|
|
||||||
<script src="/spec/vendor/require.js"></script>
|
<script src="/spec/vendor/require.js"></script>
|
||||||
|
|
||||||
<script src="/spec/env/common.js"></script>
|
|
||||||
<script>
|
<script>
|
||||||
|
var results = document.getElementById('results');
|
||||||
|
var failures = 0;
|
||||||
|
var tests = 0;
|
||||||
|
|
||||||
|
function assert(condition, message) {
|
||||||
|
tests++;
|
||||||
|
if (!condition) {
|
||||||
|
failures++;
|
||||||
|
results.textContent += 'FAIL: ' + message + '\n';
|
||||||
|
} else {
|
||||||
|
results.textContent += 'PASS: ' + message + '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
requirejs.config({
|
requirejs.config({
|
||||||
paths: {
|
paths: {
|
||||||
handlebars: '/dist/handlebars',
|
handlebars: '/dist/handlebars'
|
||||||
tests: '/tmp/tests'
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var CompilerContext = {
|
require(['handlebars'], function(Handlebars) {
|
||||||
compile: function(template, options) {
|
|
||||||
var templateSpec = handlebarsEnv.precompile(template, options);
|
|
||||||
return handlebarsEnv.template(safeEval(templateSpec));
|
|
||||||
},
|
|
||||||
compileWithPartial: function(template, options) {
|
|
||||||
return handlebarsEnv.compile(template, options);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function safeEval(templateSpec) {
|
|
||||||
try {
|
try {
|
||||||
var ret;
|
assert(typeof Handlebars !== 'undefined', 'Handlebars loaded via RequireJS');
|
||||||
eval('ret = ' + templateSpec);
|
assert(typeof Handlebars.compile === 'function', 'Handlebars.compile exists');
|
||||||
return ret;
|
assert(typeof Handlebars.template === 'function', 'Handlebars.template exists');
|
||||||
} catch (err) {
|
assert(typeof Handlebars.VERSION === 'string', 'Handlebars.VERSION exists');
|
||||||
console.error(templateSpec);
|
|
||||||
throw err;
|
var template = Handlebars.compile('Hello {{name}}!');
|
||||||
|
var output = template({ name: 'UMD' });
|
||||||
|
assert(output === 'Hello UMD!', 'Basic compilation works: ' + output);
|
||||||
|
} catch (e) {
|
||||||
|
failures++;
|
||||||
|
results.textContent += 'ERROR: ' + e.message + '\n';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
results.textContent += '\n' + tests + ' tests, ' + failures + ' failures\n';
|
||||||
|
window.mochaResults = { passes: tests - failures, failures: failures };
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<script>
|
|
||||||
onload = function(){
|
|
||||||
|
|
||||||
require(['handlebars'], function(Handlebars) {
|
|
||||||
window.Handlebars = Handlebars;
|
|
||||||
|
|
||||||
require(['tests'], function() {
|
|
||||||
mocha.globals(['mochaResults'])
|
|
||||||
// The test harness leaks under FF. We should have decent global leak coverage from other tests
|
|
||||||
if (!navigator.userAgent.match(/Firefox\/([\d.]+)/)) {
|
|
||||||
mocha.checkLeaks();
|
|
||||||
}
|
|
||||||
var runner = mocha.run();
|
|
||||||
|
|
||||||
// Reporting to test-runner
|
|
||||||
var failedTests = [];
|
|
||||||
runner.on('end', function(){
|
|
||||||
window.mochaResults = runner.stats;
|
|
||||||
window.mochaResults.reports = failedTests;
|
|
||||||
});
|
|
||||||
|
|
||||||
runner.on('fail', logFailure);
|
|
||||||
|
|
||||||
function logFailure(test, err){
|
|
||||||
|
|
||||||
var flattenTitles = function(test){
|
|
||||||
var titles = [];
|
|
||||||
while (test.parent.title){
|
|
||||||
titles.push(test.parent.title);
|
|
||||||
test = test.parent;
|
|
||||||
}
|
|
||||||
return titles.reverse();
|
|
||||||
};
|
|
||||||
|
|
||||||
failedTests.push({
|
|
||||||
name: test.title,
|
|
||||||
result: false,
|
|
||||||
message: err.message,
|
|
||||||
stack: err.stack,
|
|
||||||
titles: flattenTitles(test)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="mocha"></div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+6
-6
@@ -89,18 +89,18 @@ describe('utils', function () {
|
|||||||
|
|
||||||
describe('#isType', function () {
|
describe('#isType', function () {
|
||||||
it('should check if variable is type Array', function () {
|
it('should check if variable is type Array', function () {
|
||||||
expect(Handlebars.Utils.isArray('string')).to.equal(false);
|
expect(Handlebars.Utils.isArray('string')).toBe(false);
|
||||||
expect(Handlebars.Utils.isArray([])).to.equal(true);
|
expect(Handlebars.Utils.isArray([])).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check if variable is type Map', function () {
|
it('should check if variable is type Map', function () {
|
||||||
expect(Handlebars.Utils.isMap('string')).to.equal(false);
|
expect(Handlebars.Utils.isMap('string')).toBe(false);
|
||||||
expect(Handlebars.Utils.isMap(new Map())).to.equal(true);
|
expect(Handlebars.Utils.isMap(new Map())).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check if variable is type Set', function () {
|
it('should check if variable is type Set', function () {
|
||||||
expect(Handlebars.Utils.isSet('string')).to.equal(false);
|
expect(Handlebars.Utils.isSet('string')).toBe(false);
|
||||||
expect(Handlebars.Utils.isSet(new Set())).to.equal(true);
|
expect(Handlebars.Utils.isSet(new Set())).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
const { execNodeJsScriptWithInheritedOutput } = require('./util/exec-file');
|
|
||||||
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
|
|
||||||
const nodeJs = process.argv0;
|
|
||||||
|
|
||||||
module.exports = function (grunt) {
|
|
||||||
const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
|
|
||||||
|
|
||||||
registerAsyncTask('test:mocha', async () =>
|
|
||||||
execNodeJsScriptWithInheritedOutput('./spec/env/runner')
|
|
||||||
);
|
|
||||||
|
|
||||||
registerAsyncTask('test:cov', async () =>
|
|
||||||
execNodeJsScriptWithInheritedOutput('node_modules/nyc/bin/nyc', [
|
|
||||||
nodeJs,
|
|
||||||
'./spec/env/runner.js',
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
registerAsyncTask('test:min', async () =>
|
|
||||||
execNodeJsScriptWithInheritedOutput('./spec/env/runner', ['--min'])
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
env: {
|
globals: {
|
||||||
mocha: true,
|
describe: true,
|
||||||
|
it: true,
|
||||||
|
expect: true,
|
||||||
|
beforeEach: true,
|
||||||
|
afterEach: true,
|
||||||
|
vi: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,10 +3,6 @@ const fs = require('fs');
|
|||||||
const os = require('os');
|
const os = require('os');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const chai = require('chai');
|
|
||||||
chai.use(require('chai-diff'));
|
|
||||||
const expect = chai.expect;
|
|
||||||
|
|
||||||
const testCases = [
|
const testCases = [
|
||||||
{
|
{
|
||||||
binInputParameters: ['-a', 'spec/artifacts/empty.handlebars'],
|
binInputParameters: ['-a', 'spec/artifacts/empty.handlebars'],
|
||||||
@@ -74,7 +70,7 @@ const testCases = [
|
|||||||
{
|
{
|
||||||
binInputParameters: ['-v'],
|
binInputParameters: ['-v'],
|
||||||
outputLocation: 'stdout',
|
outputLocation: 'stdout',
|
||||||
expectedOutput: require('../package.json').version,
|
expectedOutput: require('../../package.json').version,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
binInputParameters: [
|
binInputParameters: [
|
||||||
@@ -177,15 +173,46 @@ const testCases = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports = function (grunt) {
|
expect.extend({
|
||||||
grunt.registerTask('test:bin', function () {
|
toEqualWithRelaxedSpace(received, expected) {
|
||||||
testCases.forEach(
|
const normalize = (str) =>
|
||||||
({
|
typeof str === 'string'
|
||||||
|
? str
|
||||||
|
.replace(/\r\n/g, '\n')
|
||||||
|
.split('\n')
|
||||||
|
.map((line) => line.replace(/\s+/g, ' ').trim())
|
||||||
|
.filter((line) => line.length > 0)
|
||||||
|
.join('\n')
|
||||||
|
.trim()
|
||||||
|
: str;
|
||||||
|
|
||||||
|
const normalizedReceived = normalize(received);
|
||||||
|
const normalizedExpected = normalize(expected);
|
||||||
|
const pass = normalizedReceived === normalizedExpected;
|
||||||
|
|
||||||
|
return {
|
||||||
|
pass,
|
||||||
|
message: () =>
|
||||||
|
`Expected output to match with relaxed whitespace.\n\n` +
|
||||||
|
`Expected:\n${normalizedExpected}\n\nReceived:\n${normalizedReceived}`,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('bin/handlebars', function () {
|
||||||
|
testCases.forEach(
|
||||||
|
(
|
||||||
|
{
|
||||||
binInputParameters,
|
binInputParameters,
|
||||||
outputLocation,
|
outputLocation,
|
||||||
expectedOutputSpec,
|
expectedOutputSpec,
|
||||||
expectedOutput,
|
expectedOutput,
|
||||||
}) => {
|
},
|
||||||
|
index
|
||||||
|
) => {
|
||||||
|
it(`test case ${index}: handlebars ${binInputParameters.join(
|
||||||
|
' '
|
||||||
|
)}`, function () {
|
||||||
const stdout = executeBinHandlebars(...binInputParameters);
|
const stdout = executeBinHandlebars(...binInputParameters);
|
||||||
|
|
||||||
if (!expectedOutput && expectedOutputSpec) {
|
if (!expectedOutput && expectedOutputSpec) {
|
||||||
@@ -193,25 +220,19 @@ module.exports = function (grunt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const useStdout = outputLocation === 'stdout';
|
const useStdout = outputLocation === 'stdout';
|
||||||
const normalizedOutput = normalizeCrlf(
|
const actualOutput = useStdout
|
||||||
useStdout ? stdout : fs.readFileSync(outputLocation, 'utf-8')
|
? stdout
|
||||||
);
|
: fs.readFileSync(outputLocation, 'utf-8');
|
||||||
const normalizedExpectedOutput = normalizeCrlf(expectedOutput);
|
|
||||||
|
|
||||||
if (!useStdout) {
|
if (!useStdout) {
|
||||||
fs.unlinkSync(outputLocation);
|
fs.unlinkSync(outputLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(normalizedOutput).not.to.be.differentFrom(
|
expect(actualOutput).toEqualWithRelaxedSpace(expectedOutput);
|
||||||
normalizedExpectedOutput,
|
});
|
||||||
{
|
}
|
||||||
relaxedSpace: true,
|
);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// helper functions
|
// helper functions
|
||||||
|
|
||||||
@@ -233,10 +254,3 @@ function execFilesSyncUtf8(command, args) {
|
|||||||
function addPathToNodeJs(pathEnvironment) {
|
function addPathToNodeJs(pathEnvironment) {
|
||||||
return path.dirname(process.argv0) + path.delimiter + pathEnvironment;
|
return path.dirname(process.argv0) + path.delimiter + pathEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeCrlf(string) {
|
|
||||||
if (typeof string === 'string') {
|
|
||||||
return string.replace(/\r\n/g, '\n');
|
|
||||||
}
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
+15
-15
@@ -1,13 +1,9 @@
|
|||||||
const os = require('os');
|
const os = require('os');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const chai = require('chai');
|
|
||||||
chai.use(require('dirty-chai'));
|
|
||||||
|
|
||||||
const git = require('../util/git');
|
const git = require('../util/git');
|
||||||
|
|
||||||
const expect = chai.expect;
|
|
||||||
|
|
||||||
const tmpBaseDir = path.join(os.tmpdir(), 'handlebars-task-tests');
|
const tmpBaseDir = path.join(os.tmpdir(), 'handlebars-task-tests');
|
||||||
const tmpDir = path.join(tmpBaseDir, Date.now().toString(36));
|
const tmpDir = path.join(tmpBaseDir, Date.now().toString(36));
|
||||||
const remoteDir = path.join(tmpDir, 'remote-repo');
|
const remoteDir = path.join(tmpDir, 'remote-repo');
|
||||||
@@ -21,6 +17,8 @@ describe('utils/git', function () {
|
|||||||
process.chdir(tmpDir);
|
process.chdir(tmpDir);
|
||||||
await git.git('clone', 'remote-repo', 'clone-repo');
|
await git.git('clone', 'remote-repo', 'clone-repo');
|
||||||
process.chdir(cloneDir);
|
process.chdir(cloneDir);
|
||||||
|
await git.git('config', 'user.email', 'test@test.com');
|
||||||
|
await git.git('config', 'user.name', 'Test');
|
||||||
});
|
});
|
||||||
|
|
||||||
async function createRepositoryThatActsAsRemote() {
|
async function createRepositoryThatActsAsRemote() {
|
||||||
@@ -28,6 +26,8 @@ describe('utils/git', function () {
|
|||||||
process.chdir(remoteDir);
|
process.chdir(remoteDir);
|
||||||
|
|
||||||
await git.git('init');
|
await git.git('init');
|
||||||
|
await git.git('config', 'user.email', 'test@test.com');
|
||||||
|
await git.git('config', 'user.name', 'Test');
|
||||||
await fs.writeFile('testfile.txt', 'Testfile');
|
await fs.writeFile('testfile.txt', 'Testfile');
|
||||||
await git.add('testfile.txt');
|
await git.add('testfile.txt');
|
||||||
await git.commit('commit message');
|
await git.commit('commit message');
|
||||||
@@ -44,7 +44,7 @@ describe('utils/git', function () {
|
|||||||
|
|
||||||
const result = await git.remotes();
|
const result = await git.remotes();
|
||||||
|
|
||||||
expect(result.trim().split('\n')).to.deep.equal([
|
expect(result.trim().split('\n')).toEqual([
|
||||||
'origin\thttps://test.org/test (fetch)',
|
'origin\thttps://test.org/test (fetch)',
|
||||||
'origin\thttps://test.org/test (push)',
|
'origin\thttps://test.org/test (push)',
|
||||||
'second-remote\thttps://test.org/test2 (fetch)',
|
'second-remote\thttps://test.org/test2 (fetch)',
|
||||||
@@ -59,7 +59,7 @@ describe('utils/git', function () {
|
|||||||
await git.git('branch', 'test2');
|
await git.git('branch', 'test2');
|
||||||
|
|
||||||
const result = await git.branches();
|
const result = await git.branches();
|
||||||
expect(result.trim().split('\n')).to.deep.equal([
|
expect(result.trim().split('\n')).toEqual([
|
||||||
'* master',
|
'* master',
|
||||||
' test',
|
' test',
|
||||||
' test2',
|
' test2',
|
||||||
@@ -72,21 +72,21 @@ describe('utils/git', function () {
|
|||||||
describe('the "commitInfo"-function', function () {
|
describe('the "commitInfo"-function', function () {
|
||||||
it('should list head and master sha', async function () {
|
it('should list head and master sha', async function () {
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.masterSha).to.equal(result.headSha);
|
expect(result.masterSha).toBe(result.headSha);
|
||||||
expect(result.masterSha).to.match(/^[0-9a-f]+$/);
|
expect(result.masterSha).toMatch(/^[0-9a-f]+$/);
|
||||||
expect(result.headSha).to.match(/^[0-9a-f]+$/);
|
expect(result.headSha).toMatch(/^[0-9a-f]+$/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have "isMaster=true" if the master branch is checked out', async function () {
|
it('should have "isMaster=true" if the master branch is checked out', async function () {
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.isMaster).to.be.true();
|
expect(result.isMaster).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have "isMaster=true" if the current commit is the last commit of the master branch', async function () {
|
it('should have "isMaster=true" if the current commit is the last commit of the master branch', async function () {
|
||||||
await git.git('checkout', '-b', 'new-branch');
|
await git.git('checkout', '-b', 'new-branch');
|
||||||
|
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.isMaster).to.be.true();
|
expect(result.isMaster).toBe(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 () {
|
||||||
@@ -96,13 +96,13 @@ describe('utils/git', function () {
|
|||||||
await git.commit('added new file');
|
await git.commit('added new file');
|
||||||
|
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.isMaster).to.be.false();
|
expect(result.isMaster).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show the current tag', async function () {
|
it('should show the current tag', async function () {
|
||||||
await git.git('tag', 'test-tag');
|
await git.git('tag', 'test-tag');
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.tagName).to.be.equal('test-tag');
|
expect(result.tagName).toBe('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 () {
|
||||||
@@ -110,12 +110,12 @@ describe('utils/git', function () {
|
|||||||
await git.git('tag', 'v1.2');
|
await git.git('tag', 'v1.2');
|
||||||
await git.git('tag', 'test-tag2');
|
await git.git('tag', 'test-tag2');
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.tagName).to.be.equal('v1.2');
|
expect(result.tagName).toBe('v1.2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show no tag if there is no tag', async function () {
|
it('should show no tag if there is no tag', async function () {
|
||||||
const result = await git.commitInfo();
|
const result = await git.commitInfo();
|
||||||
expect(result.tagName).to.be.null();
|
expect(result.tagName).toBeNull();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
import { playwright } from '@vitest/browser-playwright';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
projects: [
|
||||||
|
{
|
||||||
|
test: {
|
||||||
|
name: 'node',
|
||||||
|
include: ['spec/*.js'],
|
||||||
|
exclude: ['spec/env/**', 'spec/.eslintrc.js'],
|
||||||
|
setupFiles: ['spec/env/node.js'],
|
||||||
|
globals: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: {
|
||||||
|
name: 'tasks',
|
||||||
|
include: ['tasks/tests/*.test.js'],
|
||||||
|
globals: true,
|
||||||
|
pool: 'forks',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: {
|
||||||
|
name: 'browser',
|
||||||
|
include: ['spec/*.js'],
|
||||||
|
exclude: [
|
||||||
|
'spec/env/**',
|
||||||
|
'spec/.eslintrc.js',
|
||||||
|
'spec/precompiler.js',
|
||||||
|
'spec/spec.js',
|
||||||
|
'spec/require.js',
|
||||||
|
'spec/source-map.js',
|
||||||
|
],
|
||||||
|
setupFiles: [
|
||||||
|
'spec/env/browser-vitest-pre.js',
|
||||||
|
'spec/env/browser-vitest.js',
|
||||||
|
],
|
||||||
|
globals: true,
|
||||||
|
browser: {
|
||||||
|
enabled: true,
|
||||||
|
provider: playwright(),
|
||||||
|
instances: [{ browser: 'chromium' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
coverage: {
|
||||||
|
provider: 'v8',
|
||||||
|
include: ['dist/cjs/**/*.js'],
|
||||||
|
thresholds: {
|
||||||
|
statements: 100,
|
||||||
|
branches: 93,
|
||||||
|
functions: 100,
|
||||||
|
lines: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user