Skip to content

Commit

Permalink
[test] Add conformance test suite for v5 (#23798)
Browse files Browse the repository at this point in the history
  • Loading branch information
mnajdova authored Dec 2, 2020
1 parent 21b4e26 commit 21c3161
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 12 deletions.
7 changes: 6 additions & 1 deletion docs/pages/api-docs/slider.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ The `MuiSlider` name can be used for providing [default props](/customization/gl

The `ref` is forwarded to the root element.

Any other props supplied will be provided to the root element (native element).
Any other props supplied will be provided to the root element ([SliderUnstyled](/api/slider-unstyled/)).

## CSS

Expand Down Expand Up @@ -90,6 +90,11 @@ You can override the style of the component thanks to one of these customization
- With a [global class name](/guides/interoperability/#global-css).
- With a rule name as part of the component's [`styleOverrides` property](/customization/components/#global-theme-override) in a custom theme.

## Inheritance

The props of the [SliderUnstyled](/api/slider-unstyled/) component are also available.
You can take advantage of this behavior to [target nested components](/guides/api/#spread).

## Demos

- [Slider](/components/slider/)
Expand Down
5 changes: 4 additions & 1 deletion docs/src/modules/utils/parseTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ function findConformanceDescriptor(file: babel.ParseResult): babel.types.ObjectE
CallExpression(babelPath) {
const { node: callExpression } = babelPath;
const { callee } = callExpression;
if (t.isIdentifier(callee) && callee.name === 'describeConformance') {
if (
t.isIdentifier(callee) &&
(callee.name === 'describeConformance' || callee.name === 'describeConformanceV5')
) {
const [, optionsFactory] = callExpression.arguments;
if (
t.isArrowFunctionExpression(optionsFactory) &&
Expand Down
1 change: 1 addition & 0 deletions packages/material-ui/src/Slider/Slider.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const SliderValueLabel: React.FC<SliderValueLabel>;
* API:
*
* - [Slider API](https://material-ui.com/api/slider/)
* - inherits [SliderUnstyled API](https://material-ui.com/api/slider-unstyled/)
*/
declare const Slider: ExtendSliderUnstyled<SliderTypeMap>;

Expand Down
8 changes: 4 additions & 4 deletions packages/material-ui/src/Slider/Slider.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as React from 'react';
import PropTypes from 'prop-types';
import { spy, stub } from 'sinon';
import { expect } from 'chai';
import { createMount, describeConformance, act, createClientRender, fireEvent } from 'test/utils';
import { createMount, describeConformanceV5, act, createClientRender, fireEvent } from 'test/utils';
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import { SliderUnstyled } from '@material-ui/unstyled';
import clsx from 'clsx';
import Slider, { sliderClasses as classes } from './Slider';

Expand All @@ -30,12 +31,11 @@ describe('<Slider />', () => {
const mount = createMount();
const render = createClientRender();

describeConformance(<Slider value={0} />, () => ({
describeConformanceV5(<Slider value={0} />, () => ({
classes: {},
inheritComponent: 'span',
inheritComponent: SliderUnstyled,
mount,
refInstanceof: window.HTMLSpanElement,
testComponentPropWith: 'span',
}));

it('should call handlers', () => {
Expand Down
12 changes: 6 additions & 6 deletions test/utils/describeConformance.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function testRef(element, mount, onRef = assertDOMNode) {
* @param {object} options
* @param {import('react').ElementType} component
*/
function findRootComponent(wrapper, { component }) {
export function findRootComponent(wrapper, { component }) {
const outermostHostElement = findOutermostIntrinsic(wrapper).getElement();

return wrapper.find(component).filterWhere((componentWrapper) => {
Expand All @@ -57,7 +57,7 @@ function randomStringValue() {
* @param {React.ReactElement} element
* @param {() => ConformanceOptions} getOptions
*/
function testClassName(element, getOptions) {
export function testClassName(element, getOptions) {
it('applies the className to the root component', () => {
const { mount } = getOptions();
const className = randomStringValue();
Expand Down Expand Up @@ -95,7 +95,7 @@ function testComponentProp(element, getOptions) {
* @param {React.ReactElement} element
* @param {() => ConformanceOptions} getOptions
*/
function testPropsSpread(element, getOptions) {
export function testPropsSpread(element, getOptions) {
it(`spreads props to the root component`, () => {
// type def in ConformanceOptions
const { classes, inheritComponent, mount } = getOptions();
Expand All @@ -117,7 +117,7 @@ function testPropsSpread(element, getOptions) {
* @param {React.ReactElement} element
* @param {() => ConformanceOptions} getOptions
*/
function describeRef(element, getOptions) {
export function describeRef(element, getOptions) {
describe('ref', () => {
it(`attaches the ref`, () => {
// type def in ConformanceOptions
Expand All @@ -140,7 +140,7 @@ function describeRef(element, getOptions) {
* @param {React.ReactElement} element
* @param {() => ConformanceOptions} getOptions
*/
function testRootClass(element, getOptions) {
export function testRootClass(element, getOptions) {
it('applies the root class to the root component if it has this class', () => {
const { classes, mount } = getOptions();
if (classes.root == null) {
Expand All @@ -164,7 +164,7 @@ function testRootClass(element, getOptions) {
* This is important for snapshot testing with Jest (even if we don't encourage it).
* @param {React.ReactElement} element
*/
function testReactTestRenderer(element) {
export function testReactTestRenderer(element) {
it('should render without errors in ReactTestRenderer', () => {
ReactTestRenderer.act(() => {
ReactTestRenderer.create(element, {
Expand Down
58 changes: 58 additions & 0 deletions test/utils/describeConformanceV5.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* eslint-env mocha */
import { expect } from 'chai';
import * as React from 'react';
import {
testClassName,
testPropsSpread,
describeRef,
testRootClass,
findRootComponent,
testReactTestRenderer,
} from './describeConformance';

/**
* Material-UI components have a `components` prop that allows rendering a different
* Components from @inheritComponent
* @param {React.ReactElement} element
* @param {() => ConformanceOptions} getOptions
*/
function testComponentsProp(element, getOptions) {
describe('prop: components', () => {
it('can render another root component with the `components` prop', () => {
const { classes, mount, testComponentsRootPropWith: component = 'em' } = getOptions();

const wrapper = mount(React.cloneElement(element, { components: { Root: component } }));

expect(findRootComponent(wrapper, { classes, component }).exists()).to.equal(true);
});
});
}

const fullSuite = {
componentsProp: testComponentsProp,
mergeClassName: testClassName,
propsSpread: testPropsSpread,
refForwarding: describeRef,
rootClass: testRootClass,
reactTestRenderer: testReactTestRenderer,
};

/**
* Tests various aspects of a component that should be equal across Material-UI
* components.
* @param {React.ReactElement} minimalElement - the component with it's minimal required props
* @param {() => ConformanceOptions} getOptions
*/
export default function describeConformanceV5(minimalElement, getOptions) {
const { after: runAfterHook = () => {}, only = Object.keys(fullSuite), skip = [] } = getOptions();
describe('Material-UI component API', () => {
after(runAfterHook);

Object.keys(fullSuite)
.filter((testKey) => only.indexOf(testKey) !== -1 && skip.indexOf(testKey) === -1)
.forEach((testKey) => {
const test = fullSuite[testKey];
test(minimalElement, getOptions);
});
});
}
1 change: 1 addition & 0 deletions test/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './components';
export { default as describeConformance } from './describeConformance';
export { default as describeConformanceV5 } from './describeConformanceV5';
export * from './createClientRender';
export { default as createMount } from './createMount';
export { default as createServerRender } from './createServerRender';
Expand Down

0 comments on commit 21c3161

Please sign in to comment.