Skip to content
This repository has been archived by the owner on Apr 2, 2018. It is now read-only.

Commit

Permalink
Fix up tests. Add test for normalizeOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabe Scholz committed May 14, 2016
1 parent f1e9c80 commit 7ad3aac
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 80 deletions.
45 changes: 13 additions & 32 deletions src/normalizeOptions.js
@@ -1,38 +1,19 @@
import _isArray from 'lodash/isArray'
import _isString from 'lodash/isString'
import _isRegExp from 'lodash/isRegExp'

export const normalizeOptions = (opts = {}) => {
let {include, exclude} = opts
export const DEFAULT_INCLUDE = /./
export const DEFAULT_EXCLUDE = /[^a-zA-Z0-9]/

if (!_isArray(include)) {
include = [include]
}
const toRegExp = s => _isString(s) ? new RegExp(`^${s}$`) : s
const toArray = o => o ? [].concat(o) : []

if (!_isArray(exclude)) {
exclude = [exclude]
export const normalizeOptions = (opts = {}) => {
let {
include = [DEFAULT_INCLUDE],
exclude = [DEFAULT_EXCLUDE]
} = opts

return {
include: toArray(include).map(toRegExp),
exclude: toArray(exclude).map(toRegExp)
}

include = include.map(i => {
if (_isString(i)) {
return new RegExp(`^${i}$`)
} else if (!_isRegExp(i)) {
return /./
}

return i
})

exclude = exclude.map(e => {
if (_isString(e)) {
return new RegExp(`^${e}$`)
} else if (!_isRegExp(e)) {
return /[^a-zA-Z0-9]/
}

return e
})


return {...opts, include, exclude}
}
97 changes: 49 additions & 48 deletions tests/index-test.js
@@ -1,4 +1,4 @@
import assert from 'assert'
import {deepEqual, equal, ok} from 'assert'
import React from 'react'
import {render, unmountComponentAtNode} from 'react-dom'

Expand All @@ -12,7 +12,8 @@ const createConsoleStore = type => {

global.console[type] = (...args) => {
entries.push(args)
fn.call(global.console, ...args)
// uncomment to debug tests
// fn.call(global.console, ...args)
}

return {
Expand Down Expand Up @@ -58,10 +59,10 @@ describe(`whyDidYouUpdate`, () => {
const prevProps = logStore.entries[0][2]
const nextProps = logStore.entries[1][2]

assert.equal(group, `Stub.props`)
assert.ok(/Value did not change. Avoidable re-render!/.test(warnMsg))
assert.deepEqual(prevProps, {a: 1})
assert.deepEqual(nextProps, {a: 1})
equal(group, `Stub.props`)
ok(/Value did not change. Avoidable re-render!/.test(warnMsg))
deepEqual(prevProps, {a: 1})
deepEqual(nextProps, {a: 1})
})

it(`logs an warning on nested props but excludes the parent`, () => {
Expand All @@ -72,20 +73,20 @@ describe(`whyDidYouUpdate`, () => {
render(<Stub a={createProps()} />, node)
render(<Stub a={createProps()} />, node)

assert.equal(warnStore.entries.length, 3)
assert.equal(groupStore.entries.length, 3)
assert.equal(groupStore.entries[0][0], `Stub.props`)
assert.equal(groupStore.entries[1][0], `Stub.props.a`)
assert.equal(groupStore.entries[2][0], `Stub.props.a.b`)
assert.ok(warning.test(warnStore.entries[0][2]))
assert.ok(warning.test(warnStore.entries[1][2]))
assert.ok(warning.test(warnStore.entries[2][2]))
assert.deepEqual(logStore.entries[0][2], {a})
assert.deepEqual(logStore.entries[1][2], {a})
assert.deepEqual(logStore.entries[2][2], {b: a.b})
assert.deepEqual(logStore.entries[3][2], {b: a.b})
assert.deepEqual(logStore.entries[4][2], {c: a.b.c})
assert.deepEqual(logStore.entries[5][2], {c: a.b.c})
equal(warnStore.entries.length, 3)
equal(groupStore.entries.length, 3)
equal(groupStore.entries[0][0], `Stub.props`)
equal(groupStore.entries[1][0], `Stub.props.a`)
equal(groupStore.entries[2][0], `Stub.props.a.b`)
ok(warning.test(warnStore.entries[0][2]))
ok(warning.test(warnStore.entries[1][2]))
ok(warning.test(warnStore.entries[2][2]))
deepEqual(logStore.entries[0][2], {a})
deepEqual(logStore.entries[1][2], {a})
deepEqual(logStore.entries[2][2], {b: a.b})
deepEqual(logStore.entries[3][2], {b: a.b})
deepEqual(logStore.entries[4][2], {c: a.b.c})
deepEqual(logStore.entries[5][2], {c: a.b.c})
})

it(`logs a warning on function props`, () => {
Expand All @@ -98,10 +99,10 @@ describe(`whyDidYouUpdate`, () => {
render(<Stub a={{b: fn}} />, node)
render(<Stub a={{b: fn2}} />, node)

assert.equal(warnStore.entries.length, 1)
assert.ok(warning.test(warnStore.entries[0][0]))
assert.equal(logStore.entries[0][2], fn)
assert.equal(logStore.entries[1][2], fn2)
equal(warnStore.entries.length, 1)
ok(warning.test(warnStore.entries[0][0]))
equal(logStore.entries[0][2], fn)
equal(logStore.entries[1][2], fn2)
})

it(`can ignore certain names using a regexp`, () => {
Expand All @@ -111,17 +112,17 @@ describe(`whyDidYouUpdate`, () => {
render(<Stub a={1} />, node)
render(<Stub a={1} />, node)

assert.equal(warnStore.entries.length, 0)
equal(warnStore.entries.length, 0)
})

it(`can ignore certain names using a string`, () => {
React.__WHY_DID_YOU_UPDATE_RESTORE_FN__()
whyDidYouUpdate(React, {exclude: 'Stub'})
whyDidYouUpdate(React, {exclude: `Stub`})

render(<Stub a={1} />, node)
render(<Stub a={1} />, node)

assert.equal(warnStore.entries.length, 0)
equal(warnStore.entries.length, 0)
})

it(`can include only certain names using a regexp`, () => {
Expand All @@ -143,14 +144,14 @@ describe(`whyDidYouUpdate`, () => {
render(createInstance(), node)
render(createInstance(), node)

assert.equal(warnStore.entries.length, 1)
assert.equal(groupStore.entries.length, 1)
assert.equal(groupStore.entries[0][0], `Foo.props`)
equal(warnStore.entries.length, 1)
equal(groupStore.entries.length, 1)
equal(groupStore.entries[0][0], `Foo.props`)
})

it(`can include only certain names using a string`, () => {
React.__WHY_DID_YOU_UPDATE_RESTORE_FN__()
whyDidYouUpdate(React, {include: 'Foo'})
whyDidYouUpdate(React, {include: `Foo`})

class Foo extends React.Component {
render () {
Expand All @@ -174,9 +175,9 @@ describe(`whyDidYouUpdate`, () => {
render(createInstance(), node)
render(createInstance(), node)

assert.equal(warnStore.entries.length, 1)
assert.equal(groupStore.entries.length, 1)
assert.equal(groupStore.entries[0][0], `Foo.props`)
equal(warnStore.entries.length, 1)
equal(groupStore.entries.length, 1)
equal(groupStore.entries[0][0], `Foo.props`)
})

it(`can both include an exclude option`, () => {
Expand Down Expand Up @@ -205,15 +206,15 @@ describe(`whyDidYouUpdate`, () => {
render(createInstance(), node)
render(createInstance(), node)

assert.equal(warnStore.entries.length, 2)
assert.equal(groupStore.entries.length, 2)
assert.equal(groupStore.entries[0][0], `Stub.props`)
assert.equal(groupStore.entries[1][0], `StubBar.props`)
equal(warnStore.entries.length, 2)
equal(groupStore.entries.length, 2)
equal(groupStore.entries[0][0], `Stub.props`)
equal(groupStore.entries[1][0], `StubBar.props`)
})

it(`accepts arrasy as args to include/exclude`, () => {
React.__WHY_DID_YOU_UPDATE_RESTORE_FN__()
whyDidYouUpdate(React, {include: [/Stub/], exclude: [/Foo/, 'StubBar']})
whyDidYouUpdate(React, {include: [/Stub/], exclude: [/Foo/, `StubBar`]})

class StubFoo extends React.Component {
render () {
Expand All @@ -237,14 +238,14 @@ describe(`whyDidYouUpdate`, () => {
render(createInstance(), node)
render(createInstance(), node)

assert.equal(warnStore.entries.length, 1)
assert.equal(groupStore.entries.length, 1)
assert.equal(groupStore.entries[0][0], `Stub.props`)
equal(warnStore.entries.length, 1)
equal(groupStore.entries.length, 1)
equal(groupStore.entries[0][0], `Stub.props`)
})

it(`works with createClass`, () => {
const Foo = React.createClass({
displayName: 'Foo',
displayName: `Foo`,

render () {
return <noscript />
Expand All @@ -254,14 +255,14 @@ describe(`whyDidYouUpdate`, () => {
render(<Foo a={1} />, node)
render(<Foo a={1} />, node)

assert.equal(warnStore.entries.length, 1)
assert.equal(groupStore.entries.length, 1)
assert.equal(groupStore.entries[0][0], `Foo.props`)
equal(warnStore.entries.length, 1)
equal(groupStore.entries.length, 1)
equal(groupStore.entries[0][0], `Foo.props`)
})

it(`still calls the original componentDidUpdate for createClass`, done => {
const Foo = React.createClass({
displayName: 'Foo',
displayName: `Foo`,

componentDidUpdate () {
done()
Expand All @@ -275,6 +276,6 @@ describe(`whyDidYouUpdate`, () => {
render(<Foo a={1} />, node)
render(<Foo a={1} />, node)

assert.equal(warnStore.entries.length, 1)
equal(warnStore.entries.length, 1)
})
})
22 changes: 22 additions & 0 deletions tests/normalizeOptions-test.js
@@ -0,0 +1,22 @@
import {deepEqual} from 'assert'

import {normalizeOptions, DEFAULT_INCLUDE, DEFAULT_EXCLUDE} from 'src/normalizeOptions'

const toString = o => RegExp.prototype.toString.call(o)

const convertEqual = (include, includeOutput, exclude, excludeOutput) => {
const opts = normalizeOptions({include, exclude})
deepEqual(opts.include.map(toString), includeOutput.map(toString))
deepEqual(opts.exclude.map(toString), excludeOutput.map(toString))
}

describe('normalizeOptions', () => {
it('converts all include to an array of RegExps', () => {
convertEqual('A', [/^A$/], 'B', [/^B$/])
convertEqual(['A', 'B'], [/^A$/, /^B$/], undefined, [DEFAULT_EXCLUDE])
convertEqual(/A/, [/A/], [`B`], [/^B$/])
convertEqual([/A/, 'B'], [/A/, /^B$/], undefined, [DEFAULT_EXCLUDE])
convertEqual([/A/, /B/], [/A/, /B/], undefined, [DEFAULT_EXCLUDE])
convertEqual(undefined, [DEFAULT_INCLUDE], [/A/, /B/], [/A/, /B/])
})
})

0 comments on commit 7ad3aac

Please sign in to comment.