Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[test] Count profiler renders not passive effects #26678

Merged
merged 3 commits into from
Jun 11, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 82 additions & 69 deletions packages/material-ui/src/useMediaQuery/useMediaQuery.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import * as React from 'react';
import PropTypes from 'prop-types';
import { ThemeProvider } from '@material-ui/core/styles';
import useMediaQuery from '@material-ui/core/useMediaQuery';
import { act, createClientRender, createServerRender } from 'test/utils';
import { act, createClientRender, createServerRender, screen, RenderCounter } from 'test/utils';
import mediaQuery from 'css-mediaquery';
import { expect } from 'chai';
import { spy, stub } from 'sinon';
import { stub } from 'sinon';

function createMatchMedia(width, ref) {
const listeners = [];
Expand Down Expand Up @@ -42,24 +42,17 @@ describe('useMediaQuery', () => {
});

const render = createClientRender();
let values;

beforeEach(() => {
values = spy();
});

describe('without feature', () => {
it('should work without window.matchMedia available', () => {
expect(typeof window.matchMedia).to.equal('undefined');
const ref = React.createRef();
const text = () => ref.current.textContent;
const Test = () => {
const matches = useMediaQuery('(min-width:100px)');
return <span ref={ref}>{`${matches}`}</span>;
return <span data-testid="matches">{`${matches}`}</span>;
};

render(<Test />);
expect(text()).to.equal('false');
expect(screen.getByTestId('matches').textContent).to.equal('false');
});
});

Expand Down Expand Up @@ -87,153 +80,175 @@ describe('useMediaQuery', () => {

describe('option: defaultMatches', () => {
it('should be false by default', () => {
const ref = React.createRef();
const text = () => ref.current.textContent;
const getRenderCountRef = React.createRef();
const Test = () => {
const matches = useMediaQuery('(min-width:2000px)');
React.useEffect(() => values(matches));
return <span ref={ref}>{`${matches}`}</span>;
return (
<RenderCounter ref={getRenderCountRef}>
<span data-testid="matches">{`${matches}`}</span>
</RenderCounter>
);
};

render(<Test />);
expect(text()).to.equal('false');
expect(values.callCount).to.equal(1);
expect(screen.getByTestId('matches').textContent).to.equal('false');
expect(getRenderCountRef.current()).to.equal(1);
});

it('should take the option into account', () => {
const ref = React.createRef();
const text = () => ref.current.textContent;
const getRenderCountRef = React.createRef();
const Test = () => {
const matches = useMediaQuery('(min-width:2000px)', {
defaultMatches: true,
});
React.useEffect(() => values(matches));
return <span ref={ref}>{`${matches}`}</span>;
return (
<RenderCounter ref={getRenderCountRef}>
<span data-testid="matches">{`${matches}`}</span>
</RenderCounter>
);
};

render(<Test />);
expect(text()).to.equal('false');
expect(values.callCount).to.equal(2);
expect(screen.getByTestId('matches').textContent).to.equal('false');
expect(getRenderCountRef.current()).to.equal(2);
});
});

describe('option: noSsr', () => {
it('should render once if the default value match the expectation', () => {
const ref = React.createRef();
const text = () => ref.current.textContent;
const getRenderCountRef = React.createRef();
const Test = () => {
const matches = useMediaQuery('(min-width:2000px)', {
defaultMatches: false,
});
React.useEffect(() => values(matches));
return <span ref={ref}>{`${matches}`}</span>;

return (
<RenderCounter ref={getRenderCountRef}>
<span data-testid="matches">{`${matches}`}</span>
</RenderCounter>
);
};

render(<Test />);
expect(text()).to.equal('false');
expect(values.callCount).to.equal(1);
expect(screen.getByTestId('matches').textContent).to.equal('false');
expect(getRenderCountRef.current()).to.equal(1);
});

it('should render twice if the default value does not match the expectation', () => {
const ref = React.createRef();
const text = () => ref.current.textContent;
const getRenderCountRef = React.createRef();
const Test = () => {
const matches = useMediaQuery('(min-width:2000px)', {
defaultMatches: true,
});
React.useEffect(() => values(matches));
return <span ref={ref}>{`${matches}`}</span>;

return (
<RenderCounter ref={getRenderCountRef}>
<span data-testid="matches">{`${matches}`}</span>
</RenderCounter>
);
};

render(<Test />);
expect(text()).to.equal('false');
expect(values.callCount).to.equal(2);
expect(screen.getByTestId('matches').textContent).to.equal('false');
expect(getRenderCountRef.current()).to.equal(2);
});

it('should render once if the default value does not match the expectation', () => {
const ref = React.createRef();
const text = () => ref.current.textContent;
const getRenderCountRef = React.createRef();
const Test = () => {
const matches = useMediaQuery('(min-width:2000px)', {
defaultMatches: true,
noSsr: true,
});
React.useEffect(() => values(matches));
return <span ref={ref}>{`${matches}`}</span>;

return (
<RenderCounter ref={getRenderCountRef}>
<span data-testid="matches">{`${matches}`}</span>
</RenderCounter>
);
};

render(<Test />);
expect(text()).to.equal('false');
expect(values.callCount).to.equal(1);
expect(screen.getByTestId('matches').textContent).to.equal('false');
expect(getRenderCountRef.current()).to.equal(1);
});
});

it('should try to reconcile each time', () => {
const ref = React.createRef();
const text = () => ref.current.textContent;
const getRenderCountRef = React.createRef();
const Test = () => {
const matches = useMediaQuery('(min-width:2000px)', {
defaultMatches: true,
});
React.useEffect(() => values(matches));
return <span ref={ref}>{`${matches}`}</span>;

return (
<RenderCounter ref={getRenderCountRef}>
<span data-testid="matches">{`${matches}`}</span>
</RenderCounter>
);
};

const { unmount } = render(<Test />);
expect(text()).to.equal('false');
expect(values.callCount).to.equal(2);
expect(screen.getByTestId('matches').textContent).to.equal('false');
expect(getRenderCountRef.current()).to.equal(2);

unmount();

render(<Test />);
expect(text()).to.equal('false');
expect(values.callCount).to.equal(4);
expect(screen.getByTestId('matches').textContent).to.equal('false');
expect(getRenderCountRef.current()).to.equal(2);
});

it('should be able to change the query dynamically', () => {
const ref = React.createRef();
const text = () => ref.current.textContent;
const getRenderCountRef = React.createRef();
const Test = (props) => {
const matches = useMediaQuery(props.query, {
defaultMatches: true,
});
React.useEffect(() => values(matches));
return <span ref={ref}>{`${matches}`}</span>;

return (
<RenderCounter ref={getRenderCountRef}>
<span data-testid="matches">{`${matches}`}</span>
</RenderCounter>
);
};
Test.propTypes = {
query: PropTypes.string.isRequired,
};

const { setProps } = render(<Test query="(min-width:2000px)" />);
expect(text()).to.equal('false');
expect(values.callCount).to.equal(2);
expect(screen.getByTestId('matches').textContent).to.equal('false');
expect(getRenderCountRef.current()).to.equal(2);
setProps({ query: '(min-width:100px)' });
expect(text()).to.equal('true');
expect(values.callCount).to.equal(4);
expect(screen.getByTestId('matches').textContent).to.equal('true');
expect(getRenderCountRef.current()).to.equal(4);
});

it('should observe the media query', () => {
const ref = React.createRef();
const text = () => ref.current.textContent;
const getRenderCountRef = React.createRef();
const Test = (props) => {
const matches = useMediaQuery(props.query);
React.useEffect(() => values(matches));
return <span ref={ref}>{`${matches}`}</span>;

return (
<RenderCounter ref={getRenderCountRef}>
<span data-testid="matches">{`${matches}`}</span>
</RenderCounter>
);
};
Test.propTypes = {
query: PropTypes.string.isRequired,
};

render(<Test query="(min-width:2000px)" />);
expect(values.callCount).to.equal(1);
expect(text()).to.equal('false');
expect(getRenderCountRef.current()).to.equal(1);
expect(screen.getByTestId('matches').textContent).to.equal('false');

act(() => {
matchMediaInstances[0].instance.matches = true;
matchMediaInstances[0].listeners[0]();
});
expect(text()).to.equal('true');
expect(values.callCount).to.equal(2);
expect(screen.getByTestId('matches').textContent).to.equal('true');
expect(getRenderCountRef.current()).to.equal(2);
});
});

Expand All @@ -243,11 +258,10 @@ describe('useMediaQuery', () => {
it('should use the ssr match media ponyfill', () => {
let markup;
expect(() => {
const ref = React.createRef();
function MyComponent() {
const matches = useMediaQuery('(min-width:2000px)');
values(matches);
return <span ref={ref}>{`${matches}`}</span>;

return <span>{`${matches}`}</span>;
}

const Test = () => {
Expand All @@ -270,7 +284,6 @@ describe('useMediaQuery', () => {
}).toErrorDev(['Warning: useLayoutEffect does nothing on the server']);

expect(markup.text()).to.equal('true');
expect(values.callCount).to.equal(1);
});
});

Expand Down
Loading