diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8e74bf3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cc6c4b6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,62 @@ + +# Directories # +############### +reports/ +build/ + +# Compiled source # +################### +*.com +*.class +*.dll +*.exe +*.o +*.so + +# Packages # +############ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Logs and databases # +###################### +*.log +*.sql +*.sqlite + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +Icon? +ehthumbs.db +Thumbs.db +Desktop.ini + +# Temporary files # +################### +*~ + +# Node.js # +########### +/node_modules/ + +# Matlab # +########## + +# Windows default autosave extension +*.asv + +# Compiled MEX binaries (all platforms) +*.mex* diff --git a/.jshintignore b/.jshintignore new file mode 100644 index 0000000..3163c22 --- /dev/null +++ b/.jshintignore @@ -0,0 +1,14 @@ + +# Directories # +############### +build/ +reports/ +dist/ + +# Node.js # +########### +/node_modules/ + +# Git # +####### +.git* diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..d09f1fa --- /dev/null +++ b/.jshintrc @@ -0,0 +1,71 @@ +{ + "bitwise": false, + "camelcase": false, + "curly": true, + "eqeqeq": true, + "es3": false, + "forin": true, + "freeze": true, + "immed": true, + "indent": 4, + "latedef": "nofunc", + "newcap": true, + "noarg": true, + "noempty": false, + "nonbsp": true, + "nonew": true, + "plusplus": false, + "quotmark": "single", + "undef": true, + "unused": true, + "strict": true, + "maxparams": 10, + "maxdepth": 5, + "maxstatements": 100, + "maxcomplexity": false, + "maxlen": 1000, + "asi": false, + "boss": false, + "debug": false, + "eqnull": false, + "esnext": false, + "evil": false, + "expr": false, + "funcscope": false, + "globalstrict": false, + "iterator": false, + "lastsemic": false, + "laxbreak": false, + "laxcomma": false, + "loopfunc": false, + "maxerr": 1000, + "moz": false, + "multistr": false, + "notypeof": false, + "proto": false, + "scripturl": false, + "shadow": false, + "sub": true, + "supernew": false, + "validthis": false, + "noyield": false, + "browser": true, + "browserify": true, + "couch": false, + "devel": true, + "dojo": false, + "jasmine": false, + "jquery": false, + "mocha": true, + "mootools": false, + "node": true, + "nonstandard": false, + "prototypejs": false, + "qunit": false, + "rhino": false, + "shelljs": false, + "worker": false, + "wsh": false, + "yui": false, + "globals": {} +} \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..9db298d --- /dev/null +++ b/.npmignore @@ -0,0 +1,52 @@ + +# Files # +######### +Makefile +README.md +TODO.md + +# Directories # +############### +build/ +docs/ +examples/ +reports/ +support/ +test/ +benchmark/ + +# Node.js # +########### +.npmignore +/node_modules/ + +# Logs # +######## +*.log + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +Icon? +ehthumbs.db +Thumbs.db +Desktop.ini + +# Temporary files # +################### +*~ + +# Git # +####### +.git* + +# Utilities # +############# +.jshintrc +.jshintignore +.travis.yml +.editorconfig diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..29cff27 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +language: node_js +node_js: + - '0.12' + - '0.11' + - '0.10' + - '0.8' + - 'iojs' +before_install: + - npm update -g npm +after_script: + - npm run coveralls + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..097b153 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Athan Reines. + +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. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c6f009c --- /dev/null +++ b/Makefile @@ -0,0 +1,144 @@ + +############# +# VARIABLES # + +# Set the node.js environment to test: +NODE_ENV ?= test + +# Kernel name: +KERNEL ?= $(shell uname -s) + +ifeq ($(KERNEL), Darwin) + OPEN ?= open +else + OPEN ?= xdg-open +endif + +# NOTES # + +NOTES ?= 'TODO|FIXME|WARNING|HACK|NOTE' + + +# MOCHA # + +MOCHA ?= ./node_modules/.bin/mocha +_MOCHA ?= ./node_modules/.bin/_mocha +MOCHA_REPORTER ?= spec + + +# ISTANBUL # + +ISTANBUL ?= ./node_modules/.bin/istanbul +ISTANBUL_OUT ?= ./reports/coverage +ISTANBUL_REPORT ?= lcov +ISTANBUL_LCOV_INFO_PATH ?= $(ISTANBUL_OUT)/lcov.info +ISTANBUL_HTML_REPORT_PATH ?= $(ISTANBUL_OUT)/lcov-report/index.html + + +# JSHINT # + +JSHINT ?= ./node_modules/.bin/jshint +JSHINT_REPORTER ?= ./node_modules/jshint-stylish + + + +# FILES # + +# Source files: +SOURCES ?= lib/*.js + +# Test files: +TESTS ?= test/*.js + + + + +########### +# TARGETS # + + +# NOTES # + +.PHONY: notes + +notes: + grep -Ern $(NOTES) $(SOURCES) $(TESTS) + + + +# UNIT TESTS # + +.PHONY: test test-mocha + +test: test-mocha + +test-mocha: node_modules + NODE_ENV=$(NODE_ENV) \ + NODE_PATH=$(NODE_PATH_TEST) \ + $(MOCHA) \ + --reporter $(MOCHA_REPORTER) \ + $(TESTS) + + + +# CODE COVERAGE # + +.PHONY: test-cov test-istanbul-mocha + +test-cov: test-istanbul-mocha + +test-istanbul-mocha: node_modules + NODE_ENV=$(NODE_ENV) \ + NODE_PATH=$(NODE_PATH_TEST) \ + $(ISTANBUL) cover \ + --dir $(ISTANBUL_OUT) \ + --report $(ISTANBUL_REPORT) \ + $(_MOCHA) -- \ + --reporter $(MOCHA_REPORTER) \ + $(TESTS) + + + +# COVERAGE REPORT # + +.PHONY: view-cov view-istanbul-report + +view-cov: view-istanbul-report + +view-istanbul-report: + $(OPEN) $(ISTANBUL_HTML_REPORT_PATH) + + +# LINT # + +.PHONY: lint lint-jshint + +lint: lint-jshint + +lint-jshint: node_modules + $(JSHINT) \ + --reporter $(JSHINT_REPORTER) \ + ./ + + +# NODE # + +# Installing node_modules: +.PHONY: install + +install: + npm install + +# Clean node: +.PHONY: clean-node + +clean-node: + rm -rf node_modules + + + +# CLEAN # +.PHONY: clean + +clean: + rm -rf build diff --git a/README.md b/README.md new file mode 100644 index 0000000..3aa259d --- /dev/null +++ b/README.md @@ -0,0 +1,132 @@ +typed-array-like +=== +[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Dependencies][dependencies-image]][dependencies-url] + +> Validates if a value is [typed-array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays)-like. + + +## Installation + +``` bash +$ npm install validate.io-typed-array-like +``` + +For use in the browser, use [browserify](https://github.com/substack/node-browserify). + + +## Usage + +``` javascript +var isTypedArrayLike = require( 'validate.io-typed-array-like' ); +``` + +#### isTypedArrayLike( value ) + +Validates if a value is [`typed-array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays)-like. + +``` javascript +var bool; + +bool = isTypedArrayLike( new Int16Array() ); +// returns true + +bool = isTypedArrayLike({ + 'length': 10, + 'byteOffset': 0, + 'byteLength': 10, + 'BYTES_PER_ELEMENT': 4 +}); +// returns true +``` + + +## Examples + +``` javascript +var isTypedArrayLike = require( 'validate.io-typed-array-like' ); + +var arr = { + 'BYTES_PER_ELEMENT': 8, + 'length': 10, + 'byteOffset': 0, + 'byteLength': 10 +}; +console.log( isTypedArrayLike( arr ) ); +// returns true + +console.log( isTypedArrayLike( new Int8Array( 4 ) ) ); +// returns true + +console.log( isTypedArrayLike( [] ) ); +// returns false + +console.log( isTypedArrayLike( {} ) ); +// returns false + +console.log( isTypedArrayLike( null ) ); +// returns false +``` + +To run the example code from the top-level application directory, + +``` bash +$ node ./examples/index.js +``` + + +## Tests + +### Unit + +Unit tests use the [Mocha](http://mochajs.org) test framework with [Chai](http://chaijs.com) assertions. To run the tests, execute the following command in the top-level application directory: + +``` bash +$ make test +``` + +All new feature development should have corresponding unit tests to validate correct functionality. + + +### Test Coverage + +This repository uses [Istanbul](https://github.com/gotwarlost/istanbul) as its code coverage tool. To generate a test coverage report, execute the following command in the top-level application directory: + +``` bash +$ make test-cov +``` + +Istanbul creates a `./reports/coverage` directory. To access an HTML version of the report, + +``` bash +$ make view-cov +``` + + +--- +## License + +[MIT license](http://opensource.org/licenses/MIT). + + +## Copyright + +Copyright © 2015. Athan Reines. + + +[npm-image]: http://img.shields.io/npm/v/validate.io-typed-array-like.svg +[npm-url]: https://npmjs.org/package/validate.io-typed-array-like + +[travis-image]: http://img.shields.io/travis/validate-io/typed-array-like/master.svg +[travis-url]: https://travis-ci.org/validate-io/typed-array-like + +[coveralls-image]: https://img.shields.io/coveralls/validate-io/typed-array-like/master.svg +[coveralls-url]: https://coveralls.io/r/validate-io/typed-array-like?branch=master + +[dependencies-image]: http://img.shields.io/david/validate-io/typed-array-like.svg +[dependencies-url]: https://david-dm.org/validate-io/typed-array-like + +[dev-dependencies-image]: http://img.shields.io/david/dev/validate-io/typed-array-like.svg +[dev-dependencies-url]: https://david-dm.org/dev/validate-io/typed-array-like + +[github-issues-image]: http://img.shields.io/github/issues/validate-io/typed-array-like.svg +[github-issues-url]: https://github.com/validate-io/typed-array-like/issues diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..27aeb4e --- /dev/null +++ b/TODO.md @@ -0,0 +1,4 @@ +TODO +==== + + diff --git a/benchmark/b.js b/benchmark/b.js new file mode 100644 index 0000000..900fc7c --- /dev/null +++ b/benchmark/b.js @@ -0,0 +1,70 @@ +'use strict'; + +// MODULES // + +var typedArrayLike = require( './../lib' ); + + +// VARIABLES // + +var start, + stop, + arr, + len, + res, + b, + i; + +arr = {}; +arr.BYTES_PER_ELEMENT = 4; +arr.length = 10; +arr.byteOffset = 0; +arr.byteLength = 10; + + +// FUNCTIONS // + +var toStr = Object.prototype.toString; + + +// -------------------------------------- +// WARM-UP + +len = 1e6; +for ( i = 0; i < len; i++ ) { + i = i; +} + + +// -------------------------------------- +// BENCHMARK + +len = 1e6; +res = new Array( 1 ); + +// Control: +start = process.hrtime(); +for ( i = 0; i < len; i++ ) { + b = ( toStr.call( arr ) === '[object Object]' ); +} +stop = process.hrtime( start ); + +res[ 0 ] = stop[ 0 ] + stop[ 1 ]*1e-9; + +// Test: +start = process.hrtime(); +for ( i = 0; i < len; i++ ) { + b = typedArrayLike( arr ); +} +stop = process.hrtime( start ); + +res[ 1 ] = stop[ 0 ] + stop[ 1 ]*1e-9; + + +// -------------------------------------- +// RESULTS + +console.log( 'ctrl:\t%d ops/sec', Math.floor( len/res[ 0 ] ) ); +console.log( 'test:\t%d ops/sec', Math.floor( len/res[ 1 ] ) ); +console.log( '\n' ); + diff --git a/examples/index.js b/examples/index.js new file mode 100644 index 0000000..d379400 --- /dev/null +++ b/examples/index.js @@ -0,0 +1,24 @@ +'use strict'; + +var isTypedArrayLike = require( './../lib' ); + +var arr = { + 'BYTES_PER_ELEMENT': 8, + 'length': 10, + 'byteOffset': 0, + 'byteLength': 10 +}; +console.log( isTypedArrayLike( arr ) ); +// returns true + +console.log( isTypedArrayLike( new Int8Array( 4 ) ) ); +// returns true + +console.log( isTypedArrayLike( [] ) ); +// returns false + +console.log( isTypedArrayLike( {} ) ); +// returns false + +console.log( isTypedArrayLike( null ) ); +// returns false diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..94506d4 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,36 @@ +'use strict'; + +// MODULES // + +var isInteger = require( 'validate.io-integer-primitive' ); + + +// CONSTANTS // + +var MAX = require( 'compute-const-max-safe-integer' ); + + +// IS TYPED-ARRAY-LIKE // + +/** +* FUNCTION: isTypedArrayLike( value ) +* Validates if a value is typed-array-like. +* +* @param {*} value - value to validate +* @param {Boolean} boolean indicating if a value is typed-array-like +*/ +function isTypedArrayLike( value ) { + return value !== null && + typeof value === 'object' && + isInteger( value.length ) && + value.length >= 0 && + value.length <= MAX && + typeof value.BYTES_PER_ELEMENT === 'number' && + typeof value.byteOffset === 'number' && + typeof value.byteLength === 'number'; +} // end FUNCTION isTypedArrayLike() + + +// EXPORTS // + +module.exports = isTypedArrayLike; diff --git a/package.json b/package.json new file mode 100644 index 0000000..a0e07f0 --- /dev/null +++ b/package.json @@ -0,0 +1,53 @@ +{ + "name": "validate.io-typed-array-like", + "version": "0.0.0", + "description": "Validates if a value is typed-array-like.", + "author": { + "name": "Athan Reines", + "email": "kgryte@gmail.com" + }, + "contributors": [ + { + "name": "Athan Reines", + "email": "kgryte@gmail.com" + } + ], + "scripts": { + "test": "./node_modules/.bin/mocha", + "test-cov": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --dir ./reports/coverage -- -R spec", + "coveralls": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --dir ./reports/coveralls/coverage --report lcovonly -- -R spec && cat ./reports/coveralls/coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./reports/coveralls" + }, + "main": "./lib", + "repository": { + "type": "git", + "url": "git://github.com/validate-io/typed-array-like.git" + }, + "keywords": [ + "validate.io", + "validate", + "validation", + "validator", + "valid", + "typed-array", + "typed-array like", + "is", + "istypedarraylike", + "length" + ], + "bugs": { + "url": "https://github.com/validate-io/typed-array-like/issues" + }, + "dependencies": { + "compute-const-max-safe-integer": "^1.0.0", + "validate.io-integer-primitive": "^1.0.0" + }, + "devDependencies": { + "chai": "3.x.x", + "mocha": "2.x.x", + "coveralls": "^2.11.1", + "istanbul": "^0.3.0", + "jshint": "2.x.x", + "jshint-stylish": "2.x.x" + }, + "license": "MIT" +} diff --git a/test/test.js b/test/test.js new file mode 100644 index 0000000..fe6bbca --- /dev/null +++ b/test/test.js @@ -0,0 +1,114 @@ +/* global require, describe, it */ +'use strict'; + +// MODULES // + +var // Expectation library: + chai = require( 'chai' ), + + // Module to be tested: + isTypedArrayLike = require( './../lib' ); + + +// VARIABLES // + +var expect = chai.expect, + assert = chai.assert; + + +// TESTS // + +describe( 'validate.io-typed-array-like', function tests() { + + it( 'should export a function', function test() { + expect( isTypedArrayLike ).to.be.a( 'function' ); + }); + + it( 'should positively validate', function test() { + var values = [ + new Int8Array(), + new Uint8Array(), + new Int16Array(), + new Uint16Array(), + new Int32Array(), + new Uint32Array(), + new Float32Array(), + new Float64Array(), + new Uint8ClampedArray(), + { + 'length': 10, + 'BYTES_PER_ELEMENT': 4, + 'byteOffset': 0, + 'byteLength': 10 + } + ]; + + for ( var i = 0; i < values.length; i++ ) { + assert.ok( isTypedArrayLike( values[i] ), values[i] ); + } + }); + + it( 'should negatively validate', function test() { + var values = [ + 'beep', + 5, + null, + undefined, + NaN, + true, + false, + {}, + [], + function boop( a, b, c ) {}, + { + 'length': Math.PI, + 'BYTES_PER_ELEMENT': 4, + 'byteOffset': 0, + 'byteLength': 10 + }, + { + 'length': 10, + 'BYTES_PER_ELEMENT': true, + 'byteOffset': 0, + 'byteLength': 10 + }, + { + 'length': 10, + 'BYTES_PER_ELEMENT': 4, + 'byteOffset': [], + 'byteLength': 10 + }, + { + 'length': 10, + 'BYTES_PER_ELEMENT': 4, + 'byteOffset': 0, + 'byteLength': null + }, + { + 'BYTES_PER_ELEMENT': 4, + 'byteOffset': 0, + 'byteLength': 10 + }, + { + 'length': 10, + 'byteOffset': 0, + 'byteLength': 10 + }, + { + 'length': 10, + 'BYTES_PER_ELEMENT': 4, + 'byteLength': 10 + }, + { + 'length': 10, + 'BYTES_PER_ELEMENT': 4, + 'byteOffset': 0 + } + ]; + + for ( var i = 0; i < values.length; i++ ) { + assert.notOk( isTypedArrayLike( values[i] ), values[i] ); + } + }); + +});