UNPKG

specify-assertions

Version:

Beautiful assertion library.

403 lines (332 loc) 10.8 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Specify (assertions) Source: validations.js</title> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/sunlight.default.css"> <link type="text/css" rel="stylesheet" href="styles/site.cerulean.css"> </head> <body> <div class="container-fluid"> <div class="navbar navbar-fixed-top "> <div class="navbar-inner"> <a class="brand" href="index.html">Specify (assertions)</a> <ul class="nav"> <li class="dropdown"> <a href="namespaces.list.html" class="dropdown-toggle" data-toggle="dropdown">Namespaces<b class="caret"></b></a> <ul class="dropdown-menu "> <li> <a href="divergence.Divergence_.html">Divergence</a> </li> </ul> </li> <li class="dropdown"> <a href="modules.list.html" class="dropdown-toggle" data-toggle="dropdown">Modules<b class="caret"></b></a> <ul class="dropdown-menu "> <li> <a href="divergence.html">specify-assertions/lib/divergence</a> </li> <li> <a href="index_.html">specify-assertions/lib/index</a> </li> <li> <a href="validations.html">specify-assertions/lib/validations</a> </li> </ul> </li> </ul> </div> </div> <div class="row-fluid"> <div class="span12"> <div id="main"> <h1 class="page-title">Source: validations.js</h1> <section> <article> <pre class="sunlight-highlight-javascript linenums">/** * Provides common validation functions. * * @module specify-assertions/lib/validations */ // -- Dependencies ----------------------------------------------------- var curry = require('core.lambda').curry var deepEqual = require('deep-equal') var Validation = require('data.validation') var singleDivergence = require('./divergence').divergence var divergence = require('./divergence').invertibleDivergence // -- Aliases ---------------------------------------------------------- var Success = Validation.Success var Failure = Validation.Failure var classOf = Function.call.bind(Object.prototype.toString) var isPrototypeOf = Function.call.bind(Object.prototype.isPrototypeOf) // -- Helpers ---------------------------------------------------------- /** * Makes an assertion about a piece of data. * * This is a low-level method, and should be only used as a basis for * constructing higher-level validations, not as a validation itself. * * @method * @summary Boolean → Divergence → Object → Validation[Divergence, Divergence] */ exports.assert = curry(2, assert) function assert(thing, divergence) { return thing? Success(divergence) : /* otherwise */ Failure(divergence) } /** * Checks if an exception matches an expected type. * * @private * @summary * Error → Void → Boolean * Error → String → Boolean * Error → RegExp → Boolean * Error → Function → Boolean */ function matchErrorType(error, type) { return type == null? false : isString(type)? error.message === type : isTestable(type)? type.test(error) : /* otherwise */ error instanceof type } /** * Checks if something is a String. * * @private * @summary α → Boolean */ function isString(a) { return classOf(a) === '[object String]' } /** * Checks if something is testable. * * @private * @summary α → Boolean */ function isTestable(a) { return a.test &amp;&amp; typeof a.test === 'function' } /** * Inverts a divergence. * * @private * @summary Divergence → Divergence */ function invert(a) { return a.inverse() } /** * Verifies if two objects are equal. * * @private * @summary a, a → Boolean */ function isEqual(a, b) { var sender = Object(a) return 'equals' in sender? a.equals(b) : 'isEqual' in sender? a.isEqual(b) : /* otherwise */ deepEqual(a, b) } // -- Validations ------------------------------------------------------ /** * Negates an assertion function. * * @method * @summary (α → Validation[Divergence, Divergence]) → α → Validation[Divergence, Divergence] */ exports.not = curry(2, not) function not(checker, a) { return checker(a).swap() .bimap(invert, invert) } /** * Asserts structural (deep) equality between two values. * * @method * @summary α → β → Validation[Divergence, Divergence] */ exports.equal = curry(2, equal) function equal(a, b) { return assert( isEqual(a, b) , divergence( '{:actual} to structurally equal {:expected}' , '{:actual} to not structurally equal {:expected}' ).make({ expected: a, actual: b })) } /** * Asserts that something is truthy. * * @method * @summary α → Validation[Divergence, Divergence] */ exports.ok = ok function ok(a) { return assert( !!a , divergence( '{:actual} to be ok' , '{:actual} to not be ok' ).make({ actual: a })) } /** * Asserts strict equality (===) between two values. * * @method * @summary α → β → Validation[Divergence, Divergence] */ exports.strictEqual = curry(2, strictEqual) function strictEqual(a, b) { return assert( a === b , divergence( '{:actual} to structurally equal {:expected}' , '{:actual} to not structurally equal {:expected}' ).make({ expected: a, actual: b })) } /** * Asserts that something is of a certain type (according to `typeof`). * * @method * @summary String → α → Validation[Divergence, Divergence] */ exports.haveType = curry(2, haveType) function haveType(type, a) { return assert( typeof a === type , divergence( '{:actual} to be of type "{:type}"' , '{:actual} to not be of type "{:type}"' ).make({ type: type, actual: a })) } /** * Asserts that something has a certain internal `[[Class]]`. * * @method * @summary String → α → Validation[Divergence, Divergence] */ exports.haveClass = curry(2, haveClass) function haveClass(className, a) { var actualClass = classOf(a).slice(8, -1) return assert( className === actualClass , divergence( '{:actual} to be of class "{:class}," got "{:actualClass}"' , '{:actual} to not be of class "{:class}"' ).make({ actual : a , 'class' : className , actualClass : actualClass })) } /** * Asserts that something has another thing in its prototype chain. * * @method * @summary Object → Object → Validation[Divergence, Divergence] */ exports.inheritFrom = curry(2, inheritFrom) function inheritFrom(proto, a) { return assert( isPrototypeOf(proto, a) , divergence( '{:actual} to inherit from {:proto}' , '{:actual} to not inherit from {:proto}' ).make({ actual: a , proto: proto })) } /** * Asserts that a contains something as a value. * * @method * @summary α → Sequence[α] → Validation[Divergence, Divergence] */ exports.contain = curry(2, contain) function contain(x, xs) { return assert( xs.indexOf(x) != -1 , divergence( '{:actual} to contain {:thing}' , '{:actual} to not contain {:thing}' ).make({ actual: xs, thing: x })) } /** * Asserts that a value matches a regular expression. * * @method * @summary RegExp → String → Validation[Divergence, Divergence] */ exports.match = curry(2, match) function match(re, text) { return assert( re.test(text) , divergence( '{:text} to match {:re}' , '{:text} to not match {:re}' ).make({ text: text, re: re })) } /** * Asserts that a value has a certain property. * * @method * @summary String → Object → Validation[Divergence, Divergence] */ exports.have = curry(2, have) function have(name, object) { return assert( name in object , divergence( '{:actual} to have property "{:name}"' , '{:actual} to not have property "{:name}"' ).make({ actual: object, name: name })) } /** * Asserts that a computation throws a particular exception. * * @method * @summary Error → (Void → Void :: partial) → Validation[Divergence, Divergence] */ exports.raise = curry(2, raise) function raise(errorType, computation) { var _divergence = divergence( 'to throw an error {:errorType}' , 'to not throw an error {:errorType}' ).make({ errorType: errorType || '' }) try { computation() return assert(true, _divergence) } catch(e) { return assert(matchErrorType(e, errorType), _divergence) } }</pre> </article> </section> </div> <div class="clearfix"></div> <footer> <span class="copyright"> © 2014 Origami Tower </span> <br /> <span class="jsdoc-message"> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.0-alpha9</a> on Thu Dec 25 2014 14:27:25 GMT-0200 (BRST) using the <a href="https://github.com/terryweiss/docstrap">DocStrap template</a>. </span> </footer> </div> <br clear="both"> </div> </div> <script src="scripts/sunlight.js"></script> <script src="scripts/sunlight.javascript.js"></script> <script src="scripts/sunlight-plugin.doclinks.js"></script> <script src="scripts/sunlight-plugin.linenumbers.js"></script> <script src="scripts/sunlight-plugin.menu.js"></script> <script src="scripts/jquery.min.js"></script> <script src="scripts/jquery.scrollTo.js"></script> <script src="scripts/jquery.localScroll.js"></script> <script src="scripts/bootstrap-dropdown.js"></script> <script src="scripts/toc.js"></script> <script> Sunlight.highlightAll({lineNumbers:true, showMenu: true, enableDoclinks :true}); </script> <script> $( function () { $( "#toc" ).toc( { anchorName : function(i, heading, prefix) { return $(heading).attr("id") || ( prefix + i ); }, selectors : "h1,h2,h3,h4", showAndHide : false, scrollTo : 60 } ); $( "#toc>ul" ).addClass( "nav nav-pills nav-stacked" ); $( "#main span[id^='toc']" ).addClass( "toc-shim" ); } ); </script> </body> </html>