Files
Huáng JùnliàngandGitHub b6efa9c0ee Polish babel-code-frame highlight test (#15499)
* resolve chalk from @babel/highlight's workspace

* improve color supports stub to work with Chalk 4

* remove --color from test jobs

* create a valid SupportsColor Level

* also stub chalk.enabled

* obtain chalk from getChalk

* jest e2e test requires --color
2023-03-23 09:26:33 -04:00

543 lines
13 KiB
JavaScript

import stripAnsi from "strip-ansi";
import { getChalk } from "@babel/highlight";
import _codeFrame, { codeFrameColumns } from "../lib/index.js";
const codeFrame = _codeFrame.default || _codeFrame;
const chalk = getChalk({});
describe("@babel/code-frame", function () {
function stubColorSupport(supported) {
let originalChalkLevel;
let originalChalkSupportsColor;
let originalChalkEnabled;
beforeEach(function () {
originalChalkSupportsColor = chalk.supportsColor;
originalChalkLevel = chalk.level;
originalChalkEnabled = chalk.enabled;
chalk.supportsColor = supported ? { level: 1 } : false;
chalk.level = supported ? 1 : 0;
chalk.enabled = supported;
});
afterEach(function () {
chalk.supportsColor = originalChalkSupportsColor;
chalk.level = originalChalkLevel;
chalk.enabled = originalChalkEnabled;
});
}
test("basic usage", function () {
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
expect(codeFrame(rawLines, 2, 16)).toEqual(
[
" 1 | class Foo {",
"> 2 | constructor()",
" | ^",
" 3 | };",
].join("\n"),
);
});
test("optional column number", function () {
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
expect(codeFrame(rawLines, 2, null)).toEqual(
[" 1 | class Foo {", "> 2 | constructor()", " 3 | };"].join("\n"),
);
});
test("maximum context lines and padding", function () {
const rawLines = [
"/**",
" * Sums two numbers.",
" *",
" * @param a Number",
" * @param b Number",
" * @returns Number",
" */",
"",
"function sum(a, b) {",
" return a + b",
"}",
].join("\n");
expect(codeFrame(rawLines, 7, 2)).toEqual(
[
" 5 | * @param b Number",
" 6 | * @returns Number",
"> 7 | */",
" | ^",
" 8 |",
" 9 | function sum(a, b) {",
" 10 | return a + b",
].join("\n"),
);
});
test("no unnecessary padding due to one-off errors", function () {
const rawLines = [
"/**",
" * Sums two numbers.",
" *",
" * @param a Number",
" * @param b Number",
" * @returns Number",
" */",
"",
"function sum(a, b) {",
" return a + b",
"}",
].join("\n");
expect(codeFrame(rawLines, 6, 2)).toEqual(
[
" 4 | * @param a Number",
" 5 | * @param b Number",
"> 6 | * @returns Number",
" | ^",
" 7 | */",
" 8 |",
" 9 | function sum(a, b) {",
].join("\n"),
);
});
test("tabs", function () {
const rawLines = [
"\tclass Foo {",
"\t \t\t constructor\t(\t)",
"\t};",
].join("\n");
expect(codeFrame(rawLines, 2, 25)).toEqual(
[
" 1 | \tclass Foo {",
"> 2 | \t \t\t constructor\t(\t)",
" | \t \t\t \t \t ^",
" 3 | \t};",
].join("\n"),
);
});
describe("when colors are supported", () => {
stubColorSupport(true);
test("opts.highlightCode", function () {
const rawLines = "console.log('babel')";
const result = codeFrame(rawLines, 1, 9, { highlightCode: true });
const stripped = stripAnsi(result);
expect(result.length).toBeGreaterThan(stripped.length);
expect(stripped).toEqual(
["> 1 | console.log('babel')", " | ^"].join("\n"),
);
});
test("opts.highlightCode with multiple columns and lines", function () {
// prettier-ignore
const rawLines = [
"function a(b, c) {",
" return b + c;",
"}"
].join("\n");
const result = codeFrameColumns(
rawLines,
{
start: {
line: 1,
column: 1,
},
end: {
line: 3,
column: 1,
},
},
{
highlightCode: true,
message: "Message about things",
},
);
const stripped = stripAnsi(result);
expect(result.length).toBeGreaterThan(stripped.length);
expect(stripped).toEqual(
// prettier-ignore
[
"> 1 | function a(b, c) {",
" | ^^^^^^^^^^^^^^^^^^",
"> 2 | return b + c;",
" | ^^^^^^^^^^^^^^^",
"> 3 | }",
" | ^ Message about things",
].join('\n'),
);
});
test("opts.forceColor", function () {
const marker = chalk.red.bold;
const gutter = chalk.grey;
const rawLines = ["", "", "", ""].join("\n");
expect(
codeFrame(rawLines, 3, null, {
linesAbove: 1,
linesBelow: 1,
forceColor: true,
}),
).toEqual(
chalk.reset(
[
" " + gutter(" 2 |"),
marker(">") + gutter(" 3 |"),
" " + gutter(" 4 |"),
].join("\n"),
),
);
});
test("jsx", function () {
const gutter = chalk.grey;
const yellow = chalk.yellow;
const rawLines = ["<div />"].join("\n");
expect(
JSON.stringify(
codeFrame(rawLines, 0, null, {
linesAbove: 1,
linesBelow: 1,
forceColor: true,
}),
),
).toEqual(
JSON.stringify(
chalk.reset(
" " +
gutter(" 1 |") +
" " +
yellow("<") +
yellow("div") +
" " +
yellow("/") +
yellow(">"),
),
),
);
});
});
test("opts.linesAbove", function () {
const rawLines = [
"/**",
" * Sums two numbers.",
" *",
" * @param a Number",
" * @param b Number",
" * @returns Number",
" */",
"",
"function sum(a, b) {",
" return a + b",
"}",
].join("\n");
expect(codeFrame(rawLines, 7, 2, { linesAbove: 1 })).toEqual(
[
" 6 | * @returns Number",
"> 7 | */",
" | ^",
" 8 |",
" 9 | function sum(a, b) {",
" 10 | return a + b",
].join("\n"),
);
});
test("opts.linesBelow", function () {
const rawLines = [
"/**",
" * Sums two numbers.",
" *",
" * @param a Number",
" * @param b Number",
" * @returns Number",
" */",
"",
"function sum(a, b) {",
" return a + b",
"}",
].join("\n");
expect(codeFrame(rawLines, 7, 2, { linesBelow: 1 })).toEqual(
[
" 5 | * @param b Number",
" 6 | * @returns Number",
"> 7 | */",
" | ^",
" 8 |",
].join("\n"),
);
});
test("opts.linesAbove and opts.linesBelow", function () {
const rawLines = [
"/**",
" * Sums two numbers.",
" *",
" * @param a Number",
" * @param b Number",
" * @returns Number",
" */",
"",
"function sum(a, b) {",
" return a + b",
"}",
].join("\n");
expect(codeFrame(rawLines, 7, 2, { linesAbove: 1, linesBelow: 1 })).toEqual(
[" 6 | * @returns Number", "> 7 | */", " | ^", " 8 |"].join("\n"),
);
});
test("opts.linesAbove no lines above", function () {
const rawLines = [
"class Foo {",
" constructor() {",
" console.log(arguments);",
" }",
"};",
].join("\n");
expect(
codeFrameColumns(rawLines, { start: { line: 2 } }, { linesAbove: 0 }),
).toEqual(
[
"> 2 | constructor() {",
" 3 | console.log(arguments);",
" 4 | }",
" 5 | };",
].join("\n"),
);
});
test("opts.linesBelow no lines below", function () {
const rawLines = [
"class Foo {",
" constructor() {",
" console.log(arguments);",
" }",
"};",
].join("\n");
expect(
codeFrameColumns(rawLines, { start: { line: 2 } }, { linesBelow: 0 }),
).toEqual([" 1 | class Foo {", "> 2 | constructor() {"].join("\n"));
});
test("opts.linesBelow single line", function () {
const rawLines = [
"class Foo {",
" constructor() {",
" console.log(arguments);",
" }",
"};",
].join("\n");
expect(
codeFrameColumns(
rawLines,
{ start: { line: 2 } },
{ linesAbove: 0, linesBelow: 0 },
),
).toEqual(["> 2 | constructor() {"].join("\n"));
});
test("basic usage, new API", function () {
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
expect(
codeFrameColumns(rawLines, { start: { line: 2, column: 16 } }),
).toEqual(
[
" 1 | class Foo {",
"> 2 | constructor()",
" | ^",
" 3 | };",
].join("\n"),
);
});
test("mark multiple columns", function () {
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
expect(
codeFrameColumns(rawLines, {
start: { line: 2, column: 3 },
end: { line: 2, column: 16 },
}),
).toEqual(
[
" 1 | class Foo {",
"> 2 | constructor()",
" | ^^^^^^^^^^^^^",
" 3 | };",
].join("\n"),
);
});
test("mark multiple columns across lines", function () {
const rawLines = ["class Foo {", " constructor() {", " }", "};"].join(
"\n",
);
expect(
codeFrameColumns(rawLines, {
start: { line: 2, column: 17 },
end: { line: 3, column: 3 },
}),
).toEqual(
[
" 1 | class Foo {",
"> 2 | constructor() {",
" | ^",
"> 3 | }",
" | ^^^",
" 4 | };",
].join("\n"),
);
});
test("mark multiple columns across multiple lines", function () {
const rawLines = [
"class Foo {",
" constructor() {",
" console.log(arguments);",
" }",
"};",
].join("\n");
expect(
codeFrameColumns(rawLines, {
start: { line: 2, column: 17 },
end: { line: 4, column: 3 },
}),
).toEqual(
[
" 1 | class Foo {",
"> 2 | constructor() {",
" | ^",
"> 3 | console.log(arguments);",
" | ^^^^^^^^^^^^^^^^^^^^^^^^^^^",
"> 4 | }",
" | ^^^",
" 5 | };",
].join("\n"),
);
});
test("mark across multiple lines without columns", function () {
const rawLines = [
"class Foo {",
" constructor() {",
" console.log(arguments);",
" }",
"};",
].join("\n");
expect(
codeFrameColumns(rawLines, { start: { line: 2 }, end: { line: 4 } }),
).toEqual(
[
" 1 | class Foo {",
"> 2 | constructor() {",
"> 3 | console.log(arguments);",
"> 4 | }",
" 5 | };",
].join("\n"),
);
});
test("opts.message", function () {
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
expect(
codeFrameColumns(
rawLines,
{ start: { line: 2, column: 16 } },
{
message: "Missing {",
},
),
).toEqual(
[
" 1 | class Foo {",
"> 2 | constructor()",
" | ^ Missing {",
" 3 | };",
].join("\n"),
);
});
test("opts.message without column", function () {
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
expect(
codeFrameColumns(
rawLines,
{ start: { line: 2 } },
{
message: "Missing {",
},
),
).toEqual(
[
" Missing {",
" 1 | class Foo {",
"> 2 | constructor()",
" 3 | };",
].join("\n"),
);
});
test("opts.message with multiple lines", function () {
const rawLines = [
"class Foo {",
" constructor() {",
" console.log(arguments);",
" }",
"};",
].join("\n");
expect(
codeFrameColumns(
rawLines,
{
start: { line: 2, column: 17 },
end: { line: 4, column: 3 },
},
{
message: "something about the constructor body",
},
),
).toEqual(
[
" 1 | class Foo {",
"> 2 | constructor() {",
" | ^",
"> 3 | console.log(arguments);",
" | ^^^^^^^^^^^^^^^^^^^^^^^^^^^",
"> 4 | }",
" | ^^^ something about the constructor body",
" 5 | };",
].join("\n"),
);
});
test("opts.message with multiple lines without columns", function () {
const rawLines = [
"class Foo {",
" constructor() {",
" console.log(arguments);",
" }",
"};",
].join("\n");
expect(
codeFrameColumns(
rawLines,
{ start: { line: 2 }, end: { line: 4 } },
{
message: "something about the constructor body",
},
),
).toEqual(
[
" something about the constructor body",
" 1 | class Foo {",
"> 2 | constructor() {",
"> 3 | console.log(arguments);",
"> 4 | }",
" 5 | };",
].join("\n"),
);
});
});