run a callback function against specific JS types
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
test
.gitignore
.travis.yml
index.js
license
package.json
readme.md
type-iterator.png

readme.md

type-iterator

Build Status Coverage Status

About | Installation | API | Examples | Gotchas | License

About

A Node.js module that runs a callback function against multiple basic JS types. Envisioned as a testing utility to ensure that functions and methods respond appropriately to specific types. Requires Node.js 4.0 or newer.

Supports the following types/entities:

  • undefined
  • null
  • String
  • Boolean
  • Number
  • Function
  • Array
  • Object

Note that the new ES6 types are not included (Symbol, Map, Set, WeakMap, WeakSet...). I'm not opposed to adding them; I just didn't need them for my intended use of this module (yet).

Installation

Install and require in typical Node.js fashion.

Using in module: $ npm install --save type-iterator

Using in tests: $ npm install --save-dev type-iterator

API

The following object is the heart of this module:

const types = {
  'undefined': undefined,
  'null': null,
  'string': 'abc',
  'boolean': true,
  'number': 1,
  'function': new Function(),
  'array': [],
  'object': {}
}

Each value is a type literal for the type named in its key. type-iterator provides three ways to iterate over these types.

typeIterator(cb)

Iterates over all types. If cb is provided, iterate and return array of cb results. Else return unmodified types object.

typeIterator.exclude(types, cb)

Iterates over all types except specified exclusion(s). types can be a string or array of strings. If cb is provided, iterate over types except exclusions and return results. Else return modified types object.

typeIterator.include(types, cb)

Iterates over only specified type(s). types can be a string or array of strings. If cb is provided, iterate over specified types and return results. Else return modified types object.

Examples

Contrived

//----------------------------------------------------------
// setup
//----------------------------------------------------------
const typeIterator = require('type-iterator')

function exampleCb(val, key) {
  console.log(key, ':', val)
}

//----------------------------------------------------------
// allTypes
//----------------------------------------------------------
typeIterator() // returns types object with all types

typeIterator(exampleCb) // console logs each key: val pair

//----------------------------------------------------------
// exclude
//----------------------------------------------------------
// get types object sans 'undefined' type
// note: could also use an array of strings as param (for multiple types)
typeIterator.exclude('undefined')

// log all key: val type pairs except undefined
typeIterator.exclude('undefined', exampleCb)

//----------------------------------------------------------
// include
//----------------------------------------------------------
const typesToInclude = ['object', 'array']

// get types object with only object and array key: val pairs
// note: could also use a single string as param (for 1 type)
typeIterator.include(typesToInclude)

// log object and array key: val pairs
typeIterator.include(typesToInclude, exampleCb)

Semi-Realistic

// index.js
const kindOf = require('kind-of')

module.exports = function(text) {
  // explicitly throw if text isn't a string
  if (kindOf(text) !== 'string') {
    throw new Error('expected text param to be a String')
  }

  // do cool jazz here
}
// test.js
const assert       = require('chai').assert
const main         = require('./')
const typeIterator = require('type-iterator')

describe('main', () => {
  it('throws when text is not a string', () => {
    typeIterator.exclude('string', (val) => {
      assert.throws(() => main(val))
    })
  })
})

Gotchas

Keep in mind that the undefined and null type literals evaluate to false in simple conditional expressions. Consider the following contrived example with an optional parameter and a type restriction using kind-of:

function awesomeFunc(opt) {
  if (opt && kindOf(opt) === 'array' || kindOf(opt) === 'object') {
    console.log('hooray! opt provided')
  } else if (opt) {
    throw new Error('you dun goofed! wrong opt type')
  }
}

So, we can use type-iterator to write a quick test that makes sure awesomeFunc throws for all types other than array and object.

// WARNING THIS FAILS
// mocha-style test
describe('awesomeFunc', () => {
  it('throws for all types other than object and array', () => {
    typeIterator.exclude(['object', 'array'], (val) => {
      assert.throws(() => awesomeFunc(val))
    })
  })
})

This test fails. Why? Because awesomeFunc checks for the optional param with if (opt). if(null) and and if(undefined) are both false, so the throw never gets called for those values. The fix is either to make awesomeFunc's optional param checking more robust or also exclude 'null' and 'undefined' in the test case.

License

MIT