[Pkg-javascript-commits] [node-type-detect] 01/08: Imported Upstream version 4.0.0
Sruthi Chandran
srud-guest at moszumanska.debian.org
Wed Oct 12 17:52:25 UTC 2016
This is an automated email from the git hooks/post-receive script.
srud-guest pushed a commit to branch master
in repository node-type-detect.
commit c474dd5b69bedf0a02d04ac10eaa3209ed97a370
Author: Syam G Krishnan <sgk at riseup.net>
Date: Tue Oct 11 17:33:40 2016 +0530
Imported Upstream version 4.0.0
---
.gitignore | 21 +++
.travis.yml | 25 +++
LICENSE | 19 +++
MAINTAINERS | 4 +
README.md | 219 ++++++++++++++++++++++++++
bench/.eslintrc | 17 ++
bench/index.js | 78 +++++++++
index.js | 366 +++++++++++++++++++++++++++++++++++++++++++
karma.conf.js | 96 ++++++++++++
package.json | 85 ++++++++++
test/.eslintrc | 19 +++
test/dom.js | 332 +++++++++++++++++++++++++++++++++++++++
test/index.js | 272 ++++++++++++++++++++++++++++++++
test/new-ecmascript-types.js | 136 ++++++++++++++++
test/node.js | 18 +++
15 files changed, 1707 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6b5659a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,21 @@
+lib-cov
+*.seed
+*.log
+*.csv
+*.dat
+*.out
+*.pid
+*.gz
+
+pids
+logs
+results
+build
+components
+
+node_modules
+npm-debug.log
+
+coverage/
+
+type-detect.js
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..0521b42
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,25 @@
+sudo: false
+language: node_js
+addons:
+ sauce_connect: true
+cache:
+ directories:
+ - node_modules
+node_js:
+ - 0.1
+ - 4.3
+ - stable
+before_install:
+ - npm i -g npm
+script:
+ - npm t
+after_success:
+ - 'travis-after-all && npm run semantic-release'
+env:
+ global:
+ - secure: AgiUWRCNP2z0oHCjdm3lk4YawBOQz8Q4DOrzOR3tDt2fSWo2t40cynfGJlQwpFmTvec5G04lO9bEC9/yoW7xAS0ysu5p7utngXaKtKDoq3Zr0aYLLLsCv/0PAv1YstMyo/mRbRetxob76wUFcrbB3r5alIF5YW1JCmj/O9bvdUQ=
+ - secure: TepAZmznoPWUX12snu2eb7Sni+31tiOO6ZeU3wovrhCpGzykBNr6xAvUklr88L+uKtvfsTq8sipX0jtZvL7lcIEzujirTpjaj4QV5mUFiV2N40o+C3LdNmfmU9dhUcXRu9vMSs9uc7YfPers4We8X99UxTHxljK7VyJe39ULpRk=
+ - SAUCE_CONNECT_READY_FILE=/tmp/sauce-connect-ready
+ - LOGS_DIR=/tmp/chai-build/logs
+ - secure: fakflt6DaPW9NYFdUpTfQGoKFt5F1EZeSiGqWeTCZ3+VDiEC/d9rPf7JfHkDklpr4swEW7ovbfV4PHp+MeT+jje8eQAezbhdT8hAmChykeTKKfgvifMwQp6TD3DQVrf6cJqqZfkJkkzuYJjGivZ8FA4KXTglyBrjozM8KH675UU=
+ - secure: bE+qM+B4dA+oQSfHo4BM9NVU5LCdgkEmfThfmIp3kmX19RO/1R1dlu18M1rVyDUNaqFUwCsq/W/9a+Dv1r+7knmfmJoUKuXCcIjn6WBs4Pd2kPwjCjvQ+5RWTw67v44de78AFb3IH7dT2H+fhgeHrfaI3NIV27BlKx6OqTnqDRY=
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7ea799f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2013 Jake Luer <jake at alogicalparadox.com> (http://alogicalparadox.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/MAINTAINERS b/MAINTAINERS
new file mode 100644
index 0000000..baebbae
--- /dev/null
+++ b/MAINTAINERS
@@ -0,0 +1,4 @@
+keithamus
+davelosert
+lucasfcosta
+meeber
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..da892e5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,219 @@
+<h1 align=center>
+ <a href="http://chaijs.com" title="Chai Documentation">
+ <img alt="ChaiJS" src="http://chaijs.com/img/chai-logo.png"/> type-detect
+ </a>
+</h1>
+
+<p align=center>
+ Improved typeof detection for <a href="http://nodejs.org">node</a> and the browser.
+</p>
+
+<p align=center>
+ <a href="./LICENSE">
+ <img
+ alt="license:mit"
+ src="https://img.shields.io/badge/license-mit-green.svg?style=flat-square"
+ />
+ </a>
+ <a href="https://github.com/chaijs/type-detect/releases">
+ <img
+ alt="tag:?"
+ src="https://img.shields.io/github/tag/chaijs/type-detect.svg?style=flat-square"
+ />
+ </a>
+ <a href="https://travis-ci.org/chaijs/type-detect">
+ <img
+ alt="build:?"
+ src="https://img.shields.io/travis/chaijs/type-detect/master.svg?style=flat-square"
+ />
+ </a>
+ <a href="https://coveralls.io/r/chaijs/type-detect">
+ <img
+ alt="coverage:?"
+ src="https://img.shields.io/coveralls/chaijs/type-detect/master.svg?style=flat-square"
+ />
+ </a>
+ <a href="https://www.npmjs.com/packages/type-detect">
+ <img
+ alt="npm:?"
+ src="https://img.shields.io/npm/v/type-detect.svg?style=flat-square"
+ />
+ </a>
+ <a href="https://www.npmjs.com/packages/type-detect">
+ <img
+ alt="dependencies:?"
+ src="https://img.shields.io/npm/dm/type-detect.svg?style=flat-square"
+ />
+ </a>
+ <a href="">
+ <img
+ alt="devDependencies:?"
+ src="https://img.shields.io/david/chaijs/type-detect.svg?style=flat-square"
+ />
+ </a>
+ <br/>
+ <a href="https://saucelabs.com/u/chaijs-type-detect">
+ <img
+ alt="Selenium Test Status"
+ src="https://saucelabs.com/browser-matrix/chaijs-type-detect.svg"
+ />
+ </a>
+ <br>
+ <a href="https://chai-slack.herokuapp.com/">
+ <img
+ alt="Join the Slack chat"
+ src="https://img.shields.io/badge/slack-join%20chat-E2206F.svg?style=flat-square"
+ />
+ </a>
+ <a href="https://gitter.im/chaijs/chai">
+ <img
+ alt="Join the Gitter chat"
+ src="https://img.shields.io/badge/gitter-join%20chat-D0104D.svg?style=flat-square"
+ />
+ </a>
+</p>
+
+## What is Type-Detect?
+
+Type Detect is a module which you can use to detect the type of a given object. It returns a string representation of the object's type, either using [`typeof`](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-typeof-operator) or [`@@toStringTag`](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-symbol.tostringtag). It also normalizes some object names for consistency among browsers.
+
+## Why?
+
+The `typeof` operator will only specify primitive values; everthing else is `"object"` (including `null`, arrays, regexps, etc). Many developers use `Object.prototype.toString()` - which is a fine alternative and returns many more types (null returns `[object Null]`, Arrays as `[object Array]`, regexps as `[object RegExp]` etc).
+
+Sadly, `Object.prototype.toString` is slow, and buggy. By slow - we mean it is slower than `typeof`. By buggy - we mean that some values (like Promises, the global object, iterators, dataviews, a bunch of HTML elements) all report different things in different browsers.
+
+`type-detect` fixes all of the shortcomings with `Object.prototype.toString`. We have extra code to speed up checks of JS and DOM objects, as much as 20-30x faster for some values. `type-detect` also fixes any consistencies with these objects.
+
+## Installation
+
+### Node.js
+
+`type-detect` is available on [npm](http://npmjs.org). To install it, type:
+
+ $ npm install type-detect
+
+### Browsers
+
+You can also use it within the browser; install via npm and use the `type-detect.js` file found within the download. For example:
+
+```html
+<script src="./node_modules/type-detect/type-detect.js"></script>
+```
+
+## Usage
+
+The primary export of `type-detect` is function that can serve as a replacement for `typeof`. The results of this function will be more specific than that of native `typeof`.
+
+```js
+var type = require('type-detect');
+```
+
+#### array
+
+```js
+assert(type([]) === 'Array');
+assert(type(new Array()) === 'Array');
+```
+
+#### regexp
+
+```js
+assert(type(/a-z/gi) === 'RegExp');
+assert(type(new RegExp('a-z')) === 'RegExp');
+```
+
+#### function
+
+```js
+assert(type(function () {}) === 'function');
+```
+
+#### arguments
+
+```js
+(function () {
+ assert(type(arguments) === 'Arguments');
+})();
+```
+
+#### date
+
+```js
+assert(type(new Date) === 'Date');
+```
+
+#### number
+
+```js
+assert(type(1) === 'number');
+assert(type(1.234) === 'number');
+assert(type(-1) === 'number');
+assert(type(-1.234) === 'number');
+assert(type(Infinity) === 'number');
+assert(type(NaN) === 'number');
+assert(type(new Number(1)) === 'Number'); // note - the object version has a capital N
+```
+
+#### string
+
+```js
+assert(type('hello world') === 'string');
+assert(type(new String('hello')) === 'String'); // note - the object version has a capital S
+```
+
+#### null
+
+```js
+assert(type(null) === 'null');
+assert(type(undefined) !== 'null');
+```
+
+#### undefined
+
+```js
+assert(type(undefined) === 'undefined');
+assert(type(null) !== 'undefined');
+```
+
+#### object
+
+```js
+var Noop = function () {};
+assert(type({}) === 'Object');
+assert(type(Noop) !== 'Object');
+assert(type(new Noop) === 'Object');
+assert(type(new Object) === 'Object');
+```
+
+#### ECMA6 Types
+
+All new ECMAScript 2015 objects are also supported, such as Promises and Symbols:
+
+```js
+assert(type(new Map() === 'Map');
+assert(type(new WeakMap()) === 'WeakMap');
+assert(type(new Set()) === 'Set');
+assert(type(new WeakSet()) === 'WeakSet');
+assert(type(Symbol()) === 'Symbol');
+assert(type(new Promise(callback) === 'Promise');
+assert(type(new Int8Array()) === 'Int8Array');
+assert(type(new Uint8Array()) === 'Uint8Array');
+assert(type(new UInt8ClampedArray()) === 'Uint8ClampedArray');
+assert(type(new Int16Array()) === 'Int16Array');
+assert(type(new Uint16Array()) === 'Uint16Array');
+assert(type(new Int32Array()) === 'Int32Array');
+assert(type(new UInt32Array()) === 'Uint32Array');
+assert(type(new Float32Array()) === 'Float32Array');
+assert(type(new Float64Array()) === 'Float64Array');
+assert(type(new ArrayBuffer()) === 'ArrayBuffer');
+assert(type(new DataView(arrayBuffer)) === 'DataView');
+```
+
+Also, if you use `Symbol.toStringTag` to change an Objects return value of the `toString()` Method, `type()` will return this value, e.g:
+
+```js
+var myObject = {};
+myObject[Symbol.toStringTag] = 'myCustomType';
+assert(type(myObject) === 'myCustomType');
+```
diff --git a/bench/.eslintrc b/bench/.eslintrc
new file mode 100644
index 0000000..acc6682
--- /dev/null
+++ b/bench/.eslintrc
@@ -0,0 +1,17 @@
+{
+ "extends": [ "strict/test" ],
+ "env": {
+ "node": true,
+ "browser": true,
+ "es6": true
+ },
+ "rules": {
+ "no-new-wrappers": 0,
+ "no-array-constructor": 0,
+ "no-new-object": 0,
+ "no-empty-function": 0,
+ "no-undefined": 0,
+ "no-console": 0,
+ "id-length": 0
+ }
+}
diff --git a/bench/index.js b/bench/index.js
new file mode 100644
index 0000000..c5d5a01
--- /dev/null
+++ b/bench/index.js
@@ -0,0 +1,78 @@
+'use strict';
+var typeDetect = require('../');
+var Benchmark = require('benchmark');
+var benches = [];
+var fixtures = {
+ 'string literal ': '',
+ 'array literal ': [],
+ 'boolean literal ': true,
+ 'object literal ': {},
+ 'object from null ': Object.create(null),
+ 'regex literal ': /^$/,
+ 'number literal ': 1,
+ 'promise ': Promise.resolve(),
+ 'null ': null,
+ 'undefined ': undefined,
+ 'function ': function () {},
+
+ 'buffer ': new Buffer(1),
+ 'date ': new Date(),
+ 'error ': new Error(),
+ 'map ': new Map(),
+ 'regex constructor ': new RegExp(),
+ 'set ': new Set(),
+ 'string constructor': new String(),
+ 'weakmap ': new WeakMap(),
+ 'weakset ': new WeakSet(),
+ 'arguments ': (function () {
+ return arguments;
+ }()),
+};
+try {
+ fixtures['arrow function '] = eval('() => {}'); // eslint-disable-line no-eval
+} catch (error) {
+ console.error('cannot benchmark arrow functions');
+}
+try {
+ fixtures['generator function'] = eval('function * generator() {}; generator'); // eslint-disable-line no-eval
+} catch (error) {
+ console.error('cannot benchmark generator functions');
+}
+[
+ 'Float64Array', 'Float32Array',
+ 'Uint32Array', 'Uint16Array', 'Uint8Array',
+ 'Int32Array', 'Int16Array', 'Int8Array',
+ 'Uint8ClampedArray',
+].forEach(function (value) {
+ if (typeof global[value] === 'function') {
+ fixtures[value + new Array(19 - value.length).join(' ')] = new (global[value])(1);
+ }
+});
+if (typeof DataView === 'function') {
+ fixtures['DataView '] = new DataView(new ArrayBuffer(1));
+}
+
+var filter = process.argv[2] || '';
+Object.keys(fixtures).filter(function (key) {
+ return key.indexOf(filter) !== -1;
+}).forEach(function (test) {
+ benches.push(new Benchmark(test, {
+ fn: function () {
+ typeDetect(fixtures[test]);
+ },
+ onCycle: function (event) {
+ process.stdout.clearLine();
+ process.stdout.cursorTo(0);
+ process.stdout.write(event.target.toString());
+ },
+ }));
+});
+Benchmark.invoke(benches, {
+ name: 'run',
+ onCycle: function onCycle() {
+ console.log('');
+ },
+ onComplete: function onComplete() {
+ console.log('~Fin~');
+ },
+});
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..c6d7d5d
--- /dev/null
+++ b/index.js
@@ -0,0 +1,366 @@
+'use strict';
+/* !
+ * type-detect
+ * Copyright(c) 2013 jake luer <jake at alogicalparadox.com>
+ * MIT Licensed
+ */
+var promiseExists = typeof Promise === 'function';
+var globalObject = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : self; // eslint-disable-line
+var isDom = 'location' in globalObject && 'document' in globalObject;
+var symbolExists = typeof Symbol !== 'undefined';
+var mapExists = typeof Map !== 'undefined';
+var setExists = typeof Set !== 'undefined';
+var weakMapExists = typeof WeakMap !== 'undefined';
+var weakSetExists = typeof WeakSet !== 'undefined';
+var dataViewExists = typeof DataView !== 'undefined';
+var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined';
+var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined';
+var setEntriesExists = setExists && typeof Set.prototype.entries === 'function';
+var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function';
+var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries());
+var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries());
+var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
+var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
+var stringIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
+var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]());
+var toStringLeftSliceLength = 8;
+var toStringRightSliceLength = -1;
+/**
+ * ### typeOf (obj)
+ *
+ * Uses `Object.prototype.toString` to determine the type of an object,
+ * normalising behaviour across engine versions & well optimised.
+ *
+ * @param {Mixed} object
+ * @return {String} object type
+ * @api public
+ */
+module.exports = function typeDetect(obj) {
+ /* ! Speed optimisation
+ * Pre:
+ * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled)
+ * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled)
+ * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled)
+ * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled)
+ * function x 2,556,769 ops/sec ±1.73% (77 runs sampled)
+ * Post:
+ * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled)
+ * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled)
+ * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled)
+ * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled)
+ * function x 31,296,870 ops/sec ±0.96% (83 runs sampled)
+ */
+ var typeofObj = typeof obj;
+ if (typeofObj !== 'object') {
+ return typeofObj;
+ }
+
+ /* ! Speed optimisation
+ * Pre:
+ * null x 28,645,765 ops/sec ±1.17% (82 runs sampled)
+ * Post:
+ * null x 36,428,962 ops/sec ±1.37% (84 runs sampled)
+ */
+ if (obj === null) {
+ return 'null';
+ }
+
+ /* ! Spec Conformance
+ * Test: `Object.prototype.toString.call(window)``
+ * - Node === "[object global]"
+ * - Chrome === "[object global]"
+ * - Firefox === "[object Window]"
+ * - PhantomJS === "[object Window]"
+ * - Safari === "[object Window]"
+ * - IE 11 === "[object Window]"
+ * - IE Edge === "[object Window]"
+ * Test: `Object.prototype.toString.call(this)``
+ * - Chrome Worker === "[object global]"
+ * - Firefox Worker === "[object DedicatedWorkerGlobalScope]"
+ * - Safari Worker === "[object DedicatedWorkerGlobalScope]"
+ * - IE 11 Worker === "[object WorkerGlobalScope]"
+ * - IE Edge Worker === "[object WorkerGlobalScope]"
+ */
+ if (obj === globalObject) {
+ return 'global';
+ }
+
+ /* ! Speed optimisation
+ * Pre:
+ * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled)
+ * Post:
+ * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled)
+ */
+ if (Array.isArray(obj)) {
+ return 'Array';
+ }
+
+ if (isDom) {
+ /* ! Spec Conformance
+ * (https://html.spec.whatwg.org/multipage/browsers.html#location)
+ * WhatWG HTML$7.7.3 - The `Location` interface
+ * Test: `Object.prototype.toString.call(window.location)``
+ * - IE <=11 === "[object Object]"
+ * - IE Edge <=13 === "[object Object]"
+ */
+ if (obj === globalObject.location) {
+ return 'Location';
+ }
+
+ /* ! Spec Conformance
+ * (https://html.spec.whatwg.org/#document)
+ * WhatWG HTML$3.1.1 - The `Document` object
+ * Note: Most browsers currently adher to the W3C DOM Level 2 spec
+ * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268)
+ * which suggests that browsers should use HTMLTableCellElement for
+ * both TD and TH elements. WhatWG separates these.
+ * WhatWG HTML states:
+ * > For historical reasons, Window objects must also have a
+ * > writable, configurable, non-enumerable property named
+ * > HTMLDocument whose value is the Document interface object.
+ * Test: `Object.prototype.toString.call(document)``
+ * - Chrome === "[object HTMLDocument]"
+ * - Firefox === "[object HTMLDocument]"
+ * - Safari === "[object HTMLDocument]"
+ * - IE <=10 === "[object Document]"
+ * - IE 11 === "[object HTMLDocument]"
+ * - IE Edge <=13 === "[object HTMLDocument]"
+ */
+ if (obj === globalObject.document) {
+ return 'Document';
+ }
+
+ /* ! Spec Conformance
+ * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray)
+ * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray
+ * Test: `Object.prototype.toString.call(navigator.mimeTypes)``
+ * - IE <=10 === "[object MSMimeTypesCollection]"
+ */
+ if (obj === (globalObject.navigator || {}).mimeTypes) {
+ return 'MimeTypeArray';
+ }
+
+ /* ! Spec Conformance
+ * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
+ * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray
+ * Test: `Object.prototype.toString.call(navigator.plugins)``
+ * - IE <=10 === "[object MSPluginsCollection]"
+ */
+ if (obj === (globalObject.navigator || {}).plugins) {
+ return 'PluginArray';
+ }
+
+ /* ! Spec Conformance
+ * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
+ * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement`
+ * Test: `Object.prototype.toString.call(document.createElement('blockquote'))``
+ * - IE <=10 === "[object HTMLBlockElement]"
+ */
+ if (obj instanceof HTMLElement && obj.tagName === 'BLOCKQUOTE') {
+ return 'HTMLQuoteElement';
+ }
+
+ /* ! Spec Conformance
+ * (https://html.spec.whatwg.org/#htmltabledatacellelement)
+ * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement`
+ * Note: Most browsers currently adher to the W3C DOM Level 2 spec
+ * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
+ * which suggests that browsers should use HTMLTableCellElement for
+ * both TD and TH elements. WhatWG separates these.
+ * Test: Object.prototype.toString.call(document.createElement('td'))
+ * - Chrome === "[object HTMLTableCellElement]"
+ * - Firefox === "[object HTMLTableCellElement]"
+ * - Safari === "[object HTMLTableCellElement]"
+ */
+ if (obj instanceof HTMLElement && obj.tagName === 'TD') {
+ return 'HTMLTableDataCellElement';
+ }
+
+ /* ! Spec Conformance
+ * (https://html.spec.whatwg.org/#htmltableheadercellelement)
+ * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement`
+ * Note: Most browsers currently adher to the W3C DOM Level 2 spec
+ * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
+ * which suggests that browsers should use HTMLTableCellElement for
+ * both TD and TH elements. WhatWG separates these.
+ * Test: Object.prototype.toString.call(document.createElement('th'))
+ * - Chrome === "[object HTMLTableCellElement]"
+ * - Firefox === "[object HTMLTableCellElement]"
+ * - Safari === "[object HTMLTableCellElement]"
+ */
+ if (obj instanceof HTMLElement && obj.tagName === 'TH') {
+ return 'HTMLTableHeaderCellElement';
+ }
+ }
+
+ /* ! Speed optimisation
+ * Pre:
+ * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled)
+ * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled)
+ * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled)
+ * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled)
+ * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled)
+ * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled)
+ * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled)
+ * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled)
+ * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled)
+ * Post:
+ * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled)
+ * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled)
+ * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled)
+ * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled)
+ * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled)
+ * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled)
+ * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled)
+ * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled)
+ * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled)
+ */
+ var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]);
+ if (typeof stringTag === 'string') {
+ return stringTag;
+ }
+
+ var objPrototype = Object.getPrototypeOf(obj);
+ /* ! Speed optimisation
+ * Pre:
+ * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled)
+ * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled)
+ * Post:
+ * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled)
+ * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled)
+ */
+ if (objPrototype === RegExp.prototype) {
+ return 'RegExp';
+ }
+
+ /* ! Speed optimisation
+ * Pre:
+ * date x 2,130,074 ops/sec ±4.42% (68 runs sampled)
+ * Post:
+ * date x 3,953,779 ops/sec ±1.35% (77 runs sampled)
+ */
+ if (objPrototype === Date.prototype) {
+ return 'Date';
+ }
+
+ /* ! Spec Conformance
+ * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag)
+ * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise":
+ * Test: `Object.prototype.toString.call(Promise.resolve())``
+ * - Chrome <=47 === "[object Object]"
+ * - Edge <=20 === "[object Object]"
+ * - Firefox 29-Latest === "[object Promise]"
+ * - Safari 7.1-Latest === "[object Promise]"
+ */
+ if (promiseExists && objPrototype === Promise.prototype) {
+ return 'Promise';
+ }
+
+ /* ! Speed optimisation
+ * Pre:
+ * set x 2,222,186 ops/sec ±1.31% (82 runs sampled)
+ * Post:
+ * set x 4,545,879 ops/sec ±1.13% (83 runs sampled)
+ */
+ if (setExists && objPrototype === Set.prototype) {
+ return 'Set';
+ }
+
+ /* ! Speed optimisation
+ * Pre:
+ * map x 2,396,842 ops/sec ±1.59% (81 runs sampled)
+ * Post:
+ * map x 4,183,945 ops/sec ±6.59% (82 runs sampled)
+ */
+ if (mapExists && objPrototype === Map.prototype) {
+ return 'Map';
+ }
+
+ /* ! Speed optimisation
+ * Pre:
+ * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled)
+ * Post:
+ * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled)
+ */
+ if (weakSetExists && objPrototype === WeakSet.prototype) {
+ return 'WeakSet';
+ }
+
+ /* ! Speed optimisation
+ * Pre:
+ * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled)
+ * Post:
+ * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled)
+ */
+ if (weakMapExists && objPrototype === WeakMap.prototype) {
+ return 'WeakMap';
+ }
+
+ /* ! Spec Conformance
+ * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag)
+ * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView":
+ * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))``
+ * - Edge <=13 === "[object Object]"
+ */
+ if (dataViewExists && objPrototype === DataView.prototype) {
+ return 'DataView';
+ }
+
+ /* ! Spec Conformance
+ * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag)
+ * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator":
+ * Test: `Object.prototype.toString.call(new Map().entries())``
+ * - Edge <=13 === "[object Object]"
+ */
+ if (mapExists && objPrototype === mapIteratorPrototype) {
+ return 'Map Iterator';
+ }
+
+ /* ! Spec Conformance
+ * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag)
+ * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator":
+ * Test: `Object.prototype.toString.call(new Set().entries())``
+ * - Edge <=13 === "[object Object]"
+ */
+ if (setExists && objPrototype === setIteratorPrototype) {
+ return 'Set Iterator';
+ }
+
+ /* ! Spec Conformance
+ * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag)
+ * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator":
+ * Test: `Object.prototype.toString.call([][Symbol.iterator]())``
+ * - Edge <=13 === "[object Object]"
+ */
+ if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) {
+ return 'Array Iterator';
+ }
+
+ /* ! Spec Conformance
+ * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag)
+ * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator":
+ * Test: `Object.prototype.toString.call(''[Symbol.iterator]())``
+ * - Edge <=13 === "[object Object]"
+ */
+ if (stringIteratorExists && objPrototype === stringIteratorPrototype) {
+ return 'String Iterator';
+ }
+
+ /* ! Speed optimisation
+ * Pre:
+ * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled)
+ * Post:
+ * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled)
+ */
+ if (objPrototype === null) {
+ return 'Object';
+ }
+
+ return Object
+ .prototype
+ .toString
+ .call(obj)
+ .slice(toStringLeftSliceLength, toStringRightSliceLength);
+};
+
+module.exports.typeDetect = module.exports;
diff --git a/karma.conf.js b/karma.conf.js
new file mode 100644
index 0000000..e7a9848
--- /dev/null
+++ b/karma.conf.js
@@ -0,0 +1,96 @@
+'use strict';
+var packageJson = require('./package.json');
+var defaultTimeout = 120000;
+var browserifyIstanbul = require('browserify-istanbul');
+module.exports = function configureKarma(config) {
+ var localBrowsers = [
+ 'PhantomJS',
+ ];
+ var sauceLabsBrowsers = {
+ SauceChromeLatest: {
+ base: 'SauceLabs',
+ browserName: 'Chrome',
+ },
+ SauceFirefoxLatest: {
+ base: 'SauceLabs',
+ browserName: 'Firefox',
+ },
+ SauceSafariLatest: {
+ base: 'SauceLabs',
+ browserName: 'Safari',
+ platform: 'OS X 10.11',
+ },
+ SauceInternetExplorerLatest: {
+ base: 'SauceLabs',
+ browserName: 'Internet Explorer',
+ },
+ SauceInternetExplorerOldestSupported: {
+ base: 'SauceLabs',
+ browserName: 'Internet Explorer',
+ version: 9,
+ },
+ SauceEdgeLatest: {
+ base: 'SauceLabs',
+ browserName: 'MicrosoftEdge',
+ },
+ SauceAndroidLatest: {
+ base: 'SauceLabs',
+ browserName: 'Android',
+ },
+ };
+ config.set({
+ basePath: '',
+ browsers: localBrowsers,
+ logLevel: process.env.npm_config_debug ? config.LOG_DEBUG : config.LOG_INFO,
+ frameworks: [ 'browserify', 'mocha' ],
+ files: [ 'test/*.js' ],
+ exclude: [],
+ preprocessors: {
+ 'test/*.js': [ 'browserify' ],
+ },
+ browserify: {
+ debug: true,
+ bare: true,
+ transform: [
+ browserifyIstanbul({ ignore: [ '**/node_modules/**', '**/test/**' ] }),
+ ],
+ },
+ reporters: [ 'progress', 'coverage' ],
+ coverageReporter: {
+ type: 'lcov',
+ dir: 'coverage',
+ },
+ port: 9876,
+ colors: true,
+ concurrency: 3,
+ autoWatch: false,
+ captureTimeout: defaultTimeout,
+ browserDisconnectTimeout: defaultTimeout,
+ browserNoActivityTimeout: defaultTimeout,
+ singleRun: true,
+ });
+
+ if (process.env.SAUCE_ACCESS_KEY && process.env.SAUCE_USERNAME) {
+ var branch = process.env.TRAVIS_BRANCH || 'local';
+ var build = 'localbuild';
+ if (process.env.TRAVIS_JOB_NUMBER) {
+ build = 'travis@' + process.env.TRAVIS_JOB_NUMBER;
+ }
+ config.reporters.push('saucelabs');
+ config.set({
+ customLaunchers: sauceLabsBrowsers,
+ browsers: localBrowsers.concat(Object.keys(sauceLabsBrowsers)),
+ sauceLabs: {
+ testName: packageJson.name,
+ tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER || new Date().getTime(),
+ recordVideo: true,
+ startConnect: ('TRAVIS' in process.env) === false,
+ tags: [
+ 'typeDetect_' + packageJson.version,
+ process.env.SAUCE_USERNAME + '@' + branch,
+ build,
+ ],
+ },
+ });
+ }
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..c6ae189
--- /dev/null
+++ b/package.json
@@ -0,0 +1,85 @@
+{
+ "name": "type-detect",
+ "description": "Improved typeof detection for node.js and the browser.",
+ "keywords": [
+ "type",
+ "typeof",
+ "types"
+ ],
+ "license": "MIT",
+ "author": "Jake Luer <jake at alogicalparadox.com> (http://alogicalparadox.com)",
+ "contributors": [
+ "David Losert (https://github.com/davelosert)",
+ "Keith Cirkel (https://github.com/keithamus)",
+ "Miroslav Bajtoš (https://github.com/bajtos)"
+ ],
+ "files": [
+ "index.js",
+ "type-detect.js"
+ ],
+ "main": "./index.js",
+ "repository": {
+ "type": "git",
+ "url": "git+ssh://git@github.com/chaijs/type-detect.git"
+ },
+ "scripts": {
+ "bench": "node bench",
+ "build": "browserify --bare $npm_pakcage_main --standalone typeDetect -o type-detect.js",
+ "lint": "eslint --ignore-path .gitignore .",
+ "prepublish": "npm run build",
+ "semantic-release": "semantic-release pre && npm publish && semantic-release post",
+ "pretest": "npm run lint",
+ "test": "npm run test:node && npm run test:browser && npm run upload-coverage",
+ "test:browser": "karma start --singleRun=true",
+ "test:node": "istanbul cover _mocha",
+ "upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0"
+ },
+ "config": {
+ "ghooks": {
+ "commit-msg": "validate-commit-msg"
+ }
+ },
+ "eslintConfig": {
+ "extends": [
+ "strict/es5"
+ ],
+ "env": {
+ "es6": true
+ },
+ "globals": {
+ "HTMLElement": false
+ },
+ "rules": {
+ "complexity": 0,
+ "max-statements": 0
+ }
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "benchmark": "^2.1.0",
+ "browserify": "^13.0.0",
+ "browserify-istanbul": "^1.0.0",
+ "coveralls": "2.11.9",
+ "eslint": "^2.9.0",
+ "eslint-config-strict": "^8.5.0",
+ "eslint-plugin-filenames": "^0.2.0",
+ "ghooks": "^1.0.1",
+ "istanbul": "^0.4.2",
+ "karma": "^1.1.2",
+ "karma-browserify": "^5.0.2",
+ "karma-coverage": "^1.0.0",
+ "karma-mocha": "^1.0.1",
+ "karma-phantomjs-launcher": "^1.0.0",
+ "karma-sauce-launcher": "^1.0.0",
+ "lcov-result-merger": "^1.2.0",
+ "mocha": "^3.0.0",
+ "phantomjs-prebuilt": "^2.1.5",
+ "semantic-release": "^4.3.5",
+ "simple-assert": "^1.0.0",
+ "travis-after-all": "^1.4.4",
+ "validate-commit-msg": "^2.3.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+}
diff --git a/test/.eslintrc b/test/.eslintrc
new file mode 100644
index 0000000..edffc56
--- /dev/null
+++ b/test/.eslintrc
@@ -0,0 +1,19 @@
+{
+ "extends": [ "strict/test" ],
+ "env": {
+ "node": true,
+ "browser": true,
+ "es6": true,
+ "mocha": true
+ },
+ "rules": {
+ "no-new-wrappers": 0,
+ "no-array-constructor": 0,
+ "no-new-object": 0,
+ "no-empty-function": 0,
+ "no-undefined": 0,
+ "complexity": 0,
+ "max-statements": 0,
+ "id-match": 0
+ }
+}
diff --git a/test/dom.js b/test/dom.js
new file mode 100644
index 0000000..f7380ba
--- /dev/null
+++ b/test/dom.js
@@ -0,0 +1,332 @@
+'use strict';
+var assert = require('simple-assert');
+var type = require('..');
+function describeIf(condition) {
+ return condition ? describe : describe.skip;
+}
+function itIf(condition) {
+ return condition ? it : it.skip;
+}
+describeIf(typeof window !== 'undefined' && typeof window.document !== 'undefined')('DOM Specific', function () {
+
+ it('window', function () {
+ assert(type(window) === 'global');
+ });
+
+ it('document', function () {
+ assert(type(document) === 'Document');
+ });
+
+ it('domparser', function () {
+ assert(type(new DOMParser()) === 'DOMParser');
+ });
+
+ it('history', function () {
+ assert(type(window.history) === 'History');
+ });
+
+ it('location', function () {
+ assert(type(window.location) === 'Location');
+ });
+
+ it('attr', function () {
+ var div = document.createElement('div');
+ div.setAttribute('id', 'foo');
+ assert(type(div.getAttributeNode('id')) === 'Attr');
+ });
+
+ describe('Events', function () {
+
+ it('event', function () {
+ assert(type(document.createEvent('Event')) === 'Event');
+ });
+
+ itIf(typeof HashChangeEvent !== 'undefined')('HashChangeEvent', function () {
+ assert(type(new HashChangeEvent('')) === 'HashChangeEvent');
+ });
+
+ });
+
+ describe('Navigator', function () {
+
+ it('navigator', function () {
+ assert(type(window.navigator) === 'Navigator');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'geolocation' in navigator)('geolocation', function () {
+ assert(type(navigator.geolocation) === 'Geolocation');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'connection' in navigator)('networkinformation', function () {
+ assert(type(navigator.connection) === 'NetworkInformation');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'mediaDevices' in navigator)('mediadevices', function () {
+ assert(type(navigator.mediaDevices) === 'MediaDevices');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'mimeTypes' in navigator)('mimetypearray', function () {
+ assert(type(navigator.mimeTypes) === 'MimeTypeArray');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'nfc' in navigator)('nfc', function () {
+ assert(type(navigator.nfc) === 'NFC');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'permissions' in navigator)('permissions', function () {
+ assert(type(navigator.permissions) === 'Permissions');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'plugins' in navigator)('pluginarray', function () {
+ assert(type(navigator.plugins) === 'PluginArray');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'plugins' in navigator && navigator.plugins.length)('plugin', function () {
+ assert(type(navigator.plugins[0]) === 'Plugin');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'presentation' in navigator)('presentation', function () {
+ assert(type(navigator.presentation) === 'Presentation');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'serviceworker' in navigator)('serviceworkercontainer', function () {
+ assert(type(navigator.serviceworker) === 'ServiceWorkerContainer');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'services' in navigator)('serviceportcollection', function () {
+ assert(type(navigator.services) === 'ServicePortCollection');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'storage' in navigator)('storagemanager', function () {
+ assert(type(navigator.storage) === 'StorageManager');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'storageQuota' in navigator)('storagequota', function () {
+ assert(type(navigator.storageQuota) === 'StorageQuota');
+ });
+
+ itIf(typeof navigator !== 'undefined' && 'usb' in navigator)('usb', function () {
+ assert(type(navigator.usb) === 'USB');
+ });
+
+ });
+
+ describe('(HTMLElements)', function () {
+
+ it('HTMLAreaElement', function () {
+ assert(type(document.createElement('Area')) === 'HTMLAreaElement');
+ });
+
+ it('HTMLBRElement', function () {
+ assert(type(document.createElement('BR')) === 'HTMLBRElement');
+ });
+
+ it('HTMLBaseElement', function () {
+ assert(type(document.createElement('Base')) === 'HTMLBaseElement');
+ });
+
+ it('HTMLBodyElement', function () {
+ assert(type(document.createElement('Body')) === 'HTMLBodyElement');
+ });
+
+ it('HTMLButtonElement', function () {
+ assert(type(document.createElement('Button')) === 'HTMLButtonElement');
+ });
+
+ it('HTMLCanvasElement', function () {
+ assert(type(document.createElement('Canvas')) === 'HTMLCanvasElement');
+ });
+
+ it('HTMLDListElement', function () {
+ assert(type(document.createElement('DL')) === 'HTMLDListElement');
+ });
+
+ // not yet supported in Safari
+ itIf(typeof HTMLDataListElement === 'function')('HTMLDataListElement', function () {
+ assert(type(document.createElement('DataList')) === 'HTMLDataListElement');
+ });
+
+ it('HTMLDivElement', function () {
+ assert(type(document.createElement('Div')) === 'HTMLDivElement');
+ });
+
+ it('HTMLFieldSetElement', function () {
+ assert(type(document.createElement('FieldSet')) === 'HTMLFieldSetElement');
+ });
+
+ it('HTMLFormElement', function () {
+ assert(type(document.createElement('Form')) === 'HTMLFormElement');
+ });
+
+ it('HTMLFrameSetElement', function () {
+ assert(type(document.createElement('FrameSet')) === 'HTMLFrameSetElement');
+ });
+
+ it('HTMLHRElement', function () {
+ assert(type(document.createElement('HR')) === 'HTMLHRElement');
+ });
+
+ it('HTMLHeadElement', function () {
+ assert(type(document.createElement('Head')) === 'HTMLHeadElement');
+ });
+
+ it('HTMLHeadingElement', function () {
+ assert(type(document.createElement('H1')) === 'HTMLHeadingElement');
+ assert(type(document.createElement('H2')) === 'HTMLHeadingElement');
+ assert(type(document.createElement('H3')) === 'HTMLHeadingElement');
+ assert(type(document.createElement('H4')) === 'HTMLHeadingElement');
+ assert(type(document.createElement('H5')) === 'HTMLHeadingElement');
+ assert(type(document.createElement('H6')) === 'HTMLHeadingElement');
+ });
+
+ it('HTMLHtmlElement', function () {
+ assert(type(document.createElement('Html')) === 'HTMLHtmlElement');
+ });
+
+ it('HTMLIFrameElement', function () {
+ assert(type(document.createElement('IFrame')) === 'HTMLIFrameElement');
+ });
+
+ it('HTMLImageElement', function () {
+ assert(type(document.createElement('Img')) === 'HTMLImageElement');
+ });
+
+ it('HTMLInputElement', function () {
+ assert(type(document.createElement('Input')) === 'HTMLInputElement');
+ });
+
+ it('HTMLLIElement', function () {
+ assert(type(document.createElement('LI')) === 'HTMLLIElement');
+ });
+
+ it('HTMLLabelElement', function () {
+ assert(type(document.createElement('Label')) === 'HTMLLabelElement');
+ });
+
+ it('HTMLLegendElement', function () {
+ assert(type(document.createElement('Legend')) === 'HTMLLegendElement');
+ });
+
+ it('HTMLLinkElement', function () {
+ assert(type(document.createElement('Link')) === 'HTMLLinkElement');
+ });
+
+ it('HTMLMapElement', function () {
+ assert(type(document.createElement('Map')) === 'HTMLMapElement');
+ });
+
+ it('HTMLMetaElement', function () {
+ assert(type(document.createElement('Meta')) === 'HTMLMetaElement');
+ });
+
+ itIf(typeof HTMLMeterElement !== 'undefined')('HTMLMeterElement', function () {
+ assert(type(document.createElement('Meter')) === 'HTMLMeterElement');
+ });
+
+ it('HTMLModElement', function () {
+ assert(type(document.createElement('Del')) === 'HTMLModElement');
+ });
+
+ it('HTMLOListElement', function () {
+ assert(type(document.createElement('OL')) === 'HTMLOListElement');
+ });
+
+ it('HTMLOptGroupElement', function () {
+ assert(type(document.createElement('OptGroup')) === 'HTMLOptGroupElement');
+ });
+
+ it('HTMLOptionElement', function () {
+ assert(type(document.createElement('Option')) === 'HTMLOptionElement');
+ });
+
+ itIf(typeof HTMLOutputElement !== 'undefined')('HTMLOutputElement', function () {
+ assert(type(document.createElement('Output')) === 'HTMLOutputElement');
+ });
+
+ it('HTMLParagraphElement', function () {
+ assert(type(document.createElement('P')) === 'HTMLParagraphElement');
+ });
+
+ it('HTMLParamElement', function () {
+ assert(type(document.createElement('Param')) === 'HTMLParamElement');
+ });
+
+ it('HTMLPreElement', function () {
+ assert(type(document.createElement('Pre')) === 'HTMLPreElement');
+ });
+
+ itIf(typeof HTMLProgressElement !== 'undefined')('HTMLProgressElement', function () {
+ assert(type(document.createElement('Progress')) === 'HTMLProgressElement');
+ });
+
+ it('HTMLQuoteElement', function () {
+ assert(type(document.createElement('BlockQuote')) === 'HTMLQuoteElement');
+ assert(type(document.createElement('Q')) === 'HTMLQuoteElement');
+ });
+
+ it('HTMLScriptElement', function () {
+ assert(type(document.createElement('Script')) === 'HTMLScriptElement');
+ });
+
+ it('HTMLSelectElement', function () {
+ assert(type(document.createElement('Select')) === 'HTMLSelectElement');
+ });
+
+ it('HTMLSpanElement', function () {
+ assert(type(document.createElement('Span')) === 'HTMLSpanElement');
+ });
+
+ it('HTMLStyleElement', function () {
+ assert(type(document.createElement('Style')) === 'HTMLStyleElement');
+ });
+
+ it('HTMLTableCaptionElement', function () {
+ assert(type(document.createElement('Caption')) === 'HTMLTableCaptionElement');
+ });
+
+ it('HTMLTableDataCellElement', function () {
+ assert(type(document.createElement('TD')) === 'HTMLTableDataCellElement');
+ });
+
+ it('HTMLTableHeaderCellElement', function () {
+ assert(type(document.createElement('TH')) === 'HTMLTableHeaderCellElement');
+ });
+
+ it('HTMLTableColElement', function () {
+ assert(type(document.createElement('Col')) === 'HTMLTableColElement');
+ assert(type(document.createElement('ColGroup')) === 'HTMLTableColElement');
+ });
+
+ it('HTMLTableElement', function () {
+ assert(type(document.createElement('Table')) === 'HTMLTableElement');
+ });
+
+ it('HTMLTableRowElement', function () {
+ assert(type(document.createElement('TR')) === 'HTMLTableRowElement');
+ });
+
+ it('HTMLTableSectionElement', function () {
+ assert(type(document.createElement('THead')) === 'HTMLTableSectionElement');
+ assert(type(document.createElement('TBody')) === 'HTMLTableSectionElement');
+ assert(type(document.createElement('TFoot')) === 'HTMLTableSectionElement');
+ });
+
+ it('HTMLTextAreaElement', function () {
+ assert(type(document.createElement('TextArea')) === 'HTMLTextAreaElement');
+ });
+
+ it('HTMLTitleElement', function () {
+ assert(type(document.createElement('Title')) === 'HTMLTitleElement');
+ });
+
+ it('HTMLUListElement', function () {
+ assert(type(document.createElement('UL')) === 'HTMLUListElement');
+ });
+
+ it('HTMLUnknownElement', function () {
+ assert(type(document.createElement('foobarbaz')) === 'HTMLUnknownElement');
+ });
+
+ });
+
+});
diff --git a/test/index.js b/test/index.js
new file mode 100644
index 0000000..1018a70
--- /dev/null
+++ b/test/index.js
@@ -0,0 +1,272 @@
+'use strict';
+var assert = require('simple-assert');
+var type = require('..');
+describe('Generic', function () {
+
+ it('array', function () {
+ assert(type([]) === 'Array');
+ assert(type(new Array()) === 'Array');
+ });
+
+ it('regexp', function () {
+ assert(type(/a-z/gi) === 'RegExp');
+ assert(type(new RegExp('a-z')) === 'RegExp');
+ });
+
+ it('function', function () {
+ assert(type(function () {}) === 'function');
+ });
+
+ it('arguments', function () {
+ assert(type(arguments) === 'Arguments');
+ });
+
+ it('date', function () {
+ assert(type(new Date()) === 'Date');
+ });
+
+ it('number', function () {
+ assert(type(1) === 'number');
+ assert(type(1.234) === 'number');
+ assert(type(-1) === 'number');
+ assert(type(-1.234) === 'number');
+ assert(type(Infinity) === 'number');
+ assert(type(NaN) === 'number');
+ });
+
+ it('number objects', function () {
+ assert(type(new Number(2)) === 'Number');
+ });
+
+ it('string', function () {
+ assert(type('hello world') === 'string');
+ });
+
+ it('string objects', function () {
+ assert(type(new String('hello')) === 'String');
+ });
+
+ it('null', function () {
+ assert(type(null) === 'null');
+ assert(type(undefined) !== 'null');
+ });
+
+ it('undefined', function () {
+ assert(type(undefined) === 'undefined');
+ assert(type(null) !== 'undefined');
+ });
+
+ it('object', function () {
+ function Noop() {}
+ assert(type({}) === 'Object');
+ assert(type(Noop) !== 'Object');
+ assert(type(new Noop()) === 'Object');
+ assert(type(new Object()) === 'Object');
+ assert(type(Object.create(null)) === 'Object');
+ assert(type(Object.create(Object.prototype)) === 'Object');
+ });
+
+ // See: https://github.com/chaijs/type-detect/pull/25
+ it('object with .undefined property getter', function () {
+ var foo = {};
+ Object.defineProperty(foo, 'undefined', {
+ get: function () {
+ throw Error('Should never happen');
+ },
+ });
+ assert(type(foo) === 'Object');
+ });
+
+ it('boolean', function () {
+ assert(type(true) === 'boolean');
+ assert(type(false) === 'boolean');
+ assert(type(!0) === 'boolean');
+ });
+
+ it('boolean object', function () {
+ assert(type(new Boolean()) === 'Boolean');
+ });
+
+ it('error', function () {
+ assert(type(new Error()) === 'Error');
+ assert(type(new TypeError()) === 'Error');
+ assert(type(new EvalError()) === 'Error');
+ assert(type(new RangeError()) === 'Error');
+ assert(type(new ReferenceError()) === 'Error');
+ assert(type(new SyntaxError()) === 'Error');
+ assert(type(new TypeError()) === 'Error');
+ assert(type(new URIError()) === 'Error');
+ });
+
+ it('Math', function () {
+ assert(type(Math) === 'Math');
+ });
+
+ it('JSON', function () {
+ assert(type(JSON) === 'JSON');
+ });
+
+ describe('Stubbed ES2015 Types', function () {
+ var originalObjectToString = Object.prototype.toString;
+ function stubObjectToStringOnce(staticValue) {
+ Object.prototype.toString = function () { // eslint-disable-line no-extend-native
+ Object.prototype.toString = originalObjectToString; // eslint-disable-line no-extend-native
+ return staticValue;
+ };
+ }
+ function Thing() {}
+
+ it('map', function () {
+ stubObjectToStringOnce('[object Map]');
+ assert(type(new Thing()) === 'Map');
+ });
+
+ it('weakmap', function () {
+ stubObjectToStringOnce('[object WeakMap]');
+ assert(type(new Thing()) === 'WeakMap');
+ });
+
+ it('set', function () {
+ stubObjectToStringOnce('[object Set]');
+ assert(type(new Thing()) === 'Set');
+ });
+
+ it('weakset', function () {
+ stubObjectToStringOnce('[object WeakSet]');
+ assert(type(new Thing()) === 'WeakSet');
+ });
+
+ it('symbol', function () {
+ stubObjectToStringOnce('[object Symbol]');
+ assert(type(new Thing()) === 'Symbol');
+ });
+
+ it('promise', function () {
+ stubObjectToStringOnce('[object Promise]');
+ assert(type(new Thing()) === 'Promise');
+ });
+
+ it('int8array', function () {
+ stubObjectToStringOnce('[object Int8Array]');
+ assert(type(new Thing()) === 'Int8Array');
+ });
+
+ it('uint8array', function () {
+ stubObjectToStringOnce('[object Uint8Array]');
+ assert(type(new Thing()) === 'Uint8Array');
+ });
+
+ it('uint8clampedarray', function () {
+ stubObjectToStringOnce('[object Uint8ClampedArray]');
+ assert(type(new Thing()) === 'Uint8ClampedArray');
+ });
+
+ it('int16array', function () {
+ stubObjectToStringOnce('[object Int16Array]');
+ assert(type(new Thing()) === 'Int16Array');
+ });
+
+ it('uint16array', function () {
+ stubObjectToStringOnce('[object Uint16Array]');
+ assert(type(new Thing()) === 'Uint16Array');
+ });
+
+ it('int32array', function () {
+ stubObjectToStringOnce('[object Int32Array]');
+ assert(type(new Thing()) === 'Int32Array');
+ });
+
+ it('uint32array', function () {
+ stubObjectToStringOnce('[object Uint32Array]');
+ assert(type(new Thing()) === 'Uint32Array');
+ });
+
+ it('float32array', function () {
+ stubObjectToStringOnce('[object Float32Array]');
+ assert(type(new Thing()) === 'Float32Array');
+ });
+
+ it('float64array', function () {
+ stubObjectToStringOnce('[object Float64Array]');
+ assert(type(new Thing()) === 'Float64Array');
+ });
+
+ it('dataview', function () {
+ stubObjectToStringOnce('[object DataView]');
+ assert(type(new Thing()) === 'DataView');
+ });
+
+ it('arraybuffer', function () {
+ stubObjectToStringOnce('[object ArrayBuffer]');
+ assert(type(new Thing()) === 'ArrayBuffer');
+ });
+
+ it('generatorfunction', function () {
+ stubObjectToStringOnce('[object GeneratorFunction]');
+ assert(type(new Thing()) === 'GeneratorFunction');
+ });
+
+ it('generator', function () {
+ stubObjectToStringOnce('[object Generator]');
+ assert(type(new Thing()) === 'Generator');
+ });
+
+ it('string iterator', function () {
+ stubObjectToStringOnce('[object String Iterator]');
+ assert(type(new Thing()) === 'String Iterator');
+ });
+
+ it('array iterator', function () {
+ stubObjectToStringOnce('[object Array Iterator]');
+ assert(type(new Thing()) === 'Array Iterator');
+ });
+
+ it('map iterator', function () {
+ stubObjectToStringOnce('[object Map Iterator]');
+ assert(type(new Thing()) === 'Map Iterator');
+ });
+
+ it('set iterator', function () {
+ stubObjectToStringOnce('[object Set Iterator]');
+ assert(type(new Thing()) === 'Set Iterator');
+ });
+
+ });
+
+ describe('@@toStringTag Sham', function () {
+ var originalObjectToString = Object.prototype.toString;
+ before(function () {
+ global.Symbol = global.Symbol || {};
+ if (!global.Symbol.toStringTag) {
+ global.Symbol.toStringTag = '__@@toStringTag__';
+ }
+ var test = {};
+ test[Symbol.toStringTag] = function () {
+ return 'foo';
+ };
+ if (Object.prototype.toString(test) !== '[object foo]') {
+ Object.prototype.toString = function () { // eslint-disable-line no-extend-native
+ if (typeof this === 'object' && typeof this[Symbol.toStringTag] === 'function') {
+ return '[object ' + this[Symbol.toStringTag]() + ']';
+ }
+ return originalObjectToString.call(this);
+ };
+ }
+ });
+
+ after(function () {
+ Object.prototype.toString = originalObjectToString; // eslint-disable-line no-extend-native
+ });
+
+
+ it('plain object', function () {
+ var obj = {};
+ obj[Symbol.toStringTag] = function () {
+ return 'Foo';
+ };
+ assert(type(obj) === 'Foo', 'type(obj) === "Foo"');
+ });
+
+ });
+
+});
diff --git a/test/new-ecmascript-types.js b/test/new-ecmascript-types.js
new file mode 100644
index 0000000..d0028af
--- /dev/null
+++ b/test/new-ecmascript-types.js
@@ -0,0 +1,136 @@
+'use strict';
+var assert = require('simple-assert');
+var type = require('..');
+var symbolExists = typeof Symbol === 'function';
+var setExists = typeof Set === 'function';
+var mapExists = typeof Map === 'function';
+var supportArrows = false;
+var supportGenerators = false;
+try {
+ eval('function * foo () {}; foo'); // eslint-disable-line no-eval
+ supportGenerators = true;
+} catch (error) {
+ supportGenerators = false;
+}
+try {
+ eval('() => {}'); // eslint-disable-line no-eval
+ supportArrows = true;
+} catch (error) {
+ supportArrows = false;
+}
+function itIf(condition) {
+ return condition ? it : it.skip;
+}
+
+describe('ES2015 Specific', function () {
+ itIf(symbolExists && typeof String.prototype[Symbol.iterator] === 'function')('string iterator', function () {
+ assert(type(''[Symbol.iterator]()) === 'String Iterator');
+ });
+
+ itIf(symbolExists && typeof Array.prototype[Symbol.iterator] === 'function')('array iterator', function () {
+ assert(type([][Symbol.iterator]()) === 'Array Iterator');
+ });
+
+ itIf(typeof Array.prototype.entries === 'function')('array iterator (entries)', function () {
+ assert(type([].entries()) === 'Array Iterator');
+ });
+
+ itIf(mapExists)('map', function () {
+ assert(type(new Map()) === 'Map');
+ });
+
+ itIf(symbolExists && mapExists && typeof Map.prototype[Symbol.iterator] === 'function')('map iterator', function () {
+ assert(type(new Map()[Symbol.iterator]()) === 'Map Iterator');
+ });
+
+ itIf(mapExists && typeof Map.prototype.entries === 'function')('map iterator (entries)', function () {
+ assert(type(new Map().entries()) === 'Map Iterator');
+ });
+
+ itIf(typeof WeakMap === 'function')('weakmap', function () {
+ assert(type(new WeakMap()) === 'WeakMap');
+ });
+
+ itIf(setExists)('set', function () {
+ assert(type(new Set()) === 'Set');
+ });
+
+ itIf(symbolExists && setExists && typeof Set.prototype[Symbol.iterator] === 'function')('set iterator', function () {
+ assert(type(new Set()[Symbol.iterator]()) === 'Set Iterator');
+ });
+
+ itIf(setExists && typeof Set.prototype.entries === 'function')('set iterator', function () {
+ assert(type(new Set().entries()) === 'Set Iterator');
+ });
+
+ itIf(typeof WeakSet === 'function')('weakset', function () {
+ assert(type(new WeakSet()) === 'WeakSet');
+ });
+
+ itIf(typeof Symbol === 'function')('symbol', function () {
+ assert(type(Symbol()) === 'symbol');
+ });
+
+ itIf(typeof Promise === 'function')('promise', function () {
+ function noop() {}
+ assert(type(new Promise(noop)) === 'Promise');
+ });
+
+ itIf(typeof Int8Array === 'function')('int8array', function () {
+ assert(type(new Int8Array()) === 'Int8Array');
+ });
+
+ itIf(typeof Uint8Array === 'function')('uint8array', function () {
+ assert(type(new Uint8Array()) === 'Uint8Array');
+ });
+
+ itIf(typeof Uint8ClampedArray === 'function')('uint8clampedarray', function () {
+ assert(type(new Uint8ClampedArray()) === 'Uint8ClampedArray');
+ });
+
+ itIf(typeof Int16Array === 'function')('int16array', function () {
+ assert(type(new Int16Array()) === 'Int16Array');
+ });
+
+ itIf(typeof Uint16Array === 'function')('uint16array', function () {
+ assert(type(new Uint16Array()) === 'Uint16Array');
+ });
+
+ itIf(typeof Int32Array === 'function')('int32array', function () {
+ assert(type(new Int32Array()) === 'Int32Array');
+ });
+
+ itIf(typeof Uint32Array === 'function')('uint32array', function () {
+ assert(type(new Uint32Array()) === 'Uint32Array');
+ });
+
+ itIf(typeof Float32Array === 'function')('float32array', function () {
+ assert(type(new Float32Array()) === 'Float32Array');
+ });
+
+ itIf(typeof Float64Array === 'function')('float64array', function () {
+ assert(type(new Float64Array()) === 'Float64Array');
+ });
+
+ itIf(typeof DataView === 'function')('dataview', function () {
+ var arrayBuffer = new ArrayBuffer(1);
+ assert(type(new DataView(arrayBuffer)) === 'DataView');
+ });
+
+ itIf(typeof ArrayBuffer === 'function')('arraybuffer', function () {
+ assert(type(new ArrayBuffer(1)) === 'ArrayBuffer');
+ });
+
+ itIf(supportArrows)('arrow function', function () {
+ assert(type(eval('() => {}')) === 'function'); // eslint-disable-line no-eval
+ });
+
+ itIf(supportGenerators)('generator function', function () {
+ assert(type(eval('function * foo () {}; foo')) === 'function'); // eslint-disable-line no-eval
+ });
+
+ itIf(supportGenerators)('generator', function () {
+ assert(type(eval('(function * foo () {}())')) === 'Generator'); // eslint-disable-line no-eval
+ });
+
+});
diff --git a/test/node.js b/test/node.js
new file mode 100644
index 0000000..eba98f2
--- /dev/null
+++ b/test/node.js
@@ -0,0 +1,18 @@
+'use strict';
+var assert = require('simple-assert');
+var type = require('..');
+var isNode = typeof process !== 'undefined' && typeof process.release === 'object' && process.release.name;
+function describeIf(condition) {
+ return condition ? describe : describe.skip;
+}
+describeIf(isNode)('Node Specific', function () {
+
+ it('global', function () {
+ assert(type(global) === 'global');
+ });
+
+ it('process', function () {
+ assert(type(process) === 'process');
+ });
+
+});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-type-detect.git
More information about the Pkg-javascript-commits
mailing list