ronantakizawa/codereview-bench huggingface dataset:
Repository: mui/material-ui
File: packages/api-docs-builder/utils/parseTest.ts (TypeScript)

Code before:
import * as babel from '@babel/core';
import { readFile } from 'fs-extra';
import * as path from 'path';
import glob from 'fast-glob';

const workspaceRoot = path.join(__dirname, '../../../');
const babelConfigPath = path.join(workspaceRoot, 'babel.config.js');

function getTestFilesNames(filepath: string) {
  return glob.sync(
    path.join(
      path.dirname(filepath),
      `/{tests/,}{*.,}${path.basename(filepath, path.extname(filepath))}.test.{js,ts,tsx}`,
    ),
    { absolute: true },
  );
}

async function parseWithConfig(filename: string, configFilePath: string) {
  const source = await readFile(filename, { encoding: 'utf8' });
  const partialConfig = babel.loadPartialConfig({
    configFile: configFilePath,
    filename,
  });

  if (partialConfig === null) {
    throw new Error(`Could not load a babel config for ${filename} located at ${configFilePath}.`);
  }

  return babel.parseAsync(source, partialConfig.options);
}

function findConformanceDescriptor(
  file: babel.ParseResult,
): null | { name: string; body: babel.types.ObjectExpression } {
  const { types: t } = babel;

  let descriptor = null;
  babel.traverse(file, {

Review comment (suggestion):
Just the usual ;)

```suggestion
    path
      .join(
        path.dirname(filepath),
        `/{tests/,}{*.,}${path.basename(filepath, path.extname(filepath))}.test.{js,ts,tsx}`,
      )
      .replace(/\\/g, '/'),
```
(https://github.com/mrmlnc/fast-glob#how-to-write-patterns-on-windows)

Code after:
import * as babel from '@babel/core';
import { readFile } from 'fs-extra';
import * as path from 'path';
import glob from 'fast-glob';

const workspaceRoot = path.join(__dirname, '../../../');
const babelConfigPath = path.join(workspaceRoot, 'babel.config.js');

function getTestFilesNames(filepath: string) {
  return glob.sync(
    path
      .join(
        path.dirname(filepath),
        `/{tests/,}{*.,}${path.basename(filepath, path.extname(filepath))}.test.{js,ts,tsx}`,
      )
      .replace(/\\/g, '/'),
    { absolute: true },
  );
}

async function parseWithConfig(filename: string, configFilePath: string) {
  const source = await readFile(filename, { encoding: 'utf8' });
  const partialConfig = babel.loadPartialConfig({
    configFile: configFilePath,
    filename,
  });

  if (partialConfig === null) {
    throw new Error(`Could not load a babel config for ${filename} located at ${configFilePath}.`);
  }

  return babel.parseAsync(source, partialConfig.options);
}

function findConformanceDescriptor(
  file: babel.ParseResult,
): null | { name: string; body: babel.types.ObjectExpression } {
  const { types: t } = babel;
Repository: mui/material-ui
File: packages-internal/test-utils/src/describeConformance.tsx (TypeScript)

Code before:
  throw new Error(`missing "${field}" in options

  > describeConformance(element, () => options)
`);
}

/**
 * MUI components have a `className` prop. The `className` is applied to
 * the root component.
 */
export function testClassName(
  element: React.ReactElement<any>,
  getOptions: () => ConformanceOptions,
) {
  it('applies the className to the root component', () => {
    const { render } = getOptions();

    if (!render) {
      throwMissingPropError('render');
    }

    const className = randomStringValue();
    const testId = randomStringValue();

    const { getByTestId } = render(
      React.cloneElement(element, { className, 'data-testid': testId }),
    );

    expect(getByTestId(testId)).to.have.class(className);
  });
}

/**
 * MUI components have a `component` prop that allows rendering a different
 * Component from @inheritComponent
 */
export function testComponentProp(
  element: React.ReactElement<any>,
  getOptions: () => ConformanceOptions,
) {
  describe('prop: component', () => {
    it('can render another root component with the `component` prop', () => {
      const { render, testComponentPropWith: component = 'em' } = getOptions();
      if (!render) {
        throwMissingPropError('render');
      }

      if (typeof component === 'string') {
        const testId = randomStringValue();

        const { getByTestId } = render(

Review comment (suggestion):
This relies on the component applying `className` in the same component that `data-testid` is applied. This is followed in most components. We have 2 exceptions (Material's Switch and Joy's Tooltip), for which I skipped the test and added an explanation.

Code after:
  throw new Error(`missing "${field}" in options

  > describeConformance(element, () => options)
`);
}

/**
 * MUI components have a `className` prop. The `className` is applied to
 * the root component.
 */
export function testClassName(
  element: React.ReactElement<any>,
  getOptions: () => ConformanceOptions,
) {
  it('applies the className to the root component', () => {
    const { render } = getOptions();

    if (!render) {
      throwMissingPropError('render');
    }

    const className = randomStringValue();
    const testId = randomStringValue();

    const { getByTestId } = render(
      React.cloneElement(element, { className, 'data-testid': testId }),
    );

    expect(getByTestId(testId)).to.have.class(className);
  });
}

/**
 * MUI components have a `component` prop that allows rendering a different
 * Component from @inheritComponent
 */
export function testComponentProp(
  element: React.ReactElement<any>,
  getOptions: () => ConformanceOptions,
) {
  describe('prop: component', () => {
    it('can render another root component with the `component` prop', () => {
      const { render, testComponentPropWith: component = 'em' } = getOptions();
      if (!render) {
        throwMissingPropError('render');
      }

      const testId = randomStringValue();

      if (typeof component === 'string') {
        const { getByTestId } = render(
Repository: mui/material-ui
File: docs/pages/versions.js (JavaScript)

Code before:

async function getBranches() {
  const result = await fetch('https://api.github.com/repos/mui/material-ui-docs/branches', {
    headers: {
      Authorization: process.env.GITHUB_AUTH,
    },
  });
  const text = await result.text();

  if (result.status !== 200) {
    throw new Error(text);
  }

  return JSON.parse(text);
}

Page.getInitialProps = async () => {
  const FILTERED_BRANCHES = ['latest', 'l10n', 'next', 'migration', 'material-ui.com'];

  const branches = await getBranches();
  /**
   * @type {import('docs/src/pages/versions/VersionsContext').VersionsContextValue}
   */
  const versions = [];
  branches.forEach((branch) => {
    if (FILTERED_BRANCHES.includes(branch.name)) {
      const version = branch.name;
      versions.push({
        version,
        // Replace dot with dashes for Netlify branch subdomains
        url: `https://${version.replace(/\./g, '-')}.mui.com`,
      });
    }
  });
  // Current version.
  versions.push({
    version: `v${process.env.LIB_VERSION}`,
    url: 'https://mui.com',
  });
  // Legacy documentation.
  versions.push({
    version: 'v0',
    url: 'https://v0.mui.com',
  });
  versions.sort((a, b) => formatVersion(b.version).localeCompare(formatVersion(a.version)));

  if (
    branches.find((branch) => branch.name === 'next') &&
    !versions.find((version) => /beta|alpha/.test(version.version))
  ) {
    versions.unshift({

Review comment (bug):
This is incorrect. This condition should be negated because the original code was using `=== -1` (element is not found in the array) and not `!== -1` (element is found on the array).

```suggestion
    if (!FILTERED_BRANCHES.includes(branch.name)) {
```



Code after:

async function getBranches() {
  const result = await fetch('https://api.github.com/repos/mui/material-ui-docs/branches', {
    headers: {
      Authorization: process.env.GITHUB_AUTH,
    },
  });
  const text = await result.text();

  if (result.status !== 200) {
    throw new Error(text);
  }

  return JSON.parse(text);
}

Page.getInitialProps = async () => {
  const FILTERED_BRANCHES = ['latest', 'l10n', 'next', 'migration', 'material-ui.com'];

  const branches = await getBranches();
  /**
   * @type {import('docs/src/pages/versions/VersionsContext').VersionsContextValue}
   */
  const versions = [];
  branches.forEach((branch) => {
    if (!FILTERED_BRANCHES.includes(branch.name)) {
      const version = branch.name;
      versions.push({
        version,
        // Replace dot with dashes for Netlify branch subdomains
        url: `https://${version.replace(/\./g, '-')}.mui.com`,
      });
    }
  });
  // Current version.
  versions.push({
    version: `v${process.env.LIB_VERSION}`,
    url: 'https://mui.com',
  });
  // Legacy documentation.
  versions.push({
    version: 'v0',
    url: 'https://v0.mui.com',
  });
  versions.sort((a, b) => formatVersion(b.version).localeCompare(formatVersion(a.version)));

  if (
    branches.find((branch) => branch.name === 'next') &&
    !versions.find((version) => /beta|alpha/.test(version.version))
  ) {
    versions.unshift({
Repository: mui/material-ui
File: packages/mui-material/src/useScrollTrigger/useScrollTrigger.js (JavaScript)

Code before:
    if (store.current < previous) {
      return false;
    }
  }

  return store.current > threshold;
}

const defaultTarget = typeof window !== 'undefined' ? window : null;

export default function useScrollTrigger(options = {}) {
  const { getTrigger = defaultTrigger, target = defaultTarget, ...other } = options;
  const store = React.useRef();
  const [trigger, setTrigger] = React.useState(() => getTrigger(store, other));
  React.useEffect(() => {
    const handleScroll = () => {
      setTrigger(getTrigger(store, { target, ...other }));
    };

    handleScroll(); // Re-evaluate trigger when dependencies change
    target.addEventListener('scroll', handleScroll, { passive: true });
    return () => {
      target.removeEventListener('scroll', handleScroll, { passive: true });
    };
    // See Option 3. https://github.com/facebook/react/issues/14476#issuecomment-471199055
    // TODO: uncomment when compiler enabled //eslint-disable-next-line react-compiler/react-compiler - fixing this causes tests to fail
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [target, getTrigger, JSON.stringify(other)]);

  return trigger;
}


Review comment (suggestion):
```suggestion
    // TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler
```

Code after:
    if (store.current < previous) {
      return false;
    }
  }

  return store.current > threshold;
}

const defaultTarget = typeof window !== 'undefined' ? window : null;

export default function useScrollTrigger(options = {}) {
  const { getTrigger = defaultTrigger, target = defaultTarget, ...other } = options;
  const store = React.useRef();
  const [trigger, setTrigger] = React.useState(() => getTrigger(store, other));
  React.useEffect(() => {
    const handleScroll = () => {
      setTrigger(getTrigger(store, { target, ...other }));
    };

    handleScroll(); // Re-evaluate trigger when dependencies change
    target.addEventListener('scroll', handleScroll, { passive: true });
    return () => {
      target.removeEventListener('scroll', handleScroll, { passive: true });
    };
    // See Option 3. https://github.com/facebook/react/issues/14476#issuecomment-471199055
    // TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [target, getTrigger, JSON.stringify(other)]);

  return trigger;
}
Repository: mui/material-ui
File: packages/mui-material/src/styles/useTheme.js (JavaScript)

Code before:
'use client';
import * as React from 'react';
import { useTheme as useThemeSystem } from '@mui/system';
import defaultTheme from './defaultTheme';
import THEME_ID from './identifier';

export default function useTheme() {
  const theme = useThemeSystem(defaultTheme);

  if (process.env.NODE_ENV !== 'production') {
    // TODO: uncomment when compiler enabled // eslint-disable-next-line react-compiler/react-compiler
    // eslint-disable-next-line react-hooks/rules-of-hooks
    React.useDebugValue(theme);
  }

  return theme[THEME_ID] || theme;
}


Review comment (suggestion):
```suggestion
    // TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler
```

Code after:
'use client';
import * as React from 'react';
import { useTheme as useThemeSystem } from '@mui/system';
import defaultTheme from './defaultTheme';
import THEME_ID from './identifier';

export default function useTheme() {
  const theme = useThemeSystem(defaultTheme);

  if (process.env.NODE_ENV !== 'production') {
    // TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler
    // eslint-disable-next-line react-hooks/rules-of-hooks
    React.useDebugValue(theme);
  }

  return theme[THEME_ID] || theme;
}
Repository: mui/material-ui
File: packages/mui-material/src/Snackbar/Snackbar.test.js (JavaScript)

Code before:
      render(
        <React.Fragment>
          <Snackbar open onClose={handleCloseA} message="messageA" />
          <Snackbar open onClose={handleCloseB} message="messageB" />
        </React.Fragment>,
      );

      fireEvent.keyDown(document.body, { key: 'Escape' });

      expect(handleCloseA.callCount).to.equal(1);
      expect(handleCloseB.callCount).to.equal(0);
    });
  });

  describe('Consecutive messages', () => {
    it('should support synchronous onExited callback', () => {
      const messageCount = 2;

      const onClose = spy();
      const onExited = spy();
      const duration = 250;

      let setSnackbarOpen;
      function Test() {
        const [open, setOpen] = React.useState(false);
        // TODO: uncomment when compiler is enabled // eslint-disable-next-line react-compiler/react-compiler
        setSnackbarOpen = setOpen;

        function handleClose() {
          setOpen(false);
          onClose();
        }

        function handleExited() {
          onExited();
          if (onExited.callCount < messageCount) {
            setOpen(true);
          }
        }

        return (
          <Snackbar
            open={open}
            onClose={handleClose}
            TransitionProps={{ onExited: handleExited }}
            message="message"
            autoHideDuration={duration}
            transitionDuration={duration / 2}
          />
        );
      }

Review comment (suggestion):
```suggestion
        // TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler
```

Code after:
      render(
        <React.Fragment>
          <Snackbar open onClose={handleCloseA} message="messageA" />
          <Snackbar open onClose={handleCloseB} message="messageB" />
        </React.Fragment>,
      );

      fireEvent.keyDown(document.body, { key: 'Escape' });

      expect(handleCloseA.callCount).to.equal(1);
      expect(handleCloseB.callCount).to.equal(0);
    });
  });

  describe('Consecutive messages', () => {
    it('should support synchronous onExited callback', () => {
      const messageCount = 2;

      const onClose = spy();
      const onExited = spy();
      const duration = 250;

      let setSnackbarOpen;
      function Test() {
        const [open, setOpen] = React.useState(false);
        // TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler
        setSnackbarOpen = setOpen;

        function handleClose() {
          setOpen(false);
          onClose();
        }

        function handleExited() {
          onExited();
          if (onExited.callCount < messageCount) {
            setOpen(true);
          }
        }

        return (
          <Snackbar
            open={open}
            onClose={handleClose}
            TransitionProps={{ onExited: handleExited }}
            message="message"
            autoHideDuration={duration}
            transitionDuration={duration / 2}
          />
        );
      }
Repository: mui/material-ui
File: packages/mui-material/src/Popover/Popover.js (JavaScript)

Code before:
        elemTransformOrigin.horizontal += diff;
      }

      return {
        top: `${Math.round(top)}px`,
        left: `${Math.round(left)}px`,
        transformOrigin: getTransformOriginValue(elemTransformOrigin),
      };
    },
    [anchorEl, anchorReference, getAnchorOffset, getTransformOrigin, marginThreshold],
  );

  const [isPositioned, setIsPositioned] = React.useState(open);

  const setPositioningStyles = React.useCallback(() => {
    const element = paperRef.current;

    if (!element) {
      return;
    }

    const positioning = getPositioningStyle(element);

    if (positioning.top !== null) {
      // TODO: uncomment when compiler enabled // eslint-disable-next-line react-compiler/react-compiler
      element.style.top = positioning.top;
    }
    if (positioning.left !== null) {
      element.style.left = positioning.left;
    }
    element.style.transformOrigin = positioning.transformOrigin;
    setIsPositioned(true);
  }, [getPositioningStyle]);

  React.useEffect(() => {
    if (disableScrollLock) {
      window.addEventListener('scroll', setPositioningStyles);
    }
    return () => window.removeEventListener('scroll', setPositioningStyles);
  }, [anchorEl, disableScrollLock, setPositioningStyles]);

  const handleEntering = (element, isAppearing) => {
    if (onEntering) {
      onEntering(element, isAppearing);
    }

    setPositioningStyles();
  };

  const handleExited = () => {
    setIsPositioned(false);

Review comment (suggestion):
We can use `style.setProperty` and avoid the comment.

```suggestion
      element.style.setProperty('top', positioning.top);
```

Code after:
        elemTransformOrigin.horizontal += diff;
      }

      return {
        top: `${Math.round(top)}px`,
        left: `${Math.round(left)}px`,
        transformOrigin: getTransformOriginValue(elemTransformOrigin),
      };
    },
    [anchorEl, anchorReference, getAnchorOffset, getTransformOrigin, marginThreshold],
  );

  const [isPositioned, setIsPositioned] = React.useState(open);

  const setPositioningStyles = React.useCallback(() => {
    const element = paperRef.current;

    if (!element) {
      return;
    }

    const positioning = getPositioningStyle(element);

    if (positioning.top !== null) {
      element.style.setProperty('top', positioning.top);
    }
    if (positioning.left !== null) {
      element.style.left = positioning.left;
    }
    element.style.transformOrigin = positioning.transformOrigin;
    setIsPositioned(true);
  }, [getPositioningStyle]);

  React.useEffect(() => {
    if (disableScrollLock) {
      window.addEventListener('scroll', setPositioningStyles);
    }
    return () => window.removeEventListener('scroll', setPositioningStyles);
  }, [anchorEl, disableScrollLock, setPositioningStyles]);

  const handleEntering = (element, isAppearing) => {
    if (onEntering) {
      onEntering(element, isAppearing);
    }

    setPositioningStyles();
  };

  const handleExited = () => {
    setIsPositioned(false);
  };
Repository: mui/material-ui
File: docs/src/components/home/SponsorCard.tsx (TypeScript)

Code before:
import * as React from 'react';
import Avatar from '@mui/material/Avatar';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Paper from '@mui/material/Paper';
import LaunchRounded from '@mui/icons-material/LaunchRounded';
import { Link } from '@mui/docs/Link';

export default function SponsorCard(props: {
  item: {
    src: string;
    srcSet?: string;
    name: string;
    description: string;
    href: string;
  };
  inView?: boolean;
  logoSize?: number | string;
}) {
  const { item, inView = false, logoSize = 40 } = props;
  // Keep it under two rows maximum.
  if (item.description.length > 50 && logoSize === 40) {
    throw new Error(
      `${item.name}'s description is too long (${item.description.length} characters). It must fit into two line, so under 50 characters.`,
    );
  }

  return (
    <Paper
      data-ga-event-category="sponsor"
      data-ga-event-action="homepage"
      data-ga-event-label={new URL(item.href).hostname}

Review comment (bug):
`Link` is not used in this file, this made eslint fail.

Code after:
import * as React from 'react';
import Avatar from '@mui/material/Avatar';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Paper from '@mui/material/Paper';
import LaunchRounded from '@mui/icons-material/LaunchRounded';

export default function SponsorCard(props: {
  item: {
    src: string;
    srcSet?: string;
    name: string;
    description: string;
    href: string;
  };
  inView?: boolean;
  logoSize?: number | string;
}) {
  const { item, inView = false, logoSize = 40 } = props;
  // Keep it under two rows maximum.
  if (item.description.length > 50 && logoSize === 40) {
    throw new Error(
      `${item.name}'s description is too long (${item.description.length} characters). It must fit into two line, so under 50 characters.`,
    );
  }

  return (
    <Paper
      data-ga-event-category="sponsor"
      data-ga-event-action="homepage"
      data-ga-event-label={new URL(item.href).hostname}
      variant="outlined"
Repository: mui/material-ui
File: packages/mui-material/src/ButtonBase/ButtonBase.js (JavaScript)

Code before:
    borderStyle: 'none', // Remove Firefox dotted outline.
  },
  [`&.${buttonBaseClasses.disabled}`]: {
    pointerEvents: 'none', // Disable link interactions
    cursor: 'default',
  },
  '@media print': {
    colorAdjust: 'exact',
  },
});

function useRippleHandler(ripple, rippleAction, eventCallback, skipRippleAction = false) {
  return useEventCallback((event) => {
    if (eventCallback) {
      eventCallback(event);
    }

    const ignore = skipRippleAction;
    if (!ignore) {
      ripple[rippleAction](event);
    }

    return true;
  });
}

/**
 * `ButtonBase` contains as few styles as possible.
 * It aims to be a simple building block for creating a button.
 * It contains a load of style reset and some focus/ripple logic.
 */
const ButtonBase = React.forwardRef(function ButtonBase(inProps, ref) {
  const props = useDefaultProps({ props: inProps, name: 'MuiButtonBase' });
  const {
    action,
    centerRipple = false,
    children,
    className,
    component = 'button',
    disabled = false,
    disableRipple = false,
    disableTouchRipple = false,
    focusRipple = false,
    focusVisibleClassName,
    LinkComponent = 'a',
    onBlur,
    onClick,
    onContextMenu,
    onDragLeave,
    onFocus,
    onFocusVisible,

Review comment (refactor):
Move this function at the end, by convention helper functions should be last, and the main components/hooks at the start.

Code after:
    borderStyle: 'none', // Remove Firefox dotted outline.
  },
  [`&.${buttonBaseClasses.disabled}`]: {
    pointerEvents: 'none', // Disable link interactions
    cursor: 'default',
  },
  '@media print': {
    colorAdjust: 'exact',
  },
});

/**
 * `ButtonBase` contains as few styles as possible.
 * It aims to be a simple building block for creating a button.
 * It contains a load of style reset and some focus/ripple logic.
 */
const ButtonBase = React.forwardRef(function ButtonBase(inProps, ref) {
  const props = useDefaultProps({ props: inProps, name: 'MuiButtonBase' });
  const {
    action,
    centerRipple = false,
    children,
    className,
    component = 'button',
    disabled = false,
    disableRipple = false,
    disableTouchRipple = false,
    focusRipple = false,
    focusVisibleClassName,
    LinkComponent = 'a',
    onBlur,
    onClick,
    onContextMenu,
    onDragLeave,
    onFocus,
    onFocusVisible,
    onKeyDown,
    onKeyUp,
    onMouseDown,
    onMouseLeave,
    onMouseUp,
    onTouchEnd,
    onTouchMove,
    onTouchStart,
    tabIndex = 0,
    TouchRippleProps,
    touchRippleRef,
    type,
    ...other
  } = props;