intertype
Advanced tools
Comparing version 2.5.0 to 2.5.1
@@ -1,2 +0,1 @@ | ||
// Generated by CoffeeScript 2.4.1 | ||
(function() { | ||
@@ -556,8 +555,194 @@ 'use strict'; | ||
//----------------------------------------------------------------------------------------------------------- | ||
this["validation with intermediate results"] = function(T, done) { | ||
var FS, PATH, R, check_fso_exists, check_integer, check_is_file, check_is_json_file, declare, error, i, intertype, is_happy, is_sad, isa, isa_integer, len, path, paths, sad, sadden, validate, validate_integer; | ||
//......................................................................................................... | ||
PATH = require('path'); | ||
FS = require('fs'); | ||
intertype = new Intertype; | ||
({isa, validate, declare} = intertype.export()); | ||
sad = Symbol('sad'); // will be made attribute of `intertype` | ||
//......................................................................................................... | ||
/* | ||
* `validate.t x, ...`—returns `true` on success, throws error otherwise | ||
* `isa.t x, ...`—returns `true` on success, `false` otherwise | ||
* `check.t x, ...`—returns any kind of happy value on success, a sad value otherwise | ||
* * `is.t x, ...`—short for `not is_sad check.t x, ...` (???) | ||
Distinguish between | ||
* `isa.t x` with *single* argument: this tests for *constant* types (including `isa.even x` which tests | ||
against remainder of constant `n = 2`). `isa` methods always return a boolean value. | ||
* `check.t x, ...` with *variable* number of arguments (which may include previously obtained results for | ||
better speed, consistency); this includes `check.multiple_of x, 2` which is equivalent to `isa.even x` | ||
but parametrizes `n`. Checks return arbitrary values; this also holds for failed checks since even a | ||
failed check may have collected some potentially expensive data. A check has failed when its return | ||
value is sad (i.e. when `is_sad check.t x, ...` or equivalently `not is_happy check.t x, ...` is | ||
`true`), and vice versa. | ||
`sad` is the JS symbol `intertype.sad`; it has the property that it 'is sad', i.e. `is_sad intertype.sad` | ||
returns `true`. | ||
`is_sad x` is `true` for | ||
* `sad` itself, | ||
* instances of `Error`s | ||
* all objects that have an attribute `x[ sad ]` whose value is `true`. | ||
Conversely, `is_sad x` is `false` | ||
* all primitive values except `sad` itself, | ||
* for all objects `x` except those where `x[ sad ] === true`. | ||
One should never use <strike>`r is sad`</strike> to test for a bad result, as that will only capture cases | ||
where a checker returned the `sad` symbol; instead, always use `is_sad r`. | ||
There is an equivalence (invariance) between checks, isa-tests and validations such that it is always | ||
possible to express one in terms of the other, e.g. | ||
``` | ||
check_integer = ( x ) -> return try x if ( validate.integer x ) catch error then error | ||
isa_integer = ( x ) -> is_happy check_integer x | ||
validate_integer = ( x ) -> if is_happy ( R = check_integer x ) then return R else throw R | ||
``` | ||
*/ | ||
is_sad = function(x) { | ||
return (x === sad) || (x instanceof Error) || ((isa.object(x)) && (x[sad] === true)); | ||
}; | ||
is_happy = function(x) { | ||
return !is_sad(x); | ||
}; | ||
sadden = function(x) { | ||
return { | ||
[sad]: true, | ||
_: x | ||
}; | ||
}; | ||
//......................................................................................................... | ||
check_fso_exists = function(path, stats = null) { | ||
var error; | ||
try { | ||
return stats != null ? stats : FS.statSync(path); | ||
} catch (error1) { | ||
error = error1; | ||
return error; | ||
} | ||
}; | ||
//......................................................................................................... | ||
check_is_file = function(path, stats = null) { | ||
var bad; | ||
if (is_sad((bad = stats = check_fso_exists(path, stats)))) { | ||
/* Checks if `path` exists, points to a file, is readable, and parses as a JSON file | ||
Malfunction Risks: | ||
* see `check_fso_exists()` &c. | ||
* FS-related race conditions, including | ||
* longish timeouts for paths pointing to non-local or otherwise misbehaving FS resources. | ||
*/ | ||
//....................................................................................................... | ||
/* in this case, `stats` is `sad` when `check_fso_exists()` fails; in the general case, it could be any | ||
manner of object whose computation required effort, so we want to keep it; we document that fact by | ||
aliasing it as `bad`: */ | ||
return bad; | ||
} | ||
if (stats.isFile()) { | ||
return stats; | ||
} | ||
return sadden(`not a file: ${path}`); | ||
}; | ||
//......................................................................................................... | ||
check_is_json_file = function(path) { | ||
var error; | ||
try { | ||
/* Checks if `path` exists, points to a file, is readable, and is parsable as a JSON file; as a | ||
side-effect, returns the result of parsing when successful. | ||
Malfunction Risks: | ||
* see `check_is_file()` &c. | ||
* file will be read and parsed synchronously; as such, an arbitrary amount of time and space could be | ||
required in case `path` points to a large file and/or is slow to parse | ||
*/ | ||
// return bad if is_sad ( bad = stats = check_is_file path, stats ) | ||
return JSON.parse(FS.readFileSync(path)); | ||
} catch (error1) { | ||
error = error1; | ||
return error; | ||
} | ||
}; | ||
//......................................................................................................... | ||
debug('^377332-1^', is_sad(sad)); | ||
debug('^377332-6^', is_sad({ | ||
[sad]: true | ||
})); | ||
debug('^377332-7^', is_sad(new Error("wat"))); | ||
debug('^377332-2^', is_sad(42)); | ||
debug('^377332-3^', is_sad(false)); | ||
debug('^377332-4^', is_sad(null)); | ||
debug('^377332-5^', is_sad({ | ||
[sad]: false | ||
})); | ||
paths = [PATH.resolve(PATH.join(__dirname, '../../package.json')), PATH.resolve(PATH.join(__dirname, '../../XXXXX'))]; | ||
for (i = 0, len = paths.length; i < len; i++) { | ||
path = paths[i]; | ||
R = null; | ||
while (true) { | ||
if (is_sad((R = check_is_json_file(path, R)))) { | ||
// break if ( R = check_fso_exists path, R ) is sad | ||
// break if ( R = check_is_file path, R ) is sad | ||
break; | ||
} | ||
break; | ||
} | ||
if (is_sad(R)) { | ||
warn("fails with", (rpr(R)).slice(0, 80)); | ||
} else { | ||
help("is JSON file; contents:", (jr(R)).slice(0, 100)); | ||
} | ||
} | ||
warn('^99282^', (error = check_fso_exists('XXXXX')).code, CND.grey(error.message)); | ||
warn('^99282^', (error = check_is_file('XXXXX')).code, CND.grey(error.message)); | ||
warn('^99282^', (error = check_is_json_file('XXXXX')).code, CND.grey(error.message)); | ||
//......................................................................................................... | ||
/* Turning a type declaration into a check */ | ||
check_integer = function(x) { | ||
try { | ||
if (validate.integer(x)) { | ||
return x; | ||
} | ||
} catch (error1) { | ||
error = error1; | ||
return error; | ||
} | ||
}; | ||
isa_integer = function(x) { | ||
return is_happy(check_integer(x)); | ||
}; | ||
validate_integer = function(x) { | ||
if (is_happy((R = check_integer(x)))) { | ||
return R; | ||
} else { | ||
throw R; | ||
} | ||
}; | ||
//......................................................................................................... | ||
debug('^333442^', check_integer(42)); | ||
debug('^333442^', check_integer(42.5)); | ||
debug('^333442^', isa_integer(42)); | ||
debug('^333442^', isa_integer(42.5)); | ||
// debug stats | ||
// [ type, x, ] = probe | ||
// result = validate_list_of type, x | ||
// T.eq result, matcher | ||
done(); | ||
return null; | ||
}; | ||
//########################################################################################################### | ||
if (module.parent == null) { | ||
// test @ | ||
test(this["vnr, int32"]); | ||
test(this); | ||
} | ||
// test @[ "validation with intermediate results" ] | ||
// test @[ "vnr, int32" ] | ||
// test @[ "cast" ] | ||
@@ -762,3 +947,1 @@ // test @[ "isa.list_of A" ] | ||
}).call(this); | ||
//# sourceMappingURL=main.test.js.map |
{ | ||
"name": "intertype", | ||
"version": "2.5.0", | ||
"version": "2.5.1", | ||
"description": "A JavaScript typechecker", | ||
@@ -20,9 +20,9 @@ "main": "lib/main.js", | ||
"dependencies": { | ||
"cnd": "^4.5.0", | ||
"cnd": "^4.6.0", | ||
"lodash.flattendeep": "^4.4.0", | ||
"multimix": "^2.0.0" | ||
"multimix": "^2.1.0" | ||
}, | ||
"devDependencies": { | ||
"guy-test": "^1.4.0" | ||
"guy-test": "^1.4.1" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1933
229813
1
Updatedcnd@^4.6.0
Updatedmultimix@^2.1.0