Comparing version 9.3.3 to 9.3.4
@@ -28,4 +28,7 @@ /** | ||
// type schema looking for lamda types, and when we find them, parse input values as | ||
// stringified machine fn bodies, converting them to hydrated JavaScript functions. | ||
if (!(typeSchema === 'lamda' || _.isObject(typeSchema) && !_.isEqual(typeSchema, []) && !_.isEqual(typeSchema, {}))) { | ||
// stringified functions, converting them to hydrated JavaScript functions. | ||
// | ||
// But otherwise, we just go ahead and bail. | ||
if (typeSchema !== 'lamda' && | ||
(!_.isObject(typeSchema) || _.isEqual(typeSchema, []) || _.isEqual(typeSchema, {}))) { | ||
return value; | ||
@@ -79,2 +82,6 @@ } | ||
return _.reduce(typeHere, function (memo, unused, subKey){ | ||
// If the key from the type schema contains `.`, then fail with an error. | ||
if ((''+subKey).match(/\./)) { | ||
throw new Error('Keys containing dots (`.`) are not currently supported in the type schema for `rttc.hydrate`.'); | ||
} | ||
memo[subKey] = parseLamdaInputValues(val[subKey], keysSoFar.concat(subKey)); | ||
@@ -81,0 +88,0 @@ return memo; |
@@ -37,3 +37,3 @@ /** | ||
* @param {[type]} secondValue [description] | ||
* @param {[type]} typeSchema [description] | ||
* @param {[type]} typeSchemaHere [description] | ||
* @param {[type]} keypathArray [description] | ||
@@ -43,78 +43,71 @@ * @param {[type]} keyOrIndex [description] | ||
*/ | ||
return (function _isEqualRecursive(firstValue, secondValue, typeSchema, keypathArray, keyOrIndex){ | ||
return (function _isEqualRecursive(firstValue, secondValue, typeSchemaHere, keypathArray, keyOrIndex){ | ||
try { | ||
// If the key or index is a string and contains `.`, then fail with an error. | ||
if ((''+keyOrIndex).match(/\./)) { | ||
throw new Error('Keys containing dots (`.`) are not currently supported in values provided to `rttc.isEqual` when the 3rd argument is being used.'); | ||
} | ||
// console.log(' ('+keypathArray.join('.')+') \n•',firstValue,'vs', secondValue); | ||
// Clone (shallow) the keypath array so we can mutate it. | ||
if (_.isArray(keypathArray)){ | ||
keypathArray = _.clone(keypathArray); | ||
} | ||
// Attempt to look up the appropriate keypath within the type schema, or | ||
// use the top-level type schema if we haven't tracked any key/indices traversed | ||
// yet. | ||
var typeToCompareAgainst; | ||
if (keypathArray.length === 0) { | ||
typeToCompareAgainst = typeSchema; | ||
} | ||
else { | ||
var lastTypeToCompareAgainst = _.get(typeSchema, keypathArray.slice(0,-1).join('.')); | ||
// If previous comparison type was a homogenous array type (i.e. any array at this point) | ||
// ensure that we use the first item of the type schema as our type-- because otherwise | ||
// it won't exist! | ||
if (_.isArray(lastTypeToCompareAgainst)) { | ||
typeToCompareAgainst = _.get(typeSchema, keypathArray.slice(0,-1).concat([0]).join('.')); | ||
} | ||
// Otherwise, just grab the type to compare against normally: | ||
else { | ||
typeToCompareAgainst = _.get(typeSchema, keypathArray.join('.')); | ||
} | ||
} | ||
// Also look up the two value segments we'll be comparing below | ||
var firstValueSegment = keypathArray.length === 0 ? firstValue : _.get(firstValue, keypathArray.join('.')); | ||
var secondValueSegment = keypathArray.length === 0 ? secondValue : _.get(secondValue, keypathArray.join('.')); | ||
// If `keyOrIndex` is undefined, then this is the initial pass. | ||
// Otherwise it's a subsequent pass. | ||
if (!_.isUndefined(keyOrIndex)){ | ||
// Keep track of indices/keys already traversed in order to dereference the appropriate part | ||
// of the type schema (`indexOrKey` will be undefined if this is the top-level) | ||
keypathArray.push(keyOrIndex); | ||
} | ||
if (_.isArray(typeToCompareAgainst)) { | ||
if (_.isEqual(typeToCompareAgainst, [])){ | ||
return _.isEqual(firstValueSegment, secondValueSegment); | ||
} | ||
// Only take the recursive step for homogeneous arrays | ||
return _.all(firstValueSegment, function checkEachItemIn1stArray(unused, i){ | ||
return _isEqualRecursive(firstValue, secondValue, typeSchema, keypathArray, i); | ||
}) && | ||
_.all(secondValueSegment, function checkEachItemIn2ndArray(unused, i){ | ||
return _isEqualRecursive(firstValue, secondValue, typeSchema, keypathArray, i); | ||
}); | ||
// Now look up the two value segments we'll be comparing below. | ||
var firstValueSegment = keypathArray.length === 0 ? firstValue : _.get(firstValue, keypathArray.join('.')); | ||
var secondValueSegment = keypathArray.length === 0 ? secondValue : _.get(secondValue, keypathArray.join('.')); | ||
// console.log('(for key (`%s`), keypathArray:',keyOrIndex, keypathArray,'typeSchemaHere:', typeSchemaHere,')'); | ||
// console.log('at `%s`, comparing:',keypathArray.join('.'), firstValueSegment,'vs',secondValueSegment); | ||
if (_.isArray(typeSchemaHere)) { | ||
// If this path expects a generic array (i.e. `['*']` or `[]` for short), | ||
// then just use lodash. | ||
if (_.isEqual(typeSchemaHere, [])){ | ||
return _.isEqual(firstValueSegment, secondValueSegment); | ||
} | ||
else if (_.isObject(typeToCompareAgainst)) { | ||
if (_.isEqual(typeToCompareAgainst, {})){ | ||
return _.isEqual(firstValueSegment, secondValueSegment); | ||
} | ||
// Only take the recursive step for faceted arrays | ||
return _.all(firstValueSegment, function checkEachItemIn1stDict(unused, key){ | ||
return _isEqualRecursive(firstValue, secondValue, typeSchema, keypathArray, key); | ||
}) && | ||
_.all(secondValueSegment, function checkEachItemIn2ndDict(unused, key){ | ||
return _isEqualRecursive(firstValue, secondValue, typeSchema, keypathArray, key); | ||
}); | ||
} | ||
// If this type is a lamda, `.toString()` the functions and compare | ||
// them that way. | ||
else if (typeToCompareAgainst === 'lamda') { | ||
// console.log('Comparing lamdas...'); | ||
return (firstValueSegment.toString() === secondValueSegment.toString()); | ||
} | ||
else { | ||
// console.log('not lamda, its:', typeToCompareAgainst); | ||
// Otherwise, this is a homogeneous array so take the recursive step. | ||
return _.all(firstValueSegment, function checkEachItemIn1stArray(unused, i){ | ||
return _isEqualRecursive(firstValue, secondValue, typeSchemaHere[0], keypathArray, i); | ||
}) && | ||
_.all(secondValueSegment, function checkEachItemIn2ndArray(unused, i){ | ||
return _isEqualRecursive(firstValue, secondValue, typeSchemaHere[0], keypathArray, i); | ||
}); | ||
} | ||
else if (_.isObject(typeSchemaHere)) { | ||
// If this path expects a generic dictionary (i.e. `{}`), then just use lodash. | ||
if (_.isEqual(typeSchemaHere, {})){ | ||
return _.isEqual(firstValueSegment, secondValueSegment); | ||
} | ||
return _.all(firstValueSegment, function checkEachItemIn1stDict(unused, key){ | ||
return _isEqualRecursive(firstValue, secondValue, typeSchemaHere[key], keypathArray, key); | ||
}) && | ||
_.all(secondValueSegment, function checkEachItemIn2ndDict(unused, key){ | ||
return _isEqualRecursive(firstValue, secondValue, typeSchemaHere[key], keypathArray, key); | ||
}); | ||
} | ||
catch (e){ | ||
// console.log('------ ERR ------',e.stack); | ||
return false; | ||
// If this type is a lamda, `.toString()` the functions and compare | ||
// them that way. | ||
else if (typeSchemaHere === 'lamda') { | ||
// Look for any obvious mismatches and return false if they are encountered. | ||
if (!firstValueSegment || !secondValueSegment || !_.isFunction(firstValueSegment.toString) || !_.isFunction(secondValueSegment.toString)) { | ||
return false; | ||
} | ||
return (firstValueSegment.toString() === secondValueSegment.toString()); | ||
} | ||
// Miscellaneous thing. | ||
else { | ||
return _.isEqual(firstValueSegment, secondValueSegment); | ||
} | ||
})(firstValue, secondValue, typeSchema, []);//</self-calling recursive fn> | ||
}; |
{ | ||
"name": "rttc", | ||
"version": "9.3.3", | ||
"version": "9.3.4", | ||
"description": "Runtime type-checking for JavaScript.", | ||
@@ -32,3 +32,3 @@ "main": "index.js", | ||
"dependencies": { | ||
"lodash": "^3.8.0" | ||
"lodash": "3.8.0" | ||
}, | ||
@@ -35,0 +35,0 @@ "devDependencies": { |
@@ -374,7 +374,12 @@ # rttc | ||
Determine whether two values are equivalent using `_.isEqual()`, but also look for expected `lamda` values in the optional type schema and call `toString()` on functions before comparing them. | ||
Determine whether two values are equivalent using `_.isEqual()`. | ||
> This is the method used by `rttc`'s own tests to validate that expected values and actual values match. | ||
This is the method used by `rttc`'s own tests to validate that expected values and actual values match. | ||
> Experimental: | ||
> If the third argument was provided, also look for expected `lamda` values in the optional type schema and call `toString()` on functions before comparing them. The third argument SHOULD NOT BE RELIED UPON. | ||
##### .infer(exampleValue) | ||
@@ -467,2 +472,16 @@ | ||
##### .rebuild(val, transformLeaf) | ||
Rebuild (non-destructively) the specified value using the provided transformer function to change each primitive or function therein. | ||
Transformer function is provided the value as the first argument, and an rttc display type as the second (either 'string', 'number', 'boolean', 'lamda', or 'null'). | ||
e.g. | ||
```javascript | ||
return res.json(rttc.rebuild(someData, function transformLeaf(val, type){ | ||
if (type === 'string') { return val + ' (a grass-type Pokemon)'; } | ||
else { return val; } | ||
})); | ||
``` | ||
##### .getDefaultExemplar(typeSchema) | ||
@@ -469,0 +488,0 @@ |
@@ -522,3 +522,4 @@ // Export the array of tests below. | ||
// Leave `undefined` items from arrays and nested arrays alone (`'==='` case) | ||
// With `===`: | ||
// Leave `undefined` items from arrays and nested arrays alone | ||
{ | ||
@@ -530,8 +531,9 @@ example: '===', | ||
// Leave `undefined` items from arrays and nested arrays (`['===']` case) | ||
// (because '===' leaves them there) | ||
// With [`===`]: | ||
// Leave `undefined` items from NESTED arrays alone | ||
// (because they are being compared as '===') | ||
{ | ||
example: ['==='], | ||
actual: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}], | ||
result: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}] | ||
result: [{a:3}, {a: 5}, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}] | ||
}, | ||
@@ -952,3 +954,8 @@ | ||
title: 'Hank the Cowdog', | ||
surprise: {} | ||
surprise: { | ||
coolProps: 'wow so cool', | ||
constructo: 'hmm maybe ill try really annoying property names!', | ||
prototype: null, | ||
constructor: null | ||
} | ||
}] | ||
@@ -955,0 +962,0 @@ } |
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
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
228730
4893
595
+ Addedlodash@3.8.0(transitive)
- Removedlodash@3.10.1(transitive)
Updatedlodash@3.8.0