[Pkg-javascript-commits] [aproba] 01/10: Import Upstream version 1.0.4
Ross Gammon
ross-guest at moszumanska.debian.org
Tue Jan 31 19:05:00 UTC 2017
This is an automated email from the git hooks/post-receive script.
ross-guest pushed a commit to branch master
in repository aproba.
commit 4784660d5c6b9781d6a8c2f481aae3a411faf2b2
Author: Tushar Agey <agey.tushar3 at gmail.com>
Date: Thu Jan 5 09:38:07 2017 +0000
Import Upstream version 1.0.4
---
.gitignore | 3 +++
LICENSE | 14 ++++++++++
README.md | 59 ++++++++++++++++++++++++++++++++++++++++
index.js | 62 ++++++++++++++++++++++++++++++++++++++++++
package.json | 31 +++++++++++++++++++++
test/index.js | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 256 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2400189
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*~
+node_modules
+.#*
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f4be44d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,14 @@
+Copyright (c) 2015, Rebecca Turner <me at re-becca.org>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8246a9c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,59 @@
+aproba
+======
+
+A ridiculously light-weight function argument validator
+
+```
+var validate = require("aproba")
+
+function myfunc(a, b, c) {
+ // `a` must be a string, `b` a number, `c` a function
+ validate('SNF', arguments) // [a,b,c] is also valid
+}
+
+myfunc('test', 23, function () {}) // ok
+myfunc(123, 23, function () {}) // type error
+myfunc('test', 23) // missing arg error
+myfunc('test', 23, function () {}, true) // too many args error
+
+```
+
+Valid types are:
+
+type | description
+---- | -----------
+* | matches any type
+A | Array.isArray OR an arguments object
+S | typeof == string
+N | typeof == number
+F | typeof == function
+O | typeof == object and not type A and not type E
+B | typeof == boolean
+E | instanceof Error OR null
+
+Validation failures throw one of three exception types, distinguished by a
+`code` property of `EMISSINGARG`, `EINVALIDTYPE` or `ETOOMANYARGS`.
+
+If you pass in an invalid type then it will throw with a code of
+`EUNKNOWNTYPE`.
+
+If an error argument is found and is not null then the remaining arguments
+will not be validated.
+
+### Why this exists
+
+I wanted a very simple argument validator. It needed to do two things:
+
+1. Be more concise and easier to use than assertions
+
+2. Not encourage an infinite bikeshed of DSLs
+
+This is why types are specified by a single character and there's no such
+thing as an optional argument.
+
+This is not intended to validate user data. This is specifically about
+asserting the interface of your functions.
+
+If you need greater validation, I encourage you to write them by hand or
+look elsewhere.
+
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..bb5ac3c
--- /dev/null
+++ b/index.js
@@ -0,0 +1,62 @@
+'use strict'
+
+function isArguments (thingy) {
+ return typeof thingy === 'object' && thingy.hasOwnProperty('callee')
+}
+
+var types = {
+ '*': ['any', function () { return true }],
+ A: ['array', function (thingy) { return Array.isArray(thingy) || isArguments(thingy) }],
+ S: ['string', function (thingy) { return typeof thingy === 'string' }],
+ N: ['number', function (thingy) { return typeof thingy === 'number' }],
+ F: ['function', function (thingy) { return typeof thingy === 'function' }],
+ O: ['object', function (thingy) { return typeof thingy === 'object' && !types.A[1](thingy) && !types.E[1](thingy) }],
+ B: ['boolean', function (thingy) { return typeof thingy === 'boolean' }],
+ E: ['error', function (thingy) { return thingy instanceof Error }]
+}
+
+var validate = module.exports = function (schema, args) {
+ if (!schema) throw missingRequiredArg(0, 'schema')
+ if (!args) throw missingRequiredArg(1, 'args')
+ if (!types.S[1](schema)) throw invalidType(0, 'string', schema)
+ if (!types.A[1](args)) throw invalidType(1, 'array', args)
+ for (var ii = 0; ii < schema.length; ++ii) {
+ var type = schema[ii]
+ if (!types[type]) throw unknownType(ii, type)
+ var typeLabel = types[type][0]
+ var typeCheck = types[type][1]
+ if (type === 'E' && args[ii] == null) continue
+ if (args[ii] == null) throw missingRequiredArg(ii)
+ if (!typeCheck(args[ii])) throw invalidType(ii, typeLabel, args[ii])
+ if (type === 'E') return
+ }
+ if (schema.length < args.length) throw tooManyArgs(schema.length, args.length)
+}
+
+function missingRequiredArg (num) {
+ return newException('EMISSINGARG', 'Missing required argument #' + (num + 1))
+}
+
+function unknownType (num, type) {
+ return newException('EUNKNOWNTYPE', 'Unknown type ' + type + ' in argument #' + (num + 1))
+}
+
+function invalidType (num, expectedType, value) {
+ var valueType
+ Object.keys(types).forEach(function (typeCode) {
+ if (types[typeCode][1](value)) valueType = types[typeCode][0]
+ })
+ return newException('EINVALIDTYPE', 'Argument #' + (num + 1) + ': Expected ' +
+ expectedType + ' but got ' + valueType)
+}
+
+function tooManyArgs (expected, got) {
+ return newException('ETOOMANYARGS', 'Too many arguments, expected ' + expected + ' and got ' + got)
+}
+
+function newException (code, msg) {
+ var e = new Error(msg)
+ e.code = code
+ Error.captureStackTrace(e, validate)
+ return e
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..61eacd9
--- /dev/null
+++ b/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "aproba",
+ "version": "1.0.4",
+ "description": "A rediculously light-weight argument validator",
+ "main": "index.js",
+ "directories": {
+ "test": "test"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "standard": "^7.1.2",
+ "tap": "^5.7.3"
+ },
+ "scripts": {
+ "test": "standard && tap test/*.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/iarna/aproba"
+ },
+ "keywords": [
+ "argument",
+ "validate"
+ ],
+ "author": "Rebecca Turner <me at re-becca.org>",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/iarna/aproba/issues"
+ },
+ "homepage": "https://github.com/iarna/aproba"
+}
diff --git a/test/index.js b/test/index.js
new file mode 100644
index 0000000..b96fd42
--- /dev/null
+++ b/test/index.js
@@ -0,0 +1,87 @@
+'use strict'
+var test = require('tap').test
+var validate = require('../index.js')
+
+function thrown (t, code, msg, todo) {
+ validate('OSSF', arguments)
+ try {
+ todo()
+ t.fail(msg)
+ } catch (e) {
+ t.is(e.code, code, msg + e.message)
+ }
+}
+
+function notThrown (t, msg, todo) {
+ validate('OSF', arguments)
+ try {
+ todo()
+ t.pass(msg)
+ } catch (e) {
+ t.fail(msg + '\n' + e.stack)
+ }
+}
+
+test('general', function (t) {
+ t.plan(70)
+ var values = {
+ 'A': [],
+ 'S': 'test',
+ 'N': 123,
+ 'F': function () {},
+ 'O': {},
+ 'B': false,
+ 'E': new Error()
+ }
+ Object.keys(values).forEach(function (type) {
+ Object.keys(values).forEach(function (contraType) {
+ if (type === contraType) {
+ notThrown(t, type + ' matches ' + contraType, function () {
+ validate(type, [values[contraType]])
+ })
+ } else {
+ thrown(t, 'EINVALIDTYPE', type + ' does not match ' + contraType, function () {
+ validate(type, [values[contraType]])
+ })
+ }
+ })
+ if (type === 'E') {
+ notThrown(t, 'null is ok for E', function () {
+ validate(type, [null])
+ })
+ } else {
+ thrown(t, 'EMISSINGARG', 'null not ok for ' + type, function () {
+ validate(type, [null])
+ })
+ }
+ })
+ Object.keys(values).forEach(function (contraType) {
+ notThrown(t, '* matches ' + contraType, function () {
+ validate('*', [values[contraType]])
+ })
+ })
+ thrown(t, 'EMISSINGARG', 'not enough args', function () {
+ validate('SNF', ['abc', 123])
+ })
+ thrown(t, 'ETOOMANYARGS', 'too many args', function () {
+ validate('SNF', ['abc', 123, function () {}, true])
+ })
+ notThrown(t, 'E matches null', function () {
+ validate('E', [null])
+ })
+ notThrown(t, 'E matches undefined', function () {
+ validate('E', [undefined])
+ })
+ notThrown(t, 'E w/ error requires nothing else', function () {
+ validate('ESN', [new Error(), 'foo'])
+ })
+ thrown(t, 'EMISSINGARG', 'E w/o error works as usual', function () {
+ validate('ESN', [null, 'foo'])
+ })
+ try {
+ validate('O', [[]])
+ t.fail('object != array')
+ } catch (ex) {
+ t.match(ex.message, /Expected object but got array/, 'When reporting non-objects, uses aproba types')
+ }
+})
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/aproba.git
More information about the Pkg-javascript-commits
mailing list