Skip to content

Commit

Permalink
customize error message for unrecognized value
Browse files Browse the repository at this point in the history
  • Loading branch information
davidchambers committed May 12, 2017
1 parent 4fecf08 commit 496cab1
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 20 deletions.
60 changes: 40 additions & 20 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,13 @@
return s.slice('('.length, -')'.length);
}

// toMarkdownList :: (String, String, a -> String, Array a) -> String
function toMarkdownList(empty, s, f, xs) {
return isEmpty(xs) ?
empty :
Z.reduce(function(s, x) { return s + ' - ' + f(x) + '\n'; }, s, xs);
}

// trimTrailingSpaces :: String -> String
function trimTrailingSpaces(s) {
return s.replace(/[ ]+$/gm, '');
Expand Down Expand Up @@ -2219,22 +2226,39 @@
);
});

var underlinedTypeVars =
underlineTypeVars(typeInfo,
Z.reduce(function($valuesByPath, k) {
$valuesByPath[k] = valuesByPath[k];
return $valuesByPath;
}, {}, keys));

return new TypeError(trimTrailingSpaces(
'Type-variable constraint violation\n\n' +
underlineTypeVars(typeInfo,
Z.reduce(function($valuesByPath, k) {
$valuesByPath[k] = valuesByPath[k];
return $valuesByPath;
}, {}, keys)) +
Z.reduce(function(st, k) {
var values = valuesByPath[k];
return isEmpty(values) ? st : {
idx: st.idx + 1,
s: st.s + '\n' + showValuesAndTypes(env, values, st.idx + 1) + '\n'
};
}, {idx: 0, s: ''}, keys).s + '\n' +
'Since there is no type of which all the above values are ' +
'members, the type-variable constraint has been violated.\n'
values.length === 1 && isEmpty(determineActualTypesLoose(env, values)) ?
'Unrecognized value\n\n' +
underlinedTypeVars + '\n' +
'1) ' + Z.toString(values[0]) + ' :: (no types)\n\n' +
toMarkdownList(
'The environment is empty! ' +
'Polymorphic functions require a non-empty environment.\n',
'The value at position 1 is not a member of any type in ' +
'the environment.\n\n' +
'The environment contains the following types:\n\n',
showType,
env
) :
// else
'Type-variable constraint violation\n\n' +
underlinedTypeVars + '\n' +
Z.reduce(function(st, k) {
var values = valuesByPath[k];
return isEmpty(values) ? st : {
idx: st.idx + 1,
s: st.s + showValuesAndTypes(env, values, st.idx + 1) + '\n\n'
};
}, {idx: 0, s: ''}, keys).s +
'Since there is no type of which all the above values are ' +
'members, the type-variable constraint has been violated.\n'
));
}

Expand Down Expand Up @@ -2299,11 +2323,7 @@
) + '\n' +
'Expected ' + numArgs(numArgsExpected) +
' but received ' + numArgs(args.length) +
(args.length === 0 ?
'.\n' :
Z.reduce(function(s, x) { return s + ' - ' + Z.toString(x) + '\n'; },
':\n\n',
args))
toMarkdownList('.\n', ':\n\n', Z.toString, args)
));
}

Expand Down
47 changes: 47 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,53 @@ describe('def', function() {
'Since there is no type of which all the above values are members, the type-variable constraint has been violated.\n');
});

it('throws custom error for unrecognized value (empty env)', function() {
var env = [];
var def = $.create({checkTypes: true, env: env});

// id :: a -> a
var id = def('id', {}, [a, a], identity);

throws(function() { id(/xxx/); },
TypeError,
'Unrecognized value\n' +
'\n' +
'id :: a -> a\n' +
' ^\n' +
' 1\n' +
'\n' +
'1) /xxx/ :: (no types)\n' +
'\n' +
'The environment is empty! Polymorphic functions require a non-empty environment.\n');
});

it('throws custom error for unrecognized value (non-empty env)', function() {
var env = [$.Array($.Unknown), $.Boolean, $.Number, $.String];
var def = $.create({checkTypes: true, env: env});

// id :: a -> a
var id = def('id', {}, [a, a], identity);

throws(function() { id(/xxx/); },
TypeError,
'Unrecognized value\n' +
'\n' +
'id :: a -> a\n' +
' ^\n' +
' 1\n' +
'\n' +
'1) /xxx/ :: (no types)\n' +
'\n' +
'The value at position 1 is not a member of any type in the environment.\n' +
'\n' +
'The environment contains the following types:\n' +
'\n' +
' - Array ???\n' +
' - Boolean\n' +
' - Number\n' +
' - String\n');
});

it('returns a function which type checks its return value', function() {
// add :: Number -> Number -> Number
var add = def('add', {}, [$.Number, $.Number, $.Number], always('XXX'));
Expand Down

0 comments on commit 496cab1

Please sign in to comment.