Comparing version 0.0.1 to 0.0.2
278
jstype.js
@@ -1,148 +0,146 @@ | ||
/*** JsType - extended javascript type checking for Node.js and the browser ***/ | ||
(function (root, name) { | ||
var node = typeof exports === 'object', | ||
mod = node ? module : { | ||
exports: {} | ||
}; | ||
factory(mod, mod.exports); | ||
if (typeof define === 'function' && define.amd) { | ||
define(name, module.exports); | ||
} | ||
else if (!node) { | ||
root[name] = mod.exports; | ||
} | ||
// can be loaded as vanilla javascript, commonJS / Node.js module, or AMD module | ||
(function(window) { | ||
function factory(module, exports) { | ||
/****************************************************************************** | ||
* Type [object] | ||
* | ||
* an enumeration of native Object Class constructors mapped to their string | ||
* equivalents, e.g. Object => 'object', String => 'string', etc. used | ||
* internally but exposed for general usefulness in specifying types | ||
* | ||
* usage example: | ||
* var stringType = Type[String]; | ||
* | ||
***********************************/ | ||
var Type = exports.Type = {}; | ||
Type[Object] = 'object'; | ||
Type[String] = 'string'; | ||
Type[Array] = 'array'; | ||
Type[Date] = 'date'; | ||
Type[Number] = 'number'; | ||
Type[RegExp] = 'regexp'; | ||
Type[Function] = 'function'; | ||
Type[Boolean] = 'boolean'; | ||
(function (define) { | ||
var customTypes = []; | ||
var customConstructors = []; | ||
var reservedTypes = ["undefined", "null", "infinity", "nan", "date", "regexp", "array", "integer", "float", "string", "function", "boolean", "object", "arguments"]; | ||
define('JsType', function (exports) { | ||
/****************************************************************************** | ||
* type [function] | ||
* | ||
* a function that returns the type of an object similarly to 'typeof' but with | ||
* the extended type differentiation proposed for EcmaScript 6 (Harmony). This | ||
* method relies on the value returned by Object.prototype.toString, converted | ||
* to a lower case string value matching the behavior of 'typeof', with some | ||
* special cases for distinguishing different numeric and object types. | ||
* The following values: | ||
* - undefined | ||
* - null | ||
* return their value as their type. This is based on the following from the | ||
* EcmaScript 5.1 spec: | ||
* > 15.2.4.2 Object.prototype.toString ( ) | ||
* When the toString method is called, the following steps are taken: | ||
* 1. If the this value is undefined, return "[object Undefined]". | ||
* 2. If the this value is null, return "[object Null]" | ||
* This differs from typeof in regards to null, which may return 'object' for | ||
* null values. Extended numeric type differentiation is optionally available | ||
* by passing a second argument. If getting extended numeric types, the values: | ||
* - Infinity | ||
* - NaN | ||
* are given the same treatment as undefined and null - they return their value | ||
* as their type. Extended numeric types also return types the following types: | ||
* - integer | ||
* - float | ||
* for values other than NaN or Infinity. A full list of possible return values | ||
* is listed below. Extended types may be added by passing a string type name | ||
* and a constructor. In order to check for custom types, the extended argument | ||
* must be specified as true. A third argument may be specified in the case of | ||
* desiring to check against custom types but not extended numeric types. | ||
* | ||
* arguments: | ||
* value - [any] JavaScript value to get the type of | ||
* extended - [boolean] whether to distinguish between numeric values, and/or | ||
* custom defined types | ||
* numericBase - [boolean] if extended is true, specifies whether to return | ||
* extended numeric types | ||
* returns: [string] of one of one of the following types | ||
* - undefined | ||
* - null | ||
* - infinity | ||
* - nan | ||
* - date | ||
* - regexp | ||
* - array | ||
* - integer | ||
* - float | ||
* - string | ||
* - function | ||
* - boolean | ||
* - object | ||
* | ||
* usage example: | ||
* var obj = { foo: 'bar' }, | ||
* objType = type(obj); // 'object' | ||
* type(7.1, true); // 'float' | ||
* function MyClass() { } | ||
* defineType('myclass', MyClass); | ||
* var instance = new MyClass(); | ||
* type(instance); // 'myclass' | ||
***********************************/ | ||
var customTypes = []; | ||
var customConstructors = []; | ||
var reservedTypes = [ | ||
"undefined" | ||
, "null" | ||
, "infinity" | ||
, "nan" | ||
, "date" | ||
, "regexp" | ||
, "array" | ||
, "integer" | ||
, "float" | ||
, "string" | ||
, "function" | ||
, "boolean" | ||
, "object" | ||
]; | ||
/****************************************************************************** | ||
* type [function] | ||
* | ||
* a function that returns the type of an object similarly to 'typeof' but with | ||
* the extended type differentiation proposed for EcmaScript 6 (Harmony). This | ||
* method relies on the value returned by Object.prototype.toString, converted | ||
* to a lower case string value matching the behavior of 'typeof', with some | ||
* special cases for distinguishing different numeric and object types. | ||
* The following values: | ||
* - undefined | ||
* - null | ||
* return their value as their type. This is based on the following from the | ||
* EcmaScript 5.1 spec: | ||
* > 15.2.4.2 Object.prototype.toString ( ) | ||
* When the toString method is called, the following steps are taken: | ||
* 1. If the this value is undefined, return "[object Undefined]". | ||
* 2. If the this value is null, return "[object Null]" | ||
* This differs from typeof in regards to null, which may return 'object' for | ||
* null values. Extended numeric type differentiation is optionally available | ||
* by passing a second argument. If getting extended numeric types, the values: | ||
* - Infinity | ||
* - NaN | ||
* are given the same treatment as undefined and null - they return their value | ||
* as their type. Extended numeric types also return types the following types: | ||
* - integer | ||
* - float | ||
* for values other than NaN or Infinity. A full list of possible return values | ||
* is listed below. Extended types may be added by passing a string type name | ||
* and a constructor. In order to check for custom types, the extended argument | ||
* must be specified as true. A third argument may be specified in the case of | ||
* desiring to check against custom types but not extended numeric types. | ||
* | ||
* arguments: | ||
* value - [any] JavaScript value to get the type of | ||
* extended - [boolean] whether to distinguish between numeric values, and/or | ||
* custom defined types | ||
* numericBase - [boolean] if extended is true, specifies whether to return | ||
* extended numeric types | ||
* returns: [string] of one of one of the following types | ||
* - undefined | ||
* - null | ||
* - infinity | ||
* - nan | ||
* - date | ||
* - regexp | ||
* - array | ||
* - integer | ||
* - float | ||
* - string | ||
* - function | ||
* - boolean | ||
* - object | ||
* | ||
* usage example: | ||
* var obj = { foo: 'bar' }, | ||
* objType = type(obj); // 'object' | ||
* type(7.1, true); // 'float' | ||
* function MyClass() { } | ||
* defineType('myclass', MyClass); | ||
* var instance = new MyClass(); | ||
* type(instance); // 'myclass' | ||
***********************************/ | ||
exports.type = function type(value, extended, baseNumeric) { | ||
if (value === 'undefined') return 'undefined'; | ||
if (value === null) return 'null'; | ||
if (extended) { | ||
var _type = typeof value; | ||
if (_type === 'number' && !baseNumeric) { | ||
if (value.toString() === 'NaN') return 'nan'; | ||
if (value === Infinity) return 'infinity'; | ||
if (value % 1 === 0) return 'integer'; | ||
return 'float'; | ||
} | ||
_type = null; | ||
var i = customTypes.length; | ||
while (i-- && !_type) { | ||
_type = value instanceof customConstructors[i]; | ||
if (_type) return customTypes[i]; | ||
} | ||
exports.type = function type(value, extended, baseNumeric) { | ||
if (value === 'undefined') return 'undefined'; | ||
if (value === null) return 'null'; | ||
if (extended) { | ||
var _type = typeof value; | ||
if (_type === 'number' && !baseNumeric) { | ||
if (value.toString() === 'NaN') return 'nan'; | ||
if (value === Infinity) return 'infinity'; | ||
if (value % 1 === 0) return 'integer'; | ||
return 'float'; | ||
} | ||
// using split and substrings is faster than regular expressions | ||
var oclass = Object.prototype.toString.call(value).split(' ')[1]; | ||
return oclass.substr(0, oclass.length - 1).toLowerCase(); | ||
_type = null; | ||
var i = customTypes.length; | ||
while (i-- && !_type) { | ||
_type = value instanceof customConstructors[i]; | ||
if (_type) return customTypes[i]; | ||
} | ||
} | ||
/**** | ||
* defineType | ||
* | ||
* arguments: | ||
* type [ string ] - named type for the constructor instances | ||
* constructor [ function ] - an object constructor | ||
* | ||
***/ | ||
exports.define = function define(typeName, constructor) { | ||
if (typeof typeName === 'function') { | ||
constructor = typeName; | ||
typeName = constructor.name || constructor; | ||
} | ||
if (reservedTypes.indexOf(typeName) > -1 || | ||
customTypes.indexOf(typeName) > -1) { | ||
throw new Error('"' + typeName + '" is already defined as a type'); | ||
} | ||
customTypes.push(typeName); | ||
customConstructors.push(constructor); | ||
}; | ||
}); | ||
}(typeof define === 'function' && define.amd ? define : function (id, factory) { | ||
if (typeof exports !== 'undefined') { | ||
//commonjs | ||
factory(exports); | ||
} else { | ||
factory(function (value) { | ||
return window[value]; | ||
}, (window[id] = {})); | ||
// using split and substrings is faster than regular expressions | ||
var oclass = Object.prototype.toString.call(value).split(' ')[1]; | ||
return oclass.substr(0, oclass.length - 1).toLowerCase(); | ||
} | ||
})); | ||
})(this); | ||
/**** | ||
* defineType | ||
* | ||
* arguments: | ||
* type [ string ] - named type for the constructor instances | ||
* constructor [ function ] - an object constructor | ||
* | ||
***/ | ||
exports.define = function define(typeName, constructor) { | ||
if (typeof typeName === 'function') { | ||
constructor = typeName; | ||
typeName = constructor.name || constructor; | ||
} | ||
if (reservedTypes.indexOf(typeName) > -1 || customTypes.indexOf(typeName) > -1) { | ||
throw new Error('"' + typeName + '" is already defined as a type'); | ||
} | ||
customTypes.push(typeName); | ||
customConstructors.push(constructor); | ||
}; | ||
} | ||
})(this, 'jsType'); |
{ | ||
"name": "jstype", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "Extended and extensible javascript type checking", | ||
@@ -5,0 +5,0 @@ "main": "jstype.js", |
128
test/test.js
"use strict"; | ||
var assert = require('assert'), | ||
jstype = require('..'), | ||
type = jstype.type, | ||
extendType = jstype.extendType; | ||
var path = require('path'), | ||
test = require('tap').test, | ||
jsType = require('..'); | ||
var t, | ||
undef, | ||
samples = { | ||
base: { | ||
"undefined": undef, | ||
"null": null, | ||
"string": 'a string value', | ||
"function": function() { }, | ||
"boolean": true, | ||
"object": {}, | ||
"date": new Date(), | ||
"regexp": / /, | ||
"array": [1, 2, 3], | ||
"number": 1 | ||
}, | ||
extended: { | ||
"integer": 1, | ||
"infinity": Infinity, | ||
"nan": NaN, | ||
"float": 1.1 | ||
} | ||
}; | ||
test("jsType module", function (test) { | ||
var Type = jsType.Type; | ||
test.test("Type", function (test) { | ||
test.ok(jsType.Type); | ||
test.equal(jsType.Type[Object], 'object'); | ||
test.equal(jsType.Type[Array], 'array'); | ||
test.equal(jsType.Type[Date], 'date'); | ||
test.equal(jsType.Type[Function], 'function'); | ||
test.equal(jsType.Type[RegExp], 'regexp'); | ||
test.equal(jsType.Type[Boolean], 'boolean'); | ||
test.equal(jsType.Type[String], 'string'); | ||
test.equal(jsType.Type[Number], 'number'); | ||
test.end(); | ||
}); | ||
test.test("type", function (test) { | ||
var type = jsType.type; | ||
test.ok(type); | ||
test.test("base types", function (test) { | ||
test.equal(type(undefined), 'undefined'); | ||
test.equal(type(null), 'null'); | ||
test.equal(type(NaN), 'number'); | ||
test.equal(type('test string'), 'string'); | ||
test.equal(type(new Date('1-1-2011')), 'date'); | ||
test.equal(type(function test() { }), 'function'); | ||
test.equal(type(true), 'boolean'); | ||
test.equal(type(false), 'boolean'); | ||
test.equal(type(-1), 'number'); | ||
test.equal(type(0), 'number'); | ||
test.equal(type(1), 'number'); | ||
test.equal(type(9999), 'number'); | ||
test.equal(type([1, 2, 3]), 'array'); | ||
test.equal(type(['a', 'b', 'c']), 'array'); | ||
test.equal(type(/[a-z]/), 'regexp'); | ||
test.equal(type({}), 'object'); | ||
test.equal(type({ foo: 'bar' }), 'object'); | ||
test.end(); | ||
}); | ||
// test base types | ||
for (t in samples.base) { | ||
if (samples.base.hasOwnProperty(t)) { | ||
assert.equal(type(samples.base[t]), t); | ||
} | ||
} | ||
test.test("extended numeric types", function (test) { | ||
test.equal(type(1, true), 'integer'); | ||
test.equal(type(1.1, true), 'float'); | ||
test.equal(type(1 / 0, true), 'infinity'); | ||
test.equal(type(Infinity, true), 'infinity'); | ||
test.equal(type(NaN, true), 'nan'); | ||
test.end(); | ||
}); | ||
// test extended numerics | ||
for (t in samples.extended) { | ||
if (samples.extended.hasOwnProperty(t)) { | ||
assert.equal(type(samples.extended[t], true), t); | ||
} | ||
} | ||
test.test("custom defined types", function (test) { | ||
test.ok(jsType.define); | ||
// test custom defined types | ||
function Custom1() { }; | ||
function Custom2() { }; | ||
jsType.define(Custom1); | ||
jsType.define('custom2', Custom2); | ||
// test custom defined types | ||
function Custom1() { }; | ||
function Custom2() { }; | ||
jstype.define(Custom1); | ||
jstype.define('custom2', Custom2); | ||
var instance1 = new Custom1(), | ||
instance2 = new Custom2(); | ||
test.equal(type(instance1, true), 'Custom1'); | ||
test.equal(type(instance2, true), 'custom2'); | ||
var instance1 = new Custom1(), | ||
instance2 = new Custom2(); | ||
assert.equal(type(instance1, true), 'Custom1'); | ||
assert.equal(type(instance2, true), 'custom2'); | ||
test.test("baseNumeric argument with extended types", function (test) { | ||
test.equal(type(1, true, true), 'number'); | ||
test.equal(type(instance1, true, true), 'Custom1'); | ||
test.equal(type(instance2, false, true), 'object'); | ||
test.end(); | ||
}); | ||
// test baseNumeric argument with extended types | ||
assert.equal(type(1, true, true), 'number'); | ||
assert.equal(type(instance1, true, true), 'Custom1'); | ||
assert.equal(type(instance2, false, true), 'object'); | ||
test.end(); | ||
}); | ||
test.end(); | ||
}); | ||
test.end(); | ||
}); | ||
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
24941
8
370
1