ronantakizawa/codereview-bench huggingface dataset:
Repository: facebook/docusaurus
File: packages/docusaurus-theme-common/src/index.ts (TypeScript)

Code before:
  type FooterLinkItem,
  type ColorModeConfig,
} from './utils/useThemeConfig';

export {default as ThemedComponent} from './components/ThemedComponent';

export {default as StructuredData} from './components/StructuredData';

export {
  createStorageSlot,
  useStorageSlot,
  listStorageKeys,
} from './utils/storageUtils';

export {useContextualSearchFilters} from './utils/searchUtils';

export {
  useCurrentSidebarCategory,
  filterDocCardListItems,
} from './utils/docsUtils';

export {
  useBlogListPageStructuredData,
  useBlogPostStructuredData,
  makeImageStructuredData,
  makePersonStructuredData,
} from './utils/structuredDataUtils';

export {usePluralForm} from './utils/usePluralForm';

export {useCollapsible, Collapsible} from './components/Collapsible';

export {ThemeClassNames} from './utils/ThemeClassNames';

export {prefersReducedMotion} from './utils/accessibilityUtils';

export {
  useEvent,
  usePrevious,
  composeProviders,
  ReactContextError,
} from './utils/reactUtils';

export {PageMetadata, HtmlClassNameProvider} from './utils/metadataUtils';

export {useColorMode, type ColorMode} from './contexts/colorMode';

export {
  NavbarSecondaryMenuFiller,
  type NavbarSecondaryMenuComponent,
} from './contexts/navbarSecondaryMenu/content';

Review comment (suggestion):
make is not a term we use much on our codebase, I'd prefer "create" for consistency with other existing functions

Code after:
  type FooterLinkItem,
  type ColorModeConfig,
} from './utils/useThemeConfig';

export {default as ThemedComponent} from './components/ThemedComponent';

export {
  createStorageSlot,
  useStorageSlot,
  listStorageKeys,
} from './utils/storageUtils';

export {useContextualSearchFilters} from './utils/searchUtils';

export {
  useCurrentSidebarCategory,
  filterDocCardListItems,
} from './utils/docsUtils';

export {
  useBlogListPageStructuredData,
  useBlogPostStructuredData,
} from './utils/structuredDataUtils';

export {usePluralForm} from './utils/usePluralForm';

export {useCollapsible, Collapsible} from './components/Collapsible';

export {ThemeClassNames} from './utils/ThemeClassNames';

export {prefersReducedMotion} from './utils/accessibilityUtils';

export {
  useEvent,
  usePrevious,
  composeProviders,
  ReactContextError,
} from './utils/reactUtils';

export {PageMetadata, HtmlClassNameProvider} from './utils/metadataUtils';

export {useColorMode, type ColorMode} from './contexts/colorMode';

export {
  NavbarSecondaryMenuFiller,
  type NavbarSecondaryMenuComponent,
} from './contexts/navbarSecondaryMenu/content';

export {useWindowSize} from './hooks/useWindowSize';

/*
Repository: facebook/docusaurus
File: packages/docusaurus-utils/src/jsUtils.ts (TypeScript)

Code before:
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

/** Adds a given string suffix to `str`. */
export function addSuffix(str: string, suffix: string): string {
  return str.endsWith(suffix) ? str : `${str}${suffix}`;
}

/** Removes a given string prefix from `str`. */
export function removePrefix(str: string, prefix: string): string {
  return str.startsWith(prefix) ? str.slice(prefix.length) : str;
}

/**
 * `Array#map` for async operations where order matters.
 * @param array The array to traverse.
 * @param action An async action to be performed on every array item. Will be
 * awaited before working on the next.
 * @returns The list of results returned from every `action(item)`
 */
export async function mapAsyncSequential<T, R>(
  array: T[],
  action: (t: T) => Promise<R>,
): Promise<R[]> {
  const results: R[] = [];
  for (const t of array) {
    const result = await action(t);
    results.push(result);
  }
  return results;

Review comment (suggestion):
this one should also go in utils-common `stringUtils.ts`

Code after:
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

/**
 * `Array#map` for async operations where order matters.
 * @param array The array to traverse.
 * @param action An async action to be performed on every array item. Will be
 * awaited before working on the next.
 * @returns The list of results returned from every `action(item)`
 */
export async function mapAsyncSequential<T, R>(
  array: T[],
  action: (t: T) => Promise<R>,
): Promise<R[]> {
  const results: R[] = [];
  for (const t of array) {
    const result = await action(t);
    results.push(result);
  }
  return results;
}

/**
 * `Array#find` for async operations where order matters.
 * @param array The array to traverse.
 * @param predicate An async predicate to be called on every array item. Should
 * return a boolean indicating whether the currently element should be returned.
 * @returns The function immediately returns the first item on which `predicate`
 * returns `true`, or `undefined` if none matches the predicate.
 */
Repository: facebook/docusaurus
File: packages/docusaurus-utils/src/jsUtils.ts (TypeScript)

Code before:
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

/** Adds a given string suffix to `str`. */
export function addSuffix(str: string, suffix: string): string {
  return str.endsWith(suffix) ? str : `${str}${suffix}`;
}

/** Removes a given string prefix from `str`. */
export function removePrefix(str: string, prefix: string): string {
  return str.startsWith(prefix) ? str.slice(prefix.length) : str;
}

/**
 * `Array#map` for async operations where order matters.
 * @param array The array to traverse.
 * @param action An async action to be performed on every array item. Will be
 * awaited before working on the next.
 * @returns The list of results returned from every `action(item)`
 */
export async function mapAsyncSequential<T, R>(
  array: T[],
  action: (t: T) => Promise<R>,
): Promise<R[]> {
  const results: R[] = [];
  for (const t of array) {
    const result = await action(t);
    results.push(result);
  }
  return results;
}

/**
 * `Array#find` for async operations where order matters.
 * @param array The array to traverse.

Review comment (suggestion):
this one should also go in utils-common `stringUtils.ts`

Code after:
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

/**
 * `Array#map` for async operations where order matters.
 * @param array The array to traverse.
 * @param action An async action to be performed on every array item. Will be
 * awaited before working on the next.
 * @returns The list of results returned from every `action(item)`
 */
export async function mapAsyncSequential<T, R>(
  array: T[],
  action: (t: T) => Promise<R>,
): Promise<R[]> {
  const results: R[] = [];
  for (const t of array) {
    const result = await action(t);
    results.push(result);
  }
  return results;
}

/**
 * `Array#find` for async operations where order matters.
 * @param array The array to traverse.
 * @param predicate An async predicate to be called on every array item. Should
 * return a boolean indicating whether the currently element should be returned.
 * @returns The function immediately returns the first item on which `predicate`
 * returns `true`, or `undefined` if none matches the predicate.
 */
export async function findAsyncSequential<T>(
  array: T[],
  predicate: (t: T) => Promise<boolean>,
): Promise<T | undefined> {
  for (const t of array) {
Repository: facebook/docusaurus
File: packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx (TypeScript)

Code before:
          title={title}
          description={description}
          keywords={keywords}
          image={image}
        />
        <main className="container container--fluid margin-vert--lg">
          <div className={clsx('row', styles.mdxPageWrapper)}>
            <div className={clsx('col', !hideTableOfContents && 'col--8')}>
              {unlisted && <Unlisted />}
              <article>
                <MDXContent>
                  <MDXPageContent />
                </MDXContent>
              </article>
            </div>
            {!hideTableOfContents && MDXPageContent.toc.length > 0 && (
              <div className="col col--2">
                <TOC
                  toc={MDXPageContent.toc}
                  minHeadingLevel={frontMatter.toc_min_heading_level}
                  maxHeadingLevel={frontMatter.toc_max_heading_level}
                />
              </div>
            )}
          </div>
          <EditMetaRow
            className={clsx(
              'margin-top--sm',
              ThemeClassNames.blog.blogFooterEditMetaRow,
            )}
            editUrl=""
            lastUpdatedAt={lastUpdatedAt}
            lastUpdatedBy={lastUpdatedBy}
          />
        </main>
      </Layout>
    </HtmlClassNameProvider>
  );
}


Review comment (suggestion):
Need to render it conditionally, like docs/blog:

```tsx
{canDisplayEditMetaRow && <EditMetaRow/>}
```

Code after:
      )}>
      <Layout>
        <PageMetadata
          title={title}
          description={description}
          keywords={keywords}
          image={image}
        />
        <main className="container container--fluid margin-vert--lg">
          <div className={clsx('row', styles.mdxPageWrapper)}>
            <div className={clsx('col', !hideTableOfContents && 'col--8')}>
              {unlisted && <Unlisted />}
              <article>
                <MDXContent>
                  <MDXPageContent />
                </MDXContent>
              </article>
              {canDisplayEditMetaRow && (
                <EditMetaRow
                  className={clsx(
                    'margin-top--sm',
                    ThemeClassNames.pages.pageFooterEditMetaRow,
                  )}
                  editUrl={editUrl}
                  lastUpdatedAt={lastUpdatedAt}
                  lastUpdatedBy={lastUpdatedBy}
                />
              )}
            </div>
            {!hideTableOfContents && MDXPageContent.toc.length > 0 && (
              <div className="col col--2">
                <TOC
                  toc={MDXPageContent.toc}
                  minHeadingLevel={frontMatter.toc_min_heading_level}
                  maxHeadingLevel={frontMatter.toc_max_heading_level}
                />
              </div>
            )}
          </div>
        </main>
      </Layout>
    </HtmlClassNameProvider>
  );
}
Repository: facebook/docusaurus
File: website/_dogfooding/dogfooding.config.ts (TypeScript)

Code before:
      path: '_dogfooding/_blog tests',
      routeBasePath: '/tests/blog',
      editUrl:
        'https://github.com/facebook/docusaurus/edit/main/website/_dogfooding/_blog-tests',
      postsPerPage: 3,
      feedOptions: {
        type: 'all',
        title: 'Docusaurus Tests Blog',
        copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc.`,
      },
      readingTime: ({content, frontMatter, defaultReadingTime}) =>
        frontMatter.hide_reading_time
          ? undefined
          : defaultReadingTime({content, options: {wordsPerMinute: 5}}),
    } satisfies BlogOptions,
  ],

  [
    require.resolve('@docusaurus/plugin-content-pages'), // Full path
    {
      id: 'pages-tests',
      path: '_dogfooding/_pages tests',
      routeBasePath: '/tests/pages',
      showLastUpdateTime: true,
      showLastUpdateAuthor: true,
      editUrl: () => 'url placeholder',
    } satisfies PageOptions,
  ],

  function clientModuleTestPlugin(): Plugin {
    return {
      name: 'client-module-test-plugin',
      getClientModules() {
        return [
          require.resolve('./clientModuleExample.ts'),
          require.resolve('./clientModuleCSS.css'),
        ];
      },
    };
  },
];

export const dogfoodingRedirects: {from: string[]; to: string}[] = [
  {
    from: ['/home/'],
    to: '/',
  },
  {
    from: ['/home/qs'],
    to: '/?a=1',
  },

Review comment (bug):
Let's use a real value here so that the dogfood pages can be edited by clicking the edit URL link

this relative URL makes the site build fail

Code after:
      path: '_dogfooding/_blog tests',
      routeBasePath: '/tests/blog',
      editUrl:
        'https://github.com/facebook/docusaurus/edit/main/website/_dogfooding/_blog-tests',
      postsPerPage: 3,
      feedOptions: {
        type: 'all',
        title: 'Docusaurus Tests Blog',
        copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc.`,
      },
      readingTime: ({content, frontMatter, defaultReadingTime}) =>
        frontMatter.hide_reading_time
          ? undefined
          : defaultReadingTime({content, options: {wordsPerMinute: 5}}),
    } satisfies BlogOptions,
  ],

  [
    require.resolve('@docusaurus/plugin-content-pages'), // Full path
    {
      id: 'pages-tests',
      path: '_dogfooding/_pages tests',
      routeBasePath: '/tests/pages',
      showLastUpdateTime: true,
      showLastUpdateAuthor: true,
      editUrl: ({pagesPath}) =>
        `https://github.com/facebook/docusaurus/edit/main/website/_dogfooding/_pages tests/${pagesPath}`,
    } satisfies PageOptions,
  ],

  function clientModuleTestPlugin(): Plugin {
    return {
      name: 'client-module-test-plugin',
      getClientModules() {
        return [
          require.resolve('./clientModuleExample.ts'),
          require.resolve('./clientModuleCSS.css'),
        ];
      },
    };
  },
];

export const dogfoodingRedirects: {from: string[]; to: string}[] = [
  {
    from: ['/home/'],
    to: '/',
  },
  {
    from: ['/home/qs'],
    to: '/?a=1',
Repository: facebook/docusaurus
File: packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx (TypeScript)

Code before:
        </li>
      ))}
    </ul>
  );
}

function TabContent({
  className,
  lazy,
  children,
  selectedValue,
}: Props & ReturnType<typeof useTabs>) {
  const childTabs = (Array.isArray(children) ? children : [children]).filter(
    Boolean,
  ) as ReactElement<TabItemProps>[];
  if (lazy) {
    const selectedTabItem = childTabs.find(
      (tabItem) => tabItem.props.value === selectedValue,
    );
    if (!selectedTabItem) {
      // fail-safe or fail-fast? not sure what's best here
      return null;
    }
    return cloneElement(selectedTabItem, {
      className: clsx('margin-top--md', className),
    });
  }
  return (
    <div className="margin-top--md">
      {childTabs.map((tabItem, i) =>
        cloneElement(tabItem, {
          key: i,
          hidden: tabItem.props.value !== selectedValue,
        }),
      )}
    </div>
  );
}

function TabsComponent(props: Props): JSX.Element {
  const tabs = useTabs(props);
  return (
    <div className={clsx('tabs-container', styles.tabList)}>
      <TabList {...tabs} {...props} />
      <TabContent {...tabs} {...props} />
    </div>
  );
}

export default function Tabs(props: Props): JSX.Element {
  const isBrowser = useIsBrowser();

Review comment (suggestion):
Can you prove me that it works thanks to a visible example in the preview?

I suspected the code to not work and it doesn't look like it works

To me you should do `selectedTabItem.props.className` instead

Code after:
        </li>
      ))}
    </ul>
  );
}

function TabContent({
  lazy,
  children,
  selectedValue,
}: Props & ReturnType<typeof useTabs>) {
  const childTabs = (Array.isArray(children) ? children : [children]).filter(
    Boolean,
  ) as ReactElement<TabItemProps>[];
  if (lazy) {
    const selectedTabItem = childTabs.find(
      (tabItem) => tabItem.props.value === selectedValue,
    );
    if (!selectedTabItem) {
      // fail-safe or fail-fast? not sure what's best here
      return null;
    }
    return cloneElement(selectedTabItem, {
      className: clsx('margin-top--md', selectedTabItem.props.className),
    });
  }
  return (
    <div className="margin-top--md">
      {childTabs.map((tabItem, i) =>
        cloneElement(tabItem, {
          key: i,
          hidden: tabItem.props.value !== selectedValue,
        }),
      )}
    </div>
  );
}

function TabsComponent(props: Props): JSX.Element {
  const tabs = useTabs(props);
  return (
    <div className={clsx('tabs-container', styles.tabList)}>
      <TabList {...tabs} {...props} />
      <TabContent {...tabs} {...props} />
    </div>
  );
}

export default function Tabs(props: Props): JSX.Element {
  const isBrowser = useIsBrowser();
  return (
Repository: facebook/docusaurus
File: packages/docusaurus-plugin-content-docs/src/client/__tests__/docsClientUtils.test.ts (TypeScript)

Code before:
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import _ from 'lodash';
import {
  getActivePlugin,
  getLatestVersion,
  getActiveDocContext,
  getActiveVersion,
  getDocVersionSuggestions,
  sortVersionsByPathDepth,
} from '../docsClientUtils';
import type {
  GlobalPluginData,
  GlobalVersion,
  ActivePlugin,
  GlobalDoc,
} from '@docusaurus/plugin-content-docs/client';

function createVersion(name: string, path: string, isLast: boolean) {
  return {
    name,
    label: name,
    path,
    isLast,
    docs: [],
    mainDocId: '???',
    draftIds: [],
  };
}

describe('docsClientUtils', () => {
  it('getActivePlugin', () => {
    const data: {[key: string]: GlobalPluginData} = {
      pluginIosId: {
        path: '/ios',
        versions: [],
        breadcrumbs: true,
      },
      pluginAndroidId: {
        path: '/android',
        versions: [],
        breadcrumbs: true,
      },
    };

Review comment (suggestion):
Would be better to have 

```suggestion
function createVersion(partialVersion: Partial<VersionMetadata>) {
```

When multiple params have the same attribute, it's often better to have names, otherwise we rely on param position to know what it is and it makes tests less explicit

Code after:
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import _ from 'lodash';
import {fromPartial} from '@total-typescript/shoehorn';
import {
  getActivePlugin,
  getLatestVersion,
  getActiveDocContext,
  getActiveVersion,
  getDocVersionSuggestions,
} from '../docsClientUtils';
import type {
  GlobalPluginData,
  GlobalVersion,
  ActivePlugin,
  GlobalDoc,
} from '../index';

function globalVersion(partial: Partial<GlobalVersion>): GlobalVersion {
  return fromPartial<GlobalVersion>(partial);
}

function globalDoc(partial: Partial<GlobalDoc>): GlobalDoc {
  return fromPartial<GlobalDoc>(partial);
}

describe('docsClientUtils', () => {
  it('getActivePlugin', () => {
    const data: {[key: string]: GlobalPluginData} = {
      pluginIosId: {
        path: '/ios',
        versions: [],
        breadcrumbs: true,
      },
      pluginAndroidId: {
        path: '/android',
        versions: [],
        breadcrumbs: true,
      },
    };

    expect(getActivePlugin(data, '/')).toBeUndefined();
    expect(getActivePlugin(data, '/xyz')).toBeUndefined();
Repository: facebook/docusaurus
File: packages/docusaurus-mdx-loader/src/remark/contentTitle/__tests__/index.test.ts (TypeScript)

Code before:
import plugin from '../index';

async function process(
  content: string,
  options: {removeContentTitle?: boolean} = {},
) {
  const {remark} = await import('remark');
  const processor = await remark().use({plugins: [[plugin, options]]});
  return processor.process(content);
}

describe('contentTitle remark plugin', () => {
  describe('extracts data.contentTitle', () => {
    it('extracts h1 heading', async () => {
      const result = await process(
        `
# contentTitle 1

## Heading Two {#custom-heading-two}

# contentTitle 2

some **markdown** *content*
  `,
        {removeContentTitle: true},
      );

      expect(result.data.contentTitle).toBe('contentTitle 1');
    });

    it('extracts h1 heading alt syntax', async () => {
      const result = await process(
        `
contentTitle alt
===

# contentTitle 1

## Heading Two {#custom-heading-two}

# contentTitle 2

some **markdown** *content*
  `,
        {removeContentTitle: true},
      );

      expect(result.data.contentTitle).toBe('contentTitle alt');
    });

    it('works with no contentTitle', async () => {

Review comment (bug):
> Some test needed removeContentTitle: true throw Cannot handle unknown node 'mdxJsxFlowElement' and test returns content unmodified still fails thrown: "Exceeded timeout of 15000 ms for a test.


Why would that test now need `removeContentTitle: true`. I tested locally and if it now timeouts, there must be a very good reason that we should find out.


Code after:
import {escapeMarkdownHeadingIds} from '@docusaurus/utils';
import plugin from '../index';

async function process(
  content: string,
  options: {removeContentTitle?: boolean} = {},
) {
  const {remark} = await import('remark');
  const {default: mdx} = await import('remark-mdx');

  const result = await remark()
    .use(mdx)
    .use(plugin, options)
    .process(escapeMarkdownHeadingIds(content));

  return result;
}

describe('contentTitle remark plugin', () => {
  describe('extracts data.contentTitle', () => {
    it('extracts h1 heading', async () => {
      const result = await process(`
# contentTitle 1

## Heading Two {#custom-heading-two}

# contentTitle 2

some **markdown** *content*
  `);

      expect(result.data.contentTitle).toBe('contentTitle 1');
    });

    it('extracts h1 heading alt syntax', async () => {
      const result = await process(
        `
contentTitle alt
===

# contentTitle 1

## Heading Two {#custom-heading-two}

# contentTitle 2

some **markdown** *content*
  `,
      );

      expect(result.data.contentTitle).toBe('contentTitle alt');