diff --git a/README.md b/README.md index 681792c..bb31b89 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ console.log(template.parameters); // Prints [{ key: "foo" }] console.log(template({ foo: "bar" })); // Prints "bar" ``` -Parameters can have default values, specified using a colon. These come into play when the parameter is either `undefined` or `null`. +Parameters can have default values, specified using a colon. These come into play only when the parameter is `undefined`. ```js const template = parse("{{foo:bar}}"); diff --git a/index.js b/index.js index 538156f..c68df12 100644 --- a/index.js +++ b/index.js @@ -92,7 +92,8 @@ const parseString = (() => { return matches.reduce((result, match, i) => { const parameter = parameters[i]; let value = objectPath.get(context, parameter.key); - if (value == null) { + + if (typeof value === 'undefined') { value = parameter.defaultValue; } @@ -100,7 +101,7 @@ const parseString = (() => { value = value(); } - if (typeof value === 'object') { + if (typeof value === 'object' && value !== null) { return value; } diff --git a/test.js b/test.js index 8aaa199..4f4c2c6 100644 --- a/test.js +++ b/test.js @@ -326,6 +326,14 @@ describe('json-template', () => { }); }); + describe('date', () => { + it('should compute template with Date', () => { + const template = parse('{{now}}'); + const now = new Date(); + assert.strictEqual(template({ now }), now); + }); + }); + // This section tests that arbitrary types may be present // as leaf nodes of the object tree, and they are handled correctly. describe('unknown types', () => { @@ -595,26 +603,41 @@ describe('json-template', () => { }); }); - // This section tests that if the match is not found the template should be replaced by null + // This section tests that if the match is not found the template should remains undefined describe('no match on the given context', () => { - it('should replace the given template by null if no match found for an string', () => { + it('should replace the given template by undefined if no match found for an string', () => { const template = parse('{{foo}}'); - assert.equal(template({}), null); + assert.strictEqual(template({}), undefined); }); - it('should replace the given template by null if no match found for an object', () => { + it('should replace the given template by undefined if no match found for an object', () => { const template = parse({ boo: '{{foo}}' }); - assert.deepEqual(template({}), { boo: null }); + assert.deepStrictEqual(template({}), { boo: undefined }); }); it('should replace the given template by null if the found value is null', () => { const template = parse({ boo: '{{foo}}' }); - assert.deepEqual(template({ foo: null }), { boo: null }); - }); - - it('should handle multi-value expressions where the first value is null, but has a defaultValue', () => { - const template = parse({ boo: '{{foo.isNull:defaultValue}} {{foo.isNonNull}}' }); - assert.deepEqual(template({ foo: { isNull: null, isNonNull: 'value' } }), { boo: 'defaultValue value' }); + assert.deepStrictEqual(template({ foo: null }), { boo: null }); }); }); + + describe('string template', () => { + it('should be string type when there are more than one slots', () => { + const template = parse('{{foo}}{{bar}}'); + assert.equal(template({ foo: 1, bar: 'a' }), '1a'); + assert.equal(template({ bar: 'a' }), 'a'); + assert.equal(template({ foo: 1 }), '1'); + assert.equal(template({ foo: true, bar: false }), 'truefalse'); + assert.equal(template({ foo: undefined }), ''); + assert.equal(template({ foo: null }), ''); + assert.equal(template({}), ''); + assert.equal(template(), ''); + assert.equal(template({ foo: Number.NaN }), 'NaN'); + }); + + it('default value', () => { + const template = parse({ boo: '{{foo.isNull:null}} {{foo.isUndefined:undefined}} {{foo.isNonNull}}' }); + assert.deepStrictEqual(template({ foo: { isNull: null, isNonNull: 'value' } }), { boo: ' undefined value' }); + }); + }) });