Added remote folder

This commit is contained in:
Kasper Rynning-Tønnesen
2015-11-29 13:30:54 +01:00
parent 97e7dfd7c4
commit 95bb0c3919
3521 changed files with 331825 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
Copyright Node.js contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

View File

@@ -0,0 +1,68 @@
var assert = require('tap');
var t = require('./lib/util');
assert.equal(t.isArray([]), true);
assert.equal(t.isArray({}), false);
assert.equal(t.isBoolean(null), false);
assert.equal(t.isBoolean(true), true);
assert.equal(t.isBoolean(false), true);
assert.equal(t.isNull(null), true);
assert.equal(t.isNull(undefined), false);
assert.equal(t.isNull(false), false);
assert.equal(t.isNull(), false);
assert.equal(t.isNullOrUndefined(null), true);
assert.equal(t.isNullOrUndefined(undefined), true);
assert.equal(t.isNullOrUndefined(false), false);
assert.equal(t.isNullOrUndefined(), true);
assert.equal(t.isNumber(null), false);
assert.equal(t.isNumber('1'), false);
assert.equal(t.isNumber(1), true);
assert.equal(t.isString(null), false);
assert.equal(t.isString('1'), true);
assert.equal(t.isString(1), false);
assert.equal(t.isSymbol(null), false);
assert.equal(t.isSymbol('1'), false);
assert.equal(t.isSymbol(1), false);
assert.equal(t.isSymbol(Symbol()), true);
assert.equal(t.isUndefined(null), false);
assert.equal(t.isUndefined(undefined), true);
assert.equal(t.isUndefined(false), false);
assert.equal(t.isUndefined(), true);
assert.equal(t.isRegExp(null), false);
assert.equal(t.isRegExp('1'), false);
assert.equal(t.isRegExp(new RegExp()), true);
assert.equal(t.isObject({}), true);
assert.equal(t.isObject([]), true);
assert.equal(t.isObject(new RegExp()), true);
assert.equal(t.isObject(new Date()), true);
assert.equal(t.isDate(null), false);
assert.equal(t.isDate('1'), false);
assert.equal(t.isDate(new Date()), true);
assert.equal(t.isError(null), false);
assert.equal(t.isError({ err: true }), false);
assert.equal(t.isError(new Error()), true);
assert.equal(t.isFunction(null), false);
assert.equal(t.isFunction({ }), false);
assert.equal(t.isFunction(function() {}), true);
assert.equal(t.isPrimitive(null), true);
assert.equal(t.isPrimitive(''), true);
assert.equal(t.isPrimitive(0), true);
assert.equal(t.isPrimitive(new Date()), false);
assert.equal(t.isBuffer(null), false);
assert.equal(t.isBuffer({}), false);
assert.equal(t.isBuffer(new Buffer(0)), true);

View File

@@ -0,0 +1,340 @@
'use strict'
// Load modules
;
function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; }
var Url = require('url');
var Hoek = require('hoek');
var Cryptiles = require('cryptiles');
var Crypto = require('./crypto');
var Utils = require('./utils');
// Declare internals
var internals = {};
// Generate an Authorization header for a given request
/*
uri: 'http://example.com/resource?a=b' or object from Url.parse()
method: HTTP verb (e.g. 'GET', 'POST')
options: {
// Required
credentials: {
id: 'dh37fgj492je',
key: 'aoijedoaijsdlaksjdl',
algorithm: 'sha256' // 'sha1', 'sha256'
},
// Optional
ext: 'application-specific', // Application specific data sent via the ext attribute
timestamp: Date.now(), // A pre-calculated timestamp
nonce: '2334f34f', // A pre-generated nonce
localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided)
contentType: 'application/json', // Payload content-type (ignored if hash provided)
hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash
app: '24s23423f34dx', // Oz application id
dlg: '234sz34tww3sd' // Oz delegated-by application id
}
*/
exports.header = function (uri, method, options) {
var result = {
field: '',
artifacts: {}
};
// Validate inputs
if (!uri || typeof uri !== 'string' && (typeof uri === 'undefined' ? 'undefined' : _typeof(uri)) !== 'object' || !method || typeof method !== 'string' || !options || (typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
result.err = 'Invalid argument type';
return result;
}
// Application time
var timestamp = options.timestamp || Utils.nowSecs(options.localtimeOffsetMsec);
// Validate credentials
var credentials = options.credentials;
if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) {
result.err = 'Invalid credential object';
return result;
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
result.err = 'Unknown algorithm';
return result;
}
// Parse URI
if (typeof uri === 'string') {
uri = Url.parse(uri);
}
// Calculate signature
var artifacts = {
ts: timestamp,
nonce: options.nonce || Cryptiles.randomString(6),
method: method,
resource: uri.pathname + (uri.search || ''), // Maintain trailing '?'
host: uri.hostname,
port: uri.port || (uri.protocol === 'http:' ? 80 : 443),
hash: options.hash,
ext: options.ext,
app: options.app,
dlg: options.dlg
};
result.artifacts = artifacts;
// Calculate payload hash
if (!artifacts.hash && (options.payload || options.payload === '')) {
artifacts.hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
}
var mac = Crypto.calculateMac('header', credentials, artifacts);
// Construct header
var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed
var header = 'Hawk id="' + credentials.id + '", ts="' + artifacts.ts + '", nonce="' + artifacts.nonce + (artifacts.hash ? '", hash="' + artifacts.hash : '') + (hasExt ? '", ext="' + Hoek.escapeHeaderAttribute(artifacts.ext) : '') + '", mac="' + mac + '"';
if (artifacts.app) {
header = header + ', app="' + artifacts.app + (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"';
}
result.field = header;
return result;
};
// Validate server response
/*
res: node's response object
artifacts: object received from header().artifacts
options: {
payload: optional payload received
required: specifies if a Server-Authorization header is required. Defaults to 'false'
}
*/
exports.authenticate = function (res, credentials, artifacts, options) {
artifacts = Hoek.clone(artifacts);
options = options || {};
if (res.headers['www-authenticate']) {
// Parse HTTP WWW-Authenticate header
var wwwAttributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']);
if (wwwAttributes instanceof Error) {
return false;
}
// Validate server timestamp (not used to update clock since it is done via the SNPT client)
if (wwwAttributes.ts) {
var tsm = Crypto.calculateTsMac(wwwAttributes.ts, credentials);
if (tsm !== wwwAttributes.tsm) {
return false;
}
}
}
// Parse HTTP Server-Authorization header
if (!res.headers['server-authorization'] && !options.required) {
return true;
}
var attributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']);
if (attributes instanceof Error) {
return false;
}
artifacts.ext = attributes.ext;
artifacts.hash = attributes.hash;
var mac = Crypto.calculateMac('response', credentials, artifacts);
if (mac !== attributes.mac) {
return false;
}
if (!options.payload && options.payload !== '') {
return true;
}
if (!attributes.hash) {
return false;
}
var calculatedHash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, res.headers['content-type']);
return calculatedHash === attributes.hash;
};
// Generate a bewit value for a given URI
/*
uri: 'http://example.com/resource?a=b' or object from Url.parse()
options: {
// Required
credentials: {
id: 'dh37fgj492je',
key: 'aoijedoaijsdlaksjdl',
algorithm: 'sha256' // 'sha1', 'sha256'
},
ttlSec: 60 * 60, // TTL in seconds
// Optional
ext: 'application-specific', // Application specific data sent via the ext attribute
localtimeOffsetMsec: 400 // Time offset to sync with server time
};
*/
exports.getBewit = function (uri, options) {
// Validate inputs
if (!uri || typeof uri !== 'string' && (typeof uri === 'undefined' ? 'undefined' : _typeof(uri)) !== 'object' || !options || (typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object' || !options.ttlSec) {
return '';
}
options.ext = options.ext === null || options.ext === undefined ? '' : options.ext; // Zero is valid value
// Application time
var now = Utils.now(options.localtimeOffsetMsec);
// Validate credentials
var credentials = options.credentials;
if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) {
return '';
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return '';
}
// Parse URI
if (typeof uri === 'string') {
uri = Url.parse(uri);
}
// Calculate signature
var exp = Math.floor(now / 1000) + options.ttlSec;
var mac = Crypto.calculateMac('bewit', credentials, {
ts: exp,
nonce: '',
method: 'GET',
resource: uri.pathname + (uri.search || ''), // Maintain trailing '?'
host: uri.hostname,
port: uri.port || (uri.protocol === 'http:' ? 80 : 443),
ext: options.ext
});
// Construct bewit: id\exp\mac\ext
var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + options.ext;
return Hoek.base64urlEncode(bewit);
};
// Generate an authorization string for a message
/*
host: 'example.com',
port: 8000,
message: '{"some":"payload"}', // UTF-8 encoded string for body hash generation
options: {
// Required
credentials: {
id: 'dh37fgj492je',
key: 'aoijedoaijsdlaksjdl',
algorithm: 'sha256' // 'sha1', 'sha256'
},
// Optional
timestamp: Date.now(), // A pre-calculated timestamp
nonce: '2334f34f', // A pre-generated nonce
localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
}
*/
exports.message = function (host, port, message, options) {
// Validate inputs
if (!host || typeof host !== 'string' || !port || typeof port !== 'number' || message === null || message === undefined || typeof message !== 'string' || !options || (typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
return null;
}
// Application time
var timestamp = options.timestamp || Utils.nowSecs(options.localtimeOffsetMsec);
// Validate credentials
var credentials = options.credentials;
if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) {
// Invalid credential object
return null;
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return null;
}
// Calculate signature
var artifacts = {
ts: timestamp,
nonce: options.nonce || Cryptiles.randomString(6),
host: host,
port: port,
hash: Crypto.calculatePayloadHash(message, credentials.algorithm)
};
// Construct authorization
var result = {
id: credentials.id,
ts: artifacts.ts,
nonce: artifacts.nonce,
hash: artifacts.hash,
mac: Crypto.calculateMac('message', credentials, artifacts)
};
return result;
};

View File

@@ -0,0 +1,6 @@
Dave Eddy <dave@daveeddy.com>
Fred Kuo <fred.kuo@joyent.com>
Lars-Magnus Skog <ralphtheninja@riseup.net>
Mark Cavage <mcavage@gmail.com>
Patrick Mooney <pmooney@pfmooney.com>
Rob Gulewich <robert.gulewich@joyent.com>

View File

@@ -0,0 +1,8 @@
# assert-plus Changelog
## 0.2.0
- Fix `assert.object(null)` so it throws
- Fix optional/arrayOf exports for non-type-of asserts
- Add optiona/arrayOf exports for Stream/Date/Regex/uuid
- Add basic unit test coverage

View File

@@ -0,0 +1,155 @@
# assert-plus
This library is a super small wrapper over node's assert module that has two
things: (1) the ability to disable assertions with the environment variable
NODE\_NDEBUG, and (2) some API wrappers for argument testing. Like
`assert.string(myArg, 'myArg')`. As a simple example, most of my code looks
like this:
```javascript
var assert = require('assert-plus');
function fooAccount(options, callback) {
assert.object(options, 'options');
assert.number(options.id, 'options.id');
assert.bool(options.isManager, 'options.isManager');
assert.string(options.name, 'options.name');
assert.arrayOfString(options.email, 'options.email');
assert.func(callback, 'callback');
// Do stuff
callback(null, {});
}
```
# API
All methods that *aren't* part of node's core assert API are simply assumed to
take an argument, and then a string 'name' that's not a message; `AssertionError`
will be thrown if the assertion fails with a message like:
AssertionError: foo (string) is required
at test (/home/mark/work/foo/foo.js:3:9)
at Object.<anonymous> (/home/mark/work/foo/foo.js:15:1)
at Module._compile (module.js:446:26)
at Object..js (module.js:464:10)
at Module.load (module.js:353:31)
at Function._load (module.js:311:12)
at Array.0 (module.js:484:10)
at EventEmitter._tickCallback (node.js:190:38)
from:
```javascript
function test(foo) {
assert.string(foo, 'foo');
}
```
There you go. You can check that arrays are of a homogeneous type with `Arrayof$Type`:
```javascript
function test(foo) {
assert.arrayOfString(foo, 'foo');
}
```
You can assert IFF an argument is not `undefined` (i.e., an optional arg):
```javascript
assert.optionalString(foo, 'foo');
```
Lastly, you can opt-out of assertion checking altogether by setting the
environment variable `NODE_NDEBUG=1`. This is pseudo-useful if you have
lots of assertions, and don't want to pay `typeof ()` taxes to v8 in
production. Be advised: The standard functions re-exported from `assert` are
also disabled in assert-plus if NDEBUG is specified. Using them directly from
the `assert` module avoids this behavior.
The complete list of APIs is:
* assert.array
* assert.bool
* assert.buffer
* assert.func
* assert.number
* assert.object
* assert.string
* assert.stream
* assert.date
* assert.regex
* assert.uuid
* assert.arrayOfArray
* assert.arrayOfBool
* assert.arrayOfBuffer
* assert.arrayOfFunc
* assert.arrayOfNumber
* assert.arrayOfObject
* assert.arrayOfString
* assert.arrayOfStream
* assert.arrayOfDate
* assert.arrayOfUuid
* assert.optionalArray
* assert.optionalBool
* assert.optionalBuffer
* assert.optionalFunc
* assert.optionalNumber
* assert.optionalObject
* assert.optionalString
* assert.optionalStream
* assert.optionalDate
* assert.optionalUuid
* assert.optionalArrayOfArray
* assert.optionalArrayOfBool
* assert.optionalArrayOfBuffer
* assert.optionalArrayOfFunc
* assert.optionalArrayOfNumber
* assert.optionalArrayOfObject
* assert.optionalArrayOfString
* assert.optionalArrayOfStream
* assert.optionalArrayOfDate
* assert.optionalArrayOfUuid
* assert.AssertionError
* assert.fail
* assert.ok
* assert.equal
* assert.notEqual
* assert.deepEqual
* assert.notDeepEqual
* assert.strictEqual
* assert.notStrictEqual
* assert.throws
* assert.doesNotThrow
* assert.ifError
# Installation
npm install assert-plus
## License
The MIT License (MIT)
Copyright (c) 2012 Mark Cavage
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
## Bugs
See <https://github.com/mcavage/node-assert-plus/issues>.

View File

@@ -0,0 +1,206 @@
// Copyright (c) 2012, Mark Cavage. All rights reserved.
// Copyright 2015 Joyent, Inc.
var assert = require('assert');
var Stream = require('stream').Stream;
var util = require('util');
///--- Globals
/* JSSTYLED */
var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
///--- Internal
function _capitalize(str) {
return (str.charAt(0).toUpperCase() + str.slice(1));
}
function _toss(name, expected, oper, arg, actual) {
throw new assert.AssertionError({
message: util.format('%s (%s) is required', name, expected),
actual: (actual === undefined) ? typeof (arg) : actual(arg),
expected: expected,
operator: oper || '===',
stackStartFunction: _toss.caller
});
}
function _getClass(arg) {
return (Object.prototype.toString.call(arg).slice(8, -1));
}
function noop() {
// Why even bother with asserts?
}
///--- Exports
var types = {
bool: {
check: function (arg) { return typeof (arg) === 'boolean'; }
},
func: {
check: function (arg) { return typeof (arg) === 'function'; }
},
string: {
check: function (arg) { return typeof (arg) === 'string'; }
},
object: {
check: function (arg) {
return typeof (arg) === 'object' && arg !== null;
}
},
number: {
check: function (arg) {
return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg);
}
},
buffer: {
check: function (arg) { return Buffer.isBuffer(arg); },
operator: 'Buffer.isBuffer'
},
array: {
check: function (arg) { return Array.isArray(arg); },
operator: 'Array.isArray'
},
stream: {
check: function (arg) { return arg instanceof Stream; },
operator: 'instanceof',
actual: _getClass
},
date: {
check: function (arg) { return arg instanceof Date; },
operator: 'instanceof',
actual: _getClass
},
regexp: {
check: function (arg) { return arg instanceof RegExp; },
operator: 'instanceof',
actual: _getClass
},
uuid: {
check: function (arg) {
return typeof (arg) === 'string' && UUID_REGEXP.test(arg);
},
operator: 'isUUID'
}
};
function _setExports(ndebug) {
var keys = Object.keys(types);
var out;
/* re-export standard assert */
if (process.env.NODE_NDEBUG) {
out = noop;
} else {
out = function (arg, msg) {
if (!arg) {
_toss(msg, 'true', arg);
}
};
}
/* standard checks */
keys.forEach(function (k) {
if (ndebug) {
out[k] = noop;
return;
}
var type = types[k];
out[k] = function (arg, msg) {
if (!type.check(arg)) {
_toss(msg, k, type.operator, arg, type.actual);
}
};
});
/* optional checks */
keys.forEach(function (k) {
var name = 'optional' + _capitalize(k);
if (ndebug) {
out[name] = noop;
return;
}
var type = types[k];
out[name] = function (arg, msg) {
if (arg === undefined || arg === null) {
return;
}
if (!type.check(arg)) {
_toss(msg, k, type.operator, arg, type.actual);
}
};
});
/* arrayOf checks */
keys.forEach(function (k) {
var name = 'arrayOf' + _capitalize(k);
if (ndebug) {
out[name] = noop;
return;
}
var type = types[k];
var expected = '[' + k + ']';
out[name] = function (arg, msg) {
if (!Array.isArray(arg)) {
_toss(msg, expected, type.operator, arg, type.actual);
}
var i;
for (i = 0; i < arg.length; i++) {
if (!type.check(arg[i])) {
_toss(msg, expected, type.operator, arg, type.actual);
}
}
};
});
/* optionalArrayOf checks */
keys.forEach(function (k) {
var name = 'optionalArrayOf' + _capitalize(k);
if (ndebug) {
out[name] = noop;
return;
}
var type = types[k];
var expected = '[' + k + ']';
out[name] = function (arg, msg) {
if (arg === undefined || arg === null) {
return;
}
if (!Array.isArray(arg)) {
_toss(msg, expected, type.operator, arg, type.actual);
}
var i;
for (i = 0; i < arg.length; i++) {
if (!type.check(arg[i])) {
_toss(msg, expected, type.operator, arg, type.actual);
}
}
};
});
/* re-export built-in assertions */
Object.keys(assert).forEach(function (k) {
if (k === 'AssertionError') {
out[k] = assert[k];
return;
}
if (ndebug) {
out[k] = noop;
return;
}
out[k] = assert[k];
});
/* export ourselves (for unit tests _only_) */
out._setExports = _setExports;
return out;
}
module.exports = _setExports(process.env.NODE_NDEBUG);

View File

@@ -0,0 +1,82 @@
{
"author": {
"name": "Mark Cavage",
"email": "mcavage@gmail.com"
},
"name": "assert-plus",
"description": "Extra assertions on top of node's assert module",
"version": "0.2.0",
"license": "MIT",
"main": "./assert.js",
"devDependencies": {
"tape": "4.2.2",
"faucet": "0.0.1"
},
"optionalDependencies": {},
"scripts": {
"test": "tape tests/*.js | ./node_modules/.bin/faucet"
},
"repository": {
"type": "git",
"url": "git+https://github.com/mcavage/node-assert-plus.git"
},
"engines": {
"node": ">=0.8"
},
"contributors": [
{
"name": "Dave Eddy",
"email": "dave@daveeddy.com"
},
{
"name": "Fred Kuo",
"email": "fred.kuo@joyent.com"
},
{
"name": "Lars-Magnus Skog",
"email": "ralphtheninja@riseup.net"
},
{
"name": "Mark Cavage",
"email": "mcavage@gmail.com"
},
{
"name": "Patrick Mooney",
"email": "pmooney@pfmooney.com"
},
{
"name": "Rob Gulewich",
"email": "robert.gulewich@joyent.com"
}
],
"bugs": {
"url": "https://github.com/mcavage/node-assert-plus/issues"
},
"homepage": "https://github.com/mcavage/node-assert-plus#readme",
"dependencies": {},
"_id": "assert-plus@0.2.0",
"_shasum": "d74e1b87e7affc0db8aadb7021f3fe48101ab234",
"_resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
"_from": "assert-plus@>=0.2.0 <0.3.0",
"_npmVersion": "3.3.8",
"_nodeVersion": "0.10.36",
"_npmUser": {
"name": "pfmooney",
"email": "patrick.f.mooney@gmail.com"
},
"dist": {
"shasum": "d74e1b87e7affc0db8aadb7021f3fe48101ab234",
"tarball": "http://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz"
},
"maintainers": [
{
"name": "mcavage",
"email": "mcavage@gmail.com"
},
{
"name": "pfmooney",
"email": "patrick.f.mooney@gmail.com"
}
],
"directories": {}
}

View File

@@ -0,0 +1,126 @@
# node-assert-plus
This library is a super small wrapper over node's assert module that has two
things: (1) the ability to disable assertions with the environment variable
NODE_NDEBUG, and (2) some API wrappers for argument testing. Like
`assert.string(myArg, 'myArg')`. As a simple example, most of my code looks
like this:
var assert = require('assert-plus');
function fooAccount(options, callback) {
assert.object(options, 'options');
assert.number(options.id, 'options.id);
assert.bool(options.isManager, 'options.isManager');
assert.string(options.name, 'options.name');
assert.arrayOfString(options.email, 'options.email');
assert.func(callback, 'callback');
// Do stuff
callback(null, {});
}
# API
All methods that *aren't* part of node's core assert API are simply assumed to
take an argument, and then a string 'name' that's not a message; `AssertionError`
will be thrown if the assertion fails with a message like:
AssertionError: foo (string) is required
at test (/home/mark/work/foo/foo.js:3:9)
at Object.<anonymous> (/home/mark/work/foo/foo.js:15:1)
at Module._compile (module.js:446:26)
at Object..js (module.js:464:10)
at Module.load (module.js:353:31)
at Function._load (module.js:311:12)
at Array.0 (module.js:484:10)
at EventEmitter._tickCallback (node.js:190:38)
from:
function test(foo) {
assert.string(foo, 'foo');
}
There you go. You can check that arrays are of a homogenous type with `Arrayof$Type`:
function test(foo) {
assert.arrayOfString(foo, 'foo');
}
You can assert IFF an argument is not `undefined` (i.e., an optional arg):
assert.optionalString(foo, 'foo');
Lastly, you can opt-out of assertion checking altogether by setting the
environment variable `NODE_NDEBUG=1`. This is pseudo-useful if you have
lots of assertions, and don't want to pay `typeof ()` taxes to v8 in
production.
The complete list of APIs is:
* assert.bool
* assert.buffer
* assert.func
* assert.number
* assert.object
* assert.string
* assert.arrayOfBool
* assert.arrayOfFunc
* assert.arrayOfNumber
* assert.arrayOfObject
* assert.arrayOfString
* assert.optionalBool
* assert.optionalBuffer
* assert.optionalFunc
* assert.optionalNumber
* assert.optionalObject
* assert.optionalString
* assert.optionalArrayOfBool
* assert.optionalArrayOfFunc
* assert.optionalArrayOfNumber
* assert.optionalArrayOfObject
* assert.optionalArrayOfString
* assert.AssertionError
* assert.fail
* assert.ok
* assert.equal
* assert.notEqual
* assert.deepEqual
* assert.notDeepEqual
* assert.strictEqual
* assert.notStrictEqual
* assert.throws
* assert.doesNotThrow
* assert.ifError
# Installation
npm install assert-plus
## License
The MIT License (MIT)
Copyright (c) 2012 Mark Cavage
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
## Bugs
See <https://github.com/mcavage/node-assert-plus/issues>.

View File

@@ -0,0 +1,245 @@
// Copyright (c) 2012, Mark Cavage. All rights reserved.
var assert = require('assert');
var Stream = require('stream').Stream;
var util = require('util');
///--- Globals
var NDEBUG = process.env.NODE_NDEBUG || false;
var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
///--- Messages
var ARRAY_TYPE_REQUIRED = '%s ([%s]) required';
var TYPE_REQUIRED = '%s (%s) is required';
///--- Internal
function capitalize(str) {
return (str.charAt(0).toUpperCase() + str.slice(1));
}
function uncapitalize(str) {
return (str.charAt(0).toLowerCase() + str.slice(1));
}
function _() {
return (util.format.apply(util, arguments));
}
function _assert(arg, type, name, stackFunc) {
if (!NDEBUG) {
name = name || type;
stackFunc = stackFunc || _assert.caller;
var t = typeof (arg);
if (t !== type) {
throw new assert.AssertionError({
message: _(TYPE_REQUIRED, name, type),
actual: t,
expected: type,
operator: '===',
stackStartFunction: stackFunc
});
}
}
}
function _instanceof(arg, type, name, stackFunc) {
if (!NDEBUG) {
name = name || type;
stackFunc = stackFunc || _instanceof.caller;
if (!(arg instanceof type)) {
throw new assert.AssertionError({
message: _(TYPE_REQUIRED, name, type.name),
actual: _getClass(arg),
expected: type.name,
operator: 'instanceof',
stackStartFunction: stackFunc
});
}
}
}
function _getClass(object) {
return (Object.prototype.toString.call(object).slice(8, -1));
};
///--- API
function array(arr, type, name) {
if (!NDEBUG) {
name = name || type;
if (!Array.isArray(arr)) {
throw new assert.AssertionError({
message: _(ARRAY_TYPE_REQUIRED, name, type),
actual: typeof (arr),
expected: 'array',
operator: 'Array.isArray',
stackStartFunction: array.caller
});
}
for (var i = 0; i < arr.length; i++) {
_assert(arr[i], type, name, array);
}
}
}
function bool(arg, name) {
_assert(arg, 'boolean', name, bool);
}
function buffer(arg, name) {
if (!Buffer.isBuffer(arg)) {
throw new assert.AssertionError({
message: _(TYPE_REQUIRED, name || '', 'Buffer'),
actual: typeof (arg),
expected: 'buffer',
operator: 'Buffer.isBuffer',
stackStartFunction: buffer
});
}
}
function func(arg, name) {
_assert(arg, 'function', name);
}
function number(arg, name) {
_assert(arg, 'number', name);
if (!NDEBUG && (isNaN(arg) || !isFinite(arg))) {
throw new assert.AssertionError({
message: _(TYPE_REQUIRED, name, 'number'),
actual: arg,
expected: 'number',
operator: 'isNaN',
stackStartFunction: number
});
}
}
function object(arg, name) {
_assert(arg, 'object', name);
}
function stream(arg, name) {
_instanceof(arg, Stream, name);
}
function date(arg, name) {
_instanceof(arg, Date, name);
}
function regexp(arg, name) {
_instanceof(arg, RegExp, name);
}
function string(arg, name) {
_assert(arg, 'string', name);
}
function uuid(arg, name) {
string(arg, name);
if (!NDEBUG && !UUID_REGEXP.test(arg)) {
throw new assert.AssertionError({
message: _(TYPE_REQUIRED, name, 'uuid'),
actual: 'string',
expected: 'uuid',
operator: 'test',
stackStartFunction: uuid
});
}
}
///--- Exports
module.exports = {
bool: bool,
buffer: buffer,
date: date,
func: func,
number: number,
object: object,
regexp: regexp,
stream: stream,
string: string,
uuid: uuid
};
Object.keys(module.exports).forEach(function (k) {
if (k === 'buffer')
return;
var name = 'arrayOf' + capitalize(k);
if (k === 'bool')
k = 'boolean';
if (k === 'func')
k = 'function';
module.exports[name] = function (arg, name) {
array(arg, k, name);
};
});
Object.keys(module.exports).forEach(function (k) {
var _name = 'optional' + capitalize(k);
var s = uncapitalize(k.replace('arrayOf', ''));
if (s === 'bool')
s = 'boolean';
if (s === 'func')
s = 'function';
if (k.indexOf('arrayOf') !== -1) {
module.exports[_name] = function (arg, name) {
if (!NDEBUG && arg !== undefined) {
array(arg, s, name);
}
};
} else {
module.exports[_name] = function (arg, name) {
if (!NDEBUG && arg !== undefined) {
_assert(arg, s, name);
}
};
}
});
// Reexport built-in assertions
Object.keys(assert).forEach(function (k) {
if (k === 'AssertionError') {
module.exports[k] = assert[k];
return;
}
module.exports[k] = function () {
if (!NDEBUG) {
assert[k].apply(assert[k], arguments);
}
};
});

View File

@@ -0,0 +1,45 @@
{
"author": {
"name": "Mark Cavage",
"email": "mcavage@gmail.com"
},
"name": "assert-plus",
"description": "Extra assertions on top of node's assert module",
"version": "0.1.5",
"main": "./assert.js",
"devDependencies": {},
"optionalDependencies": {},
"repository": {
"type": "git",
"url": "https://github.com/mcavage/node-assert-plus.git"
},
"engines": {
"node": ">=0.8"
},
"bugs": {
"url": "https://github.com/mcavage/node-assert-plus/issues"
},
"dependencies": {},
"_id": "assert-plus@0.1.5",
"dist": {
"shasum": "ee74009413002d84cec7219c6ac811812e723160",
"tarball": "http://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz"
},
"_from": "assert-plus@0.1.x",
"_npmVersion": "1.3.11",
"_npmUser": {
"name": "mcavage",
"email": "mcavage@gmail.com"
},
"maintainers": [
{
"name": "mcavage",
"email": "mcavage@gmail.com"
}
],
"directories": {},
"_shasum": "ee74009413002d84cec7219c6ac811812e723160",
"_resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz",
"readme": "ERROR: No README data found!",
"scripts": {}
}