From b19585f7fa60e7c209a8ddd5d152f7810452dbab Mon Sep 17 00:00:00 2001 From: Will Binns-Smith Date: Tue, 6 Feb 2024 11:09:48 -0800 Subject: [PATCH] Turbopack: convert between locations correctly (#61477) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - parsed stack traces (and error stack locations in js) have 1-based lines and 1-based columns - source map tokens have 0-based lines and 0-based columns - babel code frames use 1-based lines and 0-based columns This was not always respected. This preserves the 1-based lines and columns in anything called a stack frame, 0-based lines and columns for source map apis, and converts to babel’s format as needed. Closes PACK-2341 --------- Co-authored-by: Tobias Koppers --- .../crates/napi/src/next_api/project.rs | 11 +++-- packages/next/src/build/swc/index.ts | 14 +++++- .../lib/router-utils/setup-dev-bundler.ts | 2 +- .../src/middleware-turbopack.ts | 4 +- packages/react-dev-overlay/src/middleware.ts | 5 ++- .../ReactRefreshLogBox-builtins.test.ts | 19 ++++---- .../acceptance-app/ReactRefreshLogBox.test.ts | 4 +- .../ReactRefreshRegression.test.ts | 12 ++--- .../ReactRefreshLogBox.test.ts.snap | 44 ++++++++++--------- .../acceptance-app/error-recovery.test.ts | 38 +++++----------- .../ReactRefreshLogBox-builtins.test.ts | 19 ++++---- .../acceptance/ReactRefreshLogBox.test.ts | 4 +- .../acceptance/ReactRefreshRegression.test.ts | 2 +- .../ReactRefreshLogBox.test.ts.snap | 24 +++++----- .../__snapshots__/error-recovery.test.ts.snap | 4 +- .../acceptance/error-recovery.test.ts | 8 ++-- test/development/basic/hmr.test.ts | 4 +- .../pages-dir/client-navigation/index.test.ts | 4 +- .../config-devtool-dev/test/index.test.js | 4 +- .../server-side-dev-errors/test/index.test.js | 8 ++-- test/turbopack-tests-manifest.json | 9 ++-- 21 files changed, 127 insertions(+), 116 deletions(-) diff --git a/packages/next-swc/crates/napi/src/next_api/project.rs b/packages/next-swc/crates/napi/src/next_api/project.rs index 1e8eff0c8ff72..4d2c93d83c036 100644 --- a/packages/next-swc/crates/napi/src/next_api/project.rs +++ b/packages/next-swc/crates/napi/src/next_api/project.rs @@ -791,7 +791,9 @@ pub fn project_update_info_subscribe( #[derive(Debug)] #[napi(object)] pub struct StackFrame { + // 1-indexed, unlike source map tokens pub column: Option, + // 1-indexed, unlike source map tokens pub file: String, pub is_server: bool, pub line: u32, @@ -876,7 +878,10 @@ pub async fn project_trace_source( }; let token = map - .lookup_token(frame.line as usize, frame.column.unwrap_or(0) as usize) + .lookup_token( + (frame.line as usize).saturating_sub(1), + (frame.column.unwrap_or(1) as usize).saturating_sub(1), + ) .await? .clone_value() .context("Unable to trace token from sourcemap")?; @@ -893,8 +898,8 @@ pub async fn project_trace_source( Ok(Some(StackFrame { file: source_file.to_string(), method_name: token.name, - line: token.original_line as u32, - column: Some(token.original_column as u32), + line: token.original_line as u32 + 1, + column: Some(token.original_column as u32 + 1), is_server: frame.is_server, })) }) diff --git a/packages/next/src/build/swc/index.ts b/packages/next/src/build/swc/index.ts index 3dc415575f8b6..bc8c488a11baf 100644 --- a/packages/next/src/build/swc/index.ts +++ b/packages/next/src/build/swc/index.ts @@ -507,8 +507,18 @@ export interface Issue { content?: string } range?: { - start: { line: number; column: number } - end: { line: number; column: number } + start: { + // 0-indexed + line: number + // 0-indexed + column: number + } + end: { + // 0-indexed + line: number + // 0-indexed + column: number + } } } documentationLink: string diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index a5403300ee805..bce38c0d6cfc8 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -339,7 +339,7 @@ async function startWatcher(opts: SetupOpts) { if (source && source.range) { const { start } = source.range message = `${formattedFilePath}:${start.line + 1}:${ - start.column + start.column + 1 }\n${formattedTitle}` } else if (formattedFilePath) { message = `${formattedFilePath}\n${formattedTitle}` diff --git a/packages/react-dev-overlay/src/middleware-turbopack.ts b/packages/react-dev-overlay/src/middleware-turbopack.ts index 12167f0b0f268..80219a847d970 100644 --- a/packages/react-dev-overlay/src/middleware-turbopack.ts +++ b/packages/react-dev-overlay/src/middleware-turbopack.ts @@ -16,7 +16,9 @@ interface Project { } interface TurbopackStackFrame { + // 1-based column: number | null + // 1-based file: string isServer: boolean line: number @@ -87,7 +89,7 @@ export async function createOriginalStackFrame( { start: { line: traced.frame.lineNumber, - column: traced.frame.column ?? 0, + column: traced.frame.column ?? 1, }, }, { forceColor: true } diff --git a/packages/react-dev-overlay/src/middleware.ts b/packages/react-dev-overlay/src/middleware.ts index 896559d96f0bb..49e5ca746bed1 100644 --- a/packages/react-dev-overlay/src/middleware.ts +++ b/packages/react-dev-overlay/src/middleware.ts @@ -194,6 +194,7 @@ export async function createOriginalStackFrame({ return moduleNotFoundResult } + // This returns 1-based lines and 0-based columns return await findOriginalSourcePositionAndContent(source, { line, column, @@ -225,7 +226,7 @@ export async function createOriginalStackFrame({ ? path.relative(rootDirectory, filePath) : sourcePosition.source, lineNumber: sourcePosition.line, - column: sourcePosition.column, + column: (sourcePosition.column ?? 0) + 1, methodName: sourcePosition.name || // default is not a valid identifier in JS so webpack uses a custom variable when it's an unnamed default export @@ -245,7 +246,7 @@ export async function createOriginalStackFrame({ { start: { line: sourcePosition.line, - column: sourcePosition.column ?? 0, + column: (sourcePosition.column ?? 0) + 1, }, }, { forceColor: true } diff --git a/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts b/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts index 77fe45d72e29e..371ccebe19eec 100644 --- a/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts +++ b/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts @@ -52,7 +52,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { expect(await session.hasRedbox()).toBe(true) if (process.env.TURBOPACK) { expect(await session.getRedboxSource()).toMatchInlineSnapshot(` - "./node_modules/my-package/index.js:1:12 + "./node_modules/my-package/index.js:1:13 Module not found: Can't resolve 'dns' > 1 | const dns = require('dns') | ^^^^^^^^^^^^^^ @@ -62,7 +62,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { `) } else { expect(await session.getRedboxSource()).toMatchInlineSnapshot(` - "./node_modules/my-package/index.js:1:12 + "./node_modules/my-package/index.js:1:13 Module not found: Can't resolve 'dns' https://nextjs.org/docs/messages/module-not-found @@ -98,7 +98,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { const source = await session.getRedboxSource() if (process.env.TURBOPACK) { expect(source).toMatchInlineSnapshot(` - "./index.js:1:0 + "./index.js:1:1 Module not found: Can't resolve 'b' > 1 | import Comp from 'b' | ^^^^^^^^^^^^^^^^^^^^ @@ -110,9 +110,10 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { `) } else { expect(source).toMatchInlineSnapshot(` - "./index.js:1:0 + "./index.js:1:1 Module not found: Can't resolve 'b' > 1 | import Comp from 'b' + | ^ 2 | export default function Oops() { 3 | return ( 4 |
@@ -150,7 +151,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { const source = await session.getRedboxSource() if (process.env.TURBOPACK) { expect(source).toMatchInlineSnapshot(` - "./app/page.js:2:0 + "./app/page.js:2:1 Module not found: Can't resolve 'b' 1 | 'use client' > 2 | import Comp from 'b' @@ -163,10 +164,11 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { `) } else { expect(source).toMatchInlineSnapshot(` - "./app/page.js:2:0 + "./app/page.js:2:1 Module not found: Can't resolve 'b' 1 | 'use client' > 2 | import Comp from 'b' + | ^ 3 | export default function Oops() { 4 | return ( 5 |
@@ -199,7 +201,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { const source = await session.getRedboxSource() if (process.env.TURBOPACK) { expect(source).toMatchInlineSnapshot(` - "./app/page.js:2:0 + "./app/page.js:2:1 Module not found: Can't resolve './non-existent.css' 1 | 'use client' > 2 | import './non-existent.css' @@ -212,10 +214,11 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { `) } else { expect(source).toMatchInlineSnapshot(` - "./app/page.js:2:0 + "./app/page.js:2:1 Module not found: Can't resolve './non-existent.css' 1 | 'use client' > 2 | import './non-existent.css' + | ^ 3 | export default function Page(props) { 4 | return

index page

5 | } diff --git a/test/development/acceptance-app/ReactRefreshLogBox.test.ts b/test/development/acceptance-app/ReactRefreshLogBox.test.ts index aa87dbaf7b918..bf2993edb6af5 100644 --- a/test/development/acceptance-app/ReactRefreshLogBox.test.ts +++ b/test/development/acceptance-app/ReactRefreshLogBox.test.ts @@ -222,7 +222,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { const source = next.normalizeTestDirContent(await session.getRedboxSource()) if (IS_TURBOPACK) { expect(source).toMatchInlineSnapshot(` - "./index.js:7:0 + "./index.js:7:1 Parsing ecmascript source code failed 5 | div 6 | ) @@ -357,7 +357,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { expect(await session.hasRedbox()).toBe(true) const source = await session.getRedboxSource() expect(source).toMatch( - IS_TURBOPACK ? './index.module.css:1:8' : './index.module.css:1:1' + IS_TURBOPACK ? './index.module.css:1:9' : './index.module.css:1:1' ) if (!IS_TURBOPACK) { expect(source).toMatch('Syntax error: ') diff --git a/test/development/acceptance-app/ReactRefreshRegression.test.ts b/test/development/acceptance-app/ReactRefreshRegression.test.ts index e129f43eb3c25..ecafe5dc3c1d0 100644 --- a/test/development/acceptance-app/ReactRefreshRegression.test.ts +++ b/test/development/acceptance-app/ReactRefreshRegression.test.ts @@ -286,7 +286,7 @@ describe('ReactRefreshRegression app', () => { const source = await session.getRedboxSource() expect(source.split(/\r?\n/g).slice(2).join('\n')).toMatchInlineSnapshot(` "> 1 | export default function () { throw new Error('boom'); } - | ^" + | ^" `) await cleanup() @@ -305,7 +305,7 @@ describe('ReactRefreshRegression app', () => { const source = await session.getRedboxSource() expect(source.split(/\r?\n/g).slice(2).join('\n')).toMatchInlineSnapshot(` "> 1 | export default function Page() { throw new Error('boom'); } - | ^" + | ^" `) await cleanup() @@ -326,10 +326,10 @@ describe('ReactRefreshRegression app', () => { const source = await session.getRedboxSource() expect(source.split(/\r?\n/g).slice(2).join('\n')).toMatchInlineSnapshot(` - " 1 | 'use client' - > 2 | export default function Page() { throw new Error('boom'); } - | ^" - `) + " 1 | 'use client' + > 2 | export default function Page() { throw new Error('boom'); } + | ^" + `) await cleanup() }) diff --git a/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox.test.ts.snap b/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox.test.ts.snap index 42a0e0d1f1a84..4a148704a8ab0 100644 --- a/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox.test.ts.snap +++ b/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox.test.ts.snap @@ -11,9 +11,10 @@ Import trace for requested module: `; exports[`ReactRefreshLogBox app default Import trace when module not found in layout 1`] = ` -"./app/module.js:1:0 +"./app/module.js:1:1 Module not found: Can't resolve 'non-existing-module' > 1 | import "non-existing-module" + | ^ https://nextjs.org/docs/messages/module-not-found @@ -22,31 +23,31 @@ Import trace for requested module: `; exports[`ReactRefreshLogBox app default Should not show __webpack_exports__ when exporting anonymous arrow function 1`] = ` -"index.js (3:10) @ default +"index.js (3:11) @ default 1 | export default () => { 2 | if (typeof window !== 'undefined') { > 3 | throw new Error('test') - | ^ + | ^ 4 | } 5 | 6 | return null" `; exports[`ReactRefreshLogBox app default boundaries 1`] = ` -"FunctionDefault.js (1:50) @ FunctionDefault +"FunctionDefault.js (1:51) @ FunctionDefault > 1 | export default function FunctionDefault() { throw new Error('no'); } - | ^" + | ^" `; exports[`ReactRefreshLogBox app default conversion to class component (1) 1`] = ` -"Child.js (4:10) @ ClickCount.render +"Child.js (4:11) @ ClickCount.render 2 | export default class ClickCount extends Component { 3 | render() { > 4 | throw new Error() - | ^ + | ^ 5 | } 6 | }" `; @@ -76,31 +77,31 @@ exports[`ReactRefreshLogBox app default logbox: anchors links in error messages exports[`ReactRefreshLogBox app default logbox: anchors links in error messages 9`] = `"http://example.com/"`; exports[`ReactRefreshLogBox app default module init error not shown 1`] = ` -"index.js (3:6) @ eval +"index.js (3:7) @ eval 1 | // top offset for snapshot 2 | import * as React from 'react'; > 3 | throw new Error('no') - | ^ + | ^ 4 | class ClassDefault extends React.Component { 5 | render() { 6 | return

Default Export

;" `; exports[`ReactRefreshLogBox app default should strip whitespace correctly with newline 1`] = ` -"index.js (7:14) @ onClick +"index.js (7:15) @ onClick 5 | 6 | { > 7 | throw new Error('idk') - | ^ + | ^ 8 | }}> 9 | click me 10 | " `; exports[`ReactRefreshLogBox app turbo Can't resolve @import in CSS file 1`] = ` -"./app/styles1.css:1:0 +"./app/styles1.css:1:1 Parsing css source code failed > 1 | @import "./styles2.css" | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,7 +110,7 @@ Unexpected end of file, but expected ';' or '{'" `; exports[`ReactRefreshLogBox app turbo Import trace when module not found in layout 1`] = ` -"./app/module.js:1:0 +"./app/module.js:1:1 Module not found: Can't resolve 'non-existing-module' > 1 | import "non-existing-module" | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,21 +119,22 @@ https://nextjs.org/docs/messages/module-not-found" `; exports[`ReactRefreshLogBox app turbo Should not show __webpack_exports__ when exporting anonymous arrow function 1`] = ` -"index.js (3:2) @ {default export} +"index.js (3:11) @ {default export} 1 | export default () => { 2 | if (typeof window !== 'undefined') { > 3 | throw new Error('test') - | ^ + | ^ 4 | } 5 | 6 | return null" `; exports[`ReactRefreshLogBox app turbo boundaries 1`] = ` -"FunctionDefault.js (0:67) @ FunctionDefault +"FunctionDefault.js (1:51) @ FunctionDefault - 1 | export default function FunctionDefault() { throw new Error('no'); }" +> 1 | export default function FunctionDefault() { throw new Error('no'); } + | ^" `; exports[`ReactRefreshLogBox app turbo logbox: anchors links in error messages 1`] = `"Error: end http://nextjs.org"`; @@ -152,24 +154,24 @@ exports[`ReactRefreshLogBox app turbo logbox: anchors links in error messages 8` exports[`ReactRefreshLogBox app turbo logbox: anchors links in error messages 9`] = `"http://example.com/"`; exports[`ReactRefreshLogBox app turbo module init error not shown 1`] = ` -"index.js (3:6) @ +"index.js (3:7) @ 1 | // top offset for snapshot 2 | import * as React from 'react'; > 3 | throw new Error('no') - | ^ + | ^ 4 | class ClassDefault extends React.Component { 5 | render() { 6 | return

Default Export

;" `; exports[`ReactRefreshLogBox app turbo should strip whitespace correctly with newline 1`] = ` -"index.js (7:6) @ onClick +"index.js (7:15) @ onClick 5 | 6 | { > 7 | throw new Error('idk') - | ^ + | ^ 8 | }}> 9 | click me 10 | " diff --git a/test/development/acceptance-app/error-recovery.test.ts b/test/development/acceptance-app/error-recovery.test.ts index 745d2aa20e76b..58ab9704a6196 100644 --- a/test/development/acceptance-app/error-recovery.test.ts +++ b/test/development/acceptance-app/error-recovery.test.ts @@ -6,7 +6,7 @@ import path from 'path' import { outdent } from 'outdent' describe.each(['default', 'turbo'])('Error recovery app %s', () => { - const { next, isTurbopack } = nextTestSetup({ + const { next } = nextTestSetup({ files: new FileRef(path.join(__dirname, 'fixtures', 'default-template')), dependencies: { react: 'latest', @@ -144,31 +144,17 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => { await session.waitForAndOpenRuntimeError() - if (isTurbopack) { - expect(await session.getRedboxSource()).toMatchInlineSnapshot(` - "index.js (7:5) @ eval - - 5 | const increment = useCallback(() => { - 6 | setCount(c => c + 1) - > 7 | throw new Error('oops') - | ^ - 8 | }, [setCount]) - 9 | return ( - 10 |
" - `) - } else { - expect(await session.getRedboxSource()).toMatchInlineSnapshot(` - "index.js (7:10) @ eval - - 5 | const increment = useCallback(() => { - 6 | setCount(c => c + 1) - > 7 | throw new Error('oops') - | ^ - 8 | }, [setCount]) - 9 | return ( - 10 |
" - `) - } + expect(await session.getRedboxSource()).toMatchInlineSnapshot(` + "index.js (7:11) @ eval + + 5 | const increment = useCallback(() => { + 6 | setCount(c => c + 1) + > 7 | throw new Error('oops') + | ^ + 8 | }, [setCount]) + 9 | return ( + 10 |
" + `) await session.patch( 'index.js', diff --git a/test/development/acceptance/ReactRefreshLogBox-builtins.test.ts b/test/development/acceptance/ReactRefreshLogBox-builtins.test.ts index 3250845edf88c..65069a556c8cc 100644 --- a/test/development/acceptance/ReactRefreshLogBox-builtins.test.ts +++ b/test/development/acceptance/ReactRefreshLogBox-builtins.test.ts @@ -48,7 +48,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { expect(await session.getRedboxSource()).toMatchInlineSnapshot( process.env.TURBOPACK ? ` - "./node_modules/my-package/index.js:1:12 + "./node_modules/my-package/index.js:1:13 Module not found: Can't resolve 'dns' > 1 | const dns = require('dns') | ^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { https://nextjs.org/docs/messages/module-not-found" ` : ` - "./node_modules/my-package/index.js:1:0 + "./node_modules/my-package/index.js:1:1 Module not found: Can't resolve 'dns' https://nextjs.org/docs/messages/module-not-found @@ -94,7 +94,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { const source = await session.getRedboxSource() if (process.env.TURBOPACK) { expect(source).toMatchInlineSnapshot(` - "./index.js:1:0 + "./index.js:1:1 Module not found: Can't resolve 'b' > 1 | import Comp from 'b' | ^^^^^^^^^^^^^^^^^^^^ @@ -106,9 +106,10 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { `) } else { expect(source).toMatchInlineSnapshot(` - "./index.js:1:0 + "./index.js:1:1 Module not found: Can't resolve 'b' > 1 | import Comp from 'b' + | ^ 2 | 3 | export default function Oops() { 4 | return ( @@ -146,7 +147,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { const source = await session.getRedboxSource() if (process.env.TURBOPACK) { expect(source).toMatchInlineSnapshot(` - "./pages/index.js:1:0 + "./pages/index.js:1:1 Module not found: Can't resolve 'b' > 1 | import Comp from 'b' | ^^^^^^^^^^^^^^^^^^^^ @@ -158,9 +159,10 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { `) } else { expect(source).toMatchInlineSnapshot(` - "./pages/index.js:1:0 + "./pages/index.js:1:1 Module not found: Can't resolve 'b' > 1 | import Comp from 'b' + | ^ 2 | 3 | export default function Oops() { 4 | return ( @@ -201,7 +203,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { const source = await session.getRedboxSource() if (process.env.TURBOPACK) { expect(source).toMatchInlineSnapshot(` - "./pages/_app.js:1:0 + "./pages/_app.js:1:1 Module not found: Can't resolve './non-existent.css' > 1 | import './non-existent.css' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -213,9 +215,10 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { `) } else { expect(source).toMatchInlineSnapshot(` - "./pages/_app.js:1:0 + "./pages/_app.js:1:1 Module not found: Can't resolve './non-existent.css' > 1 | import './non-existent.css' + | ^ 2 | 3 | export default function App({ Component, pageProps }) { 4 | return diff --git a/test/development/acceptance/ReactRefreshLogBox.test.ts b/test/development/acceptance/ReactRefreshLogBox.test.ts index 06553688a8997..ed28cd701e075 100644 --- a/test/development/acceptance/ReactRefreshLogBox.test.ts +++ b/test/development/acceptance/ReactRefreshLogBox.test.ts @@ -211,7 +211,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { const source = next.normalizeTestDirContent(await session.getRedboxSource()) if (process.env.TURBOPACK) { expect(source).toMatchInlineSnapshot(` - "./index.js:7:0 + "./index.js:7:1 Parsing ecmascript source code failed 5 | div 6 | ) @@ -347,7 +347,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { const source = await session.getRedboxSource() expect(source).toMatch( process.env.TURBOPACK - ? './index.module.css:1:8' + ? './index.module.css:1:9' : './index.module.css:1:1' ) if (!process.env.TURBOPACK) { diff --git a/test/development/acceptance/ReactRefreshRegression.test.ts b/test/development/acceptance/ReactRefreshRegression.test.ts index 803adc244ef58..442538e020139 100644 --- a/test/development/acceptance/ReactRefreshRegression.test.ts +++ b/test/development/acceptance/ReactRefreshRegression.test.ts @@ -288,7 +288,7 @@ describe('ReactRefreshRegression', () => { const source = await session.getRedboxSource() expect(source.split(/\r?\n/g).slice(2).join('\n')).toMatchInlineSnapshot(` "> 1 | export default function () { throw new Error('boom'); } - | ^" + | ^" `) await cleanup() diff --git a/test/development/acceptance/__snapshots__/ReactRefreshLogBox.test.ts.snap b/test/development/acceptance/__snapshots__/ReactRefreshLogBox.test.ts.snap index dfa0a3b09b2b2..bd329bdd37d5a 100644 --- a/test/development/acceptance/__snapshots__/ReactRefreshLogBox.test.ts.snap +++ b/test/development/acceptance/__snapshots__/ReactRefreshLogBox.test.ts.snap @@ -1,19 +1,19 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`ReactRefreshLogBox default boundaries 1`] = ` -"FunctionDefault.js (1:50) @ FunctionDefault +"FunctionDefault.js (1:51) @ FunctionDefault > 1 | export default function FunctionDefault() { throw new Error('no'); } - | ^" + | ^" `; exports[`ReactRefreshLogBox default conversion to class component (1) 1`] = ` -"Child.js (4:10) @ ClickCount.render +"Child.js (4:11) @ ClickCount.render 2 | export default class ClickCount extends Component { 3 | render() { > 4 | throw new Error() - | ^ + | ^ 5 | } 6 | }" `; @@ -47,24 +47,24 @@ exports[`ReactRefreshLogBox default logbox: anchors links in error messages 11`] exports[`ReactRefreshLogBox default logbox: anchors links in error messages 12`] = `"http://example.com/"`; exports[`ReactRefreshLogBox default module init error not shown 1`] = ` -"index.js (3:6) @ eval +"index.js (3:7) @ eval 1 | // top offset for snapshot 2 | import * as React from 'react'; > 3 | throw new Error('no') - | ^ + | ^ 4 | class ClassDefault extends React.Component { 5 | render() { 6 | return

Default Export

;" `; exports[`ReactRefreshLogBox default should strip whitespace correctly with newline 1`] = ` -"index.js (8:26) @ onClick +"index.js (8:27) @ onClick 6 | 7 | { > 8 | throw new Error('idk') - | ^ + | ^ 9 | }}> 10 | click me 11 | " @@ -93,24 +93,24 @@ exports[`ReactRefreshLogBox turbo logbox: anchors links in error messages 11`] = exports[`ReactRefreshLogBox turbo logbox: anchors links in error messages 12`] = `"http://example.com/"`; exports[`ReactRefreshLogBox turbo module init error not shown 1`] = ` -"index.js (3:6) @ +"index.js (3:7) @ 1 | // top offset for snapshot 2 | import * as React from 'react'; > 3 | throw new Error('no') - | ^ + | ^ 4 | class ClassDefault extends React.Component { 5 | render() { 6 | return

Default Export

;" `; exports[`ReactRefreshLogBox turbo should strip whitespace correctly with newline 1`] = ` -"index.js (8:18) @ onClick +"index.js (8:27) @ onClick 6 | 7 | { > 8 | throw new Error('idk') - | ^ + | ^ 9 | }}> 10 | click me 11 | " diff --git a/test/development/acceptance/__snapshots__/error-recovery.test.ts.snap b/test/development/acceptance/__snapshots__/error-recovery.test.ts.snap index a3ec0620565e2..8c12e2cd48138 100644 --- a/test/development/acceptance/__snapshots__/error-recovery.test.ts.snap +++ b/test/development/acceptance/__snapshots__/error-recovery.test.ts.snap @@ -1,12 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`ReactRefreshLogBox default syntax > runtime error 1`] = ` -"index.js (5:8) @ Error +"index.js (5:9) @ Error 3 | setInterval(() => { 4 | i++ > 5 | throw Error('no ' + i) - | ^ + | ^ 6 | }, 1000) 7 | export default function FunctionNamed() { 8 | return
" diff --git a/test/development/acceptance/error-recovery.test.ts b/test/development/acceptance/error-recovery.test.ts index 37d8458a71c0e..0b9e4c61216a2 100644 --- a/test/development/acceptance/error-recovery.test.ts +++ b/test/development/acceptance/error-recovery.test.ts @@ -107,24 +107,24 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { expect(await session.hasRedbox()).toBe(true) if (isTurbopack) { expect(await session.getRedboxSource()).toMatchInlineSnapshot(` - "index.js (7:5) @ + "index.js (7:11) @ 5 | const increment = useCallback(() => { 6 | setCount(c => c + 1) > 7 | throw new Error('oops') - | ^ + | ^ 8 | }, [setCount]) 9 | return ( 10 |
" `) } else { expect(await session.getRedboxSource()).toMatchInlineSnapshot(` - "index.js (7:10) @ eval + "index.js (7:11) @ eval 5 | const increment = useCallback(() => { 6 | setCount(c => c + 1) > 7 | throw new Error('oops') - | ^ + | ^ 8 | }, [setCount]) 9 | return ( 10 |
" diff --git a/test/development/basic/hmr.test.ts b/test/development/basic/hmr.test.ts index 37310e9db97d3..0e11f6ac1278d 100644 --- a/test/development/basic/hmr.test.ts +++ b/test/development/basic/hmr.test.ts @@ -524,7 +524,7 @@ describe.each([[''], ['/docs']])( `) } else if (basePath === '' && process.env.TURBOPACK) { expect(source).toMatchInlineSnapshot(` - "./pages/hmr/about2.js:7:0 + "./pages/hmr/about2.js:7:1 Parsing ecmascript source code failed 5 | div 6 | ) @@ -562,7 +562,7 @@ describe.each([[''], ['/docs']])( `) } else if (basePath === '/docs' && process.env.TURBOPACK) { expect(source).toMatchInlineSnapshot(` - "./pages/hmr/about2.js:7:0 + "./pages/hmr/about2.js:7:1 Parsing ecmascript source code failed 5 | div 6 | ) diff --git a/test/development/pages-dir/client-navigation/index.test.ts b/test/development/pages-dir/client-navigation/index.test.ts index 10a40bcc29a93..3e19c2cec2558 100644 --- a/test/development/pages-dir/client-navigation/index.test.ts +++ b/test/development/pages-dir/client-navigation/index.test.ts @@ -1385,7 +1385,7 @@ createNextDescribe( const text = await getRedboxSource(browser) expect(text).toMatch(/An Expected error occurred/) expect(text).toMatch( - /pages[\\/]error-inside-browser-page\.js \(5:12\)/ + /pages[\\/]error-inside-browser-page\.js \(5:13\)/ ) } finally { if (browser) { @@ -1404,7 +1404,7 @@ createNextDescribe( expect(await hasRedbox(browser)).toBe(true) const text = await getRedboxSource(browser) expect(text).toMatch(/An Expected error occurred/) - expect(text).toMatch(/error-in-the-browser-global-scope\.js \(2:8\)/) + expect(text).toMatch(/error-in-the-browser-global-scope\.js \(2:9\)/) } finally { if (browser) { await browser.close() diff --git a/test/integration/config-devtool-dev/test/index.test.js b/test/integration/config-devtool-dev/test/index.test.js index 6b4962b434ea5..e1f77a359e299 100644 --- a/test/integration/config-devtool-dev/test/index.test.js +++ b/test/integration/config-devtool-dev/test/index.test.js @@ -40,12 +40,12 @@ const appDir = join(__dirname, '../') // TODO: add win32 snapshot } else { expect(await getRedboxSource(browser)).toMatchInlineSnapshot(` - "pages/index.js (5:10) @ eval + "pages/index.js (5:11) @ eval 3 | export default function Index(props) { 4 | useEffect(() => { > 5 | throw new Error('this should render') - | ^ + | ^ 6 | }, []) 7 | return
Index Page
8 | }" diff --git a/test/integration/server-side-dev-errors/test/index.test.js b/test/integration/server-side-dev-errors/test/index.test.js index 6db15946e366b..f96e3a83a31ad 100644 --- a/test/integration/server-side-dev-errors/test/index.test.js +++ b/test/integration/server-side-dev-errors/test/index.test.js @@ -206,7 +206,7 @@ describe('server-side dev errors', () => { const err = stderr.slice(stderrIdx) return err.includes('pages/uncaught-rejection.js') && - (err.includes('7:19') || err.includes('7:5')) && + err.includes('7:20') && err.includes('getServerSideProps') && err.includes('catch this rejection') ? 'success' @@ -222,7 +222,7 @@ describe('server-side dev errors', () => { const cleanStderr = stripAnsi(stderr.slice(stderrIdx)) return cleanStderr.includes('pages/uncaught-empty-rejection.js') && - (cleanStderr.includes('7:19') || cleanStderr.includes('7:5')) && + cleanStderr.includes('7:20') && cleanStderr.includes('getServerSideProps') && cleanStderr.includes('new Error()') ? 'success' @@ -238,7 +238,7 @@ describe('server-side dev errors', () => { const err = stderr.slice(stderrIdx) return err.includes('pages/uncaught-exception.js') && - (err.includes('7:10') || err.includes('7:5')) && + err.includes('7:11') && err.includes('getServerSideProps') && err.includes('catch this exception') ? 'success' @@ -254,7 +254,7 @@ describe('server-side dev errors', () => { const cleanStderr = stripAnsi(stderr.slice(stderrIdx)) return cleanStderr.includes('pages/uncaught-empty-exception.js') && - (cleanStderr.includes('7:10') || cleanStderr.includes('7:5')) && + cleanStderr.includes('7:11') && cleanStderr.includes('getServerSideProps') && cleanStderr.includes('new Error()') ? 'success' diff --git a/test/turbopack-tests-manifest.json b/test/turbopack-tests-manifest.json index 23244b04026d9..f74f63cee531d 100644 --- a/test/turbopack-tests-manifest.json +++ b/test/turbopack-tests-manifest.json @@ -990,11 +990,11 @@ }, "test/development/acceptance-app/ReactRefreshRegression.test.ts": { "passed": [ - "ReactRefreshRegression app can fast refresh a page with static generation" + "ReactRefreshRegression app can fast refresh a page with static generation", + "ReactRefreshRegression app shows an overlay for server-side error in client component" ], "failed": [ "ReactRefreshRegression app shows an overlay for anonymous function server-side error", - "ReactRefreshRegression app shows an overlay for server-side error in client component", "ReactRefreshRegression app shows an overlay for server-side error in server component" ], "pending": [ @@ -1336,11 +1336,10 @@ "ReactRefreshRegression can fast refresh a page with config", "ReactRefreshRegression can fast refresh a page with getServerSideProps", "ReactRefreshRegression can fast refresh a page with getStaticProps", + "ReactRefreshRegression shows an overlay for a server-side error", "ReactRefreshRegression styled-components hydration mismatch" ], - "failed": [ - "ReactRefreshRegression shows an overlay for a server-side error" - ], + "failed": [], "pending": [ "ReactRefreshRegression Turbopack skipped tests custom loader (mdx) should have Fast Refresh enabled" ],