mirror of
https://github.com/hanzoai/esbuild.git
synced 2026-09-24 16:58:50 +00:00
339 lines
8.5 KiB
Go
339 lines
8.5 KiB
Go
package api_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/evanw/esbuild/internal/test"
|
|
"github.com/evanw/esbuild/pkg/api"
|
|
)
|
|
|
|
func TestFormatMessages(t *testing.T) {
|
|
check := func(name string, opts api.FormatMessagesOptions, msg api.Message, expected string) {
|
|
t.Helper()
|
|
t.Run(name, func(t *testing.T) {
|
|
test.AssertEqualWithDiff(t, api.FormatMessages([]api.Message{msg}, opts)[0], expected)
|
|
})
|
|
}
|
|
|
|
check("Error", api.FormatMessagesOptions{Kind: api.ErrorMessage}, api.Message{Text: "This is a test"}, "✘ [ERROR] This is a test\n\n")
|
|
check("Warning", api.FormatMessagesOptions{Kind: api.WarningMessage}, api.Message{Text: "This is a test"}, "▲ [WARNING] This is a test\n\n")
|
|
|
|
check("Basic location",
|
|
api.FormatMessagesOptions{},
|
|
api.Message{Text: "This is a test", Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 100,
|
|
Column: 5, // 0-based
|
|
Length: 3,
|
|
LineText: "this.foo();",
|
|
Suggestion: "bar",
|
|
}},
|
|
`✘ [ERROR] This is a test
|
|
|
|
some file.js:100:5:
|
|
100 │ this.foo();
|
|
│ ~~~
|
|
╵ bar
|
|
|
|
`,
|
|
)
|
|
|
|
check("Unicode location",
|
|
api.FormatMessagesOptions{
|
|
Kind: api.WarningMessage,
|
|
},
|
|
api.Message{Text: "This is a test", Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 100,
|
|
Column: 17, // In UTF-8 bytes
|
|
Length: 10, // In UTF-8 bytes
|
|
LineText: "𝓉𝒽𝒾𝓈.𝒻ℴℴ();",
|
|
Suggestion: "𝒷𝒶𝓇",
|
|
}},
|
|
`▲ [WARNING] This is a test
|
|
|
|
some file.js:100:17:
|
|
100 │ 𝓉𝒽𝒾𝓈.𝒻ℴℴ();
|
|
│ ~~~
|
|
╵ 𝒷𝒶𝓇
|
|
|
|
`,
|
|
)
|
|
|
|
check("Tab stop rendering",
|
|
api.FormatMessagesOptions{
|
|
Kind: api.WarningMessage,
|
|
},
|
|
api.Message{Text: "This is a test", Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 100,
|
|
Column: 6,
|
|
Length: 4,
|
|
LineText: "0\t1\t23\t45\t678",
|
|
}},
|
|
`▲ [WARNING] This is a test
|
|
|
|
some file.js:100:6:
|
|
100 │ 0 1 23 45 678
|
|
╵ ~~~~~~
|
|
|
|
`,
|
|
)
|
|
|
|
check("Truncated location tail, zero length",
|
|
api.FormatMessagesOptions{
|
|
TerminalWidth: 32,
|
|
},
|
|
api.Message{Text: "This is a test", Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 100,
|
|
Column: 3,
|
|
Length: 0,
|
|
LineText: "012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI",
|
|
}},
|
|
`✘ [ERROR] This is a test
|
|
|
|
some file.js:100:3:
|
|
100 │ 012345678 abcdefg...
|
|
╵ ^
|
|
|
|
`,
|
|
)
|
|
|
|
check("Truncated location tail, nonzero length",
|
|
api.FormatMessagesOptions{
|
|
TerminalWidth: 32,
|
|
},
|
|
api.Message{Text: "This is a test", Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 100,
|
|
Column: 3,
|
|
Length: 6,
|
|
LineText: "012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI",
|
|
}},
|
|
`✘ [ERROR] This is a test
|
|
|
|
some file.js:100:3:
|
|
100 │ 012345678 abcdefg...
|
|
╵ ~~~~~~
|
|
|
|
`,
|
|
)
|
|
|
|
check("Truncated location tail, truncated length",
|
|
api.FormatMessagesOptions{
|
|
TerminalWidth: 32,
|
|
},
|
|
api.Message{Text: "This is a test", Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 100,
|
|
Column: 3,
|
|
Length: 100,
|
|
LineText: "012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI",
|
|
}},
|
|
`✘ [ERROR] This is a test
|
|
|
|
some file.js:100:3:
|
|
100 │ 012345678 abcdefg...
|
|
╵ ~~~~~~~~~~~~~~
|
|
|
|
`,
|
|
)
|
|
|
|
check("Truncated location head, zero length",
|
|
api.FormatMessagesOptions{
|
|
TerminalWidth: 32,
|
|
},
|
|
api.Message{Text: "This is a test", Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 100,
|
|
Column: 200,
|
|
Length: 0,
|
|
LineText: "012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI",
|
|
}},
|
|
`✘ [ERROR] This is a test
|
|
|
|
some file.js:100:200:
|
|
100 │ ...defghi ABCDEFGHI
|
|
╵ ^
|
|
|
|
`,
|
|
)
|
|
|
|
check("Truncated location head, nonzero length",
|
|
api.FormatMessagesOptions{
|
|
TerminalWidth: 32,
|
|
},
|
|
api.Message{Text: "This is a test", Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 100,
|
|
Column: 50,
|
|
Length: 200,
|
|
LineText: "012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI",
|
|
}},
|
|
`✘ [ERROR] This is a test
|
|
|
|
some file.js:100:50:
|
|
100 │ ...cdefghi ABCDEFGHI
|
|
╵ ~~~~~~~~~
|
|
|
|
`,
|
|
)
|
|
|
|
check("Truncated location head and tail, truncated length",
|
|
api.FormatMessagesOptions{
|
|
TerminalWidth: 32,
|
|
},
|
|
api.Message{Text: "This is a test", Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 100,
|
|
Column: 30,
|
|
Length: 30,
|
|
LineText: "012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI",
|
|
}},
|
|
`✘ [ERROR] This is a test
|
|
|
|
some file.js:100:30:
|
|
100 │ ... 012345678 abc...
|
|
╵ ~~~~~~~~~~~~~
|
|
|
|
`,
|
|
)
|
|
|
|
check("Truncated location head and tail, non-truncated length",
|
|
api.FormatMessagesOptions{
|
|
TerminalWidth: 32,
|
|
},
|
|
api.Message{Text: "This is a test", Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 100,
|
|
Column: 30,
|
|
Length: 9,
|
|
LineText: "012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI",
|
|
}},
|
|
`✘ [ERROR] This is a test
|
|
|
|
some file.js:100:30:
|
|
100 │ ...HI 012345678 a...
|
|
╵ ~~~~~~~~~
|
|
|
|
`,
|
|
)
|
|
|
|
check("Multi-line line text",
|
|
api.FormatMessagesOptions{},
|
|
api.Message{Text: "ReferenceError: Cannot access 'foo' before initialization", Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 100,
|
|
Column: 2,
|
|
LineText: ` foo();
|
|
at ModuleJob.run (node:internal/modules/esm/module_job:185:25)
|
|
at async Promise.all (index 0)
|
|
at async ESMLoader.import (node:internal/modules/esm/loader:281:24)
|
|
at async loadESM (node:internal/process/esm_loader:88:5)
|
|
at async handleMainPromise (node:internal/modules/run_main:65:12)`,
|
|
}},
|
|
`✘ [ERROR] ReferenceError: Cannot access 'foo' before initialization
|
|
|
|
some file.js:100:2:
|
|
100 │ foo();
|
|
╵ ^
|
|
|
|
at ModuleJob.run (node:internal/modules/esm/module_job:185:25)
|
|
at async Promise.all (index 0)
|
|
at async ESMLoader.import (node:internal/modules/esm/loader:281:24)
|
|
at async loadESM (node:internal/process/esm_loader:88:5)
|
|
at async handleMainPromise (node:internal/modules/run_main:65:12)
|
|
|
|
`,
|
|
)
|
|
|
|
check("Note formatting",
|
|
api.FormatMessagesOptions{
|
|
TerminalWidth: 40,
|
|
},
|
|
api.Message{
|
|
Text: "Why would you do this?",
|
|
Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 1,
|
|
Column: 10,
|
|
Length: 16,
|
|
LineText: "let ten = +([+!+[]]+[+[]]);",
|
|
},
|
|
Notes: []api.Note{{
|
|
Text: "This is 1:",
|
|
Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 1,
|
|
Column: 12,
|
|
Length: 7,
|
|
LineText: "let ten = +([+!+[]]+[+[]]);",
|
|
Suggestion: "'1'",
|
|
},
|
|
}, {
|
|
Text: "This is 0:",
|
|
Location: &api.Location{
|
|
File: "some file.js",
|
|
Line: 1,
|
|
Column: 20,
|
|
Length: 5,
|
|
LineText: "let ten = +([+!+[]]+[+[]]);",
|
|
Suggestion: "'0'",
|
|
},
|
|
}, {
|
|
Text: "The number 0 is created by +[], where [] is the empty array and + is the unary plus, " +
|
|
"used to convert the right side to a numeric value. The number 1 is formed as +!+[], where " +
|
|
"the boolean value true is converted into the numeric value 1 by the prepended plus sign.",
|
|
}},
|
|
},
|
|
`✘ [ERROR] Why would you do this?
|
|
|
|
some file.js:1:10:
|
|
1 │ let ten = +([+!+[]]+[+[]]);
|
|
╵ ~~~~~~~~~~~~~~~~
|
|
|
|
This is 1:
|
|
|
|
some file.js:1:12:
|
|
1 │ let ten = +([+!+[]]+[+[]]);
|
|
│ ~~~~~~~
|
|
╵ '1'
|
|
|
|
This is 0:
|
|
|
|
some file.js:1:20:
|
|
1 │ let ten = +([+!+[]]+[+[]]);
|
|
│ ~~~~~
|
|
╵ '0'
|
|
|
|
The number 0 is created by +[], where
|
|
[] is the empty array and + is the
|
|
unary plus, used to convert the right
|
|
side to a numeric value. The number 1
|
|
is formed as +!+[], where the boolean
|
|
value true is converted into the
|
|
numeric value 1 by the prepended plus
|
|
sign.
|
|
|
|
`,
|
|
)
|
|
}
|
|
|
|
func TestEngines(t *testing.T) {
|
|
checkChromeVersions := func(a string, b string) string {
|
|
result := api.Transform("a ?? b", api.TransformOptions{
|
|
Engines: []api.Engine{
|
|
{Name: api.EngineChrome, Version: a},
|
|
{Name: api.EngineChrome, Version: b},
|
|
},
|
|
})
|
|
return string(result.Code)
|
|
}
|
|
|
|
test.AssertEqualWithDiff(t, checkChromeVersions("99", "99"), "a ?? b;\n")
|
|
test.AssertEqualWithDiff(t, checkChromeVersions("9", "9"), "a != null ? a : b;\n")
|
|
test.AssertEqualWithDiff(t, checkChromeVersions("9", "99"), "a != null ? a : b;\n")
|
|
test.AssertEqualWithDiff(t, checkChromeVersions("99", "9"), "a != null ? a : b;\n")
|
|
}
|