From a22f6a55ae65ca3675f7c97a030560e91d5b4d1f Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Sun, 9 Sep 2018 19:43:43 -0400 Subject: js: update api, add luigi-compat.js and test/compat --- js/README.mkd | 28 +++++++-------- js/luigi-compat.js | 12 +++++++ js/luigi-template.js | 11 +----- js/test/cache.js | 8 ++--- js/test/compat/cache.js | 58 +++++++++++++++++++++++++++++++ js/test/compat/default-filters.js | 73 +++++++++++++++++++++++++++++++++++++++ js/test/compat/errors.js | 34 ++++++++++++++++++ js/test/compat/filters.js | 59 +++++++++++++++++++++++++++++++ js/test/compat/template.js | 33 ++++++++++++++++++ js/test/compat/test.html | 29 ++++++++++++++++ js/test/default-filters.js | 2 +- js/test/errors.js | 6 ++-- js/test/filters.js | 12 +++---- js/test/template.js | 8 ++--- 14 files changed, 331 insertions(+), 42 deletions(-) create mode 100644 js/luigi-compat.js create mode 100644 js/test/compat/cache.js create mode 100644 js/test/compat/default-filters.js create mode 100644 js/test/compat/errors.js create mode 100644 js/test/compat/filters.js create mode 100644 js/test/compat/template.js create mode 100644 js/test/compat/test.html diff --git a/js/README.mkd b/js/README.mkd index 83eabe4..423024b 100644 --- a/js/README.mkd +++ b/js/README.mkd @@ -20,7 +20,7 @@ Usage A minimal template: // create template - var t = new LuigiTemplate('hello %{name}'); + var t = new Luigi.Template('hello %{name}'); // run template, print result to console console.log(t.run({ @@ -30,10 +30,10 @@ A minimal template: // prints "hello Paul" If you have a template that you only need to run one time, you can use -the `LuigiTemplate.run()` singleton to run it, like this: +the `Luigi.run()` singleton to run it, like this: // create and run template in one shot - var r = LuigiTemplate.run('hello %{name}', { + var r = Luigi.run('hello %{name}', { name: 'Paul', }); @@ -50,7 +50,7 @@ Here is the template from above, with the name value HTML-escaped using a built-in filter: // create template that prints hello and the HTML-escaped name - var t = new LuigiTemplate('hello %{name | h}'); + var t = new Luigi.Template('hello %{name | h}'); // run template, print result to console console.log(t.run({ @@ -74,15 +74,15 @@ The built-in templates are: You can create your own custom filters, too. The easiest way to create your own custom filter is to add it to the set -of global filters (`LuigiTemplate.FILTERS`), like so: +of global filters (`Luigi.FILTERS`), like so: // add global template filter - LuigiTemplate.FILTERS.barify = function(s) { + Luigi.FILTERS.barify = function(s) { return 'bar-' + s + '-bar'; }; // create template that uses custom global filter - var t = new LuigiTemplate('hello %{name | barify | h}'); + var t = new Luigi.Template('hello %{name | barify | h}'); // run template, print result to console console.log(t.run({ @@ -93,10 +93,10 @@ of global filters (`LuigiTemplate.FILTERS`), like so: You can also create a custom filter and limit it to a particular template by passing a custom filter hash as the second parameter to the -`LuigiTemplate` constructor, like this: +`Luigi.Template` constructor, like this: // create template with custom template-specific filter - var t = new LuigiTemplate('hello %{name | barify | h}', { + var t = new Luigi.Template('hello %{name | barify | h}', { barify: function(s) { return 'bar-' + s + '-bar'; }, @@ -113,7 +113,7 @@ You can pass arguments to your custom filters. Here's an example: // create template with custom template-specific filter named // "wrap", which wraps the value in the given filter parameters - var t = new LuigiTemplate('hello %{name | wrap head tail | h}', { + var t = new Luigi.Template('hello %{name | wrap head tail | h}', { wrap: function(s, args) { if (args.length == 2) { return [args[0], s, args[1]].join('-'; @@ -143,7 +143,7 @@ that running a template from the cache is fast too. Here's how you create a template cache: // create template cache with a single template - var cache = LuigiTemplate.cache({ + var cache = Luigi.cache({ hello: 'hello %{name | uc | h}' }); @@ -158,7 +158,7 @@ Template caches use their own set of custom filters by passing a custom filter hash when creating a template cache: // create template cache with a custom filter named "reverse" - var cache = LuigiTemplate.cache({ + var cache = Luigi.cache({ hello: 'hello %{name | uc | reverse | h}' }, { reverse: function(s) { @@ -179,14 +179,14 @@ A template cache is also a convenient way to group all of the templates in a script together: // add global filter named "reverse" - LuigiTemplate.FILTERS.reverse = function(s) { + Luigi.FILTERS.reverse = function(s) { var cs = (s || '').split(''); cs.reverse(); return cs.join(''); }; // create template cache - var TEMPLATES = LuigiTemplate.cache({ + var TEMPLATES = Luigi.cache({ upper: 'hello %{name | uc | h}', reverse: 'hello %{name | reverse | h}', }); diff --git a/js/luigi-compat.js b/js/luigi-compat.js new file mode 100644 index 0000000..c4bcc1a --- /dev/null +++ b/js/luigi-compat.js @@ -0,0 +1,12 @@ +'use strict'; + +/** + * Include this file to maintain compatibility with older (pre-0.4.2) + * versions of Luigi Template. + */ +var LuigiTemplate = Luigi.Template; +LuigiTemplate.prototype.Cache = Luigi.Cache; +LuigiTemplate.run = Luigi.run; +LuigiTemplate.FILTERS = Luigi.FILTERS; +LuigiTemplate.Cache = Luigi.Cache; +LuigiTemplate.cache = Luigi.cache; diff --git a/js/luigi-template.js b/js/luigi-template.js index 6ecd8e1..8fcf646 100644 --- a/js/luigi-template.js +++ b/js/luigi-template.js @@ -10,8 +10,7 @@ */ /** - * Template object. - * @class + * Luigi Template namespace. */ var Luigi = (function() { "use strict"; @@ -369,11 +368,3 @@ var Luigi = (function() { // expose interface return Luigi; }()); - -// backwards compatibility -var LuigiTemplate = Luigi.Template; -LuigiTemplate.prototype.Cache = Luigi.Cache; -LuigiTemplate.run = Luigi.run; -LuigiTemplate.FILTERS = Luigi.FILTERS; -LuigiTemplate.Cache = Luigi.Cache; -LuigiTemplate.cache = Luigi.cache; diff --git a/js/test/cache.js b/js/test/cache.js index 22490c1..9395223 100644 --- a/js/test/cache.js +++ b/js/test/cache.js @@ -3,7 +3,7 @@ var assert = chai.assert; it('cache', function() { - var cache = new LuigiTemplate.Cache({ + var cache = new Luigi.Cache({ foo: 'foo%{bar}', }); @@ -15,7 +15,7 @@ }); it('cache with array', function() { - var cache = new LuigiTemplate.Cache({ + var cache = new Luigi.Cache({ foo: ['foo%{bar}'], }); @@ -27,7 +27,7 @@ }); it('cache singleton', function() { - var cache = LuigiTemplate.cache({ + var cache = Luigi.cache({ foo: 'foo%{bar}', }); @@ -40,7 +40,7 @@ it('cache with custom filters', function() { - var cache = LuigiTemplate.cache({ + var cache = Luigi.cache({ foo: ['foo%{bar | cache-barify}'], }, { 'cache-barify': function(s) { diff --git a/js/test/compat/cache.js b/js/test/compat/cache.js new file mode 100644 index 0000000..22490c1 --- /dev/null +++ b/js/test/compat/cache.js @@ -0,0 +1,58 @@ +(function() { + 'use strict'; + var assert = chai.assert; + + it('cache', function() { + var cache = new LuigiTemplate.Cache({ + foo: 'foo%{bar}', + }); + + var r = cache.run('foo', { + bar: 'foo', + }); + + assert.equal(r, 'foofoo'); + }); + + it('cache with array', function() { + var cache = new LuigiTemplate.Cache({ + foo: ['foo%{bar}'], + }); + + var r = cache.run('foo', { + bar: 'foo', + }); + + assert.equal(r, 'foofoo'); + }); + + it('cache singleton', function() { + var cache = LuigiTemplate.cache({ + foo: 'foo%{bar}', + }); + + var r = cache.run('foo', { + bar: 'foo', + }); + + assert.equal(r, 'foofoo'); + }); + + + it('cache with custom filters', function() { + var cache = LuigiTemplate.cache({ + foo: ['foo%{bar | cache-barify}'], + }, { + 'cache-barify': function(s) { + return 'bar-' + s + '-bar'; + }, + }); + + // run template from cache, get result + var r = cache.run('foo', { + bar: 'foo', + }); + + assert.equal(r, 'foobar-foo-bar'); + }); +})(); diff --git a/js/test/compat/default-filters.js b/js/test/compat/default-filters.js new file mode 100644 index 0000000..f897485 --- /dev/null +++ b/js/test/compat/default-filters.js @@ -0,0 +1,73 @@ +(function() { + 'use strict'; + var assert = chai.assert; + + [{ + filter: 'uc', + template: 'foo%{bar|uc}', + args: { + bar: 'foo', + }, + expect: 'fooFOO', + }, { + filter: 'lc', + template: 'foo%{bar|lc}', + args: { + bar: 'FOO' + }, + expect: 'foofoo', + }, { + filter: 'h', + template: '%{bar|h}', + args: { + bar: '<>&"\'', + }, + expect: '<>&"'', + }, { + filter: 'u', + template: '%{bar|u}', + args: { + bar: 'asdf<>&"\' \u000f', + }, + expect: 'asdf%3C%3E%26%22%27+%0F' + }, { + filter: 'json', + template: '%{bar|json}', + args: { + bar: { + true: true, + false: false, + null: null, + number: 5, + string: 'foo', + hash: { 'foo': 'bar' }, + array: [0, 1], + }, + }, + expect: '{"true":true,"false":false,"null":null,"number":5,"string":"foo","hash":{"foo":"bar"},"array":[0,1]}', + }, { + filter: 'trim', + template: '%{bar|trim}', + args: { bar: ' \t\v\r\nfoo \t\v\r\n' }, + expect: 'foo' + }, { + filter: 's', + template: 'one foo%{foo|s}, two bar%{bar|s}', + args: { + foo: 1, + bar: 2, + }, + expect: 'one foo, two bars' + }, { + filter: 'length', + template: 'length of bar: %{bar|length}', + args: { + bar: [0, 1, 2], + }, + expect: 'length of bar: 3' + }].forEach(function(row) { + it('default filter: ' + row.filter, function() { + assert.equal(LuigiTemplate.run(row.template, row.args), row.expect); + }); + }); +})(); diff --git a/js/test/compat/errors.js b/js/test/compat/errors.js new file mode 100644 index 0000000..3ce96d5 --- /dev/null +++ b/js/test/compat/errors.js @@ -0,0 +1,34 @@ +(function() { + 'use strict'; + var assert = chai.assert; + + it('unknown key error', function() { + assert.throws(function() { + var r = LuigiTemplate.run('foo%{unknown-key}', { + bar: 'foo', + }); + }, Error, /^unknown key/); + }); + + it('unknown filter error', function() { + assert.throws(function() { + var r = LuigiTemplate.run('foo%{bar | unknown-filter}', { + bar: 'foo', + }); + }, Error, /^unknown filter/); + }); + + it('unknown template error', function() { + assert.throws(function() { + var cache = new LuigiTemplate.Cache({ + foo: [ + 'foo%{bar}', + ], + }); + + var r = cache.run('unknown-template', { + bar: 'foo', + }); + }, Error, /^unknown template/); + }); +})(); diff --git a/js/test/compat/filters.js b/js/test/compat/filters.js new file mode 100644 index 0000000..c9ba21a --- /dev/null +++ b/js/test/compat/filters.js @@ -0,0 +1,59 @@ +(function() { + 'use strict'; + var assert = chai.assert; + + it('filter', function() { + var t = new LuigiTemplate('foo%{bar|h}'), + r = t.run({ bar: '<' }); + + assert.equal(r, 'foo<'); + }); + + it('filter chain', function() { + var r = LuigiTemplate.run('foo%{bar|uc|lc}', { + bar: 'foo' + }); + + assert.equal(r, 'foofoo'); + }); + + it('custom global filter', function() { + LuigiTemplate.FILTERS.barify = function(s) { + return 'bar-' + s + '-bar'; + }; + + var r = LuigiTemplate.run('foo%{bar | barify}', { + bar: 'foo' + }); + + assert.equal(r, 'foobar-foo-bar'); + }); + + it('custom template filter', function() { + var r = LuigiTemplate.run('foo%{bar | barify}', { + bar: 'foo' + }, { + barify: function(s) { + return 'bar-' + s + '-bar'; + }, + }); + + assert.equal(r, 'foobar-foo-bar'); + }); + + it('filter args', function() { + var r = LuigiTemplate.run('foo%{bar | wrap bar}', { + bar: 'foo' + }, { + wrap: function(s, args) { + if (args.length == 1) { + return [args[0], s, args[0]].join('-'); + } else { + return s; + } + }, + }); + + assert.equal(r, 'foobar-foo-bar'); + }); +})(); diff --git a/js/test/compat/template.js b/js/test/compat/template.js new file mode 100644 index 0000000..9a0018f --- /dev/null +++ b/js/test/compat/template.js @@ -0,0 +1,33 @@ +(function() { + 'use strict'; + var assert = chai.assert; + + it('run', function() { + var t = new LuigiTemplate('foo%{bar}'), + r = t.run({ bar: 'foo' }); + + assert.equal(r, 'foofoo'); + }); + + it('run singleton', function() { + var r = LuigiTemplate.run('foo%{bar}', { bar: 'foo' }); + + assert.equal(r, 'foofoo'); + }); + + it('run with multiple keys', function() { + var r = LuigiTemplate.run('foo%{bar}%{baz}', { + bar: 'foo', + baz: 'foo', + }); + + assert.equal(r, 'foofoofoo'); + }); + + it('run with whitespace around key', function() { + var s = "%{ \t\v\r\nbar}%{ \t\v\r\nbar \t\v\r\n}%{bar \t\v\r\n}", + r = LuigiTemplate.run(s, { bar: 'foo' }); + + assert.equal(r, 'foofoofoo'); + }); +})(); diff --git a/js/test/compat/test.html b/js/test/compat/test.html new file mode 100644 index 0000000..6254e4c --- /dev/null +++ b/js/test/compat/test.html @@ -0,0 +1,29 @@ + + + + + Luigi Template Compatibility Mocha Tests + + + + +
+ + + + + + + + + + + + + + + + diff --git a/js/test/default-filters.js b/js/test/default-filters.js index f897485..26b4a44 100644 --- a/js/test/default-filters.js +++ b/js/test/default-filters.js @@ -67,7 +67,7 @@ expect: 'length of bar: 3' }].forEach(function(row) { it('default filter: ' + row.filter, function() { - assert.equal(LuigiTemplate.run(row.template, row.args), row.expect); + assert.equal(Luigi.run(row.template, row.args), row.expect); }); }); })(); diff --git a/js/test/errors.js b/js/test/errors.js index 3ce96d5..467a6c3 100644 --- a/js/test/errors.js +++ b/js/test/errors.js @@ -4,7 +4,7 @@ it('unknown key error', function() { assert.throws(function() { - var r = LuigiTemplate.run('foo%{unknown-key}', { + var r = Luigi.run('foo%{unknown-key}', { bar: 'foo', }); }, Error, /^unknown key/); @@ -12,7 +12,7 @@ it('unknown filter error', function() { assert.throws(function() { - var r = LuigiTemplate.run('foo%{bar | unknown-filter}', { + var r = Luigi.run('foo%{bar | unknown-filter}', { bar: 'foo', }); }, Error, /^unknown filter/); @@ -20,7 +20,7 @@ it('unknown template error', function() { assert.throws(function() { - var cache = new LuigiTemplate.Cache({ + var cache = new Luigi.Cache({ foo: [ 'foo%{bar}', ], diff --git a/js/test/filters.js b/js/test/filters.js index c9ba21a..9bf1a1c 100644 --- a/js/test/filters.js +++ b/js/test/filters.js @@ -3,14 +3,14 @@ var assert = chai.assert; it('filter', function() { - var t = new LuigiTemplate('foo%{bar|h}'), + var t = new Luigi.Template('foo%{bar|h}'), r = t.run({ bar: '<' }); assert.equal(r, 'foo<'); }); it('filter chain', function() { - var r = LuigiTemplate.run('foo%{bar|uc|lc}', { + var r = Luigi.run('foo%{bar|uc|lc}', { bar: 'foo' }); @@ -18,11 +18,11 @@ }); it('custom global filter', function() { - LuigiTemplate.FILTERS.barify = function(s) { + Luigi.FILTERS.barify = function(s) { return 'bar-' + s + '-bar'; }; - var r = LuigiTemplate.run('foo%{bar | barify}', { + var r = Luigi.run('foo%{bar | barify}', { bar: 'foo' }); @@ -30,7 +30,7 @@ }); it('custom template filter', function() { - var r = LuigiTemplate.run('foo%{bar | barify}', { + var r = Luigi.run('foo%{bar | barify}', { bar: 'foo' }, { barify: function(s) { @@ -42,7 +42,7 @@ }); it('filter args', function() { - var r = LuigiTemplate.run('foo%{bar | wrap bar}', { + var r = Luigi.run('foo%{bar | wrap bar}', { bar: 'foo' }, { wrap: function(s, args) { diff --git a/js/test/template.js b/js/test/template.js index 9a0018f..a364c61 100644 --- a/js/test/template.js +++ b/js/test/template.js @@ -3,20 +3,20 @@ var assert = chai.assert; it('run', function() { - var t = new LuigiTemplate('foo%{bar}'), + var t = new Luigi.Template('foo%{bar}'), r = t.run({ bar: 'foo' }); assert.equal(r, 'foofoo'); }); it('run singleton', function() { - var r = LuigiTemplate.run('foo%{bar}', { bar: 'foo' }); + var r = Luigi.run('foo%{bar}', { bar: 'foo' }); assert.equal(r, 'foofoo'); }); it('run with multiple keys', function() { - var r = LuigiTemplate.run('foo%{bar}%{baz}', { + var r = Luigi.run('foo%{bar}%{baz}', { bar: 'foo', baz: 'foo', }); @@ -26,7 +26,7 @@ it('run with whitespace around key', function() { var s = "%{ \t\v\r\nbar}%{ \t\v\r\nbar \t\v\r\n}%{bar \t\v\r\n}", - r = LuigiTemplate.run(s, { bar: 'foo' }); + r = Luigi.run(s, { bar: 'foo' }); assert.equal(r, 'foofoofoo'); }); -- cgit v1.2.3