From ca3b4d3f00d7e331cbeb8ecc9641d31b507d3150 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Wed, 31 Oct 2018 16:07:47 +1100 Subject: [PATCH] add async/nothrow variants of typeforce, with docs and tests --- README.md | 25 +++++++++++++++++++++++++ async.js | 17 +++++++++++++++++ index.js | 15 --------------- nothrow.js | 12 ++++++++++++ test/index.js | 24 ++++++++++++++++++++---- 5 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 async.js create mode 100644 nothrow.js diff --git a/README.md b/README.md index 74392c3..85a5aa2 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,31 @@ typeforce(typeforce.quacksLike('Foo'), new (function Foo() {})) // OK! ``` +**Pro**tips (no throw) +``` javascript +var typeforce = require('typeforce/nothrow') +var value = 'foobar' + +if (typeforce(typeforce.Number, value)) { + // didn't throw! + console.log(`${value} is a number`) // never happens +} else { + console.log(`Oops, ${typeforce.error.message}`) + // prints 'Oops, Expected Number, got String foobar' +} +``` + +**Pro**tips (async) +``` +var typeforce = require('typeforce/async') + +typeforce(typeforce.Number, value, function (err) { + if (err) return console.log(`Oops, ${typeforce.error.message}`) + + console.log(`${value} is a number`) // never happens +}) +``` + **WARNING**: Be very wary of using the `quacksLike` type, as it relies on the `Foo.name` property. If that property is mangled by a transpiler, such as `uglifyjs`, you will have a bad time. diff --git a/async.js b/async.js new file mode 100644 index 0000000..f891c8d --- /dev/null +++ b/async.js @@ -0,0 +1,17 @@ +var typeforce = require('./') + +// async wrapper +function tfAsync (type, value, strict, callback) { + // default to falsy strict if using shorthand overload + if (typeof strict === 'function') return tfAsync(type, value, false, strict) + + try { + typeforce(type, value, strict) + } catch (e) { + return callback(e) + } + + callback() +} + +module.exports = Object.assign(tfAsync, typeforce) diff --git a/index.js b/index.js index 75cd41c..c068cd6 100644 --- a/index.js +++ b/index.js @@ -230,21 +230,6 @@ for (typeName in EXTRA) { typeforce[typeName] = EXTRA[typeName] } -// async wrapper -function __async (type, value, strict, callback) { - // default to falsy strict if using shorthand overload - if (typeof strict === 'function') return __async(type, value, false, strict) - - try { - typeforce(type, value, strict) - } catch (e) { - return callback(e) - } - - callback() -} - -typeforce.async = __async typeforce.compile = compile typeforce.TfTypeError = TfTypeError typeforce.TfPropertyTypeError = TfPropertyTypeError diff --git a/nothrow.js b/nothrow.js new file mode 100644 index 0000000..ff5e7bf --- /dev/null +++ b/nothrow.js @@ -0,0 +1,12 @@ +var typeforce = require('./') + +function tfNoThrow (type, value, strict) { + try { + return typeforce(type, value, strict) + } catch (e) { + tfNoThrow.error = e + return false + } +} + +module.exports = Object.assign(tfNoThrow, typeforce) diff --git a/test/index.js b/test/index.js index 5b72b56..4d96714 100644 --- a/test/index.js +++ b/test/index.js @@ -1,5 +1,7 @@ var tape = require('tape') var typeforce = require('../') +var typeforceAsync = require('../async') +var typeforceNoThrow = require('../nothrow') var fixtures = require('./fixtures') var TYPES = require('./types') var VALUES = require('./values') @@ -12,12 +14,14 @@ fixtures.valid.forEach(function (f) { var compiled = typeforce.compile(type) tape('passes ' + typeDescription + ' with ' + valueDescription, function (t) { - t.plan(4) + t.plan(6) t.doesNotThrow(function () { typeforce(type, value, f.strict) }) - typeforce.async(type, value, f.strict, t.ifErr) + typeforceAsync(type, value, f.strict, t.ifErr) + t.equal(typeforceNoThrow(type, value, f.strict), true) t.doesNotThrow(function () { typeforce(compiled, value, f.strict) }) - typeforce.async(compiled, value, f.strict, t.ifErr) + typeforceAsync(compiled, value, f.strict, t.ifErr) + t.equal(typeforceNoThrow(compiled, value, f.strict), true) }) }) @@ -31,15 +35,27 @@ fixtures.invalid.forEach(function (f) { var compiled = typeforce.compile(type) tape('throws "' + f.exception + '" for type ' + typeDescription + ' with value of ' + valueDescription, function (t) { - t.plan(2) + t.plan(10) t.throws(function () { typeforce(type, value, f.strict) }, new RegExp(f.exception)) + typeforceAsync(type, value, f.strict, (err) => { + t.ok(err) + t.throws(function () { throw err }, new RegExp(f.exception)) + }) + t.equal(typeforceNoThrow(type, value, f.strict), false) + t.throws(function () { throw typeforceNoThrow.error }, new RegExp(f.exception)) t.throws(function () { typeforce(compiled, value, f.strict) }, new RegExp(f.exception)) + typeforceAsync(compiled, value, f.strict, (err) => { + t.ok(err) + t.throws(function () { throw err }, new RegExp(f.exception)) + }) + t.equal(typeforceNoThrow(compiled, value, f.strict), false) + t.throws(function () { throw typeforceNoThrow.error }, new RegExp(f.exception)) }) })