From 42faf7900a934baf2827d73df6db930004b37019 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 15 Dec 2022 11:02:10 +0100 Subject: [PATCH 1/3] [Material You] Update Button test & add active class name --- .../src/Button/Button.test.js | 296 +++++------------- .../mui-material-next/src/Button/Button.tsx | 9 +- .../src/Button/Button.types.ts | 4 + .../src/Button/buttonClasses.ts | 3 + test/utils/describeConformance.tsx | 36 ++- 5 files changed, 121 insertions(+), 227 deletions(-) diff --git a/packages/mui-material-next/src/Button/Button.test.js b/packages/mui-material-next/src/Button/Button.test.js index fc3b6389b2a16d..01293c53c22bff 100644 --- a/packages/mui-material-next/src/Button/Button.test.js +++ b/packages/mui-material-next/src/Button/Button.test.js @@ -1,54 +1,43 @@ import * as React from 'react'; import { expect } from 'chai'; -import { describeConformance, createRenderer } from 'test/utils'; -import Button, { buttonClasses as classes } from '@mui/material/Button'; -import ButtonBase from '@mui/material/ButtonBase'; +import { describeConformance, createRenderer, fireEvent } from 'test/utils'; +import Button, { buttonClasses as classes } from '@mui/material-next/Button'; +import { CssVarsProvider, extendTheme } from '@mui/material-next/styles'; describe(', () => ({ classes, - inheritComponent: ButtonBase, render, + inheritComponent: 'button', refInstanceof: window.HTMLButtonElement, muiName: 'MuiButton', testDeepOverrides: { slotName: 'startIcon', slotClassName: classes.startIcon }, testVariantProps: { variant: 'contained', fullWidth: true }, testStateOverrides: { prop: 'size', value: 'small', styleKey: 'sizeSmall' }, - skip: ['componentsProp'], + ThemeProvider: CssVarsProvider, + createTheme: extendTheme, + skip: [ + 'componentsProp', + ], })); - it('should render with the root, text, and textPrimary classes but no others', () => { + it('should render with the root, text and colorPrimary classes but no others', () => { const { getByRole } = render(); const button = getByRole('button'); expect(button).to.have.class(classes.root); expect(button).to.have.class(classes.text); - expect(button).to.have.class(classes.textPrimary); - expect(button).not.to.have.class(classes.textSecondary); + expect(button).to.have.class(classes.colorPrimary); + expect(button).not.to.have.class(classes.filled); + expect(button).not.to.have.class(classes.filledTonal); expect(button).not.to.have.class(classes.outlined); - expect(button).not.to.have.class(classes.outlinedPrimary); - expect(button).not.to.have.class(classes.outlinedSecondary); - expect(button).not.to.have.class(classes.contained); - expect(button).not.to.have.class(classes.containedPrimary); - expect(button).not.to.have.class(classes.containedSecondary); - expect(button).not.to.have.class(classes.textSizeSmall); - expect(button).not.to.have.class(classes.textSizeLarge); - expect(button).not.to.have.class(classes.outlinedSizeSmall); - expect(button).not.to.have.class(classes.outlinedSizeLarge); - expect(button).not.to.have.class(classes.containedSizeSmall); - expect(button).not.to.have.class(classes.containedSizeLarge); - }); - - it('can render a text primary button', () => { - const { getByRole } = render(); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).not.to.have.class(classes.contained); - expect(button).to.have.class(classes.textPrimary); - expect(button).not.to.have.class(classes.textSecondary); + expect(button).not.to.have.class(classes.elevated); + expect(button).not.to.have.class(classes.colorSecondary); + expect(button).not.to.have.class(classes.colorTertiary); + expect(button).not.to.have.class(classes.sizeSmall); + expect(button).not.to.have.class(classes.sizeLarge); }); it('should render a text secondary button', () => { @@ -56,208 +45,66 @@ describe('); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).to.have.class(classes.outlined); - expect(button).not.to.have.class(classes.contained); - expect(button).not.to.have.class(classes.text); - }); - - it('should render a primary outlined button', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).to.have.class(classes.outlined); - expect(button).to.have.class(classes.outlinedPrimary); - expect(button).not.to.have.class(classes.text); - expect(button).not.to.have.class(classes.textPrimary); - expect(button).not.to.have.class(classes.contained); - }); - - it('should render a secondary outlined button', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).to.have.class(classes.outlined); - expect(button).to.have.class(classes.outlinedSecondary); - expect(button).not.to.have.class(classes.text); - expect(button).not.to.have.class(classes.textSecondary); - expect(button).not.to.have.class(classes.contained); - }); - - it('should render an inherit outlined button', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).to.have.class(classes.outlined); - expect(button).to.have.class(classes.colorInherit); - expect(button).not.to.have.class(classes.text); - expect(button).not.to.have.class(classes.textSecondary); - expect(button).not.to.have.class(classes.contained); - }); - - it('should render a contained button', () => { - const { getByRole } = render(); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).not.to.have.class(classes.text); - expect(button).not.to.have.class(classes.textPrimary); - expect(button).not.to.have.class(classes.textSecondary); - expect(button).to.have.class(classes.contained); - }); - - it('should render a contained primary button', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).not.to.have.class(classes.text); - expect(button).to.have.class(classes.contained); - expect(button).to.have.class(classes.containedPrimary); - expect(button).not.to.have.class(classes.containedSecondary); - }); - - it('should render a contained secondary button', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).not.to.have.class(classes.text); - expect(button).to.have.class(classes.contained); - expect(button).not.to.have.class(classes.containedPrimary); - expect(button).to.have.class(classes.containedSecondary); - }); + expect(button).to.have.class(classes.text); + expect(button).to.have.class(classes.colorSecondary); + expect(button).not.to.have.class(classes.colorPrimary); + }); + + ['filled', 'filledTonal', 'outlined', 'elevated'].forEach((variant) => { + it(`should render an ${variant} button`, () => { + const { getByRole } = render(); + const button = getByRole('button'); + + expect(button).to.have.class(classes.root); + expect(button).to.have.class(classes[variant]); + expect(button).to.have.class(classes.colorPrimary); + expect(button).not.to.have.class(classes.text); + }); - it('should render a small text button', () => { + // these two variants do not support different colors + if(variant !== 'elevated' && variant !== 'filledTonal') { + it(`should render an ${variant} secondary button`, () => { + const { getByRole } = render(); + const button = getByRole('button'); + + expect(button).to.have.class(classes.root); + expect(button).to.have.class(classes[variant]); + expect(button).to.have.class(classes.colorSecondary); + expect(button).not.to.have.class(classes.text); + expect(button).not.to.have.class(classes.colorPrimary); + }); + + it(`should render an ${variant} tertiary button`, () => { + const { getByRole } = render(); + const button = getByRole('button'); + + expect(button).to.have.class(classes.root); + expect(button).to.have.class(classes[variant]); + expect(button).to.have.class(classes.colorTertiary); + expect(button).not.to.have.class(classes.text); + expect(button).not.to.have.class(classes.colorPrimary); + }); + } + }) + + it('should render a small button', () => { const { getByRole } = render(); const button = getByRole('button'); expect(button).to.have.class(classes.root); - expect(button).to.have.class(classes.text); - expect(button).to.have.class(classes.textSizeSmall); - expect(button).not.to.have.class(classes.textSizeLarge); - expect(button).not.to.have.class(classes.outlinedSizeSmall); - expect(button).not.to.have.class(classes.outlinedSizeLarge); - expect(button).not.to.have.class(classes.containedSizeSmall); - expect(button).not.to.have.class(classes.containedSizeLarge); + expect(button).to.have.class(classes.sizeSmall); + expect(button).not.to.have.class(classes.sizeMedium); + expect(button).not.to.have.class(classes.sizeLarge); }); - it('should render a large text button', () => { + it('should render a large button', () => { const { getByRole } = render(); const button = getByRole('button'); expect(button).to.have.class(classes.root); - expect(button).to.have.class(classes.text); - expect(button).not.to.have.class(classes.textSizeSmall); - expect(button).to.have.class(classes.textSizeLarge); - expect(button).not.to.have.class(classes.outlinedSizeSmall); - expect(button).not.to.have.class(classes.outlinedSizeLarge); - expect(button).not.to.have.class(classes.containedSizeSmall); - expect(button).not.to.have.class(classes.containedSizeLarge); - }); - - it('should render a small outlined button', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).to.have.class(classes.outlined); - expect(button).not.to.have.class(classes.textSizeSmall); - expect(button).not.to.have.class(classes.textSizeLarge); - expect(button).to.have.class(classes.outlinedSizeSmall); - expect(button).not.to.have.class(classes.outlinedSizeLarge); - expect(button).not.to.have.class(classes.containedSizeSmall); - expect(button).not.to.have.class(classes.containedSizeLarge); - }); - - it('should render a large outlined button', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).to.have.class(classes.outlined); - expect(button).not.to.have.class(classes.textSizeSmall); - expect(button).not.to.have.class(classes.textSizeLarge); - expect(button).not.to.have.class(classes.outlinedSizeSmall); - expect(button).to.have.class(classes.outlinedSizeLarge); - expect(button).not.to.have.class(classes.containedSizeSmall); - expect(button).not.to.have.class(classes.containedSizeLarge); - }); - - it('should render a small contained button', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).to.have.class(classes.contained); - expect(button).not.to.have.class(classes.textSizeSmall); - expect(button).not.to.have.class(classes.textSizeLarge); - expect(button).not.to.have.class(classes.outlinedSizeSmall); - expect(button).not.to.have.class(classes.outlinedSizeLarge); - expect(button).to.have.class(classes.containedSizeSmall); - expect(button).not.to.have.class(classes.containedSizeLarge); - }); - - it('should render a large contained button', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - expect(button).to.have.class(classes.root); - expect(button).to.have.class(classes.contained); - expect(button).not.to.have.class(classes.textSizeSmall); - expect(button).not.to.have.class(classes.textSizeLarge); - expect(button).not.to.have.class(classes.outlinedSizeSmall); - expect(button).not.to.have.class(classes.outlinedSizeLarge); - expect(button).not.to.have.class(classes.containedSizeSmall); - expect(button).to.have.class(classes.containedSizeLarge); + expect(button).to.have.class(classes.sizeLarge); + expect(button).not.to.have.class(classes.sizeMedium); + expect(button).not.to.have.class(classes.sizeSmall); }); it('should render a button with startIcon', () => { @@ -317,4 +164,13 @@ describe('); const button = getByRole('button'); - + expect(button).to.have.class(classes.root); expect(button).to.have.class(classes[variant]); expect(button).to.have.class(classes.colorPrimary); @@ -62,11 +60,15 @@ describe('); + const { getByRole } = render( + , + ); const button = getByRole('button'); - + expect(button).to.have.class(classes.root); expect(button).to.have.class(classes[variant]); expect(button).to.have.class(classes.colorSecondary); @@ -75,9 +77,13 @@ describe('); + const { getByRole } = render( + , + ); const button = getByRole('button'); - + expect(button).to.have.class(classes.root); expect(button).to.have.class(classes[variant]); expect(button).to.have.class(classes.colorTertiary); @@ -85,7 +91,7 @@ describe('); diff --git a/test/utils/describeConformance.tsx b/test/utils/describeConformance.tsx index af638d38b5dcdf..10ce83e046653d 100644 --- a/test/utils/describeConformance.tsx +++ b/test/utils/describeConformance.tsx @@ -2,7 +2,10 @@ import * as React from 'react'; import { expect } from 'chai'; import { ReactWrapper } from 'enzyme'; -import { ThemeProvider as MDThemeProvider, createTheme as mdCreateTheme } from '@mui/material/styles'; +import { + ThemeProvider as MDThemeProvider, + createTheme as mdCreateTheme, +} from '@mui/material/styles'; import { unstable_capitalize as capitalize } from '@mui/utils'; import ReactTestRenderer from 'react-test-renderer'; import createMount from './createMount'; @@ -553,7 +556,12 @@ function testThemeDefaultProps(element: React.ReactElement, getOptions: () => Co describe('theme default components:', () => { it("respect theme's defaultProps", () => { const testProp = 'data-id'; - const { muiName, render, ThemeProvider = MDThemeProvider, createTheme = mdCreateTheme } = getOptions(); + const { + muiName, + render, + ThemeProvider = MDThemeProvider, + createTheme = mdCreateTheme, + } = getOptions(); if (!muiName) { throwMissingPropError('muiName'); @@ -593,7 +601,13 @@ function testThemeStyleOverrides( if (/jsdom/.test(window.navigator.userAgent)) { this.skip(); } - const { muiName, testStateOverrides, render, ThemeProvider = MDThemeProvider, createTheme = mdCreateTheme } = getOptions(); + const { + muiName, + testStateOverrides, + render, + ThemeProvider = MDThemeProvider, + createTheme = mdCreateTheme, + } = getOptions(); if (!testStateOverrides) { return; @@ -820,7 +834,13 @@ function testThemeVariants(element: React.ReactElement, getOptions: () => Confor this.skip(); } - const { muiName, testVariantProps, render, ThemeProvider = MDThemeProvider, createTheme = mdCreateTheme } = getOptions(); + const { + muiName, + testVariantProps, + render, + ThemeProvider = MDThemeProvider, + createTheme = mdCreateTheme, + } = getOptions(); if (!testVariantProps) { throw new Error('missing testVariantProps'); @@ -867,7 +887,13 @@ function testThemeVariants(element: React.ReactElement, getOptions: () => Confor this.skip(); } - const { muiName, testCustomVariant, render, ThemeProvider = MDThemeProvider, createTheme = mdCreateTheme } = getOptions(); + const { + muiName, + testCustomVariant, + render, + ThemeProvider = MDThemeProvider, + createTheme = mdCreateTheme, + } = getOptions(); if (!testCustomVariant) { return; From a651b4f10da35e3a0eb8f14819324f308cac971f Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 15 Dec 2022 15:44:49 +0100 Subject: [PATCH 3/3] proptypes --- packages/mui-material-next/src/Button/Button.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/mui-material-next/src/Button/Button.tsx b/packages/mui-material-next/src/Button/Button.tsx index 5f811cc88a0ef2..7354643003fdef 100644 --- a/packages/mui-material-next/src/Button/Button.tsx +++ b/packages/mui-material-next/src/Button/Button.tsx @@ -576,6 +576,10 @@ Button.propTypes /* remove-proptypes */ = { * The content of the component. */ children: PropTypes.node, + /** + * Override or extend the styles applied to the component. + */ + classes: PropTypes.object, /** * @ignore */