From 6afc63753b40a3fd8c2527325fea9fddfd230742 Mon Sep 17 00:00:00 2001 From: Chris Brody Date: Tue, 31 Jan 2023 09:10:51 -0500 Subject: [PATCH] test: improve testing with Preact & React 18, etc (#48) - wrap some updates in act() wrapper from react-dom/test-utils (or preact/test-utils for Preact), using simple actWith() test utility function in many cases, to get some tests working with Preact & React 18 (without breaking on React 16) - update CI workflow labels - show console warnings for tests that still need to be skipped - other minor updates related issues: - https://github.com/react-recompose/react-recompose/issues/40 - https://github.com/react-recompose/react-recompose/issues/41 PR ref: https://github.com/react-recompose/react-recompose/pull/48 --- .github/workflows/preact-test.yml | 2 +- .github/workflows/react-18-test.yml | 2 +- .github/workflows/test-react-16.yml | 2 +- .../__tests__/componentFromStream-test.js | 32 ++++----- .../recompose/__tests__/createSink-test.js | 12 +--- .../recompose/__tests__/mapProps-test.js | 12 +--- src/packages/recompose/__tests__/nest-test.js | 6 +- .../__tests__/onlyUpdateForKeys-test.js | 15 ++-- .../__tests__/onlyUpdateForPropTypes-test.js | 15 ++-- src/packages/recompose/__tests__/pure-test.js | 15 +--- .../__tests__/renderComponent-test.js | 12 +--- .../recompose/__tests__/renderNothing-test.js | 6 +- .../recompose/__tests__/shouldUpdate-test.js | 15 +--- src/packages/recompose/__tests__/utils.js | 15 ++++ .../recompose/__tests__/withHandlers-test.js | 12 ++-- .../__tests__/withPropsOnChange-test.js | 27 ++----- .../recompose/__tests__/withReducer-test.js | 25 ++----- .../recompose/__tests__/withState-test.js | 45 ++---------- .../__tests__/withStateHandlers-test.js | 71 +++++-------------- 19 files changed, 100 insertions(+), 241 deletions(-) diff --git a/.github/workflows/preact-test.yml b/.github/workflows/preact-test.yml index adf528cd..56bb3944 100644 --- a/.github/workflows/preact-test.yml +++ b/.github/workflows/preact-test.yml @@ -5,7 +5,7 @@ # - .github/workflows/test-react-16.yml # - https://github.com/actions/starter-workflows/blob/b2e786d4e9af21f57ab07c1bc7231ed867f7675f/ci/node.js.yml -name: Preact - limited testing see issue 41 +name: Preact - skip some tests see issue 41 on: - push diff --git a/.github/workflows/react-18-test.yml b/.github/workflows/react-18-test.yml index f29535b3..df8b7f76 100644 --- a/.github/workflows/react-18-test.yml +++ b/.github/workflows/react-18-test.yml @@ -5,7 +5,7 @@ # - .github/workflows/test-react-16.yml # - https://github.com/actions/starter-workflows/blob/b2e786d4e9af21f57ab07c1bc7231ed867f7675f/ci/node.js.yml -name: React 18 - limited testing see issue 40 +name: React 18 - skip test see issue 40 on: - push diff --git a/.github/workflows/test-react-16.yml b/.github/workflows/test-react-16.yml index 0337a814..3680ca6c 100644 --- a/.github/workflows/test-react-16.yml +++ b/.github/workflows/test-react-16.yml @@ -33,4 +33,4 @@ jobs: node-version: ${{ matrix.node-version }} - run: yarn - run: yarn add --dev react@${{ matrix.react-version }} react-dom@${{ matrix.react-version }} enzyme-adapter-react-16@latest - - run: npm test + - run: npx cross-env TEST_WITH_REACT_16=1 jest diff --git a/src/packages/recompose/__tests__/componentFromStream-test.js b/src/packages/recompose/__tests__/componentFromStream-test.js index da4cc587..5dec68f0 100644 --- a/src/packages/recompose/__tests__/componentFromStream-test.js +++ b/src/packages/recompose/__tests__/componentFromStream-test.js @@ -2,6 +2,7 @@ import React from 'react' import { mount } from 'enzyme' import { Observable, Subject } from 'rxjs' import sinon from 'sinon' +import { act } from './utils' import rxjsConfig from '../rxjsObservableConfig' import { componentFromStreamWithConfig } from '../componentFromStream' @@ -41,19 +42,13 @@ test('componentFromStream unsubscribes from stream before unmounting', () => { }) test('componentFromStream renders nothing until the stream emits a value', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - if (process.env.TEST_WITH_REACT_18) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 - see react-recompose#40') - return - } - const vdom$ = new Subject() const Div = componentFromStream(() => vdom$.mapTo(
)) const wrapper = mount(
) expect(wrapper.find('div').length).toBe(0) - vdom$.next() + act(() => { + vdom$.next() + }) wrapper.update() expect(wrapper.find('div').length).toBe(1) }) @@ -102,15 +97,7 @@ test('complete props stream before unmounting', () => { expect(counter).toBe(0) }) -test('completed props stream should throw an exception', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR PREACT - see react-recompose#41') - return - } - +test('completed props stream should throw an exception (etc.)', () => { const Div = componentFromStream(props$ => { const first$ = props$.filter(() => false).first().startWith(null) @@ -124,5 +111,12 @@ test('completed props stream should throw an exception', () => { const error = sinon.stub(console, 'error') expect(() => wrapper.unmount()).toThrowError(/no elements in sequence/) - expect(error.called).toBe(true) + + if (process.env.TEST_WITH_PREACT) { + // TBD investigate why there is no console error with Preact in this test + /* eslint-disable-next-line no-console */ + console.warn('SKIP console error check for Preact in this test') + } else { + expect(error.called).toBe(true) + } }) diff --git a/src/packages/recompose/__tests__/createSink-test.js b/src/packages/recompose/__tests__/createSink-test.js index 382a1997..62418302 100644 --- a/src/packages/recompose/__tests__/createSink-test.js +++ b/src/packages/recompose/__tests__/createSink-test.js @@ -1,18 +1,10 @@ import React from 'react' import { mount } from 'enzyme' import sinon from 'sinon' +import { actWith } from './utils' import { createSink, compose, withState, mapProps } from '../' test('createSink creates a React component that fires a callback when receiving new props', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const spy = sinon.spy() const Sink = createSink(spy) const Counter = compose( @@ -29,7 +21,7 @@ test('createSink creates a React component that fires a callback when receiving
) - const { increment } = spy.lastCall.args[0] + const increment = actWith(spy.lastCall.args[0].increment) const getCounter = () => spy.lastCall.args[0].counter expect(getCounter()).toBe(0) increment() diff --git a/src/packages/recompose/__tests__/mapProps-test.js b/src/packages/recompose/__tests__/mapProps-test.js index 8b9baebf..97732f97 100644 --- a/src/packages/recompose/__tests__/mapProps-test.js +++ b/src/packages/recompose/__tests__/mapProps-test.js @@ -1,18 +1,10 @@ import React from 'react' import { mount } from 'enzyme' import sinon from 'sinon' +import { actWith } from './utils' import { mapProps, withState, compose } from '../' test('mapProps maps owner props to child props', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -27,7 +19,7 @@ test('mapProps maps owner props to child props', () => { expect(StringConcat.displayName).toBe('withState(mapProps(component))') mount() - const { updateStrings } = component.firstCall.args[0] + const updateStrings = actWith(component.firstCall.args[0].updateStrings) updateStrings(strings => [...strings, 'fa']) expect(component.firstCall.args[0].string).toBe('doremi') diff --git a/src/packages/recompose/__tests__/nest-test.js b/src/packages/recompose/__tests__/nest-test.js index fb68946f..dc33b2e6 100644 --- a/src/packages/recompose/__tests__/nest-test.js +++ b/src/packages/recompose/__tests__/nest-test.js @@ -6,8 +6,10 @@ test('nest nests components from outer to inner', () => { // TODO ref: // - https://github.com/react-recompose/react-recompose/issues/41 if (process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR PREACT - see react-recompose#41') + /* eslint-disable-next-line no-console */ + console.warn( + 'SKIP FOR PREACT - see https://github.com/react-recompose/react-recompose/issues/41' + ) return } diff --git a/src/packages/recompose/__tests__/onlyUpdateForKeys-test.js b/src/packages/recompose/__tests__/onlyUpdateForKeys-test.js index cf321634..2a8a1ade 100644 --- a/src/packages/recompose/__tests__/onlyUpdateForKeys-test.js +++ b/src/packages/recompose/__tests__/onlyUpdateForKeys-test.js @@ -1,18 +1,10 @@ import React from 'react' import { mount } from 'enzyme' import sinon from 'sinon' +import { actWith } from './utils' import { onlyUpdateForKeys, compose, withState } from '../' test('onlyUpdateForKeys implements shouldComponentUpdate()', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -27,12 +19,13 @@ test('onlyUpdateForKeys implements shouldComponentUpdate()', () => { ) mount() - const { updateCounter, updateFoobar } = component.firstCall.args[0] + const updateCounter = actWith(component.firstCall.args[0].updateCounter) + const updateFoobar = actWith(component.firstCall.args[0].updateFoobar) expect(component.lastCall.args[0].counter).toBe(0) expect(component.lastCall.args[0].foobar).toBe('foobar') - // Does not update + // should not update updateFoobar('barbaz') expect(component.calledOnce).toBe(true) diff --git a/src/packages/recompose/__tests__/onlyUpdateForPropTypes-test.js b/src/packages/recompose/__tests__/onlyUpdateForPropTypes-test.js index 28bc8f53..d526b5bc 100644 --- a/src/packages/recompose/__tests__/onlyUpdateForPropTypes-test.js +++ b/src/packages/recompose/__tests__/onlyUpdateForPropTypes-test.js @@ -2,18 +2,10 @@ import React from 'react' import PropTypes from 'prop-types' import sinon from 'sinon' import { mount, shallow } from 'enzyme' +import { actWith } from './utils' import { onlyUpdateForPropTypes, compose, withState, setPropTypes } from '../' test('onlyUpdateForPropTypes only updates for props specified in propTypes', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -29,12 +21,13 @@ test('onlyUpdateForPropTypes only updates for props specified in propTypes', () ) mount() - const { updateCounter, updateFoobar } = component.firstCall.args[0] + const updateCounter = actWith(component.firstCall.args[0].updateCounter) + const updateFoobar = actWith(component.firstCall.args[0].updateFoobar) expect(component.lastCall.args[0].counter).toBe(0) expect(component.lastCall.args[0].foobar).toBe('foobar') - // Does not update + // should not update updateFoobar('barbaz') expect(component.calledOnce).toBe(true) diff --git a/src/packages/recompose/__tests__/pure-test.js b/src/packages/recompose/__tests__/pure-test.js index 1d854064..2715f8e6 100644 --- a/src/packages/recompose/__tests__/pure-test.js +++ b/src/packages/recompose/__tests__/pure-test.js @@ -1,19 +1,10 @@ import React from 'react' import { mount } from 'enzyme' import sinon from 'sinon' +import { actWith, countRenders } from './utils' import { pure, compose, withState } from '../' -import { countRenders } from './utils' test('pure implements shouldComponentUpdate() using shallowEqual()', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -27,12 +18,12 @@ test('pure implements shouldComponentUpdate() using shallowEqual()', () => { expect(Todos.displayName).toBe('withState(pure(countRenders(component)))') mount() - const { updateTodos } = component.firstCall.args[0] + const updateTodos = actWith(component.firstCall.args[0].updateTodos) expect(component.lastCall.args[0].todos).toBe(initialTodos) expect(component.lastCall.args[0].renderCount).toBe(1) - // Does not re-render + // should not re-render updateTodos(initialTodos) expect(component.calledOnce).toBe(true) diff --git a/src/packages/recompose/__tests__/renderComponent-test.js b/src/packages/recompose/__tests__/renderComponent-test.js index 8596a9a8..ee334818 100644 --- a/src/packages/recompose/__tests__/renderComponent-test.js +++ b/src/packages/recompose/__tests__/renderComponent-test.js @@ -1,18 +1,10 @@ import React from 'react' import { mount } from 'enzyme' import sinon from 'sinon' +import { actWith } from './utils' import { renderComponent, withState, compose, branch } from '../' test('renderComponent always renders the given component', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const componentA = sinon.spy(() => null) const componentB = sinon.spy(() => null) @@ -26,7 +18,7 @@ test('renderComponent always renders the given component', () => { )(null) mount() - const { updateFlip } = componentB.firstCall.args[0] + const updateFlip = actWith(componentB.firstCall.args[0].updateFlip) expect(componentB.calledOnce).toBe(true) expect(componentA.notCalled).toBe(true) diff --git a/src/packages/recompose/__tests__/renderNothing-test.js b/src/packages/recompose/__tests__/renderNothing-test.js index bfb62ceb..1c98420d 100644 --- a/src/packages/recompose/__tests__/renderNothing-test.js +++ b/src/packages/recompose/__tests__/renderNothing-test.js @@ -6,8 +6,10 @@ test('renderNothing returns a component that renders null', () => { // TODO ref: // - https://github.com/react-recompose/react-recompose/issues/41 if (process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR PREACT - see react-recompose#41') + /* eslint-disable-next-line no-console */ + console.warn( + 'SKIP FOR PREACT - see https://github.com/react-recompose/react-recompose/issues/41' + ) return } diff --git a/src/packages/recompose/__tests__/shouldUpdate-test.js b/src/packages/recompose/__tests__/shouldUpdate-test.js index 0fa97138..a8323413 100644 --- a/src/packages/recompose/__tests__/shouldUpdate-test.js +++ b/src/packages/recompose/__tests__/shouldUpdate-test.js @@ -1,19 +1,10 @@ import React from 'react' import { mount } from 'enzyme' import sinon from 'sinon' +import { actWith, countRenders } from './utils' import { shouldUpdate, compose, withState } from '../' -import { countRenders } from './utils' test('shouldUpdate implements shouldComponentUpdate', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -29,12 +20,12 @@ test('shouldUpdate implements shouldComponentUpdate', () => { ) mount() - const { updateTodos } = component.firstCall.args[0] + const updateTodos = actWith(component.firstCall.args[0].updateTodos) expect(component.lastCall.args[0].todos).toBe(initialTodos) expect(component.lastCall.args[0].renderCount).toBe(1) - // Does not re-render + // should not re-render updateTodos(initialTodos) expect(component.calledOnce).toBe(true) diff --git a/src/packages/recompose/__tests__/utils.js b/src/packages/recompose/__tests__/utils.js index bcb09d40..fc010e08 100644 --- a/src/packages/recompose/__tests__/utils.js +++ b/src/packages/recompose/__tests__/utils.js @@ -2,6 +2,21 @@ import React from 'react' import setDisplayName from '../setDisplayName' import wrapDisplayName from '../wrapDisplayName' +/* using require here to support Preact vs React */ +/* eslint-disable */ +export const { act } = process.env.TEST_WITH_PREACT + ? require('preact/test-utils') + : process.env.TEST_WITH_REACT_16 + ? { act: f => f() } + : require('react-dom/test-utils') +/* eslint-enable */ + +export const actWith = f => arg => { + act(() => { + f(arg) + }) +} + export const countRenders = BaseComponent => { class CountRenders extends React.Component { renderCount = 0 diff --git a/src/packages/recompose/__tests__/withHandlers-test.js b/src/packages/recompose/__tests__/withHandlers-test.js index df34a919..f3a2b3e5 100644 --- a/src/packages/recompose/__tests__/withHandlers-test.js +++ b/src/packages/recompose/__tests__/withHandlers-test.js @@ -7,8 +7,10 @@ test('withHandlers passes handlers to base component', () => { // TODO ref: // - https://github.com/react-recompose/react-recompose/issues/41 if (process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR PREACT - see react-recompose#41') + /* eslint-disable-next-line no-console */ + console.warn( + 'SKIP FOR PREACT - see https://github.com/react-recompose/react-recompose/issues/41' + ) return } @@ -73,8 +75,10 @@ test('withHandlers warns if handler is not a higher-order function', () => { // - https://github.com/react-recompose/react-recompose/issues/40 // - https://github.com/react-recompose/react-recompose/issues/41 if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') + /* eslint-disable-next-line no-console */ + console.warn( + 'SKIP FOR REACT 18 & PREACT - see https://github.com/react-recompose/react-recompose/issues/40 & https://github.com/react-recompose/react-recompose/issues/41' + ) return } diff --git a/src/packages/recompose/__tests__/withPropsOnChange-test.js b/src/packages/recompose/__tests__/withPropsOnChange-test.js index e0230727..d6635ff7 100644 --- a/src/packages/recompose/__tests__/withPropsOnChange-test.js +++ b/src/packages/recompose/__tests__/withPropsOnChange-test.js @@ -1,6 +1,7 @@ import * as React from 'react' import { mount } from 'enzyme' import sinon from 'sinon' +import { actWith } from './utils' import { withPropsOnChange, withState, @@ -10,15 +11,6 @@ import { } from '../' test('withPropsOnChange maps subset of owner props to child props', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -40,12 +32,12 @@ test('withPropsOnChange maps subset of owner props to child props', () => { ) mount() - const { updateStrings } = component.firstCall.args[0] + const updateStrings = actWith(component.firstCall.args[0].updateStrings) expect(component.lastCall.args[0].foobar).toBe('ab') expect(component.calledOnce).toBe(true) expect(mapSpy.callCount).toBe(1) - // Does not re-map for non-dependent prop updates + // should not re-map for non-dependent prop updates updateStrings(strings => ({ ...strings, c: 'baz' })) expect(component.lastCall.args[0].foobar).toBe('ab') expect(component.lastCall.args[0].c).toBe('c') @@ -60,15 +52,6 @@ test('withPropsOnChange maps subset of owner props to child props', () => { }) test('withPropsOnChange maps subset of owner props to child props with custom predicate', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -110,7 +93,7 @@ test('withPropsOnChange maps subset of owner props to child props with custom pr ) mount() - const { updateResult } = component.firstCall.args[0] + const updateResult = actWith(component.firstCall.args[0].updateResult) expect(component.lastCall.args[0].errorEverHappened).toBe(false) expect(component.lastCall.args[0].lastError).toBeUndefined() expect(component.calledOnce).toBe(true) @@ -123,7 +106,7 @@ test('withPropsOnChange maps subset of owner props to child props with custom pr expect(component.calledTwice).toBe(true) expect(mapSpy.callCount).toBe(2) - // Does not re-map for false map result + // should not re-map for false map result updateResult({ loading: true, hasError: false, error: null }) expect(component.lastCall.args[0].errorEverHappened).toBe(true) expect(component.lastCall.args[0].lastError).toBe('1') diff --git a/src/packages/recompose/__tests__/withReducer-test.js b/src/packages/recompose/__tests__/withReducer-test.js index 79c574bc..d976066b 100644 --- a/src/packages/recompose/__tests__/withReducer-test.js +++ b/src/packages/recompose/__tests__/withReducer-test.js @@ -1,20 +1,12 @@ import React from 'react' import { mount } from 'enzyme' import sinon from 'sinon' +import { act, actWith } from './utils' import { withReducer, compose, flattenProp } from '../' const SET_COUNTER = 'SET_COUNTER' test('adds a stateful value and a function for updating it', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -31,7 +23,7 @@ test('adds a stateful value and a function for updating it', () => { expect(Counter.displayName).toBe('withReducer(flattenProp(component))') mount() - const { dispatch } = component.firstCall.args[0] + const dispatch = actWith(component.firstCall.args[0].dispatch) expect(component.lastCall.args[0].counter).toBe(0) @@ -78,15 +70,6 @@ test('receives state from reducer when initialState is not provided', () => { }) test('calls the given callback with new state after a dispatch call', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -104,7 +87,9 @@ test('calls the given callback with new state after a dispatch call', () => { const dispatch = sinon.spy(component.firstCall.args[0].dispatch) const callback = sinon.spy() - dispatch({ type: SET_COUNTER, payload: 11 }, callback) + act(() => { + dispatch({ type: SET_COUNTER, payload: 11 }, callback) + }) expect(dispatch.calledBefore(callback)).toBe(true) expect(dispatch.calledOnce).toBe(true) expect(callback.calledAfter(dispatch)).toBe(true) diff --git a/src/packages/recompose/__tests__/withState-test.js b/src/packages/recompose/__tests__/withState-test.js index cdfe69a0..f0f3244b 100644 --- a/src/packages/recompose/__tests__/withState-test.js +++ b/src/packages/recompose/__tests__/withState-test.js @@ -2,18 +2,11 @@ import React from 'react' import { mount } from 'enzyme' import sinon from 'sinon' +import { actWith } from './utils' + import { withState } from '../' test('withState adds a stateful value and a function for updating it', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -21,7 +14,7 @@ test('withState adds a stateful value and a function for updating it', () => { expect(Counter.displayName).toBe('withState(component)') mount() - const { updateCounter } = component.firstCall.args[0] + const updateCounter = actWith(component.firstCall.args[0].updateCounter) expect(component.lastCall.args[0].counter).toBe(0) expect(component.lastCall.args[0].pass).toBe('through') @@ -34,41 +27,24 @@ test('withState adds a stateful value and a function for updating it', () => { }) test('withState also accepts a non-function, which is passed directly to setState()', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' const Counter = withState('counter', 'updateCounter', 0)(component) mount() - const { updateCounter } = component.firstCall.args[0] + const updateCounter = actWith(component.firstCall.args[0].updateCounter) updateCounter(18) expect(component.lastCall.args[0].counter).toBe(18) }) test('withState accepts setState() callback', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - if (process.env.TEST_WITH_REACT_18) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 - see react-recompose#40') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' const Counter = withState('counter', 'updateCounter', 0)(component) mount() - const { updateCounter } = component.firstCall.args[0] + const updateCounter = actWith(component.firstCall.args[0].updateCounter) const renderSpy = sinon.spy(() => { expect(component.lastCall.args[0].counter).toBe(18) @@ -79,15 +55,6 @@ test('withState accepts setState() callback', () => { }) test('withState also accepts initialState as function of props', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -98,7 +65,7 @@ test('withState also accepts initialState as function of props', () => { )(component) mount() - const { updateCounter } = component.firstCall.args[0] + const updateCounter = actWith(component.firstCall.args[0].updateCounter) expect(component.lastCall.args[0].counter).toBe(1) updateCounter(n => n * 3) diff --git a/src/packages/recompose/__tests__/withStateHandlers-test.js b/src/packages/recompose/__tests__/withStateHandlers-test.js index b2f7527d..0b5a7442 100644 --- a/src/packages/recompose/__tests__/withStateHandlers-test.js +++ b/src/packages/recompose/__tests__/withStateHandlers-test.js @@ -2,14 +2,18 @@ import React from 'react' import { mount } from 'enzyme' import sinon from 'sinon' +import { actWith } from './utils' + import { compose, withStateHandlers } from '../' test('withStateHandlers should persist events passed as argument', () => { // TODO ref: // - https://github.com/react-recompose/react-recompose/issues/41 if (process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR PREACT - see react-recompose#41') + /* eslint-disable-next-line no-console */ + console.warn( + 'SKIP FOR PREACT - see https://github.com/react-recompose/react-recompose/issues/41' + ) return } @@ -47,15 +51,6 @@ test('withStateHandlers should persist events passed as argument', () => { }) test('withStateHandlers adds a stateful value and a function for updating it', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -70,7 +65,7 @@ test('withStateHandlers adds a stateful value and a function for updating it', ( expect(Counter.displayName).toBe('withStateHandlers(component)') mount() - const { updateCounter } = component.firstCall.args[0] + const updateCounter = actWith(component.firstCall.args[0].updateCounter) expect(component.lastCall.args[0].counter).toBe(0) expect(component.lastCall.args[0].pass).toBe('through') @@ -109,8 +104,10 @@ test('withStateHandlers initial state must be function or object or null or unde // TODO ref: // - https://github.com/react-recompose/react-recompose/issues/41 if (process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR PREACT - see react-recompose#41') + /* eslint-disable-next-line no-console */ + console.warn( + 'SKIP FOR PREACT - see https://github.com/react-recompose/react-recompose/issues/41' + ) return } @@ -126,15 +123,6 @@ test('withStateHandlers initial state must be function or object or null or unde }) test('withStateHandlers have access to props', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -156,7 +144,7 @@ test('withStateHandlers have access to props', () => { ) - const { increment } = component.firstCall.args[0] + const increment = actWith(component.firstCall.args[0].increment) increment() expect(component.lastCall.args[0].counter).toBe( @@ -165,15 +153,6 @@ test('withStateHandlers have access to props', () => { }) test('withStateHandlers passes immutable state updaters', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -195,7 +174,7 @@ test('withStateHandlers passes immutable state updaters', () => { ) - const { increment } = component.firstCall.args[0] + const increment = actWith(component.firstCall.args[0].increment) increment() expect(component.lastCall.args[0].counter).toBe( @@ -204,15 +183,6 @@ test('withStateHandlers passes immutable state updaters', () => { }) test('withStateHandlers does not rerender if state updater returns undefined', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -235,7 +205,7 @@ test('withStateHandlers does not rerender if state updater returns undefined', ( mount() expect(component.callCount).toBe(1) - const { updateCounter } = component.firstCall.args[0] + const updateCounter = actWith(component.firstCall.args[0].updateCounter) updateCounter(1) expect(component.callCount).toBe(2) @@ -245,15 +215,6 @@ test('withStateHandlers does not rerender if state updater returns undefined', ( }) test('withStateHandlers rerenders if parent props changed', () => { - // TODO ref: - // - https://github.com/react-recompose/react-recompose/issues/40 - // - https://github.com/react-recompose/react-recompose/issues/41 - if (process.env.TEST_WITH_REACT_18 || process.env.TEST_WITH_PREACT) { - /* eslint-disable-line no-console */ - console.log('SKIP FOR REACT 18 & PREACT - see react-recompose#40 & #42') - return - } - const component = sinon.spy(() => null) component.displayName = 'component' @@ -284,7 +245,9 @@ test('withStateHandlers rerenders if parent props changed', () => { mount() - const { updateParentIncrement } = component.firstCall.args[0] + const updateParentIncrement = actWith( + component.firstCall.args[0].updateParentIncrement + ) updateParentIncrement() expect(component.lastCall.args[0].counter).toBe(initialCounter + 1)