Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

rttc

Package Overview
Dependencies
Maintainers
4
Versions
108
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rttc - npm Package Compare versions

Comparing version 3.4.0 to 4.0.0

1

index.js

@@ -8,5 +8,4 @@ module.exports = {

getDisplayType: require('./lib/get-display-type'),
sanitize: require('./lib/sanitize'),
encode: require('./lib/encode'),
decode: require('./lib/decode')
};

2

lib/coerce.js

@@ -15,3 +15,3 @@ /**

* @param {~Schema} expected type schema
* @param {*} actual "mystery meat"
* @param {===} actual "mystery meat"
* @return {<expected>}

@@ -18,0 +18,0 @@ */

@@ -11,6 +11,7 @@ /**

* A variation on JSON.stringify that also takes care of a few additional
* edge-cases like stringifying functions, dates, regexps, and errors, as well
* as taking care of circular references, normalizing -Infinity, Infinity, and NaN (to 0)
* and stripping undefined keys and values. If `allowNull` is set, `null` values will not
* be stripped from the encoded string.
* edge-cases like:
* • stringifying functions, dates, regexps, and errors, as well
* • taking care of circular references
* • normalizing -Infinity, Infinity, and NaN (to 0)
* • stripping undefined (and potentially null) keys and values. If `allowNull` is set, `null` values will not be stripped from the encoded string.
*

@@ -17,0 +18,0 @@ * @param {===} value

@@ -7,2 +7,3 @@ /**

var _ = require('lodash');
var infer = require('./infer');

@@ -16,18 +17,19 @@

module.exports = function getDisplayType(x){
var displayType;
if (x === '*') {
return 'mutable reference (===)';
switch (infer(x)) {
case 'ref':
return 'mutable reference (===)';
case 'lamda':
return 'lambda function (->)';
case 'json':
return 'JSON-compatible value (*)';
default:
var displayType = typeof x;
try {
displayType = x.constructor.name;
}
catch (e){}
return displayType;
}
if (x === '->') {
return 'lambda fn (->)';
}
if (x === '%json') {
return '"%json"';
}
displayType = typeof x;
try {
displayType = x.constructor.name;
}
catch (e){}
return displayType;
};

@@ -65,3 +65,3 @@ /**

//
// (NOTE: `example: ['*']` won't make it here because it will be picked up
// (NOTE: `example: ['===']` won't make it here because it will be picked up
// by the recursive validation. And so it's different-- it will contain

@@ -98,3 +98,3 @@ // the original items, and therefore may contain dictionaries w/ keys w/ invalid values)

* (see https://github.com/isaacs/json-stringify-safe/commit/02cfafd45f06d076ac4bf0dd28be6738a07a72f9#diff-c3fcfbed30e93682746088e2ce1a4a24)
* @param {*} val [description]
* @param {===} val [description]
* @return {String} [description]

@@ -101,0 +101,0 @@ */

@@ -14,7 +14,7 @@ /**

*
* @param {*} expected
* @param {*} actual
* @param {===} expected
* @param {===} actual
* @param {Array} errors [errors encountered along the way are pushed here]
* @param {Boolean} ensureSerializable
* @return {*} coerced value
* @return {===} coerced value
*/

@@ -171,3 +171,3 @@ module.exports = function _validateRecursive (expected, actual, errors, ensureSerializable, meta, strict){

// ...expecting ANYTHING ('*')
// ...expecting ANYTHING ('===')
if (isExpectingAnything) {

@@ -174,0 +174,0 @@ return coercedValue;

@@ -20,4 +20,4 @@ /**

// Check for `type: 'ref'` (*)
if (val === '*' || val === undefined) {
// Check for `type: 'ref'` (===)
if (val === '===' || val === undefined) {
return 'ref';

@@ -31,4 +31,4 @@ }

// Check for `type: 'json'` (%json)
if (val === '%json') {
// Check for `type: 'json'` (*)
if (val === '*') {
return 'json';

@@ -35,0 +35,0 @@ }

@@ -12,12 +12,12 @@ /**

*
* @param {=} actualResult
* @param {*} compareTo
* @param {===} firstValue
* @param {===} secondValue
* @param {*} typeSchema
* @return {Boolean}
*/
module.exports = function isEqual (actualResult, compareTo, typeSchema) {
module.exports = function isEqual (firstValue, secondValue, typeSchema) {
// Use a lodash equality check, but customize it a bit
var _keypath = [];
return _.isEqual(actualResult, compareTo, function(value, other, indexOrKey) {
return _.isEqual(firstValue, secondValue, function(value, other, indexOrKey) {

@@ -30,17 +30,20 @@ // Keep track of indices/keys already traversed in order to dereference the appropriate part

try {
// 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 = typeSchema;
if (_keypath.length > 0) {
typeToCompareAgainst = _.get(typeSchema, _keypath.join('.'));
// Only do the lamda check if a `typeSchema` was provided.
if (!_.isUndefined(typeSchema)) {
try {
// 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 = typeSchema;
if (_keypath.length > 0) {
typeToCompareAgainst = _.get(typeSchema, _keypath.join('.'));
}
// If this type is a lamda, `.toString()` the functions and compare
// them that way.
if (typeToCompareAgainst === 'lamda') {
return (value.toString() === other.toString());
}
}
// If this type is a lamda, `.toString()` the functions and compare
// them that way.
if (typeToCompareAgainst === 'lamda') {
return (value.toString() === other.toString());
}
catch (e){ return false; }
}
catch (e){ return false; }

@@ -47,0 +50,0 @@ // If this is not a lamda input, just let the default lodash isEqual handling

@@ -15,3 +15,3 @@ /**

* @param {~Schema} expected type schema
* @param {*} actual "mystery meat"
* @param {===} actual "mystery meat"
*/

@@ -18,0 +18,0 @@ module.exports = function validateStrict (expected, actual) {

@@ -18,3 +18,3 @@ /**

* @param {~Schema} expected type schema
* @param {*} actual "mystery meat"
* @param {===} actual "mystery meat"
* @return {<expected>}

@@ -21,0 +21,0 @@ */

{
"name": "rttc",
"version": "3.4.0",
"version": "4.0.0",
"description": "Runtime type-checking for JavaScript.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -13,7 +13,10 @@ # rttc

```js
Want to coerce a value to match a particular type?
```javascript
var rttc = require('rttc');
rttc.coerce({ firstName: 'string'}, {firstName: 45});
// => { firstName: "45" }
rttc.coerce({ firstName: 'string'}, {firstName: 13375055});
// => { firstName: "13375055" }

@@ -23,3 +26,18 @@ rttc.coerce({ firstName: 'string'}, {something: 'totally incorrect'});

// (when confronted with something totally weird, `.coerce()` returns the "base value" for the type)
```
Want to throw an Error if a value doesn't match a particular type?
```javascript
rttc.validateStrict({ firstName: 'string'}, {firstName: 13375055});
// throws error
// (`.validateStrict()` demands a value that is precisely the correct type)
rttc.validateStrict({ firstName: 'string'}, {firstName: '13375055'});
// does not throw
```
Or if you want to be a little more forgiving:
```javascript
rttc.validate({ firstName: 'string'}, {something: 'totally incorrect'});

@@ -31,38 +49,74 @@ // throws error

// (when confronted with minor differences, `.validate()` coerces as needed to make stuff fit)
```
rttc.validateStrict({ firstName: 'string'}, {firstName: 45});
// throws error
// (`.validateStrict()` demands a value that is precisely the correct type)
rttc.validateStrict({ firstName: 'string'}, {firstName: '45'});
// does not throw, returns undefined
Not sure how to build a type schema for use with `.coerce()` or `.validate()`? Use `.infer()` to build one from an example value you've got laying around:
```javascript
rttc.infer({ firstName: 'Rosella', lastName: 'Graham', friends: ['Valencia', 'Edgar', 'Attis'] });
// => { firstName: 'string', }
```
> note that when inferring an array type, the first item of the example is used as a pattern- assuming homogeneity (i.e. that all items will look the same)
## Philosophy
All of the validation and coercion strategies used in this modules are recursive through the keys of plain old JavaScript objects and the indices of arrays.
Finally, note that all of the validation and coercion strategies used in this modules are recursive through the keys of plain old JavaScript objects and the indices of arrays.
#### Coercion vs. Validation
+ `.validateStrict()` throws if the provided value is not the right type (recursive).
+ `.validate()` either returns a (potentially "lightly" coerced) version of the value that was accepted, or it throws. The "lightly" coerced value turns `"3"` into `3`, `"true"` into `true`, `-4.5` into `"-4.5"`, etc.
+ `.coerce()` ALWAYS returns an acceptable version of the value, even if it has to mangle it to get there (i.e. by using the "base value" for the expected type.)
## Usage
#### Base values
#### .validateStrict(expectedTypeSchema, actualValue)
+ For "string", base value is `""`
+ For "number", base value is `0`
+ For "boolean", base value is `false`
+ For any "dictionary" (`{}`), base value is `{}`, with whatever keys are expected (recursive)
+ For a generic "array" (`[]`), base value is `[]`, with a single archetypal item matching the expectation (recursive)
+ For "*", base value is `"undefined"`.
Throws if the provided value is not the right type (recursive).
<!--
TODO:
+ For "stream", base value is an empty readable buffer stream (i.e. not in object mode)
-->
#### .validate(expectedTypeSchema, actualValue)
Either returns a (potentially "lightly" coerced) version of the value that was accepted, or it throws. The "lightly" coerced value turns `"3"` into `3`, `"true"` into `true`, `-4.5` into `"-4.5"`, etc.
#### .coerce(expectedTypeSchema, actualValue)
ALWAYS returns an acceptable version of the value, even if it has to mangle it to get there (i.e. by using the "base value" for the expected type. More on that below.)
#### .infer(exampleValue)
Guesses the type schema from an example value.
#### .decode(stringifiedValue, [_typeSchema_=`undefined`], [_unsafeMode_=`false`])
Decode a stringified value back into a usable value.
Very similar to `JSON.parse`, except that if `unsafeMode` is set to `true`, and a `typeSchema` is provided, this function will use that schema to figure out where "lamda" values (functions) are expected, then will use `eval()` to bring them back to life. Use with care.
#### .encode(value, [_allowNull_=`false`])
Encode a value into a string.
This is basically just a variation on JSON.stringify that also takes care of a few additional edge-cases, such as:
+ stringifies functions, regexps, and errors (grabs the `.stack` property)
+ replacing circular references with a string (e.g. `[Circular]`)
+ replaces `-Infinity`, `Infinity`, and `NaN` with 0
+ strips keys and array items with `undefined` or `null` values. If `allowNull` is set to true, `null` values will not be stripped from the encoded string.
#### .isEqual(firstValue, secondValue, [_expectedTypeSchema_=`undefined`])
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.
> This is the method used by `rttc`'s own tests to validate that expected values and actual values match.
#### .getDisplayType(value)
Given a value, return a human-readable type string (tries a few heuristics, including the `typeof` operator, examining the `.constructor` property, and calling `rttc.infer()`).
## Types

@@ -82,3 +136,3 @@

`example: {}`
`example: false`

@@ -106,8 +160,7 @@

The **faceted dictionary** type is any dictionary type schema with at least one key.
Extra keys in the actual value that are not in the type schema will be stripped out.
The **faceted dictionary** type is any dictionary type schema with at least one key. Extra keys in the actual value that are not in the type schema will be stripped out. Missing keys will cause `.validate()` to throw.
Dictionary type schemas (i.e. plain old JavaScript objects nested like `{a:{}}`) can be infinitely nested. Type validation and coercion will proceed through the nested objects recursively.
```js
```javascript
{

@@ -156,3 +209,3 @@ id: 'number',

```js
```javascript
[

@@ -176,24 +229,70 @@ {

#### Wildcards
#### Generic JSON
`example: '*'`
This special type allows anything except `undefined`. It also _does not rebuild objects_, which means it maintains the original reference (i.e. is `===`). It also does not guarantee JSON-serializability.
This works pretty much like the generic array or generic dictionary type, with two major differences: (1) the top-level value can be a string, boolean, number, dictionary, array, or null value. (2) `null` is permitted, both as a top-level value and recursively in nested arrays and dictionaries (and as you might expect, `null` values are NOT stripped from nested arrays and dictionaries when performing type coercion)
Other than the aforementioned exception for `null`, the generic JSON type follows the JSON-serializability rules from generic arrays and generic dictionaries.
#### Edge cases
+ `undefined` is _never_ valid as a _top-level value_, but it is allowed as an item or value in a nested array or dictionary validated/coerced against `example: *`.
+ `null` is only valid against `example: '*'`.
+ `NaN` is only valid against `example: '*'`.
+ `Infinity` is only valid against `example: '*'`.
+ `-Infinity` is only valid against `example: '*'`.
+ `-0` is understood as 0
+ `+0` is understood as 0
#### Mutable reference ("ref")
`example: '==='`
This special type allows anything except `undefined`. It also _does not rebuild objects_, which means it maintains the original reference (i.e. is `===`). It does not guarantee JSON-serializability.
## Examples
## Base values
As mentioned above, every type has a base value.
+ For the "string" type, base value is `""`
+ For the "number" type, base value is `0`
+ For the "boolean" type, base value is `false`
+ For the "lamda" type (`'->'`), base value is a function that uses the standard machine fn signature and triggers its "error" callback w/ a message about being the rttc default (e.g. `function(inputs,exits,env) { return exits.error(new Error('not implemented')); }`)
+ For the generic dictionary type (`{}`) or a faceted dictionary type (e.g. `{foo:'bar'}`), the base value is `{}`.
+ For the generic array type (`[]`), or a faceted/homogenous array type (e.g. `[3]` or `[{age:48,name: 'Nico'}]`), the base value is `[]`
+ For the "json" type (`'*'`), base value is `null`.
+ For the "ref" type (`'==='`), base value is `undefined`.
> Note that, for both arrays and dictionaries, any keys in the schema will get the base value for their type (and their keys for their type, etc. -- recursive)
## Edge-cases
The following is a high-level overview of important conventions used by the `rttc` module. For detailed coverage of every permutation of validation and coercion, check out the declarative tests in the `spec/` folder of this repository.
##### `undefined` and `null` values
+ `undefined` _is never valid as a top-level value_ against ANY type, even mutable reference (`===`)
+ `undefined` IS, however, allowed as an item in a nested array or value in a nested dictionary, but only against the mutable reference type (`===`)
+ `null` is only valid against the JSON (`*`) and mutable reference (`===`) types.
##### Weird psuedo-numeric values
+ `NaN` is only valid against the mutable reference type (`'==='`)
+ `Infinity` and `-Infinity` is only valid against the mutable reference type (`'==='`)
+ `Infinity` and `-Infinity` are only valid against `example: '==='`
+ `+0` and `-0` are always coerced to `0` (except against the mutable reference type)
##### Instances of ECMAScript core classes
When coerced against the generic dictionary, generic array, or the generic json types, the following is true:
+ `Error` instances are coerced to the string value of their `.stack` property (i.e. the message + stack trace you're used to seeing in the terminal)
+ `Date` instances are coerced to the string value of running their `.toJSON()` method (a ISO-8601 timestamp, e.g. `'2015-05-24T15:16:48.999Z'`. This reflects the Date in GMT/UTC time, so is therefore timezone-agnostic).
+ `RegExp` instances are coerced to the string value you get from running their `.toString()` method (e.g. `'/foo/'` or `'/^bar/gi'`)
+ Functions are coerced to the string value you get from running their `.toString()` method (e.g. `'function someFunction (some,args,like,this,maybe){ /* and some kind of implementation in here prbly */ }'`)
##### Instances of Node.js core classes
+ `Stream` and `Buffer` instances (from Node.js) are only valid against the mutable reference type.
+ Streams and Buffers are coerced to `null` against the generic dictionary, generic array, or the generic json types.
## More examples
#### rttc.infer(value)

@@ -203,3 +302,3 @@

```js
```javascript
require('rttc').infer(false);

@@ -209,3 +308,3 @@ // => 'boolean'

```js
```javascript
require('rttc').infer(0);

@@ -215,3 +314,3 @@ // => 'number'

```js
```javascript
require('rttc').infer({

@@ -223,3 +322,3 @@ foo: 'bar'

```js
```javascript
require('rttc').infer({

@@ -232,3 +331,3 @@ foo: 'whatever',

```js
```javascript
require('rttc').infer([{

@@ -240,3 +339,3 @@ foo: ['bar']

```js
```javascript
require('rttc').infer({

@@ -265,3 +364,3 @@ user: {

```js
```javascript
rttc.validate('string', 'foo');

@@ -315,5 +414,5 @@ // => 'foo'

If value cannot be properly coerced, throws error with code=`E_INVALID_TYPE`:
If value cannot be properly coerced, throws error with its `.code` property set to `E_INVALID_TYPE`:
```js
```javascript
rttc.validate('number', 'asdf');

@@ -323,5 +422,7 @@ // throws E_INVALID_TYPE

#### rttc.coerce(expected, actual)
```js
```javascript
rttc.coerce('string', 'foo');

@@ -379,1 +480,8 @@ // => 'foo'

## License
MIT
&copy; 2014 Mike McNeil, Cody Stoltman; &copy; 2015 The Treeline Company

@@ -197,3 +197,3 @@ // Export the array of tests below.

// ARRAYS (json-serializable, except `null` not allowed)
// (all of the tests below pass w/ [], not necessarily ['*'])
// (all of the tests below pass w/ [], not necessarily ['==='])
////////////////////////////////////////////

@@ -286,51 +286,51 @@

////////////////////////////////////////////
// example: '%json'
// example: '*' (any JSON-serializable value)
////////////////////////////////////////////
{ example: '%json', actual: 'bar', result: 'bar', },
{ example: '%json', actual: '', result: '', },
{ example: '%json', actual: '-1.1', result: '-1.1', },
{ example: '%json', actual: 'NaN', result: 'NaN', },
{ example: '%json', actual: 'undefined', result: 'undefined', },
{ example: '%json', actual: 'null', result: 'null', },
{ example: '%json', actual: '-Infinity', result: '-Infinity', },
{ example: '%json', actual: 'Infinity', result: 'Infinity', },
{ example: '%json', actual: 'true', result: 'true', },
{ example: '%json', actual: 'false', result: 'false', },
{ example: '%json', actual: '0', result: '0', },
{ example: '%json', actual: '1', result: '1', },
{ example: '*', actual: 'bar', result: 'bar', },
{ example: '*', actual: '', result: '', },
{ example: '*', actual: '-1.1', result: '-1.1', },
{ example: '*', actual: 'NaN', result: 'NaN', },
{ example: '*', actual: 'undefined', result: 'undefined', },
{ example: '*', actual: 'null', result: 'null', },
{ example: '*', actual: '-Infinity', result: '-Infinity', },
{ example: '*', actual: 'Infinity', result: 'Infinity', },
{ example: '*', actual: 'true', result: 'true', },
{ example: '*', actual: 'false', result: 'false', },
{ example: '*', actual: '0', result: '0', },
{ example: '*', actual: '1', result: '1', },
{ example: '%json', actual: -0, result: 0, },
{ example: '%json', actual: +0, result: 0, },
{ example: '%json', actual: 0, result: 0, },
{ example: '%json', actual: 1, result: 1, },
{ example: '%json', actual: -1.1, result: -1.1, },
{ example: '*', actual: -0, result: 0, },
{ example: '*', actual: +0, result: 0, },
{ example: '*', actual: 0, result: 0, },
{ example: '*', actual: 1, result: 1, },
{ example: '*', actual: -1.1, result: -1.1, },
{ example: '%json', actual: true, result: true, },
{ example: '%json', actual: false, result: false, },
{ example: '*', actual: true, result: true, },
{ example: '*', actual: false, result: false, },
{ example: '%json', actual: {}, result: {}, },
{ example: '%json', actual: {foo:'bar'}, result: {foo:'bar'}, },
{ example: '%json', actual: {foo:{bar:{baz:{}}}}, result: {foo:{bar:{baz:{}}}}, },
{ example: '%json', actual: {foo:['bar']}, result: {foo:['bar']}, },
{ example: '%json', actual: {foo:{bar:{baz:[{}]}}}, result: {foo:{bar:{baz:[{}]}}}, },
{ example: '*', actual: {}, result: {}, },
{ example: '*', actual: {foo:'bar'}, result: {foo:'bar'}, },
{ example: '*', actual: {foo:{bar:{baz:{}}}}, result: {foo:{bar:{baz:{}}}}, },
{ example: '*', actual: {foo:['bar']}, result: {foo:['bar']}, },
{ example: '*', actual: {foo:{bar:{baz:[{}]}}}, result: {foo:{bar:{baz:[{}]}}}, },
{ example: '%json', actual: [], result: [], },
{ example: '%json', actual: ['asdf'], result: ['asdf'], },
{ example: '%json', actual: [''], result: [''], },
{ example: '%json', actual: [235], result: [235], },
{ example: '%json', actual: [false], result: [false], },
{ example: '%json', actual: [{}], result: [{}], },
{ example: '%json', actual: [{foo:'bar'}], result: [{foo:'bar'}], },
{ example: '*', actual: [], result: [], },
{ example: '*', actual: ['asdf'], result: ['asdf'], },
{ example: '*', actual: [''], result: [''], },
{ example: '*', actual: [235], result: [235], },
{ example: '*', actual: [false], result: [false], },
{ example: '*', actual: [{}], result: [{}], },
{ example: '*', actual: [{foo:'bar'}], result: [{foo:'bar'}], },
{ example: '%json', actual: undefined, result: null, },
{ example: '*', actual: undefined, result: null, },
{ example: '%json', actual: NaN, result: 0, },
{ example: '%json', actual: Infinity, result: 0, },
{ example: '%json', actual: -Infinity, result: 0, },
{ example: '*', actual: NaN, result: 0, },
{ example: '*', actual: Infinity, result: 0, },
{ example: '*', actual: -Infinity, result: 0, },
{ example: '%json', actual: null, result: null, },
{ example: '*', actual: null, result: null, },
{ example: '%json', actual: /some regexp/gi, result: '/some regexp/gi' },
{ example: '%json', actual: new Date('November 5, 1605 GMT'), result: '1605-11-05T00:00:00.000Z' },
{ example: '*', actual: /some regexp/gi, result: '/some regexp/gi' },
{ example: '*', actual: new Date('November 5, 1605 GMT'), result: '1605-11-05T00:00:00.000Z' },

@@ -390,3 +390,3 @@

////////////////////////////////////////////
// example: * (aka undefined)
// example: === (aka undefined)
////////////////////////////////////////////

@@ -494,5 +494,5 @@

// Don't strip keys or nested keys with `undefined` values (`*` and nested `*` cases)
{ example: '*', actual: {a: undefined, b: 3, c: {x: undefined}}, result: {a: undefined, b: 3, c: {x: undefined}} },
{ example: {c:'*'}, actual: {a: undefined, b: 3, c: {x: undefined}}, result: { c: {x: undefined}} },
// Don't strip keys or nested keys with `undefined` values (`===` and nested `===` cases)
{ example: '===', actual: {a: undefined, b: 3, c: {x: undefined}}, result: {a: undefined, b: 3, c: {x: undefined}} },
{ example: {c:'==='}, actual: {a: undefined, b: 3, c: {x: undefined}}, result: { c: {x: undefined}} },

@@ -520,5 +520,5 @@

// Leave `undefined` items from arrays and nested arrays alone (`*` case)
// Leave `undefined` items from arrays and nested arrays alone (`'==='` case)
{
example: '*',
example: '===',
actual: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}],

@@ -528,6 +528,6 @@ result: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}]

// Leave `undefined` items from arrays and nested arrays (`[*]` case)
// (because '*' leaves them there)
// Leave `undefined` items from arrays and nested arrays (`['===']` case)
// (because '===' leaves them there)
{
example: ['*'],
example: ['==='],
actual: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}],

@@ -545,6 +545,6 @@ result: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}]

// Ensure that nested dictionaries inside of an array passed
// through `example: ['*']` are NOT stripped of keys with undefined values--
// through `example: ['===']` are NOT stripped of keys with undefined values--
// and are left utterly alone
{
example: ['*'],
example: ['==='],
actual: [{a:3, b: undefined}, {a: undefined}],

@@ -554,3 +554,3 @@ result: [{a: 3, b: undefined},{a:undefined}]

{
example: ['*'],
example: ['==='],
actual: [{a:3,someStuff: [{x: undefined, y: 'foo'}, {x: 'bar', y: undefined}]},{a: 5, b: undefined}],

@@ -807,3 +807,3 @@ result: [{a:3,someStuff: [{x: undefined, y: 'foo'}, {x: 'bar', y: undefined}]},{a: 5, b: undefined}]

////////////////////////////////////////////////
// example: '*'
// example: '==='
// result value should always be strictly equal (===)

@@ -824,3 +824,3 @@ ////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////
// example: nested '*' in dictionaries/arrays
// example: nested '===' in dictionaries/arrays
// TODO: needs to be tested some other way, since we'd be checking reference passing within another nested obj.

@@ -855,3 +855,3 @@ // also check against strict equality between sub-values (`!==` between nested things...)

{
example: { id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '*' },
example: { id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '===' },
actual: {},

@@ -862,3 +862,3 @@ result: { id: 0, title: '', body: '', votes: 0, resolved: false, something: undefined },

{
example: { id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '*' },
example: { id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '===' },
actual: {a:23,b:'asdg',c:true,d: {x:32,y:'sagd',z: [{a:2,b:'gsda',c:false}]}, e: [2]},

@@ -869,3 +869,3 @@ result: { id: 0, title: '', body: '', votes: 0, resolved: false, something: undefined },

{
example: { id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '*' },
example: { id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '===' },
actual: { something: new Date('November 5, 1605 GMT')},

@@ -876,3 +876,3 @@ result: { id: 0, title: '', body: '', votes: 0, resolved: false, something: new Date('November 5, 1605 GMT') },

{
example: { id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '*' },
example: { id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '===' },
actual: { something: new Date('November 5, 1605 GMT'), a:23,b:'asdg',c:true,d: {x:32,y:'sagd',z: [{a:2,b:'gsda',c:false}]}, e: [2]},

@@ -906,3 +906,3 @@ result: { id: 0, title: '', body: '', votes: 0, resolved: false, something: new Date('November 5, 1605 GMT') },

{
example: [{ id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '*' }],
example: [{ id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '===' }],
actual: [],

@@ -913,3 +913,3 @@ result: [],

{
example: [{ id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '*' }],
example: [{ id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '===' }],
actual: [{a:23,b:'asdg',c:true,d: {x:32,y:'sagd',z: [{a:2,b:'gsda',c:false}]}, e: [2]}],

@@ -920,3 +920,3 @@ result: [{ id: 0, title: '', body: '', votes: 0, resolved: false, something: undefined }],

{
example: [{ id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '*' }],
example: [{ id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '===' }],
actual: [{ something: new Date('November 5, 1605 GMT')}],

@@ -927,3 +927,3 @@ result: [{ id: 0, title: '', body: '', votes: 0, resolved: false, something: new Date('November 5, 1605 GMT') }],

{
example: [{ id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '*' }],
example: [{ id: 123, title: 'Scott', body: 'Scott', votes: 33, resolved: true, something: '===' }],
actual: [{ something: new Date('November 5, 1605 GMT'), a:23,b:'asdg',c:true,d: {x:32,y:'sagd',z: [{a:2,b:'gsda',c:false}]}, e: [2]}],

@@ -930,0 +930,0 @@ result: [{ id: 0, title: '', body: '', votes: 0, resolved: false, something: new Date('November 5, 1605 GMT') }],

@@ -16,3 +16,3 @@ /**

// For all `example: undefined` tests, also test `example: '*'`
// For all `example: undefined` tests, also test `example: '==='`
var starTests = [];

@@ -22,3 +22,3 @@ _.each(testSuite, function (test){

var newTest = {
example: '*',
example: '===',
actual: test.actual

@@ -25,0 +25,0 @@ };

@@ -195,3 +195,3 @@ // Export the array of tests below

// ARRAYS (json-serializable, except `null` not allowed)
// (all of the tests below pass w/ [], not necessarily ['*'])
// (all of the tests below pass w/ [], not necessarily ['==='])
////////////////////////////////////////////

@@ -231,3 +231,3 @@

// Note: we could bring back support for this by explicitly filtering properties of buffers in `.exec()`
// TODO: but actually, this should cause an error- use `example: '*'` for things like this.
// TODO: but actually, this should cause an error- use `example: '==='` for things like this.
{ example: [], actual: new Error('asdf'), error: true },

@@ -288,54 +288,54 @@

////////////////////////////////////////////
// example: '%json'
// example: '*' (any JSON-serializable value)
////////////////////////////////////////////
{ example: '%json', actual: 'bar', result: 'bar', },
{ example: '%json', actual: '', result: '', },
{ example: '%json', actual: '-1.1', result: '-1.1', },
{ example: '%json', actual: 'NaN', result: 'NaN', },
{ example: '%json', actual: 'undefined', result: 'undefined', },
{ example: '%json', actual: 'null', result: 'null', },
{ example: '%json', actual: '-Infinity', result: '-Infinity', },
{ example: '%json', actual: 'Infinity', result: 'Infinity', },
{ example: '%json', actual: 'true', result: 'true', },
{ example: '%json', actual: 'false', result: 'false', },
{ example: '%json', actual: '0', result: '0', },
{ example: '%json', actual: '1', result: '1', },
{ example: '*', actual: 'bar', result: 'bar', },
{ example: '*', actual: '', result: '', },
{ example: '*', actual: '-1.1', result: '-1.1', },
{ example: '*', actual: 'NaN', result: 'NaN', },
{ example: '*', actual: 'undefined', result: 'undefined', },
{ example: '*', actual: 'null', result: 'null', },
{ example: '*', actual: '-Infinity', result: '-Infinity', },
{ example: '*', actual: 'Infinity', result: 'Infinity', },
{ example: '*', actual: 'true', result: 'true', },
{ example: '*', actual: 'false', result: 'false', },
{ example: '*', actual: '0', result: '0', },
{ example: '*', actual: '1', result: '1', },
{ example: '%json', actual: -0, result: 0, },
{ example: '%json', actual: +0, result: 0, },
{ example: '%json', actual: 0, result: 0, },
{ example: '%json', actual: 1, result: 1, },
{ example: '%json', actual: -1.1, result: -1.1, },
{ example: '*', actual: -0, result: 0, },
{ example: '*', actual: +0, result: 0, },
{ example: '*', actual: 0, result: 0, },
{ example: '*', actual: 1, result: 1, },
{ example: '*', actual: -1.1, result: -1.1, },
{ example: '%json', actual: true, result: true, },
{ example: '%json', actual: false, result: false, },
{ example: '*', actual: true, result: true, },
{ example: '*', actual: false, result: false, },
{ example: '%json', actual: {}, result: {}, },
{ example: '%json', actual: {foo:'bar'}, result: {foo:'bar'}, },
{ example: '%json', actual: {foo:{bar:{baz:{}}}}, result: {foo:{bar:{baz:{}}}}, },
{ example: '%json', actual: {foo:['bar']}, result: {foo:['bar']}, },
{ example: '%json', actual: {foo:{bar:{baz:[{}]}}}, result: {foo:{bar:{baz:[{}]}}}, },
{ example: '*', actual: {}, result: {}, },
{ example: '*', actual: {foo:'bar'}, result: {foo:'bar'}, },
{ example: '*', actual: {foo:{bar:{baz:{}}}}, result: {foo:{bar:{baz:{}}}}, },
{ example: '*', actual: {foo:['bar']}, result: {foo:['bar']}, },
{ example: '*', actual: {foo:{bar:{baz:[{}]}}}, result: {foo:{bar:{baz:[{}]}}}, },
{ example: '%json', actual: [], result: [], },
{ example: '%json', actual: ['asdf'], result: ['asdf'], },
{ example: '%json', actual: [''], result: [''], },
{ example: '%json', actual: [235], result: [235], },
{ example: '%json', actual: [false], result: [false], },
{ example: '%json', actual: [{}], result: [{}], },
{ example: '%json', actual: [{foo:'bar'}], result: [{foo:'bar'}], },
{ example: '*', actual: [], result: [], },
{ example: '*', actual: ['asdf'], result: ['asdf'], },
{ example: '*', actual: [''], result: [''], },
{ example: '*', actual: [235], result: [235], },
{ example: '*', actual: [false], result: [false], },
{ example: '*', actual: [{}], result: [{}], },
{ example: '*', actual: [{foo:'bar'}], result: [{foo:'bar'}], },
{ example: '%json', actual: undefined, error: true, },
{ example: '*', actual: undefined, error: true, },
{ example: '%json', actual: NaN, result: 0 },
{ example: '%json', actual: Infinity, result: 0 },
{ example: '%json', actual: -Infinity, result: 0 },
{ example: '*', actual: NaN, result: 0 },
{ example: '*', actual: Infinity, result: 0 },
{ example: '*', actual: -Infinity, result: 0 },
{ example: '%json', actual: null, result: null, },
{ example: '*', actual: null, result: null, },
{ example: '%json', actual: /some regexp/gi, result: '/some regexp/gi' },
{ example: '%json', actual: new Date('November 5, 1605 GMT'), result: '1605-11-05T00:00:00.000Z' },
{ example: '%json', actual: (function(){var err=new Error();err.stack='test';return err;})(), result: 'test' },
{ example: '%json', actual: function(){}, result: 'function (){}' },
{ example: '%json', actual: new (require('stream').Readable)(), error: true },
{ example: '*', actual: /some regexp/gi, result: '/some regexp/gi' },
{ example: '*', actual: new Date('November 5, 1605 GMT'), result: '1605-11-05T00:00:00.000Z' },
{ example: '*', actual: (function(){var err=new Error();err.stack='test';return err;})(), result: 'test' },
{ example: '*', actual: function(){}, result: 'function (){}' },
{ example: '*', actual: new (require('stream').Readable)(), error: true },

@@ -354,5 +354,5 @@

// Missing keys (`*` case)
{ example: {a:'*'}, actual: {a: undefined}, error: true },
{ example: {a:'*'}, actual: {}, error: true },
// Missing keys (`===` case)
{ example: {a:'==='}, actual: {a: undefined}, error: true },
{ example: {a:'==='}, actual: {}, error: true },

@@ -364,4 +364,4 @@ // Strip keys with `undefined` values (`{}` case)

// Don't strip keys with `undefined` values (`*` case)
{ example: '*', actual: {a: undefined, b: 3}, result: {a: undefined, b: 3} },
// Don't strip keys with `undefined` values (`===` case)
{ example: '===', actual: {a: undefined, b: 3}, result: {a: undefined, b: 3} },

@@ -377,47 +377,47 @@ // Extra keys:

////////////////////////////////////////////
// example: *
// example: ===
////////////////////////////////////////////
{ example: '*', actual: 'bar', result: 'bar', },
{ example: '*', actual: '', result: '', },
{ example: '*', actual: '-1.1', result: '-1.1', },
{ example: '*', actual: 'NaN', result: 'NaN', },
{ example: '*', actual: 'undefined', result: 'undefined', },
{ example: '*', actual: 'null', result: 'null', },
{ example: '*', actual: '-Infinity', result: '-Infinity', },
{ example: '*', actual: 'Infinity', result: 'Infinity', },
{ example: '*', actual: 'true', result: 'true', },
{ example: '*', actual: 'false', result: 'false', },
{ example: '*', actual: '0', result: '0', },
{ example: '*', actual: '1', result: '1', },
{ example: '===', actual: 'bar', result: 'bar', },
{ example: '===', actual: '', result: '', },
{ example: '===', actual: '-1.1', result: '-1.1', },
{ example: '===', actual: 'NaN', result: 'NaN', },
{ example: '===', actual: 'undefined', result: 'undefined', },
{ example: '===', actual: 'null', result: 'null', },
{ example: '===', actual: '-Infinity', result: '-Infinity', },
{ example: '===', actual: 'Infinity', result: 'Infinity', },
{ example: '===', actual: 'true', result: 'true', },
{ example: '===', actual: 'false', result: 'false', },
{ example: '===', actual: '0', result: '0', },
{ example: '===', actual: '1', result: '1', },
{ example: '*', actual: -0, result: -0, },
{ example: '*', actual: +0, result: +0, },
{ example: '*', actual: 0, result: 0, },
{ example: '*', actual: 1, result: 1, },
{ example: '*', actual: -1.1, result: -1.1, },
{ example: '===', actual: -0, result: -0, },
{ example: '===', actual: +0, result: +0, },
{ example: '===', actual: 0, result: 0, },
{ example: '===', actual: 1, result: 1, },
{ example: '===', actual: -1.1, result: -1.1, },
{ example: '*', actual: true, result: true, },
{ example: '*', actual: false, result: false, },
{ example: '===', actual: true, result: true, },
{ example: '===', actual: false, result: false, },
{ example: '*', actual: {}, result: {}, },
{ example: '*', actual: {foo:'bar'}, result: {foo:'bar'}, },
{ example: '*', actual: {foo:{bar:{baz:{}}}}, result: {foo:{bar:{baz:{}}}}, },
{ example: '*', actual: {foo:['bar']}, result: {foo:['bar']}, },
{ example: '*', actual: {foo:{bar:{baz:[{}]}}}, result: {foo:{bar:{baz:[{}]}}}, },
{ example: '===', actual: {}, result: {}, },
{ example: '===', actual: {foo:'bar'}, result: {foo:'bar'}, },
{ example: '===', actual: {foo:{bar:{baz:{}}}}, result: {foo:{bar:{baz:{}}}}, },
{ example: '===', actual: {foo:['bar']}, result: {foo:['bar']}, },
{ example: '===', actual: {foo:{bar:{baz:[{}]}}}, result: {foo:{bar:{baz:[{}]}}}, },
{ example: '*', actual: [], result: [], },
{ example: '*', actual: ['asdf'], result: ['asdf'], },
{ example: '*', actual: [''], result: [''], },
{ example: '*', actual: [235], result: [235], },
{ example: '*', actual: [false], result: [false], },
{ example: '*', actual: [{}], result: [{}], },
{ example: '*', actual: [{foo:'bar'}], result: [{foo:'bar'}], },
{ example: '===', actual: [], result: [], },
{ example: '===', actual: ['asdf'], result: ['asdf'], },
{ example: '===', actual: [''], result: [''], },
{ example: '===', actual: [235], result: [235], },
{ example: '===', actual: [false], result: [false], },
{ example: '===', actual: [{}], result: [{}], },
{ example: '===', actual: [{foo:'bar'}], result: [{foo:'bar'}], },
{ example: '*', actual: undefined, error: true },
{ example: '===', actual: undefined, error: true },
{ example: '*', actual: NaN, result: NaN, },
{ example: '*', actual: Infinity, result: Infinity, },
{ example: '*', actual: -Infinity, result: -Infinity, },
{ example: '*', actual: null, result: null, },
{ example: '===', actual: NaN, result: NaN, },
{ example: '===', actual: Infinity, result: Infinity, },
{ example: '===', actual: -Infinity, result: -Infinity, },
{ example: '===', actual: null, result: null, },

@@ -532,5 +532,5 @@

// Don't strip keys or nested keys with `undefined` values (`*` and nested `*` cases)
{ example: '*', actual: {a: undefined, b: 3, c: {x: undefined}}, result: {a: undefined, b: 3, c: {x: undefined}} },
{ example: {c:'*'}, actual: {a: undefined, b: 3, c: {x: undefined}}, result: { c: {x: undefined}} },
// Don't strip keys or nested keys with `undefined` values (`===` and nested `===` cases)
{ example: '===', actual: {a: undefined, b: 3, c: {x: undefined}}, result: {a: undefined, b: 3, c: {x: undefined}} },
{ example: {c:'==='}, actual: {a: undefined, b: 3, c: {x: undefined}}, result: { c: {x: undefined}} },

@@ -565,5 +565,5 @@

// DO allow `undefined` items from arrays and nested arrays (`*` case)
// DO allow `undefined` items from arrays and nested arrays (`===` case)
{
example: '*',
example: '===',
actual: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}],

@@ -573,6 +573,6 @@ result: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}]

// Don't allow `undefined` items from arrays and nested arrays (`[*]` case)
// (because '*' does not allow `undefined`)
// Don't allow `undefined` items from arrays and nested arrays (`[===]` case)
// (because '===' does not allow `undefined`)
{
example: ['*'],
example: ['==='],
actual: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}],

@@ -583,6 +583,6 @@ error: true

// Ensure that nested dictionaries inside of an array passed
// through `example: ['*']` are NOT stripped of keys with undefined values--
// through `example: ['===']` are NOT stripped of keys with undefined values--
// and are left utterly alone
{
example: ['*'],
example: ['==='],
actual: [{a:3, b: undefined}, {a: undefined}],

@@ -592,3 +592,3 @@ result: [{a: 3, b: undefined},{a:undefined}]

{
example: ['*'],
example: ['==='],
actual: [{a:3,someStuff: [{x: undefined, y: 'foo'}, {x: 'bar', y: undefined}]},{a: 5, b: undefined}],

@@ -667,8 +667,8 @@ result: [{a:3,someStuff: [{x: undefined, y: 'foo'}, {x: 'bar', y: undefined}]},{a: 5, b: undefined}]

{ example: '*', actual: /some regexp/, strictEq: true },
{ example: '*', actual: function (){}, strictEq: true },
{ example: '*', actual: new Date('November 5, 1605 GMT'), strictEq: true },
{ example: '*', actual: new (require('stream').Readable)(), strictEq: true },
{ example: '*', actual: new Buffer('asdf'), strictEq: true },
{ example: '*', actual: new Error('asdf'), strictEq: true },
{ example: '===', actual: /some regexp/, strictEq: true },
{ example: '===', actual: function (){}, strictEq: true },
{ example: '===', actual: new Date('November 5, 1605 GMT'), strictEq: true },
{ example: '===', actual: new (require('stream').Readable)(), strictEq: true },
{ example: '===', actual: new Buffer('asdf'), strictEq: true },
{ example: '===', actual: new Error('asdf'), strictEq: true },

@@ -675,0 +675,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc