diff --git a/src/Field.test.js b/src/Field.test.js
index c2e45d60..77b43648 100644
--- a/src/Field.test.js
+++ b/src/Field.test.js
@@ -7,7 +7,14 @@ const onSubmitMock = values => {}
describe('Field', () => {
it('should warn if not used inside a form', () => {
+ const spy = jest.spyOn(global.console, 'error').mockImplementation(() => {})
TestUtils.renderIntoDocument()
+ expect(spy).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalledTimes(1)
+ expect(spy).toHaveBeenCalledWith(
+ 'Warning: Field must be used inside of a ReactFinalForm component'
+ )
+ spy.mockRestore()
})
it('should resubscribe if name changes', () => {
@@ -39,14 +46,14 @@ describe('Field', () => {
expect(renderInput).not.toHaveBeenCalled()
const dom = TestUtils.renderIntoDocument()
expect(renderInput).toHaveBeenCalled()
- expect(renderInput).toHaveBeenCalledTimes(2)
- expect(renderInput.mock.calls[1][0].input.value).toBe('Odie')
+ expect(renderInput).toHaveBeenCalledTimes(1)
+ expect(renderInput.mock.calls[0][0].input.value).toBe('Odie')
const button = TestUtils.findRenderedDOMComponentWithTag(dom, 'button')
TestUtils.Simulate.click(button)
- expect(renderInput).toHaveBeenCalledTimes(4)
- expect(renderInput.mock.calls[3][0].input.value).toBe('Garfield')
+ expect(renderInput).toHaveBeenCalledTimes(3)
+ expect(renderInput.mock.calls[2][0].input.value).toBe('Garfield')
})
it('should not resubscribe if name changes when not inside a
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
+ expect(render).toHaveBeenCalledTimes(1)
expect(renderInput).toHaveBeenCalled()
- expect(renderInput).toHaveBeenCalledTimes(2)
+ expect(renderInput).toHaveBeenCalledTimes(1)
})
it('should unsubscribe on unmount', () => {
@@ -141,29 +154,28 @@ describe('Field', () => {
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- expect(render.mock.calls[1][0].active).toBeUndefined()
- expect(render.mock.calls[1][0].values.foo).toBeUndefined()
+ expect(render).toHaveBeenCalledTimes(1)
+ expect(render.mock.calls[0][0].active).toBeUndefined()
+ expect(render.mock.calls[0][0].values.foo).toBeUndefined()
const input = TestUtils.findRenderedDOMComponentWithTag(dom, 'input')
TestUtils.Simulate.focus(input)
- expect(render).toHaveBeenCalledTimes(3)
- expect(render.mock.calls[2][0].active).toBe('foo')
- expect(render.mock.calls[2][0].values.foo).toBeUndefined()
+ expect(render).toHaveBeenCalledTimes(2)
+ expect(render.mock.calls[1][0].active).toBe('foo')
+ expect(render.mock.calls[1][0].values.foo).toBeUndefined()
TestUtils.Simulate.change(input, { target: { value: 'bar' } })
- expect(render).toHaveBeenCalledTimes(4)
- expect(render.mock.calls[3][0].active).toBe('foo')
- expect(render.mock.calls[3][0].values.foo).toBe('bar')
+ expect(render).toHaveBeenCalledTimes(3)
+ expect(render.mock.calls[2][0].active).toBe('foo')
+ expect(render.mock.calls[2][0].values.foo).toBe('bar')
TestUtils.Simulate.blur(input)
- expect(render).toHaveBeenCalledTimes(5)
- expect(render.mock.calls[4][0].active).toBeUndefined()
- expect(render.mock.calls[4][0].values.foo).toBe('bar')
+ expect(render).toHaveBeenCalledTimes(4)
+ expect(render.mock.calls[3][0].active).toBeUndefined()
+ expect(render.mock.calls[3][0].values.foo).toBe('bar')
})
it("should convert '' to undefined on change", () => {
@@ -179,21 +191,20 @@ describe('Field', () => {
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- expect(render.mock.calls[1][0].values.foo).toBeUndefined()
+ expect(render).toHaveBeenCalledTimes(1)
+ expect(render.mock.calls[0][0].values.foo).toBeUndefined()
const input = TestUtils.findRenderedDOMComponentWithTag(dom, 'input')
TestUtils.Simulate.change(input, { target: { value: 'bar' } })
- expect(render).toHaveBeenCalledTimes(3)
- expect(render.mock.calls[2][0].values.foo).toBe('bar')
+ expect(render).toHaveBeenCalledTimes(2)
+ expect(render.mock.calls[1][0].values.foo).toBe('bar')
TestUtils.Simulate.change(input, { target: { value: '' } })
- expect(render).toHaveBeenCalledTimes(4)
- expect(render.mock.calls[3][0].values.foo).toBeUndefined()
+ expect(render).toHaveBeenCalledTimes(3)
+ expect(render.mock.calls[2][0].values.foo).toBeUndefined()
})
it('should accept a null parse prop to preserve empty strings', () => {
@@ -209,21 +220,20 @@ describe('Field', () => {
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- expect(render.mock.calls[1][0].values.foo).toBeUndefined()
+ expect(render).toHaveBeenCalledTimes(1)
+ expect(render.mock.calls[0][0].values.foo).toBeUndefined()
const input = TestUtils.findRenderedDOMComponentWithTag(dom, 'input')
TestUtils.Simulate.change(input, { target: { value: '' } })
- expect(render).toHaveBeenCalledTimes(3)
- expect(render.mock.calls[2][0].values.foo).toBe('')
+ expect(render).toHaveBeenCalledTimes(2)
+ expect(render.mock.calls[1][0].values.foo).toBe('')
TestUtils.Simulate.change(input, { target: { value: 'abc' } })
- expect(render).toHaveBeenCalledTimes(4)
- expect(render.mock.calls[3][0].values.foo).toBe('abc')
+ expect(render).toHaveBeenCalledTimes(3)
+ expect(render.mock.calls[2][0].values.foo).toBe('abc')
})
it('should accept a format function prop', () => {
@@ -240,25 +250,24 @@ describe('Field', () => {
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- expect(render.mock.calls[1][0].values.foo).toBeUndefined()
+ expect(render).toHaveBeenCalledTimes(1)
+ expect(render.mock.calls[0][0].values.foo).toBeUndefined()
expect(format).toHaveBeenCalled()
- expect(format).toHaveBeenCalledTimes(2)
+ expect(format).toHaveBeenCalledTimes(1)
expect(format.mock.calls[0]).toEqual([undefined, 'foo'])
expect(renderInput).toHaveBeenCalled()
- expect(renderInput).toHaveBeenCalledTimes(2)
+ expect(renderInput).toHaveBeenCalledTimes(1)
expect(renderInput.mock.calls[0][0].input.value).toBe('format.undefined')
renderInput.mock.calls[0][0].input.onChange('bar')
- expect(format).toHaveBeenCalledTimes(4)
- expect(format.mock.calls[3]).toEqual(['bar', 'foo'])
+ expect(format).toHaveBeenCalledTimes(3)
+ expect(format.mock.calls[2]).toEqual(['bar', 'foo'])
- expect(renderInput).toHaveBeenCalledTimes(4)
- expect(renderInput.mock.calls[3][0].input.value).toBe('format.bar')
+ expect(renderInput).toHaveBeenCalledTimes(3)
+ expect(renderInput.mock.calls[2][0].input.value).toBe('format.bar')
})
it('should accept a null format prop to preserve undefined values', () => {
@@ -276,18 +285,17 @@ describe('Field', () => {
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- expect(render.mock.calls[1][0].values.foo).toBeUndefined()
+ expect(render).toHaveBeenCalledTimes(1)
+ expect(render.mock.calls[0][0].values.foo).toBeUndefined()
expect(renderInput).toHaveBeenCalled()
- expect(renderInput).toHaveBeenCalledTimes(2)
- expect(renderInput.mock.calls[1][0].input.value).toBeUndefined()
+ expect(renderInput).toHaveBeenCalledTimes(1)
+ expect(renderInput.mock.calls[0][0].input.value).toBeUndefined()
renderInput.mock.calls[0][0].input.onChange('bar')
- expect(renderInput).toHaveBeenCalledTimes(4)
- expect(renderInput.mock.calls[3][0].input.value).toBe('bar')
+ expect(renderInput).toHaveBeenCalledTimes(3)
+ expect(renderInput.mock.calls[2][0].input.value).toBe('bar')
})
it('should provide a value of [] when empty on a select multiple', () => {
@@ -322,18 +330,18 @@ describe('Field', () => {
)
expect(renderInput).toHaveBeenCalled()
- expect(renderInput).toHaveBeenCalledTimes(2)
- expect(renderInput.mock.calls[1][0].input.value).toBe('')
+ expect(renderInput).toHaveBeenCalledTimes(1)
+ expect(renderInput.mock.calls[0][0].input.value).toBe('')
renderInput.mock.calls[0][0].input.onChange('bar')
- expect(renderInput).toHaveBeenCalledTimes(4)
- expect(renderInput.mock.calls[3][0].input.value).toBe('bar')
+ expect(renderInput).toHaveBeenCalledTimes(3)
+ expect(renderInput.mock.calls[2][0].input.value).toBe('bar')
renderInput.mock.calls[1][0].input.onChange(null)
- expect(renderInput).toHaveBeenCalledTimes(6)
- expect(renderInput.mock.calls[5][0].input.value).toBe('')
+ expect(renderInput).toHaveBeenCalledTimes(5)
+ expect(renderInput.mock.calls[4][0].input.value).toBe('')
})
it('should optionally allow null values', () => {
@@ -355,18 +363,18 @@ describe('Field', () => {
expect(render).toHaveBeenCalled()
// called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- expect(render.mock.calls[1][0].values.foo).toBeUndefined()
+ expect(render).toHaveBeenCalledTimes(1)
+ expect(render.mock.calls[0][0].values.foo).toBeUndefined()
renderInput.mock.calls[0][0].input.onChange('bar')
- expect(render).toHaveBeenCalledTimes(3)
- expect(render.mock.calls[2][0].values.foo).toBe('bar')
+ expect(render).toHaveBeenCalledTimes(2)
+ expect(render.mock.calls[1][0].values.foo).toBe('bar')
renderInput.mock.calls[0][0].input.onChange(null)
- expect(render).toHaveBeenCalledTimes(4)
- expect(render.mock.calls[3][0].values.foo).toBe(null)
+ expect(render).toHaveBeenCalledTimes(3)
+ expect(render.mock.calls[2][0].values.foo).toBe(null)
})
it('should not let validate prop bleed through', () => {
@@ -404,8 +412,8 @@ describe('Field', () => {
expect(input).toHaveBeenCalled()
// called twice due to field registration adding touched and visited values
- expect(input).toHaveBeenCalledTimes(2)
- expect(input.mock.calls[1][0].subscription).toBeUndefined()
+ expect(input).toHaveBeenCalledTimes(1)
+ expect(input.mock.calls[0][0].subscription).toBeUndefined()
})
it('should allow changing field-level validation function', () => {
@@ -485,9 +493,8 @@ describe('Field', () => {
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- expect(render.mock.calls[1][0].values.foo).toBe(true)
+ expect(render).toHaveBeenCalledTimes(1)
+ expect(render.mock.calls[0][0].values.foo).toBe(true)
const input = TestUtils.findRenderedDOMComponentWithTag(dom, 'input')
expect(input.checked).toBe(true)
@@ -510,9 +517,8 @@ describe('Field', () => {
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- expect(render.mock.calls[1][0].values.foo).toEqual(['a', 'b', 'c'])
+ expect(render).toHaveBeenCalledTimes(1)
+ expect(render.mock.calls[0][0].values.foo).toEqual(['a', 'b', 'c'])
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(dom, 'input')
expect(inputs[0].checked).toBe(true)
@@ -538,17 +544,16 @@ describe('Field', () => {
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- expect(render.mock.calls[1][0].values.foo).toEqual(['a', 'b', 'c'])
+ expect(render).toHaveBeenCalledTimes(1)
+ expect(render.mock.calls[0][0].values.foo).toEqual(['a', 'b', 'c'])
expect(checkboxA).toHaveBeenCalled()
- expect(checkboxA).toHaveBeenCalledTimes(2)
- expect(checkboxA.mock.calls[1][0].input.checked).toBe(true)
+ expect(checkboxA).toHaveBeenCalledTimes(1)
+ expect(checkboxA.mock.calls[0][0].input.checked).toBe(true)
expect(checkboxD).toHaveBeenCalled()
- expect(checkboxD).toHaveBeenCalledTimes(2)
- expect(checkboxD.mock.calls[1][0].input.checked).toBe(false)
+ expect(checkboxD).toHaveBeenCalledTimes(1)
+ expect(checkboxD.mock.calls[0][0].input.checked).toBe(false)
})
it('should render radio buttons with checked prop', () => {
@@ -568,9 +573,8 @@ describe('Field', () => {
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- expect(render.mock.calls[1][0].values.foo).toBe('Bar')
+ expect(render).toHaveBeenCalledTimes(1)
+ expect(render.mock.calls[0][0].values.foo).toBe('Bar')
const [barInput, bazInput] = TestUtils.scryRenderedDOMComponentsWithTag(
dom,
diff --git a/src/FormSpy.test.js b/src/FormSpy.test.js
index f644b989..1b00d91e 100644
--- a/src/FormSpy.test.js
+++ b/src/FormSpy.test.js
@@ -16,7 +16,14 @@ const hasFormApi = props => {
describe('FormSpy', () => {
it('should warn error if not used inside a form', () => {
+ const spy = jest.spyOn(global.console, 'error').mockImplementation(() => {})
TestUtils.renderIntoDocument( } />)
+ expect(spy).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalledTimes(1)
+ expect(spy).toHaveBeenCalledWith(
+ 'Warning: FormSpy must be used inside of a ReactFinalForm component'
+ )
+ spy.mockRestore()
})
it('should allow subscribing to everything', () => {
@@ -47,7 +54,7 @@ describe('FormSpy', () => {
expect(render.mock.calls[1][0].validating).toBe(false)
expect(render.mock.calls[1][0].values).toEqual({})
expect(renderInput).toHaveBeenCalled()
- expect(renderInput).toHaveBeenCalledTimes(2)
+ expect(renderInput).toHaveBeenCalledTimes(1)
// change value
renderInput.mock.calls[0][0].input.onChange('bar')
@@ -64,7 +71,7 @@ describe('FormSpy', () => {
expect(render.mock.calls[3][0].valid).toBe(true)
expect(render.mock.calls[3][0].validating).toBe(false)
expect(render.mock.calls[3][0].values).toEqual({ foo: 'bar' })
- expect(renderInput).toHaveBeenCalledTimes(4)
+ expect(renderInput).toHaveBeenCalledTimes(3)
})
it('should resubscribe if subscription changes', () => {
@@ -150,39 +157,38 @@ describe('FormSpy', () => {
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- hasFormApi(render.mock.calls[1][0])
- expect(render.mock.calls[1][0].dirty).toBe(false)
- expect(render.mock.calls[1][0].errors).toBeUndefined()
- expect(render.mock.calls[1][0].invalid).toBeUndefined()
- expect(render.mock.calls[1][0].pristine).toBeUndefined()
- expect(render.mock.calls[1][0].submitFailed).toBeUndefined()
- expect(render.mock.calls[1][0].submitSucceeded).toBeUndefined()
- expect(render.mock.calls[1][0].submitting).toBeUndefined()
- expect(render.mock.calls[1][0].valid).toBeUndefined()
- expect(render.mock.calls[1][0].validating).toBeUndefined()
- expect(render.mock.calls[1][0].values).toEqual({})
+ expect(render).toHaveBeenCalledTimes(1)
+ hasFormApi(render.mock.calls[0][0])
+ expect(render.mock.calls[0][0].dirty).toBe(false)
+ expect(render.mock.calls[0][0].errors).toBeUndefined()
+ expect(render.mock.calls[0][0].invalid).toBeUndefined()
+ expect(render.mock.calls[0][0].pristine).toBeUndefined()
+ expect(render.mock.calls[0][0].submitFailed).toBeUndefined()
+ expect(render.mock.calls[0][0].submitSucceeded).toBeUndefined()
+ expect(render.mock.calls[0][0].submitting).toBeUndefined()
+ expect(render.mock.calls[0][0].valid).toBeUndefined()
+ expect(render.mock.calls[0][0].validating).toBeUndefined()
+ expect(render.mock.calls[0][0].values).toEqual({})
expect(renderInput).toHaveBeenCalled()
- expect(renderInput).toHaveBeenCalledTimes(2)
+ expect(renderInput).toHaveBeenCalledTimes(1)
// change value
renderInput.mock.calls[0][0].input.onChange('bar')
// once because whole form rerendered, and again because state changed
- expect(render).toHaveBeenCalledTimes(4)
- hasFormApi(render.mock.calls[3][0])
- expect(render.mock.calls[3][0].dirty).toBe(true)
- expect(render.mock.calls[3][0].errors).toBeUndefined()
- expect(render.mock.calls[3][0].invalid).toBeUndefined()
- expect(render.mock.calls[3][0].pristine).toBeUndefined()
- expect(render.mock.calls[3][0].submitFailed).toBeUndefined()
- expect(render.mock.calls[3][0].submitSucceeded).toBeUndefined()
- expect(render.mock.calls[3][0].submitting).toBeUndefined()
- expect(render.mock.calls[3][0].valid).toBeUndefined()
- expect(render.mock.calls[3][0].validating).toBeUndefined()
- expect(render.mock.calls[3][0].values).toEqual({ foo: 'bar' })
- expect(renderInput).toHaveBeenCalledTimes(4)
+ expect(render).toHaveBeenCalledTimes(3)
+ hasFormApi(render.mock.calls[2][0])
+ expect(render.mock.calls[2][0].dirty).toBe(true)
+ expect(render.mock.calls[2][0].errors).toBeUndefined()
+ expect(render.mock.calls[2][0].invalid).toBeUndefined()
+ expect(render.mock.calls[2][0].pristine).toBeUndefined()
+ expect(render.mock.calls[2][0].submitFailed).toBeUndefined()
+ expect(render.mock.calls[2][0].submitSucceeded).toBeUndefined()
+ expect(render.mock.calls[2][0].submitting).toBeUndefined()
+ expect(render.mock.calls[2][0].valid).toBeUndefined()
+ expect(render.mock.calls[2][0].validating).toBeUndefined()
+ expect(render.mock.calls[2][0].values).toEqual({ foo: 'bar' })
+ expect(renderInput).toHaveBeenCalledTimes(3)
})
it('should not unsubscribe/resubscribe if not in form', () => {
@@ -206,6 +212,7 @@ describe('FormSpy', () => {
)
}
}
+ const spy = jest.spyOn(global.console, 'error').mockImplementation(() => {})
expect(render).not.toHaveBeenCalled()
const dom = TestUtils.renderIntoDocument()
expect(render).toHaveBeenCalled()
@@ -215,6 +222,12 @@ describe('FormSpy', () => {
TestUtils.Simulate.click(button)
expect(render).toHaveBeenCalledTimes(2)
+ expect(spy).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalledTimes(1)
+ expect(spy).toHaveBeenCalledWith(
+ 'Warning: FormSpy must be used inside of a ReactFinalForm component'
+ )
+ spy.mockRestore()
})
it('should unsubscribe on unmount', () => {
@@ -259,14 +272,14 @@ describe('FormSpy', () => {
)
expect(input).toHaveBeenCalled()
- expect(input).toHaveBeenCalledTimes(2)
+ expect(input).toHaveBeenCalledTimes(1)
expect(onChange).toHaveBeenCalled()
expect(onChange).toHaveBeenCalledTimes(1)
expect(onChange).toHaveBeenCalledWith({ dirty: false })
input.mock.calls[0][0].input.onChange('bar')
- expect(input).toHaveBeenCalledTimes(4)
+ expect(input).toHaveBeenCalledTimes(3)
expect(onChange).toHaveBeenCalledTimes(2)
expect(onChange).toHaveBeenCalledWith({ dirty: true })
})
diff --git a/src/ReactFinalForm.js b/src/ReactFinalForm.js
index 94131ce3..7db309dd 100644
--- a/src/ReactFinalForm.js
+++ b/src/ReactFinalForm.js
@@ -41,6 +41,7 @@ export default class ReactFinalForm extends React.Component {
props: Props
state: State
form: FormApi
+ mounted: boolean
unsubscriptions: Unsubscribe[]
static childContextTypes = {
@@ -52,22 +53,15 @@ export default class ReactFinalForm extends React.Component {
constructor(props: Props) {
super(props)
const {
- children,
- component,
debug,
decorators,
initialValues,
mutators,
onSubmit,
- render,
subscription,
validate,
validateOnBlur
} = props
- warning(
- render || typeof children === 'function' || component,
- 'Must specify either a render prop, a render function as children, or a component prop'
- )
const config: Config = {
debug,
initialValues,
@@ -76,25 +70,19 @@ export default class ReactFinalForm extends React.Component {
validate,
validateOnBlur
}
+ this.mounted = false
try {
this.form = createForm(config)
} catch (e) {
warning(false, e.message)
}
- let initialState
this.unsubscriptions = []
if (this.form) {
- this.unsubscriptions.push(
- this.form.subscribe((state: FormState) => {
- if (initialState) {
- this.notify(state)
- } else {
- initialState = state
- }
- }, subscription || all)
- )
- }
- if (initialState) {
+ // set initial state
+ let initialState: FormState
+ this.form.subscribe((state: FormState) => {
+ initialState = state
+ }, subscription || all)()
this.state = { state: initialState }
}
if (decorators) {
@@ -110,7 +98,11 @@ export default class ReactFinalForm extends React.Component {
}
}
- notify = (state: FormState) => this.setState({ state })
+ notify = (state: FormState) => {
+ if (this.mounted) {
+ this.setState({ state })
+ }
+ }
handleSubmit = (event?: SyntheticEvent) => {
if (event && typeof event.preventDefault === 'function') {
@@ -128,8 +120,12 @@ export default class ReactFinalForm extends React.Component {
componentDidMount() {
if (this.form) {
+ this.unsubscriptions.push(
+ this.form.subscribe(this.notify, this.props.subscription || all)
+ )
this.form.resumeValidation()
}
+ this.mounted = true
}
componentWillReceiveProps(nextProps: Props) {
diff --git a/src/ReactFinalForm.test.js b/src/ReactFinalForm.test.js
index c11de6eb..2a85e87d 100644
--- a/src/ReactFinalForm.test.js
+++ b/src/ReactFinalForm.test.js
@@ -1,4 +1,5 @@
import React from 'react'
+import ReactDOMServer from 'react-dom/server'
import TestUtils from 'react-dom/test-utils'
import Form from './ReactFinalForm'
import Field from './Field'
@@ -26,15 +27,27 @@ describe('ReactFinalForm', () => {
})
it('should print a warning with no render or children specified', () => {
+ const spy = jest.spyOn(global.console, 'error').mockImplementation(() => {})
TestUtils.renderIntoDocument()
+ expect(spy).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalledTimes(1)
+ expect(spy).toHaveBeenCalledWith(
+ 'Warning: Must specify either a render prop, a render function as children, or a component prop to ReactFinalForm'
+ )
+ spy.mockRestore()
})
it('should print a warning with no onSubmit specified', () => {
+ const spy = jest.spyOn(global.console, 'error').mockImplementation(() => {})
const render = jest.fn(() => )
expect(render).not.toHaveBeenCalled()
TestUtils.renderIntoDocument()
expect(render).toHaveBeenCalled()
expect(render).toHaveBeenCalledTimes(1)
+ expect(spy).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalledTimes(1)
+ expect(spy).toHaveBeenCalledWith('Warning: No onSubmit function specified')
+ spy.mockRestore()
})
it('should allow render to be a component', () => {
@@ -91,18 +104,17 @@ describe('ReactFinalForm', () => {
)
expect(render).toHaveBeenCalled()
- // called twice due to field registration adding touched and visited values
- expect(render).toHaveBeenCalledTimes(2)
- expect(render.mock.calls[1][0].dirty).toEqual(false)
- expect(typeof render.mock.calls[1][0].handleSubmit).toBe('function')
- expect(render.mock.calls[1][0].invalid).toEqual(false)
- expect(render.mock.calls[1][0].pristine).toEqual(true)
- expect(render.mock.calls[1][0].submitFailed).toEqual(false)
- expect(render.mock.calls[1][0].submitSucceeded).toEqual(false)
- expect(render.mock.calls[1][0].submitting).toEqual(false)
- expect(render.mock.calls[1][0].valid).toEqual(true)
- expect(render.mock.calls[1][0].validating).toEqual(false)
- expect(render.mock.calls[1][0].values).toEqual({})
+ expect(render).toHaveBeenCalledTimes(1)
+ expect(render.mock.calls[0][0].dirty).toEqual(false)
+ expect(typeof render.mock.calls[0][0].handleSubmit).toBe('function')
+ expect(render.mock.calls[0][0].invalid).toEqual(false)
+ expect(render.mock.calls[0][0].pristine).toEqual(true)
+ expect(render.mock.calls[0][0].submitFailed).toEqual(false)
+ expect(render.mock.calls[0][0].submitSucceeded).toEqual(false)
+ expect(render.mock.calls[0][0].submitting).toEqual(false)
+ expect(render.mock.calls[0][0].valid).toEqual(true)
+ expect(render.mock.calls[0][0].validating).toEqual(false)
+ expect(render.mock.calls[0][0].values).toEqual({})
})
it('should render with a field with a limited subscription', () => {
@@ -377,4 +389,19 @@ describe('ReactFinalForm', () => {
expect(unsubscribe).toHaveBeenCalled()
})
+
+ it('should work with server-side rendering', () => {
+ const spy = jest.spyOn(global.console, 'error')
+ ReactDOMServer.renderToString(
+
+ )}
+ />
+ )
+ expect(spy).not.toHaveBeenCalled()
+ })
})