diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 0000000..57494f4
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,6 @@
+const config = require('kcd-scripts/jest')
+
+module.exports = {
+ ...config,
+ testEnvironment: 'jsdom',
+}
diff --git a/package.json b/package.json
index 58af3eb..eb044c0 100644
--- a/package.json
+++ b/package.json
@@ -51,7 +51,7 @@
"devDependencies": {
"@testing-library/jest-dom": "^4.1.0",
"angular": "^1.7.8",
- "angular-mock": "^1.0.0",
+ "angular-mocks": "^1.7.8",
"cross-env": "^6.0.0",
"kcd-scripts": "^1.7.0",
"npm-run-all": "^4.1.5",
@@ -59,7 +59,7 @@
},
"peerDependencies": {
"angular": "*",
- "angular-mock": "*"
+ "angular-mocks": "*"
},
"eslintConfig": {
"extends": "./node_modules/kcd-scripts/eslint.js",
diff --git a/src/__tests__/__snapshots__/render.js.snap b/src/__tests__/__snapshots__/render.js.snap
index eaf4144..2c6dc42 100644
--- a/src/__tests__/__snapshots__/render.js.snap
+++ b/src/__tests__/__snapshots__/render.js.snap
@@ -2,11 +2,22 @@
exports[`supports fragments 1`] = `
-
-
- DocumentFragment
-
- is pretty cool!
-
+
+
+
+
+
+
+
+ DocumentFragment
+
+ is pretty cool!
+
+
+
+
+
`;
diff --git a/src/__tests__/render.js b/src/__tests__/render.js
index 28d7f9e..b338c7c 100644
--- a/src/__tests__/render.js
+++ b/src/__tests__/render.js
@@ -1,89 +1,31 @@
-import React from 'react'
-import ReactDOM from 'react-dom'
+import angular from 'angular'
+import 'angular-mocks'
import {render} from '../'
-test('renders div into document', () => {
- const ref = React.createRef()
- const {container} = render(
)
- expect(container.firstChild).toBe(ref.current)
+beforeEach(() => {
+ angular.module('atl', [])
+ angular.mock.module('atl')
})
-test('works great with react portals', () => {
- class MyPortal extends React.Component {
- constructor(...args) {
- super(...args)
- this.portalNode = document.createElement('div')
- this.portalNode.dataset.testid = 'my-portal'
- }
- componentDidMount() {
- document.body.appendChild(this.portalNode)
- }
- componentWillUnmount() {
- this.portalNode.parentNode.removeChild(this.portalNode)
- }
- render() {
- return ReactDOM.createPortal(
- ,
- this.portalNode,
- )
- }
- }
-
- function Greet({greeting, subject}) {
- return (
-
-
- {greeting} {subject}
-
-
- )
- }
-
- const {unmount, getByTestId, getByText} = render()
- expect(getByText('Hello World')).toBeInTheDocument()
- const portalNode = getByTestId('my-portal')
- expect(portalNode).toBeInTheDocument()
- unmount()
- expect(portalNode).not.toBeInTheDocument()
+test('renders div into document', () => {
+ const {container} = render(``)
+ expect(container.firstChild.id).toBe('child')
})
test('returns baseElement which defaults to document.body', () => {
- const {baseElement} = render()
+ const {baseElement} = render(``)
expect(baseElement).toBe(document.body)
})
test('supports fragments', () => {
- class Test extends React.Component {
- render() {
- return (
-
- DocumentFragment
is pretty cool!
-
- )
- }
- }
-
- const {asFragment} = render()
- expect(asFragment()).toMatchSnapshot()
-})
-
-test('renders options.wrapper around node', () => {
- const WrapperComponent = ({children}) => (
- {children}
- )
-
- const {container, getByTestId} = render(, {
- wrapper: WrapperComponent,
+ angular.module('atl').component('atlFragment', {
+ template: `
+
+ DocumentFragment
is pretty cool!
+
+ `,
})
- expect(getByTestId('wrapper')).toBeInTheDocument()
- expect(container.firstChild).toMatchInlineSnapshot(`
-
-`)
+ const {asFragment} = render(``)
+ expect(asFragment()).toMatchSnapshot()
})
diff --git a/src/pure.js b/src/pure.js
index 1b1838b..589e20c 100644
--- a/src/pure.js
+++ b/src/pure.js
@@ -1,35 +1,14 @@
-import React from 'react'
-import ReactDOM from 'react-dom'
+import angular from 'angular'
+import 'angular-mocks'
import {
getQueriesForElement,
prettyDOM,
fireEvent as dtlFireEvent,
- configure as configureDTL,
} from '@testing-library/dom'
-import act, {asyncAct} from './act-compat'
-
-configureDTL({
- asyncWrapper: async cb => {
- let result
- await asyncAct(async () => {
- result = await cb()
- })
- return result
- },
-})
const mountedContainers = new Set()
-function render(
- ui,
- {
- container,
- baseElement = container,
- queries,
- hydrate = false,
- wrapper: WrapperComponent,
- } = {},
-) {
+function render(ui, {container, baseElement = container, queries} = {}) {
if (!baseElement) {
// default to document.body instead of documentElement to avoid output of potentially-large
// head elements (such as JSS style blocks) in debug output
@@ -44,18 +23,19 @@ function render(
// they're passing us a custom container or not.
mountedContainers.add(container)
- const wrapUiIfNeeded = innerElement =>
- WrapperComponent
- ? React.createElement(WrapperComponent, null, innerElement)
- : innerElement
+ let $scope
+ angular.mock.inject([
+ '$compile',
+ '$rootScope',
+ ($compile, $rootScope) => {
+ $scope = $rootScope.$new()
- act(() => {
- if (hydrate) {
- ReactDOM.hydrate(wrapUiIfNeeded(ui), container)
- } else {
- ReactDOM.render(wrapUiIfNeeded(ui), container)
- }
- })
+ const element = $compile(ui)($scope)[0]
+ container.appendChild(element)
+
+ $scope.$digest()
+ },
+ ])
return {
container,
@@ -66,12 +46,6 @@ function render(
el.forEach(e => console.log(prettyDOM(e)))
: // eslint-disable-next-line no-console,
console.log(prettyDOM(el)),
- unmount: () => ReactDOM.unmountComponentAtNode(container),
- rerender: rerenderUi => {
- render(wrapUiIfNeeded(rerenderUi), {container, baseElement})
- // Intentionally do not return anything to avoid unnecessarily complicating the API.
- // folks can use all the same utilities we return in the first place that are bound to the container
- },
asFragment: () => {
/* istanbul ignore if (jsdom limitation) */
if (typeof document.createRange === 'function') {
@@ -84,6 +58,7 @@ function render(
template.innerHTML = container.innerHTML
return template.content
},
+ $scope,
...getQueriesForElement(baseElement, queries),
}
}
@@ -95,63 +70,21 @@ function cleanup() {
// maybe one day we'll expose this (perhaps even as a utility returned by render).
// but let's wait until someone asks for it.
function cleanupAtContainer(container) {
- ReactDOM.unmountComponentAtNode(container)
if (container.parentNode === document.body) {
document.body.removeChild(container)
}
mountedContainers.delete(container)
}
-// react-testing-library's version of fireEvent will call
-// dom-testing-library's version of fireEvent wrapped inside
-// an "act" call so that after all event callbacks have been
-// been called, the resulting useEffect callbacks will also
-// be called.
function fireEvent(...args) {
- let returnValue
- act(() => {
- returnValue = dtlFireEvent(...args)
- })
- return returnValue
+ return dtlFireEvent(...args)
}
Object.keys(dtlFireEvent).forEach(key => {
fireEvent[key] = (...args) => {
- let returnValue
- act(() => {
- returnValue = dtlFireEvent[key](...args)
- })
- return returnValue
+ return dtlFireEvent[key](...args)
}
})
-// React event system tracks native mouseOver/mouseOut events for
-// running onMouseEnter/onMouseLeave handlers
-// @link https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/events/EnterLeaveEventPlugin.js#L24-L31
-fireEvent.mouseEnter = fireEvent.mouseOver
-fireEvent.mouseLeave = fireEvent.mouseOut
-
-fireEvent.select = (node, init) => {
- // React tracks this event only on focused inputs
- node.focus()
-
- // React creates this event when one of the following native events happens
- // - contextMenu
- // - mouseUp
- // - dragEnd
- // - keyUp
- // - keyDown
- // so we can use any here
- // @link https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/events/SelectEventPlugin.js#L203-L224
- fireEvent.keyUp(node, init)
-}
-
-// just re-export everything from dom-testing-library
export * from '@testing-library/dom'
-export {render, cleanup, fireEvent, act}
-
-// NOTE: we're not going to export asyncAct because that's our own compatibility
-// thing for people using react-dom@16.8.0. Anyone else doesn't need it and
-// people should just upgrade anyway.
-
-/* eslint func-name-matching:0 */
+export {render, cleanup, fireEvent}