<commit_before>/* eslint-env jest */
import { sandbox } from './helpers'

jest.setTimeout(1000 * 60 * 5)

test('logbox: can recover from a syntax error without losing state', async () => {
  const [session, cleanup] = await sandbox()

  await session.patch(
    'index.js',
    `
      import { useCallback, useState } from 'react'

      export default function Index() {
        const [count, setCount] = useState(0)
        const increment = useCallback(() => setCount(c => c + 1), [setCount])
        return (
          <main>
            <p>{count}</p>
            <button onClick={increment}>Increment</button>
          </main>
        )
      }
    `
  )

  await session.evaluate(() => document.querySelector('button').click())
  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('1')

  await session.patch('index.js', `export default () => <div/`)

  expect(await session.hasRedbox(true)).toBe(true)
  expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
    "./index.js:1:26
    Syntax error: Unexpected token, expected \\"jsxTagEnd\\"

    > 1 | export default () => <div/
        |                           ^"
  `)

  await session.patch(
    'index.js',
    `
      import { useCallback, useState } from 'react'

      export default function Index() {
        const [count, setCount] = useState(0)
        const increment = useCallback(() => setCount(c => c + 1), [setCount])
        return (
          <main>
            <p>Count: {count}</p>
            <button onClick={increment}>Increment</button>
          </main>
        )
      }
    `
  )

  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('Count: 1')

  expect(await session.hasRedbox()).toBe(false)

  await cleanup()
})

test('logbox: can recover from a event handler error', async () => {
  const [session, cleanup] = await sandbox()

  await session.patch(
    'index.js',
    `
      import { useCallback, useState } from 'react'

      export default function Index() {
        const [count, setCount] = useState(0)
        const increment = useCallback(() => {
          setCount(c => c + 1)
          throw new Error('oops')
        }, [setCount])
        return (
          <main>
            <p>{count}</p>
            <button onClick={increment}>Increment</button>
          </main>
        )
      }
    `
  )

  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('0')
  await session.evaluate(() => document.querySelector('button').click())
  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('1')

  expect(await session.hasRedbox(true)).toBe(true)
  if (process.platform === 'win32') {
    expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
      "index.js (8:16) @ <unknown>

         6 | const increment = useCallback(() => {
         7 |   setCount(c => c + 1)
      >  8 |   throw new Error('oops')
           |        ^
         9 | }, [setCount])
        10 | return (
        11 |   <main>"
    `)
  } else {
    expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
      "index.js (8:16) @ eval

         6 | const increment = useCallback(() => {
         7 |   setCount(c => c + 1)
      >  8 |   throw new Error('oops')
           |        ^
         9 | }, [setCount])
        10 | return (
        11 |   <main>"
    `)
  }

  await session.patch(
    'index.js',
    `
      import { useCallback, useState } from 'react'

      export default function Index() {
        const [count, setCount] = useState(0)
        const increment = useCallback(() => setCount(c => c + 1), [setCount])
        return (
          <main>
            <p>Count: {count}</p>
            <button onClick={increment}>Increment</button>
          </main>
        )
      }
    `
  )

  expect(await session.hasRedbox()).toBe(false)

  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('Count: 1')
  await session.evaluate(() => document.querySelector('button').click())
  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('Count: 2')

  expect(await session.hasRedbox()).toBe(false)

  await cleanup()
})

test('logbox: can recover from a component error', async () => {
  const [session, cleanup] = await sandbox()

  await session.write(
    'child.js',
    `
      export default function Child() {
        return <p>Hello</p>;
      }
    `
  )

  await session.patch(
    'index.js',
    `
      import Child from './child'

      export default function Index() {
        return (
          <main>
            <Child />
          </main>
        )
      }
    `
  )

  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('Hello')

  await session.patch(
    'child.js',
    `
      // hello
      export default function Child() {
        throw new Error('oops')
      }
    `
  )

  expect(await session.hasRedbox(true)).toBe(true)
  expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
    "child.js (4:14) @ Child

      2 |   // hello
      3 |   export default function Child() {
    > 4 |     throw new Error('oops')
        |          ^
      5 |   }
      6 | "
  `)

  const didNotReload = await session.patch(
    'child.js',
    `
      export default function Child() {
        return <p>Hello</p>;
      }
    `
  )

  expect(didNotReload).toBe(true)
  expect(await session.hasRedbox()).toBe(false)
  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('Hello')

  await cleanup()
})

// https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137262
test('render error not shown right after syntax error', async () => {
  const [session, cleanup] = await sandbox()

  // Starting here:
  await session.patch(
    'index.js',
    `
      class ClassDefault extends React.Component {
        render() {
          return <h1>Default Export</h1>;
        }
      }

      export default ClassDefault;
    `
  )

  expect(
    await session.evaluate(() => document.querySelector('h1').textContent)
  ).toBe('Default Export')

  // Break it with a syntax error:
  await session.patch(
    'index.js',
    `
      import * as React from 'react';

      class ClassDefault extends React.Component {
        render()
          return <h1>Default Export</h1>;
        }
      }

      export default ClassDefault;
    `
  )
  expect(await session.hasRedbox(true)).toBe(true)

  // Now change the code to introduce a runtime error without fixing the syntax error:
  await session.patch(
    'index.js',
    `
      import * as React from 'react';

      class ClassDefault extends React.Component {
        render()
          throw new Error('nooo');
          return <h1>Default Export</h1>;
        }
      }

      export default ClassDefault;
    `
  )
  expect(await session.hasRedbox(true)).toBe(true)

  // Now fix the syntax error:
  await session.patch(
    'index.js',
    `
      import * as React from 'react';

      class ClassDefault extends React.Component {
        render() {
          throw new Error('nooo');
          return <h1>Default Export</h1>;
        }
      }

      export default ClassDefault;
    `
  )
  expect(await session.hasRedbox(true)).toBe(true)
  expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
    "index.js (6:16) @ ClassDefault.render

      4 | class ClassDefault extends React.Component {
      5 |   render() {
    > 6 |     throw new Error('nooo');
        |          ^
      7 |     return <h1>Default Export</h1>;
      8 |   }
      9 | }"
  `)

  await cleanup()
})

// https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137807
test('module init error not shown', async () => {
  // Start here:
  const [session, cleanup] = await sandbox()

  // We start here.
  await session.patch(
    'index.js',
    `
      import * as React from 'react';
      class ClassDefault extends React.Component {
        render() {
          return <h1>Default Export</h1>;
        }
      }
      export default ClassDefault;
    `
  )

  expect(
    await session.evaluate(() => document.querySelector('h1').textContent)
  ).toBe('Default Export')

  // Add a throw in module init phase:
  await session.patch(
    'index.js',
    `
      // top offset for snapshot
      import * as React from 'react';
      throw new Error('no')
      class ClassDefault extends React.Component {
        render() {
          return <h1>Default Export</h1>;
        }
      }
      export default ClassDefault;
    `
  )

  expect(await session.hasRedbox(true)).toBe(true)
  expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
    "index.js (4:12) @ eval

      2 | // top offset for snapshot
      3 | import * as React from 'react';
    > 4 | throw new Error('no')
        |      ^
      5 | class ClassDefault extends React.Component {
      6 |   render() {
      7 |     return <h1>Default Export</h1>;"
  `)

  await cleanup()
})

// https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554144016
test('stuck error', async () => {
  const [session, cleanup] = await sandbox()

  // We start here.
  await session.patch(
    'index.js',
    `
      import * as React from 'react';

      function FunctionDefault() {
        return <h1>Default Export Function</h1>;
      }

      export default FunctionDefault;
    `<commit_msg>Fix Windows LogBox Test (#13147)<commit_after>/* eslint-env jest */
import { sandbox } from './helpers'

jest.setTimeout(1000 * 60 * 5)

test('logbox: can recover from a syntax error without losing state', async () => {
  const [session, cleanup] = await sandbox()

  await session.patch(
    'index.js',
    `
      import { useCallback, useState } from 'react'

      export default function Index() {
        const [count, setCount] = useState(0)
        const increment = useCallback(() => setCount(c => c + 1), [setCount])
        return (
          <main>
            <p>{count}</p>
            <button onClick={increment}>Increment</button>
          </main>
        )
      }
    `
  )

  await session.evaluate(() => document.querySelector('button').click())
  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('1')

  await session.patch('index.js', `export default () => <div/`)

  expect(await session.hasRedbox(true)).toBe(true)
  expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
    "./index.js:1:26
    Syntax error: Unexpected token, expected \\"jsxTagEnd\\"

    > 1 | export default () => <div/
        |                           ^"
  `)

  await session.patch(
    'index.js',
    `
      import { useCallback, useState } from 'react'

      export default function Index() {
        const [count, setCount] = useState(0)
        const increment = useCallback(() => setCount(c => c + 1), [setCount])
        return (
          <main>
            <p>Count: {count}</p>
            <button onClick={increment}>Increment</button>
          </main>
        )
      }
    `
  )

  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('Count: 1')

  expect(await session.hasRedbox()).toBe(false)

  await cleanup()
})

test('logbox: can recover from a event handler error', async () => {
  const [session, cleanup] = await sandbox()

  await session.patch(
    'index.js',
    `
      import { useCallback, useState } from 'react'

      export default function Index() {
        const [count, setCount] = useState(0)
        const increment = useCallback(() => {
          setCount(c => c + 1)
          throw new Error('oops')
        }, [setCount])
        return (
          <main>
            <p>{count}</p>
            <button onClick={increment}>Increment</button>
          </main>
        )
      }
    `
  )

  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('0')
  await session.evaluate(() => document.querySelector('button').click())
  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('1')

  expect(await session.hasRedbox(true)).toBe(true)
  if (process.platform === 'win32') {
    expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
      "index.js (8:16) @ <unknown>

         6 | const increment = useCallback(() => {
         7 |   setCount(c => c + 1)
      >  8 |   throw new Error('oops')
           |        ^
         9 | }, [setCount])
        10 | return (
        11 |   <main>"
    `)
  } else {
    expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
      "index.js (8:16) @ eval

         6 | const increment = useCallback(() => {
         7 |   setCount(c => c + 1)
      >  8 |   throw new Error('oops')
           |        ^
         9 | }, [setCount])
        10 | return (
        11 |   <main>"
    `)
  }

  await session.patch(
    'index.js',
    `
      import { useCallback, useState } from 'react'

      export default function Index() {
        const [count, setCount] = useState(0)
        const increment = useCallback(() => setCount(c => c + 1), [setCount])
        return (
          <main>
            <p>Count: {count}</p>
            <button onClick={increment}>Increment</button>
          </main>
        )
      }
    `
  )

  expect(await session.hasRedbox()).toBe(false)

  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('Count: 1')
  await session.evaluate(() => document.querySelector('button').click())
  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('Count: 2')

  expect(await session.hasRedbox()).toBe(false)

  await cleanup()
})

test('logbox: can recover from a component error', async () => {
  const [session, cleanup] = await sandbox()

  await session.write(
    'child.js',
    `
      export default function Child() {
        return <p>Hello</p>;
      }
    `
  )

  await session.patch(
    'index.js',
    `
      import Child from './child'

      export default function Index() {
        return (
          <main>
            <Child />
          </main>
        )
      }
    `
  )

  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('Hello')

  await session.patch(
    'child.js',
    `
      // hello
      export default function Child() {
        throw new Error('oops')
      }
    `
  )

  expect(await session.hasRedbox(true)).toBe(true)
  expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
    "child.js (4:14) @ Child

      2 |   // hello
      3 |   export default function Child() {
    > 4 |     throw new Error('oops')
        |          ^
      5 |   }
      6 | "
  `)

  const didNotReload = await session.patch(
    'child.js',
    `
      export default function Child() {
        return <p>Hello</p>;
      }
    `
  )

  expect(didNotReload).toBe(true)
  expect(await session.hasRedbox()).toBe(false)
  expect(
    await session.evaluate(() => document.querySelector('p').textContent)
  ).toBe('Hello')

  await cleanup()
})

// https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137262
test('render error not shown right after syntax error', async () => {
  const [session, cleanup] = await sandbox()

  // Starting here:
  await session.patch(
    'index.js',
    `
      class ClassDefault extends React.Component {
        render() {
          return <h1>Default Export</h1>;
        }
      }

      export default ClassDefault;
    `
  )

  expect(
    await session.evaluate(() => document.querySelector('h1').textContent)
  ).toBe('Default Export')

  // Break it with a syntax error:
  await session.patch(
    'index.js',
    `
      import * as React from 'react';

      class ClassDefault extends React.Component {
        render()
          return <h1>Default Export</h1>;
        }
      }

      export default ClassDefault;
    `
  )
  expect(await session.hasRedbox(true)).toBe(true)

  // Now change the code to introduce a runtime error without fixing the syntax error:
  await session.patch(
    'index.js',
    `
      import * as React from 'react';

      class ClassDefault extends React.Component {
        render()
          throw new Error('nooo');
          return <h1>Default Export</h1>;
        }
      }

      export default ClassDefault;
    `
  )
  expect(await session.hasRedbox(true)).toBe(true)

  // Now fix the syntax error:
  await session.patch(
    'index.js',
    `
      import * as React from 'react';

      class ClassDefault extends React.Component {
        render() {
          throw new Error('nooo');
          return <h1>Default Export</h1>;
        }
      }

      export default ClassDefault;
    `
  )
  expect(await session.hasRedbox(true)).toBe(true)
  expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
    "index.js (6:16) @ ClassDefault.render

      4 | class ClassDefault extends React.Component {
      5 |   render() {
    > 6 |     throw new Error('nooo');
        |          ^
      7 |     return <h1>Default Export</h1>;
      8 |   }
      9 | }"
  `)

  await cleanup()
})

// https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137807
test('module init error not shown', async () => {
  // Start here:
  const [session, cleanup] = await sandbox()

  // We start here.
  await session.patch(
    'index.js',
    `
      import * as React from 'react';
      class ClassDefault extends React.Component {
        render() {
          return <h1>Default Export</h1>;
        }
      }
      export default ClassDefault;
    `
  )

  expect(
    await session.evaluate(() => document.querySelector('h1').textContent)
  ).toBe('Default Export')

  // Add a throw in module init phase:
  await session.patch(
    'index.js',
    `
      // top offset for snapshot
      import * as React from 'react';
      throw new Error('no')
      class ClassDefault extends React.Component {
        render() {
          return <h1>Default Export</h1>;
        }
      }
      export default ClassDefault;
    `
  )

  expect(await session.hasRedbox(true)).toBe(true)
  if (process.platform === 'win32') {
    expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
      "index.js (4:12) @ Module../index.js

        2 | // top offset for snapshot
        3 | import * as React from 'react';
      > 4 | throw new Error('no')
          |      ^
        5 | class ClassDefault extends React.Component {
        6 |   render() {
        7 |     return <h1>Default Export</h1>;"
    `)
  } else {
    expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
      "index.js (4:12) @ eval

        2 | // top offset for snapshot
        3 | import * as React from 'react';
      > 4 | throw new Error('no')
          |      ^
        5 | class ClassDefault extends React.Component {
        6 |   render() {
        7 |     return <h1>Default Export</h1>;"
    `)
  }

  await cleanup()
})

// https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554144016
test('stuck error', async () => {
  const [session, cleanup] = await sandbox()

  // We start here.
  await session.patch(
    'index.js',
    `
      import * as React from 'react';

      function FunctionDefault() {
        return <h1>Default Export Function</h1>;
      }

      export default FunctionDefault;
    `
{'fraction_non_alphanumeric': 0.14328174643845445, 'fraction_numerical': 0.013938710669263093, 'mean_word_length': 2.1908109875735775, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 0, '>': 188, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7238315', 'n_tokens_mistral': 6015, 'n_tokens_neox': 5887, 'n_words': 1385}