Invariant checker for JavaScript
var someObject = {
swap: function(from, to) {
var amount = this.getAmount();
var gotError = checkArguments({
from: [
{invariant: from < 0, error: 'too small'},
{invariant: from >= amount, error: 'too big'}
],
to: [
{invariant: to < 0, error: 'too small'},
{invariant: to >= amount, error: 'too big'}
]
}, 'someObject.swap');
// you could throw an exception instead if you want to
if(gotError) {
return false;
}
// logic goes here
...
},
...
};
var items = [1, 2, 3];
var index = 1;
checkIndex(index, items.length, 'items');
function checkIndex(index, amount, errorPrefix, suppressWarning) {
function defined(value) {
return typeof(value) !== 'undefined';
}
return checkArguments({
index: [
{invariant: !defined(index), error: 'not defined'},
{invariant: index < 0, error: 'too small'},
{invariant: index >= amount, error: 'too big'}
]
}, errorPrefix, suppressWarning);
};
function checkArguments(errors, errorPrefix, suppressWarning) {
errorPrefix = errorPrefix? errorPrefix + ': ': '';
var gotError = false;
for(var argName in errors) {
// remember to attach forEach to Array or replace this with a more generic
// definition
errors[argName].forEach(function(check) {
if(check.invariant) {
if(!suppressWarning) {
var warning = errorPrefix + argName + ' ' + check.error + '.';
console.warn(warning);
}
gotError = true;
}
})
}
return gotError;
};