[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