~statianzo/angularjs-testing-library

78021a6ab00e5d5bad113ab3001c2889d9dd40f3 — Jason Staten 4 years ago 9257e06
feat: call $destroy on cleanup
3 files changed, 26 insertions(+), 59 deletions(-)

D src/__tests__/act.js
M src/__tests__/cleanup.js
M src/pure.js
D src/__tests__/act.js => src/__tests__/act.js +0 -45
@@ 1,45 0,0 @@
import React from 'react'
import {render, fireEvent} from '../'

test('render calls useEffect immediately', () => {
  const effectCb = jest.fn()
  function MyUselessComponent() {
    React.useEffect(effectCb)
    return null
  }
  render(<MyUselessComponent />)
  expect(effectCb).toHaveBeenCalledTimes(1)
})

test('findByTestId returns the element', async () => {
  const ref = React.createRef()
  const {findByTestId} = render(<div ref={ref} data-testid="foo" />)
  expect(await findByTestId('foo')).toBe(ref.current)
})

test('fireEvent triggers useEffect calls', () => {
  const effectCb = jest.fn()
  function Counter() {
    React.useEffect(effectCb)
    const [count, setCount] = React.useState(0)
    return <button onClick={() => setCount(count + 1)}>{count}</button>
  }
  const {
    container: {firstChild: buttonNode},
  } = render(<Counter />)

  effectCb.mockClear()
  fireEvent.click(buttonNode)
  expect(buttonNode).toHaveTextContent('1')
  expect(effectCb).toHaveBeenCalledTimes(1)
})

test('calls to hydrate will run useEffects', () => {
  const effectCb = jest.fn()
  function MyUselessComponent() {
    React.useEffect(effectCb)
    return null
  }
  render(<MyUselessComponent />, {hydrate: true})
  expect(effectCb).toHaveBeenCalledTimes(1)
})

M src/__tests__/cleanup.js => src/__tests__/cleanup.js +19 -14
@@ 1,28 1,33 @@
import React from 'react'
import angular from 'angular'
import 'angular-mocks'
import {render, cleanup} from '../'

beforeEach(() => {
  angular.module('atl', [])
  angular.mock.module('atl')
})

test('cleans up the document', () => {
  const spy = jest.fn()
  const divId = 'my-div'

  class Test extends React.Component {
    componentWillUnmount() {
      expect(document.getElementById(divId)).toBeInTheDocument()
      spy()
    }
  angular.module('atl').component('atlCleanup', {
    template: `<div id="{{$ctrl.divId}}"></div>`,
    controller: class {
      divId = 'my-div'

    render() {
      return <div id={divId} />
    }
  }
      $onDestroy() {
        expect(document.getElementById(this.divId)).toBeInTheDocument()
        spy()
      }
    },
  })

  render(<Test />)
  render(`<atl-cleanup></atl-cleanup>`)
  cleanup()
  expect(document.body.innerHTML).toBe('')
  expect(spy).toHaveBeenCalledTimes(1)
})

test('cleanup does not error when an element is not a child', () => {
  render(<div />, {container: document.createElement('div')})
  render(`<div></div>`, {container: document.createElement('div')})
  cleanup()
})

M src/pure.js => src/pure.js +7 -0
@@ 7,6 7,7 @@ import {
} from '@testing-library/dom'

const mountedContainers = new Set()
const mountedScopes = new Set()

function render(ui, {container, baseElement = container, queries} = {}) {
  if (!baseElement) {


@@ 29,6 30,7 @@ function render(ui, {container, baseElement = container, queries} = {}) {
    '$rootScope',
    ($compile, $rootScope) => {
      $scope = $rootScope.$new()
      mountedScopes.add($scope)

      const element = $compile(ui)($scope)[0]
      container.appendChild(element)


@@ 64,6 66,7 @@ function render(ui, {container, baseElement = container, queries} = {}) {
}

function cleanup() {
  mountedScopes.forEach(cleanupScope)
  mountedContainers.forEach(cleanupAtContainer)
}



@@ 76,6 79,10 @@ function cleanupAtContainer(container) {
  mountedContainers.delete(container)
}

function cleanupScope(scope) {
  scope.$destroy()
}

function fireEvent(...args) {
  return dtlFireEvent(...args)
}