├── .gitignore ├── .gitmodules ├── .npmignore ├── AUTHORS ├── CHANGES.md ├── CONTRIBUTING.md ├── Jenkinsfile ├── LICENSE ├── Makefile ├── README.md ├── assert.js ├── package.json ├── tests ├── all.test.js ├── exports.test.js └── ndebug.test.js └── tools ├── jsl.node.conf └── jsstyle.conf /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/jsstyle"] 2 | path = deps/jsstyle 3 | url = https://github.com/TritonDataCenter/jsstyle 4 | [submodule "deps/javascriptlint"] 5 | path = deps/javascriptlint 6 | url = https://github.com/TritonDataCenter/javascriptlint 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | deps 3 | tools 4 | tests 5 | .gitmodules 6 | .npmignore 7 | CONTRIBUTING.md 8 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Dave Eddy 2 | Fred Kuo 3 | Lars-Magnus Skog 4 | Mark Cavage 5 | Patrick Mooney 6 | Rob Gulewich 7 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | # assert-plus Changelog 2 | 3 | ## 1.0.0 4 | 5 | - *BREAKING* assert.number (and derivatives) now accept Infinity as valid input 6 | - Add assert.finite check. Previous assert.number callers should use this if 7 | they expect Infinity inputs to throw. 8 | 9 | ## 0.2.0 10 | 11 | - *BREAKING* Fix `assert.object(null)` so it throws 12 | - Fix optional/arrayOf exports for non-type-of asserts 13 | - Add optiona/arrayOf exports for Stream/Date/Regex/uuid 14 | - Add basic unit test coverage 15 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This repository uses GitHub pull requests for code review. 4 | 5 | See the [Joyent Engineering 6 | Guidelines](https://github.com/joyent/eng/blob/master/docs/index.md) for general 7 | best practices expected in this repository. 8 | 9 | Contributions should be "make prepush" clean. The "prepush" target runs the 10 | "check" target, which requires these separate tools: 11 | 12 | * https://github.com/joyent/jsstyle 13 | * https://github.com/joyent/javascriptlint 14 | 15 | If you're changing something non-trivial or user-facing, you may want to submit 16 | an issue first. 17 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | @Library('jenkins-joylib@v1.0.8') _ 2 | 3 | pipeline { 4 | 5 | agent none 6 | 7 | options { 8 | buildDiscarder(logRotator(numToKeepStr: '45')) 9 | timestamps() 10 | } 11 | 12 | stages { 13 | stage('top') { 14 | parallel { 15 | stage('v0.10.48-zone') { 16 | agent { 17 | label joyCommonLabels(image_ver: '15.4.1') 18 | } 19 | tools { 20 | nodejs 'sdcnode-v0.10.48-zone' 21 | } 22 | stages { 23 | stage('check') { 24 | steps{ 25 | sh('make check') 26 | } 27 | } 28 | stage('test') { 29 | steps{ 30 | sh('make test') 31 | } 32 | } 33 | } 34 | } 35 | 36 | stage('v4-zone') { 37 | agent { 38 | label joyCommonLabels(image_ver: '15.4.1') 39 | } 40 | tools { 41 | nodejs 'sdcnode-v4-zone' 42 | } 43 | stages { 44 | stage('check') { 45 | steps{ 46 | sh('make check') 47 | } 48 | } 49 | stage('test') { 50 | steps{ 51 | sh('make test') 52 | } 53 | } 54 | } 55 | } 56 | 57 | stage('v6-zone64') { 58 | agent { 59 | label joyCommonLabels(image_ver: '18.4.0') 60 | } 61 | tools { 62 | nodejs 'sdcnode-v6-zone64' 63 | } 64 | stages { 65 | stage('check') { 66 | steps{ 67 | sh('make check') 68 | } 69 | } 70 | stage('test') { 71 | steps{ 72 | sh('make test') 73 | } 74 | } 75 | } 76 | } 77 | } 78 | } 79 | } 80 | 81 | post { 82 | always { 83 | joySlackNotifications() 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018, Joyent, Inc. and assert-plus authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Joyent, Inc. and assert-plus authors 3 | # 4 | 5 | NPM = npm 6 | 7 | JS_FILES := $(shell find assert.js tests/ -name '*.js') 8 | 9 | JSL_CONF = tools/jsl.node.conf 10 | JSSTYLE_FLAGS = -f tools/jsstyle.conf 11 | 12 | JSL_EXEC ?= deps/javascriptlint/build/install/jsl 13 | JSSTYLE_EXEC ?= deps/jsstyle/jsstyle 14 | JSL ?= $(JSL_EXEC) 15 | JSSTYLE ?= $(JSSTYLE_EXEC) 16 | 17 | .PHONY: install 18 | install: 19 | $(NPM) install 20 | 21 | .PHONY: clean 22 | clean: 23 | rm -rf node_modules coverage 24 | 25 | .PHONY: test 26 | test: install 27 | npm test 28 | 29 | .PHONY: check 30 | check: $(JSL_EXEC) $(JSSTYLE_EXEC) 31 | $(JSL) --conf $(JSL_CONF) $(JS_FILES) 32 | $(JSSTYLE) $(JSSTYLE_FLAGS) $(JS_FILES) 33 | 34 | .PHONY: prepush 35 | prepush: check test 36 | 37 | 38 | $(JSL_EXEC): | deps/javascriptlint/.git 39 | cd deps/javascriptlint && make install 40 | 41 | $(JSSTYLE_EXEC): | deps/jsstyle/.git 42 | 43 | .SECONDARY: $($(wildcard deps/*):%=%/.git) 44 | 45 | deps/%/.git: 46 | git submodule update --init deps/$* 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # assert-plus 2 | 3 | This library is a thin wrapper over the Node built-in `assert` module, 4 | providing two main enhancements: 5 | 6 | 1. the ability to disable assertions with the environment variable 7 | `NODE_NDEBUG` 8 | 9 | 2. some API wrappers for argument testing; e.g., `assert.string(myArg, 10 | 'myArg')`. As a simple example: 11 | 12 | ```javascript 13 | var assert = require('assert-plus'); 14 | 15 | function fooAccount(options, callback) { 16 | assert.object(options, 'options'); 17 | assert.number(options.id, 'options.id'); 18 | assert.bool(options.isManager, 'options.isManager'); 19 | assert.string(options.name, 'options.name'); 20 | assert.arrayOfString(options.email, 'options.email'); 21 | assert.func(callback, 'callback'); 22 | 23 | // Do stuff 24 | callback(null, {}); 25 | } 26 | ``` 27 | 28 | See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to submit changes. 29 | 30 | ## API 31 | 32 | All methods that *aren't* part of node's core assert API are simply assumed to 33 | take an argument, and then a string 'name' that's not a message; `AssertionError` 34 | will be thrown if the assertion fails with a message like: 35 | 36 | AssertionError: foo (string) is required 37 | at test (/home/mark/work/foo/foo.js:3:9) 38 | at Object. (/home/mark/work/foo/foo.js:15:1) 39 | at Module._compile (module.js:446:26) 40 | at Object..js (module.js:464:10) 41 | at Module.load (module.js:353:31) 42 | at Function._load (module.js:311:12) 43 | at Array.0 (module.js:484:10) 44 | at EventEmitter._tickCallback (node.js:190:38) 45 | 46 | from: 47 | 48 | ```javascript 49 | function test(foo) { 50 | assert.string(foo, 'foo'); 51 | } 52 | ``` 53 | 54 | There you go. You can check that arrays are of a homogeneous type with `Arrayof$Type`: 55 | 56 | ```javascript 57 | function test(foo) { 58 | assert.arrayOfString(foo, 'foo'); 59 | } 60 | ``` 61 | 62 | You can assert IFF an argument is not `undefined` (i.e., an optional arg): 63 | 64 | ```javascript 65 | assert.optionalString(foo, 'foo'); 66 | ``` 67 | 68 | Lastly, you can opt-out of assertion checking altogether by setting the 69 | environment variable `NODE_NDEBUG=1`. This is pseudo-useful if you have 70 | lots of assertions, and don't want to pay `typeof ()` taxes to v8 in 71 | production. Be advised: The standard functions re-exported from `assert` are 72 | also disabled in assert-plus if NDEBUG is specified. Using them directly from 73 | the `assert` module avoids this behavior. 74 | 75 | The complete list of APIs is: 76 | 77 | * `assert.array` 78 | * `assert.bool` 79 | * `assert.buffer` 80 | * `assert.func` 81 | * `assert.number` 82 | * `assert.finite` 83 | * `assert.object` 84 | * `assert.string` 85 | * `assert.stream` 86 | * `assert.date` 87 | * `assert.regexp` 88 | * `assert.uuid` 89 | * `assert.arrayOfArray` 90 | * `assert.arrayOfBool` 91 | * `assert.arrayOfBuffer` 92 | * `assert.arrayOfFunc` 93 | * `assert.arrayOfNumber` 94 | * `assert.arrayOfFinite` 95 | * `assert.arrayOfObject` 96 | * `assert.arrayOfString` 97 | * `assert.arrayOfStream` 98 | * `assert.arrayOfDate` 99 | * `assert.arrayOfRegexp` 100 | * `assert.arrayOfUuid` 101 | * `assert.optionalArray` 102 | * `assert.optionalBool` 103 | * `assert.optionalBuffer` 104 | * `assert.optionalFunc` 105 | * `assert.optionalNumber` 106 | * `assert.optionalFinite` 107 | * `assert.optionalObject` 108 | * `assert.optionalString` 109 | * `assert.optionalStream` 110 | * `assert.optionalDate` 111 | * `assert.optionalRegexp` 112 | * `assert.optionalUuid` 113 | * `assert.optionalArrayOfArray` 114 | * `assert.optionalArrayOfBool` 115 | * `assert.optionalArrayOfBuffer` 116 | * `assert.optionalArrayOfFunc` 117 | * `assert.optionalArrayOfNumber` 118 | * `assert.optionalArrayOfFinite` 119 | * `assert.optionalArrayOfObject` 120 | * `assert.optionalArrayOfString` 121 | * `assert.optionalArrayOfStream` 122 | * `assert.optionalArrayOfDate` 123 | * `assert.optionalArrayOfRegexp` 124 | * `assert.optionalArrayOfUuid` 125 | * `assert.AssertionError` 126 | * `assert.fail` 127 | * `assert.ok` 128 | * `assert.equal` 129 | * `assert.notEqual` 130 | * `assert.deepEqual` 131 | * `assert.notDeepEqual` 132 | * `assert.strictEqual` 133 | * `assert.notStrictEqual` 134 | * `assert.throws` 135 | * `assert.doesNotThrow` 136 | * `assert.ifError` 137 | 138 | ## Installation 139 | 140 | npm install assert-plus 141 | 142 | ## License 143 | 144 | The MIT License (MIT) 145 | 146 | Copyright (c) 2018, Joyent, Inc. and assert-plus authors 147 | 148 | Permission is hereby granted, free of charge, to any person obtaining a copy of 149 | this software and associated documentation files (the "Software"), to deal in 150 | the Software without restriction, including without limitation the rights to 151 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 152 | the Software, and to permit persons to whom the Software is furnished to do so, 153 | subject to the following conditions: 154 | 155 | The above copyright notice and this permission notice shall be included in all 156 | copies or substantial portions of the Software. 157 | 158 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 159 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 160 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 161 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 162 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 163 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 164 | SOFTWARE. 165 | -------------------------------------------------------------------------------- /assert.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. and assert-plus authors 3 | */ 4 | 5 | var assert = require('assert'); 6 | var Stream = require('stream').Stream; 7 | var util = require('util'); 8 | 9 | 10 | ///--- Globals 11 | 12 | /* JSSTYLED */ 13 | 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}$/; 14 | 15 | 16 | ///--- Internal 17 | 18 | function _capitalize(str) { 19 | return (str.charAt(0).toUpperCase() + str.slice(1)); 20 | } 21 | 22 | function _toss(name, expected, oper, arg, actual) { 23 | throw new assert.AssertionError({ 24 | message: util.format('%s (%s) is required', name, expected), 25 | actual: (actual === undefined) ? typeof (arg) : actual(arg), 26 | expected: expected, 27 | operator: oper || '===', 28 | stackStartFunction: _toss.caller 29 | }); 30 | } 31 | 32 | function _getClass(arg) { 33 | return (Object.prototype.toString.call(arg).slice(8, -1)); 34 | } 35 | 36 | function noop() { 37 | // Why even bother with asserts? 38 | } 39 | 40 | 41 | ///--- Exports 42 | 43 | var types = { 44 | bool: { 45 | check: function (arg) { return typeof (arg) === 'boolean'; } 46 | }, 47 | func: { 48 | check: function (arg) { return typeof (arg) === 'function'; } 49 | }, 50 | string: { 51 | check: function (arg) { return typeof (arg) === 'string'; } 52 | }, 53 | object: { 54 | check: function (arg) { 55 | return typeof (arg) === 'object' && arg !== null; 56 | } 57 | }, 58 | number: { 59 | check: function (arg) { 60 | return typeof (arg) === 'number' && !isNaN(arg); 61 | } 62 | }, 63 | finite: { 64 | check: function (arg) { 65 | return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); 66 | } 67 | }, 68 | buffer: { 69 | check: function (arg) { return Buffer.isBuffer(arg); }, 70 | operator: 'Buffer.isBuffer' 71 | }, 72 | array: { 73 | check: function (arg) { return Array.isArray(arg); }, 74 | operator: 'Array.isArray' 75 | }, 76 | stream: { 77 | check: function (arg) { return arg instanceof Stream; }, 78 | operator: 'instanceof', 79 | actual: _getClass 80 | }, 81 | date: { 82 | check: function (arg) { return arg instanceof Date; }, 83 | operator: 'instanceof', 84 | actual: _getClass 85 | }, 86 | regexp: { 87 | check: function (arg) { return arg instanceof RegExp; }, 88 | operator: 'instanceof', 89 | actual: _getClass 90 | }, 91 | uuid: { 92 | check: function (arg) { 93 | return typeof (arg) === 'string' && UUID_REGEXP.test(arg); 94 | }, 95 | operator: 'isUUID' 96 | } 97 | }; 98 | 99 | function _setExports(ndebug) { 100 | var keys = Object.keys(types); 101 | var out; 102 | 103 | /* re-export standard assert */ 104 | if (process.env.NODE_NDEBUG) { 105 | out = noop; 106 | } else { 107 | out = function (arg, msg) { 108 | if (!arg) { 109 | _toss(msg, 'true', arg); 110 | } 111 | }; 112 | } 113 | 114 | /* standard checks */ 115 | keys.forEach(function (k) { 116 | if (ndebug) { 117 | out[k] = noop; 118 | return; 119 | } 120 | var type = types[k]; 121 | out[k] = function (arg, msg) { 122 | if (!type.check(arg)) { 123 | _toss(msg, k, type.operator, arg, type.actual); 124 | } 125 | }; 126 | }); 127 | 128 | /* optional checks */ 129 | keys.forEach(function (k) { 130 | var name = 'optional' + _capitalize(k); 131 | if (ndebug) { 132 | out[name] = noop; 133 | return; 134 | } 135 | var type = types[k]; 136 | out[name] = function (arg, msg) { 137 | if (arg === undefined || arg === null) { 138 | return; 139 | } 140 | if (!type.check(arg)) { 141 | _toss(msg, k, type.operator, arg, type.actual); 142 | } 143 | }; 144 | }); 145 | 146 | /* arrayOf checks */ 147 | keys.forEach(function (k) { 148 | var name = 'arrayOf' + _capitalize(k); 149 | if (ndebug) { 150 | out[name] = noop; 151 | return; 152 | } 153 | var type = types[k]; 154 | var expected = '[' + k + ']'; 155 | out[name] = function (arg, msg) { 156 | if (!Array.isArray(arg)) { 157 | _toss(msg, expected, type.operator, arg, type.actual); 158 | } 159 | var i; 160 | for (i = 0; i < arg.length; i++) { 161 | if (!type.check(arg[i])) { 162 | _toss(msg, expected, type.operator, arg, type.actual); 163 | } 164 | } 165 | }; 166 | }); 167 | 168 | /* optionalArrayOf checks */ 169 | keys.forEach(function (k) { 170 | var name = 'optionalArrayOf' + _capitalize(k); 171 | if (ndebug) { 172 | out[name] = noop; 173 | return; 174 | } 175 | var type = types[k]; 176 | var expected = '[' + k + ']'; 177 | out[name] = function (arg, msg) { 178 | if (arg === undefined || arg === null) { 179 | return; 180 | } 181 | if (!Array.isArray(arg)) { 182 | _toss(msg, expected, type.operator, arg, type.actual); 183 | } 184 | var i; 185 | for (i = 0; i < arg.length; i++) { 186 | if (!type.check(arg[i])) { 187 | _toss(msg, expected, type.operator, arg, type.actual); 188 | } 189 | } 190 | }; 191 | }); 192 | 193 | /* re-export built-in assertions */ 194 | Object.keys(assert).forEach(function (k) { 195 | if (k === 'AssertionError') { 196 | out[k] = assert[k]; 197 | return; 198 | } 199 | if (ndebug) { 200 | out[k] = noop; 201 | return; 202 | } 203 | out[k] = assert[k]; 204 | }); 205 | 206 | /* export ourselves (for unit tests _only_) */ 207 | out._setExports = _setExports; 208 | 209 | return out; 210 | } 211 | 212 | module.exports = _setExports(process.env.NODE_NDEBUG); 213 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Mark Cavage ", 3 | "name": "assert-plus", 4 | "description": "Extra assertions on top of node's assert module", 5 | "version": "1.0.0", 6 | "license": "MIT", 7 | "main": "./assert.js", 8 | "devDependencies": { 9 | "tape": "4.2.2", 10 | "faucet": "0.0.1" 11 | }, 12 | "optionalDependencies": {}, 13 | "scripts": { 14 | "test": "./node_modules/.bin/tape tests/*.js | ./node_modules/.bin/faucet" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/joyent/node-assert-plus.git" 19 | }, 20 | "engines": { 21 | "node": ">=0.8" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/all.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. and assert-plus authors 3 | */ 4 | 5 | var f = require('util').format; 6 | var stream = require('stream'); 7 | var test = require('tape'); 8 | 9 | 10 | ///--- Globals 11 | 12 | var assertPlus; 13 | 14 | 15 | ///--- Helpers 16 | 17 | function capitalize(s) { 18 | return s[0].toUpperCase() + s.substr(1); 19 | } 20 | 21 | 22 | ///--- Tests 23 | 24 | /* 25 | * Example JavaScript objects and primitives to test. The keys of this object 26 | * will match the methods exported by the assert-plus module. 27 | * 28 | * The idea is to check all "valid" examples against their respective methods 29 | * and ensure hey do NOT throw, and also check all "invalid" examples 30 | * against the same method and ensure that they DO throw. 31 | */ 32 | var examples = { 33 | array: { 34 | valid: [ 35 | [], 36 | ['asdf'] 37 | ], 38 | invalid: [ 39 | false, 40 | true 41 | -1, 42 | 0, 43 | Infinity, 44 | NaN, 45 | 'foo', 46 | '00000000-0000-0000-0000-000000000000', 47 | /regex/, 48 | {}, 49 | new Date(), 50 | new Buffer(0), 51 | new stream(), 52 | function () {} 53 | ] 54 | }, 55 | bool: { 56 | valid: [ 57 | false, 58 | true 59 | ], 60 | invalid: [ 61 | -1, 62 | 0, 63 | Infinity, 64 | NaN, 65 | 'foo', 66 | '00000000-0000-0000-0000-000000000000', 67 | /regex/, 68 | [], 69 | {}, 70 | new Date(), 71 | new Buffer(0), 72 | new stream(), 73 | function () {} 74 | ] 75 | }, 76 | buffer: { 77 | valid: [ 78 | new Buffer(0), 79 | new Buffer('foo') 80 | ], 81 | invalid: [ 82 | false, 83 | true, 84 | -1, 85 | 0, 86 | Infinity, 87 | NaN, 88 | 'foo', 89 | '00000000-0000-0000-0000-000000000000', 90 | /regex/, 91 | [], 92 | {}, 93 | new Date(), 94 | new stream(), 95 | function () {} 96 | ] 97 | }, 98 | date: { 99 | valid: [ 100 | new Date(), 101 | new Date(0) 102 | ], 103 | invalid: [ 104 | false, 105 | true, 106 | -1, 107 | 0, 108 | Infinity, 109 | NaN, 110 | 'foo', 111 | '00000000-0000-0000-0000-000000000000', 112 | /regex/, 113 | [], 114 | {}, 115 | new Buffer(0), 116 | new stream(), 117 | function () {} 118 | ] 119 | }, 120 | func: { 121 | valid: [ 122 | function () {}, 123 | console.log 124 | ], 125 | invalid: [ 126 | false, 127 | true, 128 | -1, 129 | 0, 130 | Infinity, 131 | NaN, 132 | 'foo', 133 | '00000000-0000-0000-0000-000000000000', 134 | /regex/, 135 | [], 136 | {}, 137 | new Date(), 138 | new Buffer(0), 139 | new stream() 140 | ] 141 | }, 142 | number: { 143 | valid: [ 144 | -1, 145 | 0, 146 | 1, 147 | 0.5, 148 | Math.PI, 149 | Infinity 150 | ], 151 | invalid: [ 152 | false, 153 | true, 154 | NaN, 155 | 'foo', 156 | '00000000-0000-0000-0000-000000000000', 157 | /regex/, 158 | [], 159 | {}, 160 | new Date(), 161 | new Buffer(0), 162 | new stream(), 163 | function () {} 164 | ] 165 | }, 166 | finite: { 167 | valid: [ 168 | -1, 169 | 0, 170 | 1, 171 | 0.5, 172 | Math.PI 173 | ], 174 | invalid: [ 175 | false, 176 | true, 177 | Infinity, 178 | NaN, 179 | 'foo', 180 | '00000000-0000-0000-0000-000000000000', 181 | /regex/, 182 | [], 183 | {}, 184 | new Date(), 185 | new Buffer(0), 186 | new stream(), 187 | function () {} 188 | ] 189 | }, 190 | object: { 191 | valid: [ 192 | {}, 193 | console, 194 | /regex/ 195 | ], 196 | invalid: [ 197 | false, 198 | true, 199 | -1, 200 | 0, 201 | Infinity, 202 | NaN, 203 | 'foo', 204 | '00000000-0000-0000-0000-000000000000', 205 | null 206 | ] 207 | }, 208 | regexp: { 209 | valid: [ 210 | /foo/, 211 | new RegExp('foo') 212 | ], 213 | invalid: [ 214 | false, 215 | true, 216 | -1, 217 | 0, 218 | Infinity, 219 | NaN, 220 | 'foo', 221 | '00000000-0000-0000-0000-000000000000', 222 | [], 223 | {}, 224 | new Date(), 225 | new Buffer(0), 226 | new stream(), 227 | function () {} 228 | ] 229 | }, 230 | stream: { 231 | valid: [ 232 | new stream(), 233 | process.stdout 234 | ], 235 | invalid: [ 236 | false, 237 | true, 238 | -1, 239 | 0, 240 | Infinity, 241 | NaN, 242 | 'foo', 243 | '00000000-0000-0000-0000-000000000000', 244 | /regex/, 245 | [], 246 | {}, 247 | new Date(), 248 | new Buffer(0), 249 | function () {} 250 | ] 251 | }, 252 | string: { 253 | valid: [ 254 | 'foo', 255 | 'bar', 256 | 'baz' 257 | ], 258 | invalid: [ 259 | false, 260 | true, 261 | -1, 262 | 0, 263 | Infinity, 264 | NaN, 265 | /regex/, 266 | [], 267 | {}, 268 | new Date(), 269 | new Buffer(0), 270 | new stream(), 271 | function () {} 272 | ] 273 | }, 274 | uuid: { 275 | valid: [ 276 | 'B3A4A7B5-11C3-449B-B46F-86C57AA99022', 277 | '76d26c04-d351-42b7-bba9-c130169cc162' 278 | ], 279 | invalid: [ 280 | false, 281 | true, 282 | -1, 283 | 0, 284 | Infinity, 285 | NaN, 286 | 'foo', 287 | /regex/, 288 | [], 289 | {}, 290 | new Date(), 291 | new Buffer(0), 292 | new stream(), 293 | function () {} 294 | ] 295 | } 296 | }; 297 | 298 | test('test setup', function (t) { 299 | t.ifError(process.env.NODE_NDEBUG, 'run with NDEBUG off'); 300 | assertPlus = require('../'); 301 | t.ok(assertPlus); 302 | t.end(); 303 | }); 304 | 305 | Object.keys(examples).forEach(function (type) { 306 | var capType = capitalize(type); 307 | 308 | /* test normal */ 309 | test(f('assert.%s', type), function (t) { 310 | var name = type; 311 | 312 | examples[type].valid.forEach(function (val) { 313 | t.doesNotThrow(function () { 314 | assertPlus[name](val); 315 | }, f('%s(%s) should succeed', name, val)); 316 | }); 317 | 318 | examples[type].invalid.forEach(function (val) { 319 | t.throws(function () { 320 | assertPlus[name](val); 321 | }, f('%s(%s) should throw', name, val)); 322 | }); 323 | 324 | t.end(); 325 | }); 326 | 327 | /* test optional */ 328 | test(f('assert.%s (optional)', type), function (t) { 329 | var name = 'optional' + capType; 330 | 331 | examples[type].valid.forEach(function (val) { 332 | t.doesNotThrow(function () { 333 | assertPlus[name](val); 334 | }, f('%s(%s) should succeed', name, val)); 335 | }); 336 | t.doesNotThrow(function () { 337 | assertPlus[name](null); 338 | }, f('%s(%s) should succeed', name, null)); 339 | t.doesNotThrow(function () { 340 | assertPlus[name](undefined); 341 | }, f('%s(%s) should succeed', name, undefined)); 342 | 343 | examples[type].invalid.forEach(function (val) { 344 | /* null is valid for optional tests */ 345 | if (val === null) { 346 | return; 347 | } 348 | t.throws(function () { 349 | assertPlus[name](val); 350 | }, f('%s(%s) should throw', name, val)); 351 | }); 352 | 353 | t.end(); 354 | }); 355 | 356 | /* test arrayOf */ 357 | test(f('assert.%s (arrayOf)', type), function (t) { 358 | var name = 'arrayOf' + capType; 359 | var val = examples[type].valid; 360 | 361 | t.doesNotThrow(function () { 362 | assertPlus[name](val); 363 | }, f('%s(%s) should succeed', name, val)); 364 | 365 | val = examples[type].invalid; 366 | t.throws(function () { 367 | assertPlus[name](val); 368 | }, f('%s(%s) should throw', type, val)); 369 | 370 | t.end(); 371 | }); 372 | 373 | /* test optionalArrayOf */ 374 | test(f('assert.%s (optionalArrayOf)', type), function (t) { 375 | var name = 'optionalArrayOf' + capType; 376 | var val = examples[type].valid; 377 | 378 | t.doesNotThrow(function () { 379 | assertPlus[name](val); 380 | }, f('%s(%s) should succeed', name, val)); 381 | t.doesNotThrow(function () { 382 | assertPlus[name](null); 383 | }, f('%s(%s) should succeed', name, null)); 384 | t.doesNotThrow(function () { 385 | assertPlus[name](undefined); 386 | }, f('%s(%s) should succeed', name, undefined)); 387 | 388 | val = examples[type].invalid; 389 | t.throws(function () { 390 | assertPlus[name](val); 391 | }, f('%s(%s) should throw', type, val)); 392 | 393 | t.end(); 394 | }); 395 | }); 396 | -------------------------------------------------------------------------------- /tests/exports.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. and assert-plus authors 3 | */ 4 | 5 | var assert = require('assert'); 6 | var test = require('tape'); 7 | var assertPlus = require('../'); 8 | 9 | test('standard asserts are exported', function (t) { 10 | t.equal(typeof (assertPlus), 'function'); 11 | 12 | t.doesNotThrow(function () { 13 | assertPlus(true); 14 | }, 'assertPlus(true)'); 15 | 16 | t.throws(function () { 17 | assertPlus(false); 18 | }, 'assertPlus(false)'); 19 | 20 | // ensure all exports on "assert" exist on "assert-plus" 21 | Object.keys(assert).forEach(function (key) { 22 | t.ok(assertPlus[key], 'missing exported property ' + key); 23 | }); 24 | 25 | t.end(); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/ndebug.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. and assert-plus authors 3 | */ 4 | 5 | var assert = require('assert'); 6 | var test = require('tape'); 7 | 8 | 9 | ///--- Globals 10 | 11 | var regularExport; 12 | var ndebugExport; 13 | 14 | 15 | ///--- Tests 16 | 17 | test('simulated import', function (t) { 18 | t.ifError(process.env.NODE_NDEBUG, 'run with NDEBUG off'); 19 | 20 | regularExport = require('../'); 21 | t.ok(regularExport); 22 | 23 | /* fake setting NODE_NDEBUG */ 24 | ndebugExport = regularExport._setExports(true); 25 | t.end(); 26 | }); 27 | 28 | test('assertions suppressed via ndebug', function (t) { 29 | t.throws(function () { 30 | regularExport.fail('fail!'); 31 | }); 32 | 33 | t.doesNotThrow(function () { 34 | ndebugExport.fail('fail!'); 35 | }); 36 | t.end(); 37 | }); 38 | -------------------------------------------------------------------------------- /tools/jsl.node.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Configuration File for JavaScript Lint 3 | # 4 | # This configuration file can be used to lint a collection of scripts, or to enable 5 | # or disable warnings for scripts that are linted via the command line. 6 | # 7 | 8 | ### Warnings 9 | # Enable or disable warnings based on requirements. 10 | # Use "+WarningName" to display or "-WarningName" to suppress. 11 | # 12 | +ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent 13 | +ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity 14 | +ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement 15 | +anon_no_return_value # anonymous function does not always return value 16 | +assign_to_function_call # assignment to a function call 17 | -block_without_braces # block statement without curly braces 18 | +comma_separated_stmts # multiple statements separated by commas (use semicolons?) 19 | +comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==) 20 | +default_not_at_end # the default case is not at the end of the switch statement 21 | +dup_option_explicit # duplicate "option explicit" control comment 22 | +duplicate_case_in_switch # duplicate case in switch statement 23 | +duplicate_formal # duplicate formal argument {name} 24 | +empty_statement # empty statement or extra semicolon 25 | +identifier_hides_another # identifer {name} hides an identifier in a parent scope 26 | -inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement 27 | +incorrect_version # Expected /*jsl:content-type*/ control comment. The script was parsed with the wrong version. 28 | +invalid_fallthru # unexpected "fallthru" control comment 29 | +invalid_pass # unexpected "pass" control comment 30 | +jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax 31 | +leading_decimal_point # leading decimal point may indicate a number or an object member 32 | +legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax 33 | +meaningless_block # meaningless block; curly braces have no impact 34 | +mismatch_ctrl_comments # mismatched control comment; "ignore" and "end" control comments must have a one-to-one correspondence 35 | -misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma 36 | +missing_break # missing break statement 37 | +missing_break_for_last_case # missing break statement for last case in switch 38 | +missing_default_case # missing default case in switch statement 39 | +missing_option_explicit # the "option explicit" control comment is missing 40 | +missing_semicolon # missing semicolon 41 | +missing_semicolon_for_lambda # missing semicolon for lambda assignment 42 | +multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs 43 | +nested_comment # nested comment 44 | +no_return_value # function {name} does not always return a value 45 | +octal_number # leading zeros make an octal number 46 | +parseint_missing_radix # parseInt missing radix parameter 47 | +partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag 48 | +redeclared_var # redeclaration of {name} 49 | +trailing_comma_in_array # extra comma is not recommended in array initializers 50 | +trailing_decimal_point # trailing decimal point may indicate a number or an object member 51 | +undeclared_identifier # undeclared identifier: {name} 52 | +unreachable_code # unreachable code 53 | -unreferenced_argument # argument declared but never referenced: {name} 54 | -unreferenced_function # function is declared but never referenced: {name} 55 | +unreferenced_variable # variable is declared but never referenced: {name} 56 | +unsupported_version # JavaScript {version} is not supported 57 | +use_of_label # use of label 58 | +useless_assign # useless assignment 59 | +useless_comparison # useless comparison; comparing identical expressions 60 | -useless_quotes # the quotation marks are unnecessary 61 | +useless_void # use of the void type may be unnecessary (void is always undefined) 62 | +var_hides_arg # variable {name} hides argument 63 | +want_assign_or_call # expected an assignment or function call 64 | +with_statement # with statement hides undeclared variables; use temporary variable instead 65 | -identifier_hides_another 66 | 67 | ### Output format 68 | # Customize the format of the error message. 69 | # __FILE__ indicates current file path 70 | # __FILENAME__ indicates current file name 71 | # __LINE__ indicates current line 72 | # __COL__ indicates current column 73 | # __ERROR__ indicates error message (__ERROR_PREFIX__: __ERROR_MSG__) 74 | # __ERROR_NAME__ indicates error name (used in configuration file) 75 | # __ERROR_PREFIX__ indicates error prefix 76 | # __ERROR_MSG__ indicates error message 77 | # 78 | # For machine-friendly output, the output format can be prefixed with 79 | # "encode:". If specified, all items will be encoded with C-slashes. 80 | # 81 | # Visual Studio syntax (default): 82 | +output-format __FILE__(__LINE__): __ERROR__ 83 | # Alternative syntax: 84 | #+output-format __FILE__:__LINE__: __ERROR__ 85 | 86 | 87 | ### Context 88 | # Show the in-line position of the error. 89 | # Use "+context" to display or "-context" to suppress. 90 | # 91 | +context 92 | 93 | 94 | ### Control Comments 95 | # Both JavaScript Lint and the JScript interpreter confuse each other with the syntax for 96 | # the /*@keyword@*/ control comments and JScript conditional comments. (The latter is 97 | # enabled in JScript with @cc_on@). The /*jsl:keyword*/ syntax is preferred for this reason, 98 | # although legacy control comments are enabled by default for backward compatibility. 99 | # 100 | -legacy_control_comments 101 | 102 | 103 | ### Defining identifiers 104 | # By default, "option explicit" is enabled on a per-file basis. 105 | # To enable this for all files, use "+always_use_option_explicit" 106 | -always_use_option_explicit 107 | 108 | # Define certain identifiers of which the lint is not aware. 109 | # (Use this in conjunction with the "undeclared identifier" warning.) 110 | # 111 | # Common uses for webpages might be: 112 | +define __dirname 113 | +define clearInterval 114 | +define clearTimeout 115 | +define console 116 | +define exports 117 | +define global 118 | +define module 119 | +define process 120 | +define require 121 | +define setInterval 122 | +define setImmediate 123 | +define setTimeout 124 | +define Buffer 125 | +define JSON 126 | +define Math 127 | 128 | ### JavaScript Version 129 | # To change the default JavaScript version: 130 | #+default-type text/javascript;version=1.5 131 | #+default-type text/javascript;e4x=1 132 | 133 | ### Files 134 | # Specify which files to lint 135 | # Use "+recurse" to enable recursion (disabled by default). 136 | # To add a set of files, use "+process FileName", "+process Folder\Path\*.js", 137 | # or "+process Folder\Path\*.htm". 138 | # 139 | 140 | -------------------------------------------------------------------------------- /tools/jsstyle.conf: -------------------------------------------------------------------------------- 1 | indent=4 2 | doxygen 3 | unparenthesized-return=0 4 | blank-after-start-comment=0 5 | --------------------------------------------------------------------------------