parent
ace9f5bdbf
commit
1706665619
@ -1,39 +1,60 @@
|
||||
import React from 'react'
|
||||
import angular from 'angular'
|
||||
import 'angular-mocks'
|
||||
import {render, wait} from '../'
|
||||
|
||||
const fetchAMessage = () =>
|
||||
new Promise(resolve => {
|
||||
class controller {
|
||||
loading = true
|
||||
data = null
|
||||
|
||||
constructor($q, $timeout) {
|
||||
this.$q = $q
|
||||
this.$timeout = $timeout
|
||||
}
|
||||
|
||||
load() {
|
||||
return this.$q(resolve => {
|
||||
// we are using random timeout here to simulate a real-time example
|
||||
// of an async operation calling a callback at a non-deterministic time
|
||||
const randomTimeout = Math.floor(Math.random() * 100)
|
||||
setTimeout(() => {
|
||||
this.$timeout(() => {
|
||||
resolve({returnedMessage: 'Hello World'})
|
||||
}, randomTimeout)
|
||||
})
|
||||
}
|
||||
|
||||
class ComponentWithLoader extends React.Component {
|
||||
state = {loading: true}
|
||||
async componentDidMount() {
|
||||
const data = await fetchAMessage()
|
||||
this.setState({data, loading: false}) // eslint-disable-line
|
||||
$onInit() {
|
||||
this.load().then(response => {
|
||||
this.loading = false
|
||||
this.data = response
|
||||
})
|
||||
}
|
||||
render() {
|
||||
if (this.state.loading) {
|
||||
return <div>Loading...</div>
|
||||
}
|
||||
return (
|
||||
<div data-testid="message">
|
||||
Loaded this message: {this.state.data.returnedMessage}!
|
||||
|
||||
const template = `
|
||||
<div ng-if="$ctrl.loading">Loading...</div>
|
||||
<div
|
||||
ng-if="!$ctrl.loading"
|
||||
data-testid="message"
|
||||
>
|
||||
Loaded this message: {{$ctrl.data.returnedMessage}}!
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
beforeEach(() => {
|
||||
angular.module('atl', [])
|
||||
angular.mock.module('atl')
|
||||
angular.module('atl').component('atlEnd', {
|
||||
template,
|
||||
controller,
|
||||
})
|
||||
})
|
||||
|
||||
test('it waits for the data to be loaded', async () => {
|
||||
const {queryByText, queryByTestId} = render(<ComponentWithLoader />)
|
||||
const {queryByText, findByTestId} = render(`<atl-end></atl-end>`)
|
||||
|
||||
expect(queryByText('Loading...')).toBeTruthy()
|
||||
|
||||
await wait(() => expect(queryByText('Loading...')).toBeNull())
|
||||
expect(queryByTestId('message').textContent).toMatch(/Hello World/)
|
||||
const message = await findByTestId('message')
|
||||
expect(message.textContent).toMatch(/Hello World/)
|
||||
})
|
||||
|
@ -1,47 +0,0 @@
|
||||
/* istanbul ignore file */
|
||||
// the part of this file that we need tested is definitely being run
|
||||
// and the part that is not cannot easily have useful tests written
|
||||
// anyway. So we're just going to ignore coverage for this file
|
||||
/**
|
||||
* copied from React's enqueueTask.js
|
||||
*/
|
||||
|
||||
let didWarnAboutMessageChannel = false
|
||||
let enqueueTask
|
||||
try {
|
||||
// read require off the module object to get around the bundlers.
|
||||
// we don't want them to detect a require and bundle a Node polyfill.
|
||||
const requireString = `require${Math.random()}`.slice(0, 7)
|
||||
const nodeRequire = module && module[requireString]
|
||||
// assuming we're in node, let's try to get node's
|
||||
// version of setImmediate, bypassing fake timers if any.
|
||||
enqueueTask = nodeRequire('timers').setImmediate
|
||||
} catch (_err) {
|
||||
// we're in a browser
|
||||
// we can't use regular timers because they may still be faked
|
||||
// so we try MessageChannel+postMessage instead
|
||||
enqueueTask = callback => {
|
||||
if (didWarnAboutMessageChannel === false) {
|
||||
didWarnAboutMessageChannel = true
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
typeof MessageChannel !== 'undefined',
|
||||
'This browser does not have a MessageChannel implementation, ' +
|
||||
'so enqueuing tasks via await act(async () => ...) will fail. ' +
|
||||
'Please file an issue at https://github.com/facebook/react/issues ' +
|
||||
'if you encounter this warning.',
|
||||
)
|
||||
}
|
||||
const channel = new MessageChannel()
|
||||
channel.port1.onmessage = callback
|
||||
channel.port2.postMessage(undefined)
|
||||
}
|
||||
}
|
||||
|
||||
export default function flushMicroTasks() {
|
||||
return {
|
||||
then(resolve) {
|
||||
enqueueTask(resolve)
|
||||
},
|
||||
}
|
||||
}
|
Loading…
Reference in new issue