Skip to content

Commit

Permalink
add tests for uncontrolled components (React)
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinMalfait committed Jul 29, 2022
1 parent 11c7b76 commit 0fd0493
Show file tree
Hide file tree
Showing 4 changed files with 493 additions and 0 deletions.
128 changes: 128 additions & 0 deletions packages/@headlessui-react/src/components/combobox/combobox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,134 @@ describe('Rendering', () => {
// Verify that the third combobox option is active
assertActiveComboboxOption(options[2])
})

describe('Uncontrolled', () => {
it('should be possible to use in an uncontrolled way', async () => {
let handleSubmission = jest.fn()

render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<Combobox name="assignee">
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="alice">Alice</Combobox.Option>
<Combobox.Option value="bob">Bob</Combobox.Option>
<Combobox.Option value="charlie">Charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
<button id="submit">submit</button>
</form>
)

await click(document.getElementById('submit'))

// No values
expect(handleSubmission).toHaveBeenLastCalledWith({})

// Open combobox
await click(getComboboxButton())

// Choose alice
await click(getComboboxOptions()[0])

// Submit
await click(document.getElementById('submit'))

// Alice should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'alice' })

// Open combobox
await click(getComboboxButton())

// Choose charlie
await click(getComboboxOptions()[2])

// Submit
await click(document.getElementById('submit'))

// Charlie should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'charlie' })
})

it('should be possible to provide a default value', async () => {
let handleSubmission = jest.fn()

render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<Combobox name="assignee" defaultValue="bob">
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="alice">Alice</Combobox.Option>
<Combobox.Option value="bob">Bob</Combobox.Option>
<Combobox.Option value="charlie">Charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
<button id="submit">submit</button>
</form>
)

await click(document.getElementById('submit'))

// Bob is the defaultValue
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'bob' })

// Open combobox
await click(getComboboxButton())

// Choose alice
await click(getComboboxOptions()[0])

// Submit
await click(document.getElementById('submit'))

// Alice should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'alice' })
})

it('should still call the onChange listeners when choosing new values', async () => {
let handleChange = jest.fn()

render(
<Combobox name="assignee" onChange={handleChange}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="alice">Alice</Combobox.Option>
<Combobox.Option value="bob">Bob</Combobox.Option>
<Combobox.Option value="charlie">Charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
)

// Open combobox
await click(getComboboxButton())

// Choose alice
await click(getComboboxOptions()[0])

// Open combobox
await click(getComboboxButton())

// Choose bob
await click(getComboboxOptions()[1])

// Change handler should have been called twice
expect(handleChange).toHaveBeenNthCalledWith(1, 'alice')
expect(handleChange).toHaveBeenNthCalledWith(2, 'bob')
})
})
})

describe('Rendering composition', () => {
Expand Down
125 changes: 125 additions & 0 deletions packages/@headlessui-react/src/components/listbox/listbox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,131 @@ describe('Rendering', () => {
// Verify that the third menu item is active
assertActiveListboxOption(options[2])
})

describe('Uncontrolled', () => {
it('should be possible to use in an uncontrolled way', async () => {
let handleSubmission = jest.fn()

render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<Listbox name="assignee">
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">Alice</Listbox.Option>
<Listbox.Option value="bob">Bob</Listbox.Option>
<Listbox.Option value="charlie">Charlie</Listbox.Option>
</Listbox.Options>
</Listbox>
<button id="submit">submit</button>
</form>
)

await click(document.getElementById('submit'))

// No values
expect(handleSubmission).toHaveBeenLastCalledWith({})

// Open listbox
await click(getListboxButton())

// Choose alice
await click(getListboxOptions()[0])

// Submit
await click(document.getElementById('submit'))

// Alice should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'alice' })

// Open listbox
await click(getListboxButton())

// Choose charlie
await click(getListboxOptions()[2])

// Submit
await click(document.getElementById('submit'))

// Charlie should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'charlie' })
})

it('should be possible to provide a default value', async () => {
let handleSubmission = jest.fn()

render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<Listbox name="assignee" defaultValue="bob">
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">Alice</Listbox.Option>
<Listbox.Option value="bob">Bob</Listbox.Option>
<Listbox.Option value="charlie">Charlie</Listbox.Option>
</Listbox.Options>
</Listbox>
<button id="submit">submit</button>
</form>
)

await click(document.getElementById('submit'))

// Bob is the defaultValue
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'bob' })

// Open listbox
await click(getListboxButton())

// Choose alice
await click(getListboxOptions()[0])

// Submit
await click(document.getElementById('submit'))

// Alice should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'alice' })
})

it('should still call the onChange listeners when choosing new values', async () => {
let handleChange = jest.fn()

render(
<Listbox name="assignee" onChange={handleChange}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">Alice</Listbox.Option>
<Listbox.Option value="bob">Bob</Listbox.Option>
<Listbox.Option value="charlie">Charlie</Listbox.Option>
</Listbox.Options>
</Listbox>
)

// Open listbox
await click(getListboxButton())

// Choose alice
await click(getListboxOptions()[0])

// Open listbox
await click(getListboxButton())

// Choose bob
await click(getListboxOptions()[1])

// Change handler should have been called twice
expect(handleChange).toHaveBeenNthCalledWith(1, 'alice')
expect(handleChange).toHaveBeenNthCalledWith(2, 'bob')
})
})
})

describe('Rendering composition', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,116 @@ describe('Rendering', () => {
})
)
})

describe('Uncontrolled', () => {
it(
'should be possible to use in an uncontrolled way',
suppressConsoleLogs(async () => {
let handleSubmission = jest.fn()

render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<RadioGroup name="assignee">
<RadioGroup.Option value="alice">Alice</RadioGroup.Option>
<RadioGroup.Option value="bob">Bob</RadioGroup.Option>
<RadioGroup.Option value="charlie">Charlie</RadioGroup.Option>
</RadioGroup>
<button id="submit">submit</button>
</form>
)

await click(document.getElementById('submit'))

// No values
expect(handleSubmission).toHaveBeenLastCalledWith({})

// Choose alice
await click(getRadioGroupOptions()[0])

// Submit
await click(document.getElementById('submit'))

// Alice should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'alice' })

// Choose charlie
await click(getRadioGroupOptions()[2])

// Submit
await click(document.getElementById('submit'))

// Charlie should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'charlie' })
})
)

it(
'should be possible to provide a default value',
suppressConsoleLogs(async () => {
let handleSubmission = jest.fn()

render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<RadioGroup name="assignee" defaultValue="bob">
<RadioGroup.Option value="alice">Alice</RadioGroup.Option>
<RadioGroup.Option value="bob">Bob</RadioGroup.Option>
<RadioGroup.Option value="charlie">Charlie</RadioGroup.Option>
</RadioGroup>
<button id="submit">submit</button>
</form>
)

await click(document.getElementById('submit'))

// Bob is the defaultValue
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'bob' })

// Choose alice
await click(getRadioGroupOptions()[0])

// Submit
await click(document.getElementById('submit'))

// Alice should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'alice' })
})
)

it(
'should still call the onChange listeners when choosing new values',
suppressConsoleLogs(async () => {
let handleChange = jest.fn()

render(
<RadioGroup name="assignee" onChange={handleChange}>
<RadioGroup.Option value="alice">Alice</RadioGroup.Option>
<RadioGroup.Option value="bob">Bob</RadioGroup.Option>
<RadioGroup.Option value="charlie">Charlie</RadioGroup.Option>
</RadioGroup>
)

// Choose alice
await click(getRadioGroupOptions()[0])

// Choose bob
await click(getRadioGroupOptions()[1])

// Change handler should have been called twice
expect(handleChange).toHaveBeenNthCalledWith(1, 'alice')
expect(handleChange).toHaveBeenNthCalledWith(2, 'bob')
})
)
})
})

describe('Keyboard interactions', () => {
Expand Down

0 comments on commit 0fd0493

Please sign in to comment.