diff --git a/bin/handlebars b/bin/handlebars index fabbb3951..17a36609d 100755 --- a/bin/handlebars +++ b/bin/handlebars @@ -111,6 +111,7 @@ delete argv._; const Precompiler = require('../dist/cjs/precompiler'); Precompiler.loadTemplates(argv, function(err, opts) { + if (err) { throw err; } diff --git a/spec/artifacts/known.helpers.handlebars b/spec/artifacts/known.helpers.handlebars new file mode 100644 index 000000000..74ab9d47b --- /dev/null +++ b/spec/artifacts/known.helpers.handlebars @@ -0,0 +1,6 @@ +{{#someHelper true}} +
Some known helper
+ {{#anotherHelper true}} +
Another known helper
+ {{/anotherHelper}} +{{/someHelper}} diff --git a/spec/artifacts/non.default.extension.hbs b/spec/artifacts/non.default.extension.hbs new file mode 100644 index 000000000..9c3af95fc --- /dev/null +++ b/spec/artifacts/non.default.extension.hbs @@ -0,0 +1 @@ +
This is a test
\ No newline at end of file diff --git a/spec/artifacts/partial.template.handlebars b/spec/artifacts/partial.template.handlebars new file mode 100644 index 000000000..f99ae8ebc --- /dev/null +++ b/spec/artifacts/partial.template.handlebars @@ -0,0 +1 @@ +
Test Partial
\ No newline at end of file diff --git a/spec/artifacts/source.map.amd.txt b/spec/artifacts/source.map.amd.txt new file mode 100644 index 000000000..88c18f847 --- /dev/null +++ b/spec/artifacts/source.map.amd.txt @@ -0,0 +1 @@ +{"version":3,"sources":["test"],"names":["compiler","main","container","depth0","helpers","partials","data","useData"],"mappings":"kHAAA,CAAAA,SAAA,CAAA,EAAA,YAAAC,KAAA,SAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAAA,MAAA,gBAAAC,SAAA"} \ No newline at end of file diff --git a/spec/expected/compiled.string.txt b/spec/expected/compiled.string.txt new file mode 100644 index 000000000..8b1a14d8c --- /dev/null +++ b/spec/expected/compiled.string.txt @@ -0,0 +1,3 @@ +{"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return "
Test String
"; +},"useData":true} \ No newline at end of file diff --git a/spec/expected/empty.amd.min.js b/spec/expected/empty.amd.min.js new file mode 100644 index 000000000..8fc31a610 --- /dev/null +++ b/spec/expected/empty.amd.min.js @@ -0,0 +1 @@ +define(["handlebars.runtime"],function(e){var t=(e=e.default).template;return(e.templates=e.templates||{}).empty=t({compiler:[8,">= 4.3.0"],main:function(e,t,a,n,r){return""},useData:!0})}); \ No newline at end of file diff --git a/spec/expected/empty.amd.namespace.js b/spec/expected/empty.amd.namespace.js new file mode 100644 index 000000000..1972fb437 --- /dev/null +++ b/spec/expected/empty.amd.namespace.js @@ -0,0 +1,6 @@ +define(['handlebars.runtime'], function(Handlebars) { + Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = CustomNamespace.templates = CustomNamespace.templates || {}; +return templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return ""; +},"useData":true}); +}); diff --git a/spec/expected/empty.amd.simple.js b/spec/expected/empty.amd.simple.js new file mode 100644 index 000000000..b4014bb83 --- /dev/null +++ b/spec/expected/empty.amd.simple.js @@ -0,0 +1,3 @@ +{"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return ""; +},"useData":true} \ No newline at end of file diff --git a/spec/expected/empty.common.js b/spec/expected/empty.common.js new file mode 100644 index 000000000..099f2f2de --- /dev/null +++ b/spec/expected/empty.common.js @@ -0,0 +1,6 @@ +(function() { + var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; +templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return ""; +},"useData":true}); +})(); \ No newline at end of file diff --git a/spec/expected/empty.name.amd.js b/spec/expected/empty.name.amd.js new file mode 100644 index 000000000..13c377f64 --- /dev/null +++ b/spec/expected/empty.name.amd.js @@ -0,0 +1,10 @@ +define(['handlebars.runtime'], function(Handlebars) { + Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; +templates['firstTemplate'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return "
1
"; +},"useData":true}); +templates['secondTemplate'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return "
2
"; +},"useData":true}); +return templates; +}); \ No newline at end of file diff --git a/spec/expected/empty.root.amd.js b/spec/expected/empty.root.amd.js new file mode 100644 index 000000000..11ea55d5a --- /dev/null +++ b/spec/expected/empty.root.amd.js @@ -0,0 +1,6 @@ +define(['handlebars.runtime'], function(Handlebars) { + Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; +return templates['artifacts/partial.template'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return "
Test Partial
"; +},"useData":true}); +}); \ No newline at end of file diff --git a/spec/expected/handlebar.path.amd.js b/spec/expected/handlebar.path.amd.js new file mode 100644 index 000000000..b3aa1f08a --- /dev/null +++ b/spec/expected/handlebar.path.amd.js @@ -0,0 +1,6 @@ +define(['some-path/handlebars.runtime'], function(Handlebars) { + Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; + return templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return ""; + },"useData":true}); + }); \ No newline at end of file diff --git a/spec/expected/help.menu.txt b/spec/expected/help.menu.txt new file mode 100644 index 000000000..027bb73a7 --- /dev/null +++ b/spec/expected/help.menu.txt @@ -0,0 +1,25 @@ +Precompile handlebar templates. +Usage: handlebars [template|directory]... + +Options: + --help Outputs this message [boolean] + -f, --output Output File [string] + --map Source Map File [string] + -a, --amd Exports amd style (require.js) [boolean] + -c, --commonjs Exports CommonJS style, path to Handlebars module [string] [default: null] + -h, --handlebarPath Path to handlebar.js (only valid for amd-style) [string] [default: ""] + -k, --known Known helpers [string] + -o, --knownOnly Known helpers only [boolean] + -m, --min Minimize output [boolean] + -n, --namespace Template namespace [string] [default: "Handlebars.templates"] + -s, --simple Output template function only. [boolean] + -N, --name Name of passed string templates. Optional if running in a simple mode. Required when operating on + multiple templates. [string] + -i, --string Generates a template from the passed CLI argument. + "-" is treated as a special value and causes stdin to be read for the template value. [string] + -r, --root Template root. Base value that will be stripped from template names. [string] + -p, --partial Compiling a partial template [boolean] + -d, --data Include data when compiling [boolean] + -e, --extension Template extension. [string] [default: "handlebars"] + -b, --bom Removes the BOM (Byte Order Mark) from the beginning of the templates. [boolean] + -v, --version Show version number [boolean] \ No newline at end of file diff --git a/spec/expected/namespace.amd.js b/spec/expected/namespace.amd.js new file mode 100644 index 000000000..cdd91f0df --- /dev/null +++ b/spec/expected/namespace.amd.js @@ -0,0 +1,10 @@ +define(['handlebars.runtime'], function(Handlebars) { + Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = someNameSpace = someNameSpace || {}; + templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return ""; + },"useData":true}); + templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return ""; + },"useData":true}); + return templates; + }); \ No newline at end of file diff --git a/spec/expected/non.default.extension.amd.js b/spec/expected/non.default.extension.amd.js new file mode 100644 index 000000000..264499a7c --- /dev/null +++ b/spec/expected/non.default.extension.amd.js @@ -0,0 +1,6 @@ +define(['handlebars.runtime'], function(Handlebars) { + Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; + return templates['non.default.extension'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return "
This is a test
"; + },"useData":true}); + }); \ No newline at end of file diff --git a/spec/expected/non.empty.amd.known.helper.js b/spec/expected/non.empty.amd.known.helper.js new file mode 100644 index 000000000..75c81cdce --- /dev/null +++ b/spec/expected/non.empty.amd.known.helper.js @@ -0,0 +1,24 @@ +define(['handlebars.runtime'], function(Handlebars) { +Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; +return templates['known.helpers'] = template({"1":function(container,depth0,helpers,partials,data) { +var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) { +if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { +return parent[propertyName]; +} +return undefined +}; +return "
Some known helper
\n" ++ ((stack1 = lookupProperty(helpers,"anotherHelper").call(depth0 != null ? depth0 : (container.nullContext || {}),true,{"name":"anotherHelper","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":3,"column":4},"end":{"line":5,"column":22}}})) != null ? stack1 : ""); +},"2":function(container,depth0,helpers,partials,data) { +return "
Another known helper
\n"; +},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { +var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) { +if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { +return parent[propertyName]; +} +return undefined +}; +return ((stack1 = lookupProperty(helpers,"someHelper").call(depth0 != null ? depth0 : (container.nullContext || {}),true,{"name":"someHelper","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":15}}})) != null ? stack1 : ""); +},"useData":true}); +}); + \ No newline at end of file diff --git a/spec/expected/partial.template.js b/spec/expected/partial.template.js new file mode 100644 index 000000000..e73aaa1d7 --- /dev/null +++ b/spec/expected/partial.template.js @@ -0,0 +1,6 @@ +define(['handlebars.runtime'], function(Handlebars) { + Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; + return Handlebars.partials['partial.template'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { + return "
Test Partial
"; + },"useData":true}); + }); \ No newline at end of file diff --git a/spec/expected/source.map.amd.js b/spec/expected/source.map.amd.js new file mode 100644 index 000000000..1f010db73 --- /dev/null +++ b/spec/expected/source.map.amd.js @@ -0,0 +1,2 @@ +define(["handlebars.runtime"],function(e){var t=(e=e.default).template;return(e.templates=e.templates||{}).test=t({compiler:[8,">= 4.3.0"],main:function(e,t,a,n,i){return"
1
"},useData:!0})}); +//# sourceMappingURL=./spec/artifacts/source.map.amd.txt \ No newline at end of file diff --git a/spec/expected/version.txt b/spec/expected/version.txt new file mode 100644 index 000000000..4178d093f --- /dev/null +++ b/spec/expected/version.txt @@ -0,0 +1 @@ +4.7.3 \ No newline at end of file diff --git a/spec/precompiler.js b/spec/precompiler.js index 2261023cc..c668e9156 100644 --- a/spec/precompiler.js +++ b/spec/precompiler.js @@ -307,8 +307,9 @@ describe('precompiler', function() { Precompiler.loadTemplates( { files: [__dirname + '/artifacts'], extension: 'hbs' }, function(err, opts) { - equal(opts.templates.length, 1); + equal(opts.templates.length, 2); equal(opts.templates[0].name, 'example_2'); + done(err); } ); @@ -317,7 +318,7 @@ describe('precompiler', function() { Precompiler.loadTemplates( { files: [__dirname + '/artifacts'], extension: 'handlebars' }, function(err, opts) { - equal(opts.templates.length, 3); + equal(opts.templates.length, 5); equal(opts.templates[0].name, 'bom'); equal(opts.templates[1].name, 'empty'); equal(opts.templates[2].name, 'example_1'); diff --git a/tasks/test-bin.js b/tasks/test-bin.js index 3a9c43095..5d3e9927a 100644 --- a/tasks/test-bin.js +++ b/tasks/test-bin.js @@ -7,22 +7,194 @@ const chai = require('chai'); chai.use(require('chai-diff')); const expect = chai.expect; -module.exports = function(grunt) { - grunt.registerTask('test:bin', function() { - const stdout = executeBinHandlebars( +const testCases = [ + { + binInputParameters: ['-a', 'spec/artifacts/empty.handlebars'], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/empty.amd.js' + }, + { + binInputParameters: [ '-a', + '-f', + 'TEST_OUTPUT', 'spec/artifacts/empty.handlebars' - ); + ], + outputLocation: 'TEST_OUTPUT', + expectedOutputSpec: './spec/expected/empty.amd.js' + }, + { + binInputParameters: [ + '-a', + '-n', + 'CustomNamespace.templates', + 'spec/artifacts/empty.handlebars' + ], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/empty.amd.namespace.js' + }, + { + binInputParameters: [ + '-a', + '--namespace', + 'CustomNamespace.templates', + 'spec/artifacts/empty.handlebars' + ], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/empty.amd.namespace.js' + }, + { + binInputParameters: ['-a', '-s', 'spec/artifacts/empty.handlebars'], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/empty.amd.simple.js' + }, + { + binInputParameters: ['-a', '-m', 'spec/artifacts/empty.handlebars'], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/empty.amd.min.js' + }, + { + binInputParameters: [ + 'spec/artifacts/known.helpers.handlebars', + '-a', + '-k', + 'someHelper', + '-k', + 'anotherHelper', + '-o' + ], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/non.empty.amd.known.helper.js' + }, + { + binInputParameters: ['--help'], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/help.menu.txt' + }, + { + binInputParameters: ['-v'], + outputLocation: 'stdout', + expectedOutput: require('../package.json').version + }, + { + binInputParameters: [ + '-a', + '-e', + 'hbs', + './spec/artifacts/non.default.extension.hbs' + ], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/non.default.extension.amd.js' + }, + { + binInputParameters: [ + '-a', + '-p', + './spec/artifacts/partial.template.handlebars' + ], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/partial.template.js' + }, + { + binInputParameters: ['spec/artifacts/empty.handlebars', '-c'], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/empty.common.js' + }, + { + binInputParameters: [ + 'spec/artifacts/empty.handlebars', + 'spec/artifacts/empty.handlebars', + '-a', + '-n', + 'someNameSpace' + ], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/namespace.amd.js' + }, + { + binInputParameters: [ + 'spec/artifacts/empty.handlebars', + '-h', + 'some-path/', + '-a' + ], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/handlebar.path.amd.js' + }, + { + binInputParameters: [ + 'spec/artifacts/partial.template.handlebars', + '-r', + 'spec', + '-a' + ], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/empty.root.amd.js' + }, + { + binInputParameters: [ + '-i', + '
1
', + '-i', + '
2
', + '-N', + 'firstTemplate', + '-N', + 'secondTemplate', + '-a' + ], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/empty.name.amd.js' + }, + { + binInputParameters: [ + '-i', + '
1
', + '-a', + '-m', + '-N', + 'test', + '--map', + './spec/artifacts/source.map.amd.txt' + ], + outputLocation: 'stdout', + expectedOutputSpec: './spec/expected/source.map.amd.js' + } +]; - const expectedOutput = fs.readFileSync( - './spec/expected/empty.amd.js', - 'utf-8' - ); +module.exports = function(grunt) { + grunt.registerTask('test:bin', function() { + testCases.forEach( + ({ + binInputParameters, + outputLocation, + expectedOutputSpec, + expectedOutput + }) => { + const stdout = executeBinHandlebars(...binInputParameters); + + if (!expectedOutput && expectedOutputSpec) { + expectedOutput = fs.readFileSync(expectedOutputSpec, 'utf-8'); + } - const normalizedOutput = normalizeCrlf(stdout); - const normalizedExpectedOutput = normalizeCrlf(expectedOutput); + const useStdout = outputLocation === 'stdout'; + const normalizedOutput = normalizeCrlf( + useStdout ? stdout : fs.readFileSync(outputLocation, 'utf-8') + ); + const normalizedExpectedOutput = normalizeCrlf(expectedOutput); - expect(normalizedOutput).not.to.be.differentFrom(normalizedExpectedOutput); + if (!useStdout) { + fs.unlinkSync(outputLocation); + } + + expect(normalizedOutput).not.to.be.differentFrom( + normalizedExpectedOutput, + { + relaxedSpace: true + } + ); + } + ); }); };