parent
1706665619
commit
d7c50a87d1
@ -1,56 +1,74 @@
|
|||||||
import React from 'react'
|
import angular from 'angular'
|
||||||
import {render, fireEvent} from '../'
|
import 'angular-mocks'
|
||||||
|
import {render, fireEvent, wait} from '../'
|
||||||
|
|
||||||
|
class StopWatch {
|
||||||
|
lapse = 0
|
||||||
|
running = false
|
||||||
|
|
||||||
|
constructor($interval) {
|
||||||
|
this.$interval = $interval
|
||||||
|
}
|
||||||
|
|
||||||
class StopWatch extends React.Component {
|
|
||||||
state = {lapse: 0, running: false}
|
|
||||||
handleRunClick = () => {
|
handleRunClick = () => {
|
||||||
this.setState(state => {
|
if (this.running) {
|
||||||
if (state.running) {
|
|
||||||
clearInterval(this.timer)
|
clearInterval(this.timer)
|
||||||
} else {
|
} else {
|
||||||
const startTime = Date.now() - this.state.lapse
|
const startTime = Date.now() - this.lapse
|
||||||
this.timer = setInterval(() => {
|
this.timer = this.$interval(() => {
|
||||||
this.setState({lapse: Date.now() - startTime})
|
this.lapse = Date.now() - startTime
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return {running: !state.running}
|
this.running = !this.running
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClearClick = () => {
|
handleClearClick = () => {
|
||||||
clearInterval(this.timer)
|
this.$interval.cancel(this.timer)
|
||||||
this.setState({lapse: 0, running: false})
|
this.lapse = 0
|
||||||
|
this.running = false
|
||||||
}
|
}
|
||||||
componentWillUnmount() {
|
|
||||||
clearInterval(this.timer)
|
$onDestroy() {
|
||||||
|
this.$interval.cancel(this.timer)
|
||||||
}
|
}
|
||||||
render() {
|
}
|
||||||
const {lapse, running} = this.state
|
|
||||||
return (
|
const template = `
|
||||||
<div>
|
<div>
|
||||||
<span>{lapse}ms</span>
|
<span data-testid="elapsed">{{$ctrl.lapse}}ms</span>
|
||||||
<button onClick={this.handleRunClick}>
|
<button ng-click="$ctrl.handleRunClick()">
|
||||||
{running ? 'Stop' : 'Start'}
|
{{$ctrl.running ? 'Stop' : 'Start'}}
|
||||||
</button>
|
</button>
|
||||||
<button onClick={this.handleClearClick}>Clear</button>
|
<button ng-click="$ctrl.handleClearClick()">Clear</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
`
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const wait = time => new Promise(resolve => setTimeout(resolve, time))
|
beforeEach(() => {
|
||||||
|
angular.module('atl', [])
|
||||||
|
angular.mock.module('atl')
|
||||||
|
angular.module('atl').component('atlStopwatch', {
|
||||||
|
template,
|
||||||
|
controller: StopWatch,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test('unmounts a component', async () => {
|
test('unmounts a component', async () => {
|
||||||
jest.spyOn(console, 'error').mockImplementation(() => {})
|
const {$scope, unmount, getByText, getByTestId} = render(
|
||||||
const {unmount, getByText, container} = render(<StopWatch />)
|
`<atl-stopwatch></atl-stopwatch>`,
|
||||||
|
)
|
||||||
|
const elapsedTime = getByTestId('elapsed')
|
||||||
|
|
||||||
|
expect(elapsedTime).toHaveTextContent('0ms')
|
||||||
|
|
||||||
fireEvent.click(getByText('Start'))
|
fireEvent.click(getByText('Start'))
|
||||||
|
// Ensure it starts
|
||||||
|
getByText('Stop')
|
||||||
|
|
||||||
|
await wait()
|
||||||
|
|
||||||
|
expect(elapsedTime.textContent).not.toEqual('0ms')
|
||||||
|
|
||||||
unmount()
|
unmount()
|
||||||
// hey there reader! You don't need to have an assertion like this one
|
|
||||||
// this is just me making sure that the unmount function works.
|
expect($scope.$$destroyed).toBe(true)
|
||||||
// You don't need to do this in your apps. Just rely on the fact that this works.
|
|
||||||
expect(container.innerHTML).toBe('')
|
|
||||||
// just wait to see if the interval is cleared or not
|
|
||||||
// if it's not, then we'll call setState on an unmounted component
|
|
||||||
// and get an error.
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
await wait(() => expect(console.error).not.toHaveBeenCalled())
|
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in new issue