Skip to content

Commit

Permalink
test(ui-react-utils): migrate old React-utils tests
Browse files Browse the repository at this point in the history
Closes: INSTUI-3981
  • Loading branch information
git-nandor committed Feb 19, 2024
1 parent 908bfd6 commit 87318b3
Show file tree
Hide file tree
Showing 14 changed files with 367 additions and 273 deletions.
3 changes: 2 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/ui-react-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"license": "MIT",
"devDependencies": {
"@instructure/ui-babel-preset": "8.53.2",
"@instructure/ui-test-utils": "8.53.2"
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^14.0.0"
},
"dependencies": {
"@babel/runtime": "^7.23.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,21 @@

import React, { Component, ReactNode } from 'react'
import PropTypes from 'prop-types'
import { mount, expect, stub } from '@instructure/ui-test-utils'

import { render } from '@testing-library/react'
import '@testing-library/jest-dom'

import { ComponentIdentifier } from '../ComponentIdentifier'

describe('ComponentIdentifier', async () => {
describe('ComponentIdentifier', () => {
beforeAll(() => {
// Mocking console warnings to prevent test output pollution
jest.spyOn(console, 'warn').mockImplementation(() => {})
})
afterAll(() => {
jest.restoreAllMocks()
})

class Trigger extends ComponentIdentifier<any> {
static displayName = 'Trigger'
}
Expand All @@ -53,46 +64,42 @@ describe('ComponentIdentifier', async () => {
}
}

it('should render only child', async () => {
it('should render only child', () => {
let buttonRef: HTMLButtonElement
await mount(
render(
<App>
<Trigger>
<button ref={(el) => (buttonRef = el!)}>Click Me</button>
</Trigger>
</App>
)

expect(buttonRef!.textContent).to.equal('Click Me')
expect(buttonRef!.textContent).toEqual('Click Me')
})

it('should not error when no children provided', async () => {
let error = false
try {
await mount(
it('should not error when no children provided', () => {
const renderApp = () =>
render(
<App>
<Trigger />
</App>
)
} catch (e) {
error = true
}

expect(error).to.be.false()
expect(renderApp).not.toThrow()
})

it('should pass props', async () => {
it('should pass props', () => {
let buttonRef: HTMLButtonElement | null
const onClick = stub()
await mount(
const onClick = jest.fn()
render(
<App>
<Trigger onClick={onClick}>
<button ref={(el) => (buttonRef = el)}>Click Me</button>
</Trigger>
</App>
)

await buttonRef!.click()
expect(onClick).to.have.been.called()
buttonRef!.click()
expect(onClick).toHaveBeenCalled()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
*/

import React from 'react'
import ReactDOM from 'react-dom'
import ReactTestUtils from 'react-dom/test-utils'

import { expect, mount } from '@instructure/ui-test-utils'
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'

import {
withDeterministicId,
DeterministicIdContextProvider,
Expand All @@ -39,7 +39,11 @@ class TestComponent extends React.Component<
React.PropsWithChildren<WithDeterministicIdProps>
> {
render() {
return <div id={this.props.deterministicId!()}>{this.props.children}</div>
return (
<div data-testid="test-component" id={this.props.deterministicId!()}>
{this.props.children}
</div>
)
}
}

Expand All @@ -53,73 +57,70 @@ class WrapperComponent extends React.Component {
}
}

const uniqueIds = (el: { getDOMNode: () => Element }) => {
const idList = Array.from(el.getDOMNode().children).map((el) => el.id)

const uniqueIds = (el: Element) => {
const idList = Array.from(el.children).map((child) => child.id)
return new Set(idList).size === idList.length
}

describe('DeterministicIdContext', () => {
it('can be found and tested with ReactTestUtils', async () => {
const rootNode = document.createElement('div')
document.body.appendChild(rootNode)
it('can be found and tested with ReactTestUtils', () => {
render(<WrapperComponent />)
const testComponent = screen.getByTestId('test-component')

// eslint-disable-next-line react/no-render-return-value
const rendered = ReactDOM.render(<WrapperComponent />, rootNode)
ReactTestUtils.findRenderedComponentWithType(
rendered as any,
(TestComponent as any).originalType
)
expect(testComponent).toBeInTheDocument()
expect(testComponent.id).toBeDefined()
})

it('should generate unique ids without Provider wrapper', async () => {
const el = await mount(
<div>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
it('should generate unique ids without Provider wrapper', () => {
render(
<div data-testid="test-components">
<TestComponent />
<TestComponent />
<TestComponent />
<TestComponent />
<TestComponent />
</div>
)
const el = screen.getByTestId('test-components')

expect(uniqueIds(el)).to.be.true()
expect(uniqueIds(el)).toBe(true)
})

it('should generate unique ids when components are rendered both out and inside of provider', async () => {
const el = await mount(
<div>
it('should generate unique ids when components are rendered both out and inside of provider', () => {
render(
<div data-testid="test-components">
<DeterministicIdContextProvider>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
<TestComponent />
<TestComponent />
<TestComponent />
</DeterministicIdContextProvider>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
<TestComponent />
<TestComponent />
</div>
)
const el = screen.getByTestId('test-components')

expect(uniqueIds(el)).to.be.true()
expect(uniqueIds(el)).toBe(true)
})

//skipping this test because it will fail either in strictmode or normal mode
it('should generate unique ids with provider only', async () => {
it('should generate unique ids with provider only', () => {
const Wrapper = ({ children }: any) => {
return (
<DeterministicIdContextProvider
instanceCounterMap={generateInstanceCounterMap()}
>
<div id="wrapper">{children}</div>
<div data-testid="wrapper">{children}</div>
</DeterministicIdContextProvider>
)
}
const children = []
for (let i = 0; i < 10; i++) {
children.push(<TestComponent></TestComponent>)
children.push(<TestComponent key={i} />)
}

const el = await mount(<Wrapper>{children}</Wrapper>)
render(<Wrapper>{children}</Wrapper>)
const el = screen.getByTestId('wrapper')

expect(uniqueIds(el)).to.be.true()
expect(uniqueIds(el)).toBe(true)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -24,60 +24,63 @@

import React from 'react'
import PropTypes from 'prop-types'
import { expect, mount } from '@instructure/ui-test-utils'

import { render } from '@testing-library/react'
import '@testing-library/jest-dom'

import { callRenderProp } from '../callRenderProp'

describe('callRenderProp', async () => {
/* eslint-disable mocha/no-synchronous-tests */
describe('callRenderProp', () => {
it('strings', () => {
expect(callRenderProp('foo')).to.equal('foo')
expect(callRenderProp('foo')).toEqual('foo')
})

it('numbers', () => {
expect(callRenderProp(2)).to.equal(2)
expect(callRenderProp(2)).toEqual(2)
})

it('arrays', () => {
const prop = ['foo', 'bar', 'baz']
expect(callRenderProp(prop)).to.deep.equal(prop)
expect(callRenderProp([])).to.deep.equal([])

expect(callRenderProp(prop)).toStrictEqual(prop)
expect(callRenderProp([])).toStrictEqual([])
})

it('booleans', () => {
expect(callRenderProp(false)).to.equal(false)
expect(callRenderProp(false)).toEqual(false)
})

it('JSX literals', () => {
const Foo = () => <div>hello</div>
expect(callRenderProp(<Foo />)).to.deep.equal(<Foo />)
expect(callRenderProp(<Foo />)).toStrictEqual(<Foo />)
})
/* eslint-enable mocha/no-synchronous-tests */

it('React classes', async () => {
it('React classes', () => {
class Foo extends React.Component {
render() {
return <div>hello</div>
}
}

const Result = callRenderProp(Foo)
expect(Result).to.deep.equal(<Foo />)
expect(Result).toStrictEqual(<Foo />)

const subject = await mount(Result)
expect(subject.getDOMNode()).to.exist()
const { getByText } = render(Result)
expect(getByText('hello')).toBeInTheDocument()
})

it('functions', async () => {
it('functions', () => {
const Baz = function () {
return 'some text'
}
const result = callRenderProp(Baz)

const subject = await mount(<div>{result}</div>)
const { getByText } = render(<div>{result}</div>)

expect(subject.getDOMNode()).to.have.text('some text')
expect(getByText('some text')).toBeInTheDocument()
})
it('fat arrow functions', async () => {

it('fat arrow functions', () => {
const Baz = () => 'some text'

// in this test we are trying to test that it works with fat arrow functions,
Expand All @@ -91,23 +94,23 @@ describe('callRenderProp', async () => {

const result = callRenderProp(Baz)

const subject = await mount(<div>{result}</div>)
const { getByText } = render(<div>{result}</div>)

expect(subject.getDOMNode()).to.have.text('some text')
expect(getByText('some text')).toBeInTheDocument()
})

describe('passing props', async () => {
it('should pass props correctly to functions', async () => {
describe('passing props', () => {
it('should pass props correctly to functions', () => {
const someFunc = ({ shape }: { shape: string }) => <div>{shape}</div>

const result = callRenderProp(someFunc, { shape: 'rectangle' })

const subject = await mount(<div>{result}</div>)
const { getByText } = render(<div>{result}</div>)

expect(subject.getDOMNode()).to.have.text('rectangle')
expect(getByText('rectangle')).toBeInTheDocument()
})

it('should pass props correctly to React classes', async () => {
it('should pass props correctly to React classes', () => {
type FooProps = { shape?: string }
class Foo extends React.Component<FooProps> {
static propTypes = {
Expand All @@ -125,9 +128,9 @@ describe('callRenderProp', async () => {

const result = callRenderProp(Foo, { shape: 'rectangle' })

const subject = await mount(<div>{result}</div>)
const { getByText } = render(<div>{result}</div>)

expect(subject.getDOMNode()).to.have.text('rectangle')
expect(getByText('rectangle')).toBeInTheDocument()
})
})
})
Loading

0 comments on commit 87318b3

Please sign in to comment.