Skip to content

Commit 2ea1aa2

Browse files
fixed that undefined/null value still reports MissingValue for properties
This commit also marks the first use of Z (sanctuary-type-classes), which should open up for many of the code reductions we already know from Sanctuary. Added one more test for Types with properties/keys, without a name, are missing and the value is null/undefined.
1 parent 6d4f677 commit 2ea1aa2

File tree

2 files changed

+116
-58
lines changed

2 files changed

+116
-58
lines changed

index.js

Lines changed: 80 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,13 @@
251251
};
252252
}
253253

254+
// map :: Functor f => (a -⁠> b) -⁠> f a -⁠> f b
255+
// function map(f) {
256+
// return function(xs) {
257+
// return Z.map (f, xs);
258+
// };
259+
// }
260+
254261
// init :: Array a -> Array a
255262
function init(xs) { return xs.slice (0, -1); }
256263

@@ -1508,9 +1515,64 @@
15081515
//. which refers to the entire value.
15091516
function validate(t) {
15101517
return function(x) {
1518+
// 1. build list of prop, validate function and value object for all keys
1519+
// 2. when value = null, use MissingValue object
1520+
// 3. run all remainder validate functions for nested type validation
1521+
// 4. remove all Rights from list
1522+
// 5. concatenate $$ (in returnValue) with all Lefts
1523+
15111524
var returnValue = [];
15121525
var $$Result = t.validate ([]) (x);
15131526

1527+
// 1 and 2
1528+
// props :: Array (Either Object Object)
1529+
var props = t.keys.map (function(p) {
1530+
return x == null
1531+
? Left ({
1532+
error: 'MissingValue',
1533+
type: t.name || t.type,
1534+
name: p,
1535+
value: x
1536+
})
1537+
: Right ({
1538+
name: p,
1539+
type: t.types[p],
1540+
value: x[p]
1541+
});
1542+
});
1543+
1544+
var validateRights = Z.compose (function(p) {
1545+
if (p.result.isLeft) {
1546+
if (p.name in x) {
1547+
return Left ({
1548+
error: 'WrongValue',
1549+
// TODO: figure out what propPath really is
1550+
type: p.result.value.propPath.length > 0
1551+
? p.type.types[p.result.value.propPath[0]].name
1552+
: p.type.name,
1553+
name: p.name,
1554+
value: p.value
1555+
});
1556+
} else {
1557+
return Left ({
1558+
error: 'MissingValue',
1559+
type: p.type.name,
1560+
name: p.name,
1561+
value: p.value
1562+
});
1563+
}
1564+
} else {
1565+
return Right (p);
1566+
}
1567+
}, function(p) {
1568+
return {
1569+
name: p.name,
1570+
result: p.type.validate ([]) (p.value),
1571+
type: p.type,
1572+
value: p.value
1573+
};
1574+
});
1575+
15141576
returnValue.push (
15151577
$$Result.isLeft
15161578
? Left ({
@@ -1522,43 +1584,24 @@
15221584
: $$Result
15231585
);
15241586

1525-
if (x != null && t.keys.length > 0) {
1526-
var props = t.keys;
1527-
1528-
for (var i = 0, len = props.length; i < len; i += 1) {
1529-
var propName = props[i];
1530-
var propValue = x[propName];
1531-
var type = t.types[propName];
1532-
var result = type.validate ([]) (propValue);
1533-
1534-
if (result.isLeft) {
1535-
if (propName in x) {
1536-
returnValue.push (
1537-
Left ({
1538-
error: 'WrongValue',
1539-
// TODO: figure what propPath really is
1540-
type: result.value.propPath.length > 0
1541-
? type.types[result.value.propPath[0]].name
1542-
: type.name,
1543-
name: propName,
1544-
value: propValue
1545-
})
1546-
);
1547-
} else {
1548-
returnValue.push (
1549-
Left ({
1550-
error: 'MissingValue',
1551-
type: type.name,
1552-
name: propName,
1553-
value: propValue
1554-
})
1555-
);
1556-
}
1557-
}
1558-
}
1559-
}
1560-
1561-
return returnValue;
1587+
// 3
1588+
var tmp0 = Z.map (function(prop) {
1589+
return Z.chain (validateRights, prop);
1590+
}, props);
1591+
1592+
// 4
1593+
var tmp1 = Z.filter (function(either) {
1594+
return either.isLeft;
1595+
}, tmp0);
1596+
1597+
// 5
1598+
return Z.concat (returnValue, tmp1);
1599+
// return Z.concat (
1600+
// returnValue,
1601+
// Z.filter (
1602+
// either => either.isLeft,
1603+
// Z.map (prop => Z.map (validateRights, prop), props))
1604+
// );
15621605
};
15631606
}
15641607

test/index.js

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3898,42 +3898,50 @@ suite ('validate', () => {
38983898

38993899
// null is not a member of ‘FooBar’
39003900
eq ($.validate (FooBar) (null))
3901-
([Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': null})]);
3901+
([
3902+
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': null}),
3903+
Left ({'error': 'MissingValue', 'name': 'bar', 'type': 'FooBar', 'value': null}),
3904+
Left ({'error': 'MissingValue', 'name': 'foo', 'type': 'FooBar', 'value': null}),
3905+
]);
39023906

39033907
// undefined is not a member of ‘FooBar’
39043908
eq ($.validate (FooBar) (undefined))
3905-
([Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': undefined})]);
3909+
([
3910+
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': undefined}),
3911+
Left ({'error': 'MissingValue', 'name': 'bar', 'type': 'FooBar', 'value': undefined}),
3912+
Left ({'error': 'MissingValue', 'name': 'foo', 'type': 'FooBar', 'value': undefined}),
3913+
]);
39063914

39073915
// ''bar' field is missing', ''foo' field is missing'
39083916
eq ($.validate (FooBar) ({}))
3909-
([
3910-
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': {}}),
3911-
Left ({'error': 'MissingValue', 'name': 'bar', 'type': 'Number', 'value': undefined}),
3912-
Left ({'error': 'MissingValue', 'name': 'foo', 'type': 'String', 'value': undefined}),
3913-
]);
3917+
([
3918+
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': {}}),
3919+
Left ({'error': 'MissingValue', 'name': 'bar', 'type': 'Number', 'value': undefined}),
3920+
Left ({'error': 'MissingValue', 'name': 'foo', 'type': 'String', 'value': undefined}),
3921+
]);
39143922

39153923
// 'bar' field is missing
39163924
eq ($.validate (FooBar) ({foo: null}))
3917-
([
3918-
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': {'foo': null}}),
3919-
Left ({'error': 'MissingValue', 'name': 'bar', 'type': 'Number', 'value': undefined}),
3920-
Left ({'error': 'WrongValue', 'name': 'foo', 'type': 'String', 'value': null}),
3921-
]);
3925+
([
3926+
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': {'foo': null}}),
3927+
Left ({'error': 'MissingValue', 'name': 'bar', 'type': 'Number', 'value': undefined}),
3928+
Left ({'error': 'WrongValue', 'name': 'foo', 'type': 'String', 'value': null}),
3929+
]);
39223930

39233931
// Value of 'bar' field, null, is not a member of ‘Number’
39243932
eq ($.validate (FooBar) ({foo: null, bar: null}))
3925-
([
3926-
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': {'bar': null, 'foo': null}}),
3927-
Left ({'error': 'WrongValue', 'name': 'bar', 'type': 'Number', 'value': null}),
3928-
Left ({'error': 'WrongValue', 'name': 'foo', 'type': 'String', 'value': null}),
3929-
]);
3933+
([
3934+
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': {'bar': null, 'foo': null}}),
3935+
Left ({'error': 'WrongValue', 'name': 'bar', 'type': 'Number', 'value': null}),
3936+
Left ({'error': 'WrongValue', 'name': 'foo', 'type': 'String', 'value': null}),
3937+
]);
39303938

39313939
// Value of 'foo' field, null, is not a member of ‘String’
39323940
eq ($.validate (FooBar) ({foo: null, bar: 42}))
3933-
([
3934-
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': {'bar': 42, 'foo': null}}),
3935-
Left ({'error': 'WrongValue', 'name': 'foo', 'type': 'String', 'value': null}),
3936-
]);
3941+
([
3942+
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'FooBar', 'value': {'bar': 42, 'foo': null}}),
3943+
Left ({'error': 'WrongValue', 'name': 'foo', 'type': 'String', 'value': null}),
3944+
]);
39373945

39383946
eq ($.validate (FooBar) ({foo: 'blue', bar: 42}))
39393947
([Right ({foo: 'blue', bar: 42})]);
@@ -3968,6 +3976,13 @@ suite ('validate', () => {
39683976
Left ({'error': 'WrongValue', 'name': 'date', 'type': 'DateIso', 'value': '2020-04-100'}),
39693977
]);
39703978

3979+
eq ($.validate (model2) (undefined))
3980+
([
3981+
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'RECORD', 'value': undefined}),
3982+
Left ({'error': 'MissingValue', 'name': 'date', 'type': 'RECORD', 'value': undefined}),
3983+
Left ({'error': 'MissingValue', 'name': 'bool', 'type': 'RECORD', 'value': undefined}),
3984+
]);
3985+
39713986
eq ($.validate (model2) ({bool: 'foobar', date: '2020-04-100'}))
39723987
([
39733988
Left ({'error': 'WrongValue', 'name': '$$', 'type': 'RECORD', 'value': {'bool': 'foobar', 'date': '2020-04-100'}}),

0 commit comments

Comments
 (0)