rttc
Version:
Runtime type-checking for JavaScript.
329 lines (296 loc) • 18.3 kB
JavaScript
var util = require('util');
var assert = require('assert');
var _ = require('@sailshq/lodash');
var rttc = require('../');
describe('.stringifyHuman()', function() {
it('should coerce things to match the type schema, but as strings', function() {
assert.strictEqual( rttc.stringifyHuman('foo', 'string'), 'foo');
assert.strictEqual( rttc.stringifyHuman('', 'string'), '');
assert.strictEqual( rttc.stringifyHuman('4', 'string'), '4');
assert.strictEqual( rttc.stringifyHuman('-99', 'string'), '-99');
assert.strictEqual( rttc.stringifyHuman('Infinity', 'string'), 'Infinity');
assert.strictEqual( rttc.stringifyHuman('-Infinity', 'string'), '-Infinity');
assert.strictEqual( rttc.stringifyHuman('NaN', 'string'), 'NaN');
assert.strictEqual( rttc.stringifyHuman('true', 'string'), 'true');
assert.strictEqual( rttc.stringifyHuman('false', 'string'), 'false');
assert.strictEqual( rttc.stringifyHuman('foo', 'json'), '"foo"');
assert.strictEqual( rttc.stringifyHuman('', 'json'), '""');
assert.strictEqual( rttc.stringifyHuman('4', 'json'), '"4"');
assert.strictEqual( rttc.stringifyHuman('-99', 'json'), '"-99"');
assert.strictEqual( rttc.stringifyHuman('true', 'json'), '"true"');
assert.strictEqual( rttc.stringifyHuman('false', 'json'), '"false"');
assert.strictEqual( rttc.stringifyHuman('null', 'json'), '"null"');
assert.strictEqual( rttc.stringifyHuman('foo', 'ref'), '"foo"');
assert.strictEqual( rttc.stringifyHuman('', 'ref'), '""');
assert.strictEqual( rttc.stringifyHuman('4', 'ref'), '"4"');
assert.strictEqual( rttc.stringifyHuman('-99', 'ref'), '"-99"');
assert.strictEqual( rttc.stringifyHuman('true', 'ref'), '"true"');
assert.strictEqual( rttc.stringifyHuman('false', 'ref'), '"false"');
assert.strictEqual( rttc.stringifyHuman('null', 'ref'), '"null"');
assert.strictEqual( rttc.stringifyHuman(4, 'number'), '4');
assert.strictEqual( rttc.stringifyHuman(10.345, 'number'), '10.345');
assert.strictEqual( rttc.stringifyHuman(-99, 'number'), '-99');
assert.strictEqual( rttc.stringifyHuman(Math.PI, 'number'), '3.141592653589793');
assert.strictEqual( rttc.stringifyHuman(4, 'json'), '4');
assert.strictEqual( rttc.stringifyHuman(10.345, 'json'), '10.345');
assert.strictEqual( rttc.stringifyHuman(-99, 'json'), '-99');
assert.strictEqual( rttc.stringifyHuman(Math.PI, 'json'), '3.141592653589793');
assert.strictEqual( rttc.stringifyHuman(4, 'ref'), '4');
assert.strictEqual( rttc.stringifyHuman(10.345, 'ref'), '10.345');
assert.strictEqual( rttc.stringifyHuman(-99, 'ref'), '-99');
assert.strictEqual( rttc.stringifyHuman(Math.PI, 'ref'), '3.141592653589793');
assert.strictEqual( rttc.stringifyHuman(false, 'boolean'), 'false');
assert.strictEqual( rttc.stringifyHuman(true, 'boolean'), 'true');
assert.strictEqual( rttc.stringifyHuman(true, 'json'), 'true');
assert.strictEqual( rttc.stringifyHuman(false, 'json'), 'false');
assert.strictEqual( rttc.stringifyHuman(true, 'ref'), 'true');
assert.strictEqual( rttc.stringifyHuman(false, 'ref'), 'false');
assert.strictEqual( rttc.stringifyHuman({}, {}), '{}');
assert.strictEqual( rttc.stringifyHuman({}, 'json'), '{}');
assert.strictEqual( rttc.stringifyHuman({}, 'ref'), '{}');
assert.strictEqual( rttc.stringifyHuman([], []), '[]');
assert.strictEqual( rttc.stringifyHuman([], 'json'), '[]');
assert.strictEqual( rttc.stringifyHuman([], 'ref'), '[]');
assert.strictEqual( rttc.stringifyHuman(function asdf(){}, 'lamda'), 'function asdf(){}');
assert.strictEqual( rttc.stringifyHuman(null, 'json'), 'null');
assert.strictEqual( rttc.stringifyHuman(null, 'ref'), 'null');
});
it('should be reversible using .parseHuman()', function() {
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('foo', 'string'), 'string', true), 'foo', 'string' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('', 'string'), 'string', true), '', 'string' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('4', 'string'), 'string', true), '4', 'string' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('-99', 'string'), 'string', true), '-99', 'string' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('Infinity', 'string'), 'string', true), 'Infinity', 'string' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('-Infinity', 'string'), 'string', true), '-Infinity', 'string' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('NaN', 'string'), 'string', true), 'NaN', 'string' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('true', 'string'), 'string', true), 'true', 'string' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('false', 'string'), 'string', true), 'false', 'string' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('foo', 'json'), 'json', true), 'foo', 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('', 'json'), 'json', true), '', 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('4', 'json'), 'json', true), '4', 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('-99', 'json'), 'json', true), '-99', 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('true', 'json'), 'json', true), 'true', 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('false', 'json'), 'json', true), 'false', 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('null', 'json'), 'json', true), 'null', 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('foo', 'ref'), 'ref', true), 'foo', 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('', 'ref'), 'ref', true), '', 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('4', 'ref'), 'ref', true), '4', 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('-99', 'ref'), 'ref', true), '-99', 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('true', 'ref'), 'ref', true), 'true', 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('false', 'ref'), 'ref', true), 'false', 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman('null', 'ref'), 'ref', true), 'null', 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(4, 'number'), 'number', true), 4, 'number' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(10.345, 'number'), 'number', true), 10.345, 'number' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(-99, 'number'), 'number', true), -99, 'number' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(Math.PI, 'number'), 'number', true), Math.PI, 'number' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(4, 'json'), 'json', true), 4, 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(10.345, 'json'), 'json', true), 10.345, 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(-99, 'json'), 'json', true), -99, 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(Math.PI, 'json'), 'json', true), Math.PI, 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(4, 'ref'), 'ref', true), 4, 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(10.345, 'ref'), 'ref', true), 10.345, 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(-99, 'ref'), 'ref', true), -99, 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(Math.PI, 'ref'), 'ref', true), Math.PI, 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(false, 'boolean'), 'boolean', true), false, 'boolean' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(true, 'boolean'), 'boolean', true), true, 'boolean' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(true, 'json'), 'json', true), true, 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(false, 'json'), 'json', true), false, 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(true, 'ref'), 'ref', true), true, 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(false, 'ref'), 'ref', true), false, 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman({}, {}), {}, true), {}, {} ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman({}, 'json'), 'json', true), {}, 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman({}, 'ref'), 'ref', true), {}, 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman([], []), [], true), [], [] ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman([], 'json'), 'json', true), [], 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman([], 'ref'), 'ref', true), [], 'ref' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(function asdf(){}, 'lamda'), 'lamda', true), function asdf(){}, 'lamda' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(null, 'json'), 'json', true), null, 'json' ) );
assert( rttc.isEqual( rttc.parseHuman(rttc.stringifyHuman(null, 'ref'), 'ref', true), null, 'ref' ) );
});
it('should add quotes to strings when type schema is "json"', function() {
assert.strictEqual(rttc.stringifyHuman('stuff', 'json'), '"stuff"' );
});
it('should add NOT quotes to numbers, booleans, dictionaries, arrays, or `null` when type schema is "json"', function() {
assert.strictEqual(rttc.stringifyHuman(3, 'json'), '3' );
assert.strictEqual(rttc.stringifyHuman(true, 'json'), 'true' );
assert.strictEqual(rttc.stringifyHuman({}, 'json'), '{}' );
assert.strictEqual(rttc.stringifyHuman([], 'json'), '[]' );
assert.strictEqual(rttc.stringifyHuman(null, 'json'), 'null' );
});
it('should tolerate `null` for "json" type schemas', function() {
assert.strictEqual( rttc.stringifyHuman(null, 'json'), 'null');
});
it('should tolerate `null` for "ref" type schemas', function() {
assert.strictEqual( rttc.stringifyHuman(null, 'ref'), 'null' );
});
it('should tolerate `null` for type schemas w/ nested "json" types', function() {
assert.strictEqual( rttc.stringifyHuman([null], ['json']), '[null]' );
assert.strictEqual( rttc.stringifyHuman({x:null}, {x:'json'}), '{"x":null}' );
});
it('should tolerate `null` for type schemas w/ nested "ref" types', function() {
assert.strictEqual( rttc.stringifyHuman([null], ['ref']), '[null]');
assert.strictEqual( rttc.stringifyHuman({x:null}, {x:'ref'}), '{"x":null}' );
});
it('should NOT tolerate `null` for {} or [] type schemas', function() {
assert.throws(function (){
rttc.stringifyHuman(null, {});
});
assert.throws(function (){
rttc.stringifyHuman(null, []);
});
assert.throws(function (){
rttc.stringifyHuman([null], [{}]);
});
assert.throws(function (){
rttc.stringifyHuman([null], [[]]);
});
assert.throws(function (){
rttc.stringifyHuman({x:null}, {x:{}});
});
assert.throws(function (){
rttc.stringifyHuman({x:null}, {x:[]});
});
});
it('should dehydrate functions (if we have a lamda type schema)', function() {
assert(
rttc.isEqual(rttc.stringifyHuman(function foo (){}, 'lamda'), 'function foo(){}', 'lamda')
);
});
it('should dehydrate nested functions (if we have a type schema w/ nested lamdas in the appropriate places)', function() {
assert.equal(
rttc.stringifyHuman({x:function foo (){}}, {x:'lamda'}),
'{"x":"function foo(){}"}'
);
assert.equal(
rttc.stringifyHuman({x:{y:function foo (){}}}, {x:{y:'lamda'}}),
'{"x":{"y":"function foo(){}"}}'
);
assert.equal(
rttc.stringifyHuman([{x:{y:function foo (){}}}], [{x:{y:'lamda'}}]),
'[{"x":{"y":"function foo(){}"}}]'
);
assert.equal(
rttc.stringifyHuman([function foo (){}], ['lamda']),
'["function foo(){}"]'
);
});
describe('edge-cases', function (){
it('should refuse to work if not provided a type schema', function() {
assert.throws(function (){
rttc.stringifyHuman(4);
});
});
describe('stringification cannot be safely reversed', function(){
// Against `json`
it('should throw when given a function against type: `ref`',function(){
assert.throws(function (){
rttc.stringifyHuman(function asdf(){}, 'ref');
});
});
it('should throw when given an Error against type: `ref`',function(){
assert.throws(function (){
rttc.stringifyHuman(new Error('foo'), 'ref');
});
});
it('should throw when given a Date against type: `ref`',function(){
assert.throws(function (){
rttc.stringifyHuman(new Date('foo'), 'ref');
});
});
it('should throw when given a RegExp against type: `ref`',function(){
assert.throws(function (){
rttc.stringifyHuman(/sadg/g, 'ref');
});
});
it('should throw when given a Stream against type: `ref`',function(){
assert.throws(function (){
rttc.stringifyHuman(new (require('stream').Readable)(), 'ref');
});
assert.throws(function (){
rttc.stringifyHuman(new (require('stream').Stream)(), 'ref');
});
});
it('should throw when given a Buffer against type: `ref`',function(){
assert.throws(function (){
rttc.stringifyHuman(new Buffer(), 'ref');
});
});
it('should throw when given Infinity, -Infinity, or NaN against type: `ref`',function(){
assert.throws(function (){
rttc.stringifyHuman(Infinity, 'ref');
});
assert.throws(function (){
rttc.stringifyHuman(-Infinity, 'ref');
});
assert.throws(function (){
rttc.stringifyHuman(NaN, 'ref');
});
});
// Against `json`
it('should throw when given a function against type: `json`',function(){
assert.throws(function (){
rttc.stringifyHuman(function asdf(){}, 'json');
});
});
it('should throw when given an Error against type: `json`',function(){
assert.throws(function (){
rttc.stringifyHuman(new Error('foo'), 'json');
});
});
it('should throw when given a Date against type: `json`',function(){
assert.throws(function (){
rttc.stringifyHuman(new Date('foo'), 'json');
});
});
it('should throw when given a RegExp against type: `json`',function(){
assert.throws(function (){
rttc.stringifyHuman(/sadg/g, 'json');
});
});
it('should throw when given a Stream against type: `json`',function(){
assert.throws(function (){
rttc.stringifyHuman(new (require('stream').Readable)(), 'json');
});
assert.throws(function (){
rttc.stringifyHuman(new (require('stream').Stream)(), 'json');
});
});
it('should throw when given a Buffer against type: `json`',function(){
assert.throws(function (){
rttc.stringifyHuman(new Buffer(), 'json');
});
});
it('should throw when given Infinity, -Infinity, or NaN against type: `json`',function(){
assert.throws(function (){
rttc.stringifyHuman(Infinity, 'json');
});
assert.throws(function (){
rttc.stringifyHuman(-Infinity, 'json');
});
assert.throws(function (){
rttc.stringifyHuman(NaN, 'json');
});
});
});
it('should refuse to work if value does not strictly validate against type schema', function() {
assert.throws(function (){
rttc.stringifyHuman('whatever', 'lamda');
});
assert.throws(function (){
rttc.stringifyHuman('whatever', 'boolean');
});
assert.throws(function (){
rttc.stringifyHuman(4, 'boolean');
});
assert.throws(function (){
rttc.stringifyHuman(4, 'string');
});
assert.throws(function (){
rttc.stringifyHuman('4', 'number');
});
assert.throws(function(){
rttc.stringifyHuman(function asdf(){}, 'json');
});
});
});
});