-
Notifications
You must be signed in to change notification settings - Fork 245
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: make several API and implementation improvements (#348)
BREAKING CHANGE: Remove `allAtOnce` option in favor of `delay: 0` or `paste` event BREAKING CHANGE: Make `hover` and `unhover` sync BREAKING CHANGE: Remove `toggleSelectedOptions` in favor of `deselectOptions` BREAKING CHANGE: (Potentially...) improve correctness of all APIs (so we fire some additional events and improve general correctness). This may or may not break your usage depending on whether you relied on our in-correctness 😅 BREAKING CHANGE: `type` now *actually* defaults the `delay` to `0`, so it's not necessarily `async` anymore. It's only async if you pass a `delay`.
- Loading branch information
Showing
38 changed files
with
3,595 additions
and
2,125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"rules": { | ||
// everything in this directory is intentionally running in series, not parallel | ||
// because user's cannot fire multiple events at the same time and we need | ||
// all events fired in a predictable order. | ||
"no-await-in-loop": "off" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// this helps us track what the state is before and after an event is fired | ||
// this is needed for determining the snapshot values | ||
const actual = jest.requireActual('@testing-library/dom') | ||
|
||
function getTrackedElementValues(element) { | ||
return { | ||
value: element.value, | ||
checked: element.checked, | ||
selectionStart: element.selectionStart, | ||
selectionEnd: element.selectionEnd, | ||
|
||
// unfortunately, changing a select option doesn't happen within fireEvent | ||
// but rather imperatively via `options.selected = newValue` | ||
// because of this we don't (currently) have a way to track before/after | ||
// in a given fireEvent call. | ||
} | ||
} | ||
|
||
function wrapWithTestData(fn) { | ||
return (element, init) => { | ||
const before = getTrackedElementValues(element) | ||
const testData = {before} | ||
|
||
// put it on the element so the event handler can grab it | ||
element.testData = testData | ||
const result = fn(element, init) | ||
|
||
const after = getTrackedElementValues(element) | ||
Object.assign(testData, {after}) | ||
|
||
// elete the testData for the next event | ||
delete element.testData | ||
return result | ||
} | ||
} | ||
|
||
const mockFireEvent = wrapWithTestData(actual.fireEvent) | ||
|
||
for (const key of Object.keys(actual.fireEvent)) { | ||
if (typeof actual.fireEvent[key] === 'function') { | ||
mockFireEvent[key] = wrapWithTestData(actual.fireEvent[key], key) | ||
} else { | ||
mockFireEvent[key] = actual.fireEvent[key] | ||
} | ||
} | ||
|
||
module.exports = { | ||
...actual, | ||
fireEvent: mockFireEvent, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import {blur} from '../blur' | ||
import {focus} from '../focus' | ||
import {setup} from './helpers/utils' | ||
|
||
test('blur a button', () => { | ||
const {element, getEventSnapshot, clearEventCalls} = setup(`<button />`) | ||
focus(element) | ||
clearEventCalls() | ||
blur(element) | ||
expect(getEventSnapshot()).toMatchInlineSnapshot(` | ||
Events fired on: button | ||
button - blur | ||
button - focusout | ||
`) | ||
expect(element).not.toHaveFocus() | ||
}) | ||
|
||
test('no events fired on an unblurable input', () => { | ||
const {element, getEventSnapshot, clearEventCalls} = setup(`<div />`) | ||
focus(element) | ||
clearEventCalls() | ||
blur(element) | ||
expect(getEventSnapshot()).toMatchInlineSnapshot( | ||
`No events were fired on: div`, | ||
) | ||
expect(element).not.toHaveFocus() | ||
}) | ||
|
||
test('blur with tabindex', () => { | ||
const {element, getEventSnapshot, clearEventCalls} = setup( | ||
`<div tabindex="0" />`, | ||
) | ||
focus(element) | ||
clearEventCalls() | ||
blur(element) | ||
expect(getEventSnapshot()).toMatchInlineSnapshot(` | ||
Events fired on: div | ||
div - blur | ||
div - focusout | ||
`) | ||
expect(element).not.toHaveFocus() | ||
}) | ||
|
||
test('no events fired on a disabled blurable input', () => { | ||
const {element, getEventSnapshot, clearEventCalls} = setup( | ||
`<button disabled />`, | ||
) | ||
focus(element) | ||
clearEventCalls() | ||
blur(element) | ||
expect(getEventSnapshot()).toMatchInlineSnapshot( | ||
`No events were fired on: button`, | ||
) | ||
expect(element).not.toHaveFocus() | ||
}) | ||
|
||
test('no events fired if the element is not focused', () => { | ||
const {element, getEventSnapshot} = setup(`<button />`) | ||
blur(element) | ||
expect(getEventSnapshot()).toMatchInlineSnapshot( | ||
`No events were fired on: button`, | ||
) | ||
expect(element).not.toHaveFocus() | ||
}) |
Oops, something went wrong.