Comparing version 0.2.3 to 0.2.4
543
assert.js
@@ -1,143 +0,187 @@ | ||
(function (root, factory) { | ||
'use strict'; | ||
if (typeof define === 'function' && define.amd) { | ||
define([], factory); | ||
} else if (typeof exports === 'object') { | ||
module.exports = factory(); | ||
} else { | ||
root.f = factory(); | ||
// flowcheck 0.2.3 | ||
// https://github.com/gcanti/flowcheck | ||
// (c) 2015 Giulio Canti <giulio.canti@gmail.com> | ||
// flowcheck may be freely distributed under the MIT license. | ||
// (checked with Flow and transpiled with jsx) | ||
/* @flow */ | ||
'use strict'; | ||
function getFunctionName(f) { | ||
return f.displayName || f.name || ("<function" + f.length + ">"); | ||
} | ||
function Failure(actual, expected, ctx) { | ||
this.actual = actual; | ||
this.expected = expected; | ||
this.ctx = ctx; | ||
} | ||
Failure.prototype.toString = function () { | ||
var ctx = this.ctx ? this.ctx.join(' / ') : ''; | ||
ctx = ctx ? (", context: " + ctx) : ', (no context)'; | ||
return ("Expected an instance of " + this.expected.name + " got " + (Failure.stringify(this.actual) + ctx)); | ||
}; | ||
Failure.stringify = function (x) { | ||
try { // handle circular references | ||
return JSON.stringify(x, function (k, v) { | ||
if (typeof v === 'function') { | ||
return ("[" + getFunctionName(v) + ", Function]"); | ||
} // handle functions | ||
if (v instanceof RegExp) { | ||
return ("[" + String(v) + ", RegExp]"); | ||
} // handle regexps | ||
return v; | ||
}, 2); | ||
} catch (e) { | ||
return String(x); | ||
} | ||
}(this, function () { | ||
'use strict'; | ||
function Failure(actual, expected, ctx) { | ||
this.actual = actual; | ||
this.expected = expected; | ||
this.ctx = ctx; | ||
}; | ||
function Type(name, validate) { | ||
this.name = name; | ||
this.validate = validate; | ||
} | ||
Type.prototype.is = function (x) { | ||
return this.validate(x, null, true) === null; | ||
}; | ||
function define(name, is) { | ||
var type = new Type(name, function (x, ctx) { | ||
return is(x) ? null : [new Failure(x, type, ctx)]; | ||
}); | ||
return type; | ||
} | ||
var Any = define('any', function () { | ||
return true; | ||
}); | ||
var Mixed = define('mixed', function () { | ||
return true; | ||
}); | ||
var Void = define('void', function (x) { | ||
return x === void 0; | ||
}); | ||
var Str = define('string', function (x) { | ||
return typeof x === 'string'; | ||
}); | ||
var Num = define('number', function (x) { | ||
return typeof x === 'number'; | ||
}); | ||
var Bool = define('boolean', function (x) { | ||
return x === true || x === false; | ||
}); | ||
var Arr = define('array', function (x) { | ||
return x instanceof Array; | ||
}); | ||
var Obj = define('object', function (x) { | ||
return x !== null && x !== undefined && typeof x === 'object' && !Arr.is(x); | ||
}); | ||
var Func = define('function', function (x) { | ||
return typeof x === 'function'; | ||
}); | ||
function validate(x, type, ctx, failOnFirstError) { | ||
if (type.validate) { | ||
return type.validate(x, ctx, failOnFirstError); | ||
} | ||
Failure.prototype.toString = function () { | ||
var ctx = this.ctx ? this.ctx.join(' / ') : ''; | ||
ctx = ctx ? ', context: ' + ctx : ', (no context)'; | ||
return 'Expected an instance of ' + this.expected.name + | ||
' got ' + JSON.stringify(this.actual) + ctx; | ||
}; | ||
function Type(name, validate, is) { | ||
this.name = name; | ||
this.validate = validate; | ||
if (is) { this.is = is; } | ||
} | ||
Type.prototype.is = function (x) { | ||
return this.validate(x, null, true) === null; | ||
}; | ||
function define(name, is) { | ||
var type = new Type(name, function (x, ctx) { | ||
return is(x) ? null : [new Failure(x, type, ctx)]; | ||
}, is); | ||
return type; | ||
} | ||
var Any = define('any', function () { | ||
return true; | ||
return x instanceof type ? null : [new Failure(x, type, ctx)]; | ||
} | ||
function list(type, name) { | ||
name = name || ("Array<" + type.name + ">"); | ||
return new Type(name, function (x, ctx, failOnFirstError) { | ||
ctx = ctx || []; | ||
ctx.push(name); | ||
// if x is not an array, fail fast | ||
if (!Arr.is(x)) { | ||
return [new Failure(x, Arr, ctx)]; | ||
} | ||
var errors = null, | ||
suberrors; | ||
for (var i = 0, len = x.length; i < len; i++) { | ||
suberrors = validate(x[i], type, ctx.concat(i)); | ||
if (suberrors) { | ||
if (failOnFirstError) { | ||
return suberrors; | ||
} | ||
errors = errors || []; | ||
errors.push.apply(errors, suberrors); | ||
} | ||
} | ||
return errors; | ||
}); | ||
var Mixed = define('mixed', function () { | ||
return true; | ||
} | ||
function optional(type, name) { | ||
name = name || (type.name + "?"); | ||
return new Type(name, function (x, ctx, failOnFirstError) { | ||
if (x === void 0) { | ||
return null; | ||
} | ||
ctx = ctx || []; | ||
ctx.push(name); | ||
return validate(x, type, ctx, failOnFirstError); | ||
}); | ||
var Void = define('void', function (x) { | ||
return x === void 0; | ||
} | ||
function maybe(type, name) { | ||
name = name || ("?" + type.name); | ||
return new Type(name, function (x, ctx, failOnFirstError) { | ||
if (x === null) { | ||
return null; | ||
} | ||
ctx = ctx || []; | ||
ctx.push(name); | ||
return validate(x, type, ctx, failOnFirstError); | ||
}); | ||
var Str = define('string', function (x) { | ||
return typeof x === 'string'; | ||
} | ||
function getName(type) { | ||
return type.name; | ||
} | ||
function tuple(types, name) { | ||
name = name || ("[" + types.map(getName).join(', ') + "]"); | ||
var dimension = types.length; | ||
var type = new Type(name, function (x, ctx, failOnFirstError) { | ||
ctx = ctx || []; | ||
// if x is not an array, fail fast | ||
if (!Arr.is(x)) { | ||
return [new Failure(x, Arr, ctx.concat(name))]; | ||
} | ||
// if x has a wrong length, fail failOnFirstError | ||
if (x.length !== dimension) { | ||
return [new Failure(x, type, ctx)]; | ||
} | ||
var errors = null, | ||
suberrors; | ||
for (var i = 0; i < dimension; i++) { | ||
suberrors = validate(x[i], types[i], ctx.concat(name, i)); | ||
if (suberrors) { | ||
if (failOnFirstError) { | ||
return suberrors; | ||
} | ||
errors = errors || []; | ||
errors.push.apply(errors, suberrors); | ||
} | ||
} | ||
return errors; | ||
}); | ||
var Num = define('number', function (x) { | ||
return typeof x === 'number'; | ||
}); | ||
var Bool = define('boolean', function (x) { | ||
return x === true || x === false; | ||
}); | ||
var Arr = define('array', function (x) { | ||
return x instanceof Array; | ||
}); | ||
var Obj = define('object', function (x) { | ||
return x != null && typeof x === 'object' && !Arr.is(x); | ||
}); | ||
var Func = define('function', function (x) { | ||
return typeof x === 'function'; | ||
}); | ||
function validate(x, type, ctx, fast) { | ||
if (type.validate) { return type.validate(x, ctx, fast); } | ||
return x instanceof type ? null : [new Failure(x, type, ctx)]; | ||
} | ||
function list(type, name) { | ||
name = name || 'Array<' + type.name + '>'; | ||
return new Type(name, function (x, ctx, fast) { | ||
ctx = ctx || []; | ||
ctx.push(name); | ||
// if x is not an array, fail fast | ||
if (!Arr.is(x)) { return [new Failure(x, Arr, ctx)]; } | ||
var errors = null, suberrors; | ||
for (var i = 0, len = x.length ; i < len ; i++ ) { | ||
suberrors = validate(x[i], type, ctx.concat(i)); | ||
return type; | ||
} | ||
function dict(domain, codomain, name) { | ||
name = name || ("{[key: " + domain.name + "]: " + codomain.name + "}"); | ||
return new Type(name, function (x, ctx, failOnFirstError) { | ||
ctx = ctx || []; | ||
// if x is not an object, fail fast | ||
if (!Obj.is(x)) { | ||
return [new Failure(x, Obj, ctx.concat(name))]; | ||
} | ||
var errors = null, | ||
suberrors; | ||
for (var k in x) { | ||
if (x.hasOwnProperty(k)) { | ||
// check domain | ||
suberrors = validate(k, domain, ctx.concat(name, k)); | ||
if (suberrors) { | ||
if (fast) { return suberrors; } | ||
if (failOnFirstError) { | ||
return suberrors; | ||
} | ||
errors = errors || []; | ||
errors.push.apply(errors, suberrors); | ||
} | ||
} | ||
return errors; | ||
}); | ||
} | ||
function optional(type, name) { | ||
name = name || type.name + '?'; | ||
return new Type(name, function (x, ctx, fast) { | ||
if (x === void 0) { return null; } | ||
ctx = ctx || []; | ||
ctx.push(name); | ||
return validate(x, type, ctx, fast); | ||
}); | ||
} | ||
function maybe(type, name) { | ||
name = name || '?' + type.name; | ||
return new Type(name, function (x, ctx, fast) { | ||
if (x === null) { return null; } | ||
ctx = ctx || []; | ||
ctx.push(name); | ||
return validate(x, type, ctx, fast); | ||
}); | ||
} | ||
function getName(type) { | ||
return type.name; | ||
} | ||
function tuple(types, name) { | ||
name = name || '[' + types.map(getName).join(', ') + ']'; | ||
var dimension = types.length; | ||
var type = new Type(name, function (x, ctx, fast) { | ||
ctx = ctx || []; | ||
// if x is not an array, fail fast | ||
if (!Arr.is(x)) { return [new Failure(x, Arr, ctx.concat(name))]; } | ||
// if x has a wrong length, fail fast | ||
if (x.length !== dimension) { return [new Failure(x, type, ctx)]; } | ||
var errors = null, suberrors; | ||
for (var i = 0 ; i < dimension ; i++ ) { | ||
suberrors = validate(x[i], types[i], ctx.concat(name, i)); | ||
// check codomain | ||
suberrors = validate(x[k], codomain, ctx.concat(name, k)); | ||
if (suberrors) { | ||
if (fast) { return suberrors; } | ||
if (failOnFirstError) { | ||
return suberrors; | ||
} | ||
errors = errors || []; | ||
@@ -147,140 +191,125 @@ errors.push.apply(errors, suberrors); | ||
} | ||
return errors; | ||
}); | ||
return type; | ||
} | ||
function dict(domain, codomain, name) { | ||
name = name || '{[key: ' + domain.name + ']: ' + codomain.name + '}'; | ||
return new Type(name, function (x, ctx, fast) { | ||
ctx = ctx || []; | ||
// if x is not an object, fail fast | ||
if (!Obj.is(x)) { return [new Failure(x, Obj, ctx.concat(name))]; } | ||
var errors = null, suberrors; | ||
for (var k in x) { | ||
if (x.hasOwnProperty(k)) { | ||
// check domain | ||
suberrors = validate(k, domain, ctx.concat(name, k)); | ||
if (suberrors) { | ||
if (fast) { return suberrors; } | ||
errors = errors || []; | ||
errors.push.apply(errors, suberrors); | ||
} | ||
return errors; | ||
}); | ||
} | ||
function shape(props, name) { | ||
name = name || ("{" + Object.keys(props).map(function (k) { | ||
return k + ': ' + props[k].name + ';'; | ||
}).join(' ') + "}"); | ||
return new Type(name, function (x, ctx, failOnFirstError) { | ||
ctx = ctx || []; | ||
// if x is not an object, fail fast | ||
if (!Obj.is(x)) { | ||
return [new Failure(x, Obj, ctx.concat(name))]; | ||
} | ||
var errors = null, | ||
suberrors; | ||
for (var k in props) { | ||
if (props.hasOwnProperty(k)) { | ||
suberrors = validate(x[k], props[k], ctx.concat(name, k)); | ||
if (suberrors) { | ||
if (failOnFirstError) { | ||
return suberrors; | ||
} | ||
// check codomain | ||
suberrors = validate(x[k], codomain, ctx.concat(name, k)); | ||
if (suberrors) { | ||
if (fast) { return suberrors; } | ||
errors = errors || []; | ||
errors.push.apply(errors, suberrors); | ||
} | ||
errors = errors || []; | ||
errors.push.apply(errors, suberrors); | ||
} | ||
} | ||
return errors; | ||
}); | ||
} | ||
return errors; | ||
}); | ||
} | ||
function union(types, name) { | ||
name = name || types.map(getName).join(' | '); | ||
var type = new Type(name, function (x, ctx) { | ||
if (types.some(function (type) { | ||
return type.is(x); | ||
})) { | ||
return null; | ||
} | ||
ctx = ctx || []; | ||
return [new Failure(x, type, ctx.concat(name))]; | ||
}); | ||
return type; | ||
} | ||
function slice(arr, start, end) { | ||
return Array.prototype.slice.call(arr, start, end); | ||
} | ||
function args(types, varargs) { | ||
var name = ("(" + types.map(getName).join(', ') + ", ..." + (varargs || Any).name + ")"); | ||
var length = types.length; | ||
var typesTuple = tuple(types); | ||
if (varargs) { | ||
varargs = list(varargs); | ||
} | ||
function shape(props, name) { | ||
name = name || '{' + Object.keys(props).map(function (k) { return k + ': ' + props[k].name + ';'; }).join(' ') + '}'; | ||
return new Type(name, function (x, ctx, fast) { | ||
ctx = ctx || []; | ||
// if x is not an object, fail fast | ||
if (!Obj.is(x)) { return [new Failure(x, Obj, ctx.concat(name))]; } | ||
var errors = null, suberrors; | ||
for (var k in props) { | ||
if (props.hasOwnProperty(k)) { | ||
suberrors = validate(x[k], props[k], ctx.concat(name, k)); | ||
if (suberrors) { | ||
if (fast) { return suberrors; } | ||
errors = errors || []; | ||
errors.push.apply(errors, suberrors); | ||
} | ||
} | ||
return new Type(name, function (x, ctx, failOnFirstError) { | ||
ctx = ctx || []; | ||
var args = x; | ||
// test if args is an array-like structure | ||
if (args.hasOwnProperty('length')) { | ||
args = slice(args, 0, length); | ||
// handle optional arguments filling the array with undefined values | ||
if (args.length < length) { | ||
args.length = length; | ||
} | ||
return errors; | ||
}); | ||
} | ||
function union(types, name) { | ||
name = name || types.map(getName).join(' | '); | ||
var type = new Type(name, function (x, ctx) { | ||
if (types.some(function (type) { | ||
return type.is(x); | ||
})) { return null; } | ||
ctx = ctx || []; | ||
return [new Failure(x, type, ctx.concat(name))]; | ||
}); | ||
return type; | ||
} | ||
function slice(arr, start, end) { | ||
return Array.prototype.slice.call(arr, start, end); | ||
} | ||
function args(types, varargs) { | ||
var name = '(' + types.map(getName).join(', ') + ', ...' + (varargs || Any).name + ')'; | ||
var len = types.length; | ||
var typesTuple = tuple(types); | ||
if (varargs) { varargs = list(varargs); } | ||
return new Type(name, function (x, ctx, fast) { | ||
ctx = ctx || []; | ||
var args = x; | ||
// test if args is an array-like structure | ||
if (args.hasOwnProperty('length')) { | ||
args = slice(args, 0, len); | ||
// handle optional arguments filling the array with undefined values | ||
if (args.length < len) { args.length = len; } | ||
} | ||
var errors = null, | ||
suberrors; | ||
suberrors = typesTuple.validate(args, ctx.concat('arguments'), failOnFirstError); | ||
if (suberrors) { | ||
if (failOnFirstError) { | ||
return suberrors; | ||
} | ||
var errors = null, suberrors; | ||
suberrors = typesTuple.validate(args, ctx.concat('arguments'), fast); | ||
errors = errors || []; | ||
errors.push.apply(errors, suberrors); | ||
} | ||
if (varargs) { | ||
suberrors = varargs.validate(slice(x, length), ctx.concat('varargs'), failOnFirstError); | ||
if (suberrors) { | ||
if (fast) { return suberrors; } | ||
if (failOnFirstError) { | ||
return suberrors; | ||
} | ||
errors = errors || []; | ||
errors.push.apply(errors, suberrors); | ||
} | ||
if (varargs) { | ||
suberrors = varargs.validate(slice(x, len), ctx.concat('varargs'), fast); | ||
if (suberrors) { | ||
if (fast) { return suberrors; } | ||
errors = errors || []; | ||
errors.push.apply(errors, suberrors); | ||
} | ||
} | ||
return errors; | ||
}); | ||
} | ||
function check(x, type) { | ||
var errors = validate(x, type); | ||
if (errors) { | ||
var message = [].concat(errors).join('\n'); | ||
} | ||
return errors; | ||
}); | ||
} | ||
var failed = false; | ||
function check(x, type) { | ||
var errors = validate(x, type); | ||
if (errors) { | ||
var message = [].concat(errors).join('\n'); | ||
if (!failed) { // start the debugger only once | ||
/*jshint debug: true*/ | ||
debugger; | ||
throw new TypeError(message); | ||
} | ||
return x; | ||
failed = true; | ||
throw new TypeError(message); | ||
} | ||
var exports = { | ||
Type: Type, | ||
define: define, | ||
any: Any, | ||
mixed: Mixed, | ||
'void': Void, | ||
number: Num, | ||
string: Str, | ||
'boolean': Bool, | ||
object: Obj, | ||
'function': Func, | ||
list: list, | ||
optional: optional, | ||
maybe: maybe, | ||
tuple: tuple, | ||
dict: dict, | ||
shape: shape, | ||
union: union, | ||
arguments: args, | ||
check: check | ||
}; | ||
return exports; | ||
})); | ||
return x; | ||
} | ||
module.exports = { | ||
Failure: Failure, | ||
Type: Type, | ||
define: define, | ||
any: Any, | ||
mixed: Mixed, | ||
'void': Void, | ||
number: Num, | ||
string: Str, | ||
'boolean': Bool, | ||
object: Obj, | ||
'function': Func, | ||
list: list, | ||
optional: optional, | ||
maybe: maybe, | ||
tuple: tuple, | ||
dict: dict, | ||
shape: shape, | ||
union: union, | ||
arguments: args, | ||
check: check | ||
}; |
@@ -1,19 +0,43 @@ | ||
v0.2.3 2015-02-06 | ||
# Changelog | ||
- it shouldn't die if requiring JSON, fix #12 | ||
> **Tags:** | ||
> - [New Feature] | ||
> - [Bug Fix] | ||
> - [Breaking Change] | ||
> - [Documentation] | ||
> - [Internal] | ||
> - [Polish] | ||
v0.2.1 2015-01-23 | ||
**Note**: Gaps between patch versions are faulty/broken releases. | ||
- changed the default namespace from `f` to `_f` to avoid likely name conflicts | ||
- added a `visitProgram` to `visitor.js`. It adds `var _f = require("flowcheck/assert");` at the beginning of the file, fix #4 | ||
- added a boolean option `skipImport` (default `false`). If set to `true`, skips the `visitProgram` visitor (useful for tests or if you want to import by hand the module flowcheck/assert as a global) | ||
- added to `visitProgram` a `namespace.indexOf('require') === -1` check in order to not break flowcheck-loader (temporary) | ||
## v0.2.4 | ||
v0.2 2015-01-21 | ||
- **Bug Fix** | ||
+ Removed CRLF from `visitProgram` causing wrong bad sourceMaps | ||
- **Internal** | ||
+ Upgrade to latest babelify | ||
- polished code | ||
- added more tests | ||
## v0.2.3 | ||
v0.1 2015-01-20 | ||
- **Internal** | ||
+ It shouldn't die if requiring JSON, fix #12 | ||
- first release | ||
## v0.2.1 | ||
- **Internal** | ||
+ Changed the default namespace from `f` to `_f` to avoid likely name conflicts | ||
+ Added a `visitProgram` to `visitor.js`. It adds `var _f = require("flowcheck/assert");` at the beginning of the file, fix #4 | ||
+ Added to `visitProgram` a `namespace.indexOf('require') === -1` check in order to not break flowcheck-loader (temporary) | ||
- **New Feature** | ||
+ Added a boolean option `skipImport` (default `false`). If set to `true`, skips the `visitProgram` visitor (useful for tests or if you want to import by hand the module flowcheck/assert as a global) | ||
## v0.2 | ||
- **Polish** | ||
+ Code refactoring | ||
- **Internal** | ||
+ Added more tests | ||
## v0.1 | ||
- First release |
{ | ||
"name": "flowcheck", | ||
"version": "0.2.3", | ||
"version": "0.2.4", | ||
"description": "Runtime type checking for Flow", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "node test | tap-spec", | ||
"demo": "watchify -t reactify docs/demo/index.jsx -o docs/demo/bundle.js -v -x react" | ||
"test": "node test | tap-spec" | ||
}, | ||
@@ -25,8 +24,13 @@ "repository": { | ||
"devDependencies": { | ||
"6to5ify": "^3.1.2", | ||
"babelify": "^6.0.2", | ||
"browserify": "^8.1.1", | ||
"codemirror": "^4.11.0", | ||
"gulp": "^3.8.10", | ||
"gulp-beautify": "^1.1.2", | ||
"gulp-header": "^1.2.2", | ||
"gulp-jshint": "^1.9.2", | ||
"gulp-react": "^2.0.0", | ||
"js-beautify": "^1.5.4", | ||
"jshint-stylish": "^1.0.0", | ||
"react-code-mirror": "^3.0.3", | ||
"reactify": "^0.17.1", | ||
"reactify": "^1.1.0", | ||
"tap-spec": "^2.1.1", | ||
@@ -33,0 +37,0 @@ "tape": "^3.0.3" |
'use strict'; | ||
var jstransform = require('jstransform'); | ||
var typeSyntax = require('jstransform/visitors/type-syntax'); | ||
var visitorList = require('./visitors').visitorList; | ||
@@ -12,3 +11,3 @@ var Buffer = require('buffer').Buffer; | ||
options.sourceMap = options['source-map'] || options.sourceMap; | ||
options.module = options['module'] || options.module || 'flowcheck/assert'; | ||
options.module = options.module || 'flowcheck/assert'; | ||
options.skipImport = options['skip-import'] || options.skipImport; | ||
@@ -26,3 +25,3 @@ return options; | ||
json.sourcesContent = [sourceCode]; | ||
var base64 = Buffer(JSON.stringify(json)).toString('base64'); | ||
var base64 = new Buffer(JSON.stringify(json)).toString('base64'); | ||
return '//# sourceMappingURL=data:application/json;base64,' + | ||
@@ -29,0 +28,0 @@ base64; |
@@ -183,3 +183,3 @@ 'use strict'; | ||
} | ||
visitTypedVariableDeclarator.test = function(node, path, state) { | ||
visitTypedVariableDeclarator.test = function(node) { | ||
return node.type === Syntax.VariableDeclarator && | ||
@@ -228,3 +228,3 @@ node.id.typeAnnotation; | ||
} | ||
visitTypedFunction.test = function(node, path, state) { | ||
visitTypedFunction.test = function(node) { | ||
return (node.type === Syntax.FunctionDeclaration || node.type === Syntax.FunctionExpression) && | ||
@@ -248,3 +248,3 @@ ( | ||
} | ||
visitTypeAlias.test = function (node, path, state) { | ||
visitTypeAlias.test = function (node) { | ||
return node.type === Syntax.TypeAlias; | ||
@@ -258,7 +258,7 @@ }; | ||
if (!ctx.skipImport && namespace.indexOf('require') === -1) { | ||
utils.append('var ' + namespace + ' = require(' + JSON.stringify(ctx.module) + ');\n\n', state); | ||
utils.append('var ' + namespace + ' = require(' + JSON.stringify(ctx.module) + ');', state); | ||
} | ||
return true; | ||
} | ||
visitProgram.test = function (node, path, state) { | ||
visitProgram.test = function (node) { | ||
return node.type === Syntax.Program; | ||
@@ -265,0 +265,0 @@ }; |
27091
10
672
13