diff --git a/.circleci/config.yml b/.circleci/config.yml index 8a7522064b9485..f3ae30d7483584 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,7 @@ commands: command: | node scripts/use-react-dist-tag # log a patch for maintainers who want to check out this change - git diff HEAD + git --no-pager diff HEAD - restore_cache: keys: - v2-yarn-sha-{{ checksum "yarn.lock" }} @@ -152,7 +152,7 @@ jobs: command: | node scripts/use-typescript-dist-tag # log a patch for maintainers who want to check out this change - git diff HEAD + git --no-pager diff HEAD - install_js - run: name: Tests TypeScript definitions diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js index 09d0fe20703753..cbdbffcb5364d3 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.test.js @@ -67,7 +67,9 @@ describe('ThemeProvider', () => { const text = () => ref.current.textContent; function Test() { const theme = useTheme(); - themes.push(theme); + React.useEffect(() => { + themes.push(theme); + }); return ( diff --git a/packages/material-ui/src/FormControl/FormControl.test.js b/packages/material-ui/src/FormControl/FormControl.test.js index cd734bdc08aa10..d40afa9c5dbb3e 100644 --- a/packages/material-ui/src/FormControl/FormControl.test.js +++ b/packages/material-ui/src/FormControl/FormControl.test.js @@ -3,7 +3,7 @@ import { expect } from 'chai'; import { spy } from 'sinon'; import { createMount, getClasses } from '@material-ui/core/test-utils'; import describeConformance from '../test-utils/describeConformance'; -import { createClientRender } from 'test/utils/createClientRender'; +import { act, createClientRender } from 'test/utils/createClientRender'; import Input from '../Input'; import Select from '../Select'; import FormControl from './FormControl'; @@ -16,7 +16,9 @@ describe('', () => { function TestComponent(props) { const context = useFormControl(); - props.contextCallback(context); + React.useEffect(() => { + props.contextCallback(context); + }); return null; } @@ -101,7 +103,9 @@ describe('', () => { ); expect(readContext.args[0][0]).to.have.property('focused', false); - container.querySelector('input').focus(); + act(() => { + container.querySelector('input').focus(); + }); expect(readContext.args[1][0]).to.have.property('focused', true); setProps({ disabled: true }); diff --git a/packages/material-ui/src/Paper/Paper.js b/packages/material-ui/src/Paper/Paper.js index 99b78c1bbb792d..6c249a4742d532 100644 --- a/packages/material-ui/src/Paper/Paper.js +++ b/packages/material-ui/src/Paper/Paper.js @@ -1,6 +1,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; +import { chainPropTypes } from '@material-ui/utils'; import withStyles from '../styles/withStyles'; export const styles = (theme) => { @@ -41,12 +42,6 @@ const Paper = React.forwardRef(function Paper(props, ref) { ...other } = props; - if (process.env.NODE_ENV !== 'production') { - if (classes[`elevation${elevation}`] === undefined) { - console.error(`Material-UI: this elevation \`${elevation}\` is not implemented.`); - } - } - return ( { + const { classes, elevation } = props; + // in case `withStyles` fails to inject we don't need this warning + if (classes === undefined) { + return null; + } + if (elevation != null && classes[`elevation${elevation}`] === undefined) { + return new Error(`Material-UI: this elevation \`${elevation}\` is not implemented.`); + } + return null; + }), /** * If `true`, rounded corners are disabled. */ diff --git a/packages/material-ui/src/Paper/Paper.test.js b/packages/material-ui/src/Paper/Paper.test.js index c7d511eab567c4..82314ecbd426a1 100644 --- a/packages/material-ui/src/Paper/Paper.test.js +++ b/packages/material-ui/src/Paper/Paper.test.js @@ -1,6 +1,7 @@ import * as React from 'react'; import { assert } from 'chai'; import { createMount, createShallow, getClasses } from '@material-ui/core/test-utils'; +import * as PropTypes from 'prop-types'; import describeConformance from '../test-utils/describeConformance'; import Paper from './Paper'; import { createMuiTheme, ThemeProvider } from '../styles'; @@ -11,14 +12,6 @@ describe('', () => { let shallow; let classes; - beforeEach(() => { - consoleErrorMock.spy(); - }); - - afterEach(() => { - consoleErrorMock.reset(); - }); - before(() => { mount = createMount({ strict: true }); shallow = createShallow({ dive: true }); @@ -77,16 +70,6 @@ describe('', () => { ); }); - it('warns if the given `elevation` is not implemented in the theme', () => { - mount(); - - assert.strictEqual(consoleErrorMock.callCount(), 1); - assert.include( - consoleErrorMock.messages()[0], - 'Material-UI: this elevation `25` is not implemented.', - ); - }); - it('allows custom elevations via theme.shadows', () => { const theme = createMuiTheme(); theme.shadows.push('20px 20px'); @@ -98,4 +81,30 @@ describe('', () => { assert.strictEqual(wrapper.find('div[data-testid="paper"]').hasClass('custom-elevation'), true); }); + + describe('warnings', () => { + beforeEach(() => { + consoleErrorMock.spy(); + PropTypes.resetWarningCache(); + }); + + afterEach(() => { + consoleErrorMock.reset(); + }); + + it('warns if the given `elevation` is not implemented in the theme', () => { + PropTypes.checkPropTypes( + Paper.Naked.propTypes, + { classes: { elevation24: 'elevation-24', elevation26: 'elevation-26' }, elevation: 25 }, + 'prop', + 'MockedPaper', + ); + + assert.strictEqual(consoleErrorMock.callCount(), 1); + assert.include( + consoleErrorMock.messages()[0], + 'Material-UI: this elevation `25` is not implemented.', + ); + }); + }); }); diff --git a/packages/material-ui/src/Popover/Popover.test.js b/packages/material-ui/src/Popover/Popover.test.js index 644c8476333312..8e7651c3402a81 100644 --- a/packages/material-ui/src/Popover/Popover.test.js +++ b/packages/material-ui/src/Popover/Popover.test.js @@ -2,6 +2,7 @@ import * as React from 'react'; import { assert, expect } from 'chai'; import { spy, stub, useFakeTimers } from 'sinon'; import { createMount, findOutermostIntrinsic, getClasses } from '@material-ui/core/test-utils'; +import * as PropTypes from 'prop-types'; import describeConformance from '../test-utils/describeConformance'; import consoleErrorMock from 'test/utils/consoleErrorMock'; import Grow from '../Grow'; @@ -460,6 +461,7 @@ describe('', () => { describe('warnings', () => { beforeEach(() => { consoleErrorMock.spy(); + PropTypes.resetWarningCache(); }); afterEach(() => { @@ -467,18 +469,29 @@ describe('', () => { }); it('should warn if anchorEl is not valid', () => { - const otherWrapper = mount(); - assert.strictEqual(otherWrapper.find(Modal).props().container, undefined); + PropTypes.checkPropTypes( + Popover.Naked.propTypes, + { classes: {}, open: true }, + 'prop', + 'MockedPopover', + ); + assert.strictEqual(consoleErrorMock.callCount(), 1); assert.include(consoleErrorMock.messages()[0], 'It should be an Element instance'); }); it('warns if a component for the Paper is used that cant hold a ref', () => { - mount(
, elevation: 4 }} />); + PropTypes.checkPropTypes( + Popover.Naked.propTypes, + { ...defaultProps, classes: {}, PaperProps: { component: () =>
, elevation: 4 } }, + 'prop', + 'MockedPopover', + ); + assert.strictEqual(consoleErrorMock.callCount(), 1); assert.include( consoleErrorMock.messages()[0], - 'Warning: Failed prop type: Invalid prop `PaperProps.component` supplied to `ForwardRef(Popover)`. Expected an element type that can hold a ref.', + 'Warning: Failed prop type: Invalid prop `PaperProps.component` supplied to `MockedPopover`. Expected an element type that can hold a ref.', ); }); diff --git a/scripts/use-react-dist-tag.js b/scripts/use-react-dist-tag.js index 8525850ce21484..02a261738fd00c 100644 --- a/scripts/use-react-dist-tag.js +++ b/scripts/use-react-dist-tag.js @@ -45,7 +45,10 @@ async function main(distTag) { packageJson.resolutions[reactPackageName] = version; }); - // CircleCI seemingly times out if it has a newline diff at the end + // https://github.com/enzymejs/enzyme/issues/2358 + packageJson.devDependencies['enzyme-adapter-react-16'] = 'npm:@eps1lon/enzyme-adapter-react-next'; + + // add newline for clean diff fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}${os.EOL}`); } diff --git a/scripts/use-typescript-dist-tag.js b/scripts/use-typescript-dist-tag.js index 8656a31d4d1184..68c63509481a0d 100644 --- a/scripts/use-typescript-dist-tag.js +++ b/scripts/use-typescript-dist-tag.js @@ -44,7 +44,7 @@ async function main(distTag) { packageJson.devDependencies.typescript = version; packageJson.resolutions['**/dtslint/typescript'] = version; - // CircleCI seemingly times out if it has a newline diff at the end + // add newline for clean diff fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}${os.EOL}`); }