Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix string formatter for unexpected truncation on non-ASCII characters #6861

Merged
merged 3 commits into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/late-otters-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"stylelint": patch
---

Fixed: `string` formatter for unexpected truncation on non-ASCII characters
61 changes: 61 additions & 0 deletions lib/formatters/__tests__/stringFormatter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,31 @@ describe('stringFormatter', () => {
path/to/file.css
1:1 × Unexpected foo bar

1 problem (1 error, 0 warnings)`);
});

it('outputs warnings contains non-ASCII characters', () => {
const results = [
{
source: 'path/to/file.css',
warnings: [
{
line: 1,
column: 1,
rule: 'bar',
severity: 'error',
text: '简体中文こんにちは안녕하세요',
},
],
},
];

const output = prepareFormatterOutput(results, stringFormatter);

expect(output).toBe(stripIndent`
path/to/file.css
1:1 × 简体中文こんにちは안녕하세요 bar

1 problem (1 error, 0 warnings)`);
});

Expand Down Expand Up @@ -136,6 +161,42 @@ path/to/file.css
1:1 × Unexpected very very very very very very very bar-very-very-very-very-very-long
very very very very very very long foo

1 problem (1 error, 0 warnings)`);
});

it('outputs warnings with more than 80 non-ASCII characters and `process.stdout.columns` equal 90 characters', () => {
// For Windows tests
process.stdout.isTTY = true;
process.stdout.columns = 90;

const results = [
{
source: 'path/to/file.css',
warnings: [
{
line: 1,
column: 1,
rule: 'bar-very-very-very-very-very-long',
severity: 'error',
text:
'简体中文こんにちは안녕하세요简体中文こんにちは안녕하세요简体中文こんにちは안녕하세요简体中文こんにちは안녕하세요简体中文' +
'こんにちは안녕하세요简体中文こんにちは안녕하세요简体中文こんにちは안녕하세요简体中文こんにちは안녕하세요简体中文こんにちは안녕하세요',
},
],
},
];

const output = prepareFormatterOutput(results, stringFormatter);

expect(output).toBe(stripIndent`
path/to/file.css
1:1 × 简体中文こんにちは안녕하세요简体中文こんにち bar-very-very-very-very-very-long
は안녕하세요简体中文こんにちは안녕하세요简体
中文こんにちは안녕하세요简体中文こんにちは안
녕하세요简体中文こんにちは안녕하세요简体中文
こんにちは안녕하세요简体中文こんにちは안녕하
세요简体中文こんにちは안녕하세요

1 problem (1 error, 0 warnings)`);
});

Expand Down
8 changes: 6 additions & 2 deletions lib/formatters/stringFormatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const { assertNumber } = require('../utils/validateTypes');
const preprocessWarnings = require('./preprocessWarnings');
const terminalLink = require('./terminalLink');

const NON_ASCII_PATTERN = /\P{ASCII}/u;
const MARGIN_WIDTHS = 9;

/**
Expand Down Expand Up @@ -200,6 +201,9 @@ function formatter(messages, source, cwd) {
return row;
});

const messageWidth = getMessageWidth(columnWidths);
const hasNonAsciiChar = messages.some((msg) => NON_ASCII_PATTERN.test(msg.text));

output += table
.table(cleanedMessages, {
border: table.getBorderCharacters('void'),
Expand All @@ -209,8 +213,8 @@ function formatter(messages, source, cwd) {
2: { alignment: 'center', width: columnWidths[2] },
3: {
alignment: 'left',
width: getMessageWidth(columnWidths),
wrapWord: getMessageWidth(columnWidths) > 1,
width: messageWidth,
wrapWord: messageWidth > 1 && !hasNonAsciiChar,
},
4: { alignment: 'left', width: columnWidths[4], paddingRight: 0 },
},
Expand Down