-
-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[test] Create the conformance test suite for the new API (#187)
- Loading branch information
1 parent
be98149
commit d34fab9
Showing
8 changed files
with
234 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import * as React from 'react'; | ||
import { expect } from 'chai'; | ||
import { type BaseUiConformanceTestsOptions } from '../describeConformance'; | ||
import { throwMissingPropError } from './utils'; | ||
|
||
export function testClassName( | ||
element: React.ReactElement, | ||
getOptions: () => BaseUiConformanceTestsOptions, | ||
) { | ||
describe('prop: className', () => { | ||
const { render } = getOptions(); | ||
|
||
if (!render) { | ||
throwMissingPropError('render'); | ||
} | ||
|
||
it('should apply the className when passed as a string', async () => { | ||
const { container } = await render(React.cloneElement(element, { className: 'test-class' })); | ||
expect(container.firstElementChild?.className).to.contain('test-class'); | ||
}); | ||
}); | ||
} |
51 changes: 51 additions & 0 deletions
51
packages/mui-base/test/conformanceTests/propForwarding.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import * as React from 'react'; | ||
import { expect } from 'chai'; | ||
import { randomStringValue } from '@mui/internal-test-utils'; | ||
import { throwMissingPropError } from './utils'; | ||
import { type BaseUiConformanceTestsOptions } from '../describeConformance'; | ||
|
||
export function testPropForwarding( | ||
element: React.ReactElement, | ||
getOptions: () => BaseUiConformanceTestsOptions, | ||
) { | ||
const { render, testRenderPropWith: Element = 'div' } = getOptions(); | ||
|
||
if (!render) { | ||
throwMissingPropError('render'); | ||
} | ||
|
||
describe('prop forwarding', () => { | ||
it('forwards custom props to the default root element', async () => { | ||
const otherProps = { | ||
lang: 'fr', | ||
'data-foobar': randomStringValue(), | ||
}; | ||
|
||
const { getByTestId } = await render( | ||
React.cloneElement(element, { 'data-testid': 'root', ...otherProps }), | ||
); | ||
|
||
const customRoot = getByTestId('root'); | ||
expect(customRoot).to.have.attribute('lang', otherProps.lang); | ||
expect(customRoot).to.have.attribute('data-foobar', otherProps['data-foobar']); | ||
}); | ||
|
||
it('forwards custom props to the customized root element', async () => { | ||
const otherProps = { | ||
lang: 'fr', | ||
'data-foobar': randomStringValue(), | ||
}; | ||
|
||
const { getByTestId } = await render( | ||
React.cloneElement(element, { | ||
render: (props: any) => <Element {...props} data-testid="custom-root" />, | ||
...otherProps, | ||
}), | ||
); | ||
|
||
const customRoot = getByTestId('custom-root'); | ||
expect(customRoot).to.have.attribute('lang', otherProps.lang); | ||
expect(customRoot).to.have.attribute('data-foobar', otherProps['data-foobar']); | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import * as React from 'react'; | ||
import { expect } from 'chai'; | ||
import { type BaseUiConformanceTestsOptions } from '../describeConformance'; | ||
import { throwMissingPropError } from './utils'; | ||
|
||
async function verifyRef( | ||
element: React.ReactElement, | ||
render: BaseUiConformanceTestsOptions['render'], | ||
onRef: (instance: unknown, element: HTMLElement | null) => void, | ||
) { | ||
if (!render) { | ||
throwMissingPropError('render'); | ||
} | ||
|
||
const ref = React.createRef(); | ||
|
||
const { container } = await render( | ||
<React.Fragment>{React.cloneElement(element, { ref })}</React.Fragment>, | ||
); | ||
|
||
onRef(ref.current, container); | ||
} | ||
|
||
export function testRefForwarding( | ||
element: React.ReactElement, | ||
getOptions: () => BaseUiConformanceTestsOptions, | ||
) { | ||
describe('ref', () => { | ||
it(`attaches the ref`, async () => { | ||
const { render, refInstanceof } = getOptions(); | ||
|
||
await verifyRef(element, render, (instance) => { | ||
expect(instance).to.be.instanceof(refInstanceof); | ||
}); | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import * as React from 'react'; | ||
import { expect } from 'chai'; | ||
import { type BaseUiConformanceTestsOptions } from '../describeConformance'; | ||
import { throwMissingPropError } from './utils'; | ||
|
||
export function testRenderProp( | ||
element: React.ReactElement, | ||
getOptions: () => BaseUiConformanceTestsOptions, | ||
) { | ||
const { render, testRenderPropWith: Element = 'div' } = getOptions(); | ||
|
||
if (!render) { | ||
throwMissingPropError('render'); | ||
} | ||
|
||
const Wrapper = React.forwardRef<any, { children?: React.ReactNode }>( | ||
function Wrapper(props, forwardedRef) { | ||
return ( | ||
<div data-testid="wrapper"> | ||
{/* @ts-ignore */} | ||
<Element ref={forwardedRef} {...props} /> | ||
</div> | ||
); | ||
}, | ||
); | ||
|
||
describe('prop: render', () => { | ||
it('renders a customized root element', async () => { | ||
const { container, getByTestId } = await render( | ||
React.cloneElement(element, { | ||
render: (props: any) => <Wrapper {...props} />, | ||
}), | ||
); | ||
|
||
expect(container.firstElementChild).to.equal(getByTestId('wrapper')); | ||
}); | ||
|
||
it('should pass the ref to the custom component', () => { | ||
let instanceFromRef = null; | ||
|
||
function Test() { | ||
return React.cloneElement(element, { | ||
ref: (el: HTMLElement | null) => { | ||
instanceFromRef = el; | ||
}, | ||
render: (props: {}) => <Wrapper {...props} />, | ||
'data-testid': 'wrapped', | ||
}); | ||
} | ||
|
||
render(<Test />); | ||
expect(instanceFromRef!.tagName).to.equal(Element.toUpperCase()); | ||
expect(instanceFromRef!).to.have.attribute('data-testid', 'wrapped'); | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export function throwMissingPropError(field: string): never { | ||
throw new Error(`missing "${field}" in options | ||
> describeConformance(element, () => options) | ||
`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import * as React from 'react'; | ||
import { | ||
ConformanceOptions, | ||
MuiRenderResult, | ||
RenderOptions, | ||
createDescribe, | ||
testReactTestRenderer, | ||
} from '@mui/internal-test-utils'; | ||
import { testPropForwarding } from './conformanceTests/propForwarding'; | ||
import { testRefForwarding } from './conformanceTests/refForwarding'; | ||
import { testRenderProp } from './conformanceTests/renderProp'; | ||
import { testClassName } from './conformanceTests/className'; | ||
|
||
export interface BaseUiConformanceTestsOptions | ||
extends Omit<Partial<ConformanceOptions>, 'render' | 'mount' | 'skip' | 'classes'> { | ||
render: ( | ||
element: React.ReactElement<any, string | React.JSXElementConstructor<any>>, | ||
options?: RenderOptions | undefined, | ||
) => Promise<MuiRenderResult> | MuiRenderResult; | ||
skip?: (keyof typeof fullSuite)[]; | ||
testRenderPropWith?: keyof JSX.IntrinsicElements; | ||
} | ||
|
||
const fullSuite = { | ||
propsSpread: testPropForwarding, | ||
reactTestRenderer: testReactTestRenderer, | ||
refForwarding: testRefForwarding, | ||
renderProp: testRenderProp, | ||
className: testClassName, | ||
}; | ||
|
||
function describeConformanceFn( | ||
minimalElement: React.ReactElement, | ||
getOptions: () => BaseUiConformanceTestsOptions, | ||
) { | ||
const { after: runAfterHook = () => {}, only = Object.keys(fullSuite), skip = [] } = getOptions(); | ||
|
||
const filteredTests = Object.keys(fullSuite).filter( | ||
(testKey) => | ||
only.indexOf(testKey) !== -1 && skip.indexOf(testKey as keyof typeof fullSuite) === -1, | ||
) as (keyof typeof fullSuite)[]; | ||
|
||
after(runAfterHook); | ||
|
||
filteredTests.forEach((testKey) => { | ||
const test = fullSuite[testKey]; | ||
test(minimalElement, getOptions as any); | ||
}); | ||
} | ||
|
||
const describeConformance = createDescribe('Base UI component API', describeConformanceFn); | ||
|
||
export { describeConformance }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters