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

[T-650] Fix number padding in codeframe being incorrect if endLine == 10 #4874

Merged
merged 10 commits into from
Jul 12, 2020
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ dist
coverage
node_modules
tmp
fixtures
29 changes: 15 additions & 14 deletions packages/core/codeframe/src/codeframe.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ export default function codeFrame(
// Prefix lines with the line number
const lineNumberPrefixer = (params: {|
lineNumber?: string,
endLine: string,
lineNumberLength: number,
isHighlighted: boolean,
|}) => {
let {lineNumber, endLine, isHighlighted} = params;
let {lineNumber, lineNumberLength, isHighlighted} = params;

return `${isHighlighted ? highlighter('>') : ' '} ${
lineNumber
? lineNumber.padEnd(endLine.length, ' ')
: ' '.repeat(endLine.length)
? lineNumber.padStart(lineNumberLength, ' ')
: ' '.repeat(lineNumberLength)
} | `;
};

Expand Down Expand Up @@ -111,12 +111,13 @@ export default function codeFrame(
// Calculate first and last line index of codeframe
let startLine = firstHighlight.start.line - opts.padding.before;
startLine = startLine < 0 ? 0 : startLine;
let endLine = lastHighlight.end.line + opts.padding.after;
endLine =
endLine - startLine > opts.maxLines
let endLineIndex = lastHighlight.end.line + opts.padding.after;
endLineIndex =
endLineIndex - startLine > opts.maxLines
? startLine + opts.maxLines - 1
: endLine;
let endLineString = endLine.toString(10);
: endLineIndex;

let lineNumberLength = (endLineIndex + 1).toString(10).length;

// Split input into lines and highlight syntax
let lines = code.split(NEWLINE);
Expand All @@ -134,7 +135,7 @@ export default function codeFrame(
currentLineIndex < syntaxHighlightedLines.length;
currentLineIndex++
) {
if (currentLineIndex > endLine) break;
if (currentLineIndex > endLineIndex) break;
if (currentLineIndex > syntaxHighlightedLines.length - 1) break;

// Find highlights that need to get rendered on the current line
Expand All @@ -158,8 +159,8 @@ export default function codeFrame(
);

let lineLengthLimit =
opts.terminalWidth > endLineString.length + 7
? opts.terminalWidth - (endLineString.length + 5)
opts.terminalWidth > lineNumberLength + 7
? opts.terminalWidth - (lineNumberLength + 5)
: 10;

// Split the line into line parts that will fit the provided terminal width
Expand Down Expand Up @@ -189,7 +190,7 @@ export default function codeFrame(
resultLines.push(
lineNumberPrefixer({
lineNumber: (currentLineIndex + 1).toString(10),
endLine: endLineString,
lineNumberLength,
isHighlighted: lineHighlights.length > 0,
}) + syntaxHighlightedLine,
);
Expand Down Expand Up @@ -274,7 +275,7 @@ export default function codeFrame(
if (highlightLine) {
resultLines.push(
lineNumberPrefixer({
endLine: endLineString,
lineNumberLength,
isHighlighted: true,
}) + highlightLine,
);
Expand Down
73 changes: 64 additions & 9 deletions packages/core/codeframe/test/codeframe.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import assert from 'assert';
import {readFileSync} from 'fs';
import {join as joinPath} from 'path';

import codeframe from '../src/codeframe';

Expand Down Expand Up @@ -393,7 +395,7 @@ describe('codeframe', () => {
assert.equal(lines[7], ' 9 | test');
});

it('should properly pad numbers', () => {
it('should properly pad numbers for large files', () => {
let codeframeString = codeframe('test\n'.repeat(1000), [
{
start: {
Expand All @@ -415,17 +417,22 @@ describe('codeframe', () => {
column: 2,
line: 100,
},
message: 'test',
message: 'test 2',
},
]);

let lines = codeframeString.split(LINE_END);
assert.equal(lines.length, 7);
assert.equal(lines[0], ' 98 | test');
assert.equal(lines[0], ' 98 | test');
assert.equal(lines[1], '> 99 | test');
assert.equal(lines[2], '> | ^ test');
assert.equal(lines[3], '> 100 | test');
assert.equal(lines[4], '> | ^ test 2');
assert.equal(lines[5], ' 101 | test');
assert.equal(lines[6], ' 102 | test');
});

it('should properly pad numbers', () => {
it('should properly pad numbers for short files', () => {
let codeframeString = codeframe('test\n'.repeat(1000), [
{
start: {
Expand Down Expand Up @@ -453,13 +460,17 @@ describe('codeframe', () => {

let lines = codeframeString.split(LINE_END);
assert.equal(lines.length, 11);
assert.equal(lines[0], ' 6 | test');
assert.equal(lines[0], ' 6 | test');
assert.equal(lines[4], ' 9 | test');
assert.equal(lines[5], ' 10 | test');
assert.equal(lines[6], ' 11 | test');
assert.equal(lines[10], ' 14 | test');
});

it('should properly use maxLines', () => {
let line = 'test '.repeat(100);
let codeframeString = codeframe(
'test\n'.repeat(100),
`${line}\n`.repeat(100),
[
{
start: {
Expand Down Expand Up @@ -487,14 +498,16 @@ describe('codeframe', () => {
{
useColor: false,
maxLines: 10,
terminalWidth: 5,
},
);

let lines = codeframeString.split(LINE_END);
assert.equal(lines.length, 13);
assert.equal(lines[0], ' 4 | test');
assert.equal(lines[11], '> 13 | test');
assert.equal(lines[12], '> | ^^^^');
assert.equal(lines[0], ' 4 | test test ');
assert.equal(lines[7], ' 10 | test test ');
assert.equal(lines[11], '> 13 | test test ');
assert.equal(lines[12], '> | ^^^^^^^^^^');
});

it('should be able to handle tabs', () => {
Expand Down Expand Up @@ -741,4 +754,46 @@ describe('codeframe', () => {
assert.equal(lines[2], '> 2 | ew line new line ne');
assert.equal(lines[3], '> | ^^^^^^ I have a message');
});

it('Should pad properly, T-650', () => {
let fileContent = readFileSync(
joinPath(__dirname, './fixtures/a.js'),
'utf8',
);
let codeframeString = codeframe(
fileContent,
[
{
start: {
line: 8,
column: 10,
},
end: {
line: 8,
column: 48,
},
},
],
{
useColor: false,
syntaxHighlighting: false,
language: 'js',
terminalWidth: 100,
},
);

let lines = codeframeString.split(LINE_END);
assert.equal(lines.length, 5);
assert.equal(lines[0], ` 7 | import Tooltip from '../tooltip';`);
assert.equal(
lines[1],
`> 8 | import VisuallyHidden from '../visually-hidden';`,
);
assert.equal(
lines[2],
'> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^',
);
assert.equal(lines[3], ' 9 | ');
assert.equal(lines[4], ' 10 | /**');
});
});
13 changes: 13 additions & 0 deletions packages/core/codeframe/test/fixtures/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import test from 'test';
import component from './component';

/**
* This is a comment
*/
import Tooltip from '../tooltip';
import VisuallyHidden from '../visually-hidden';

/**
* This is another comment
*/
import {Label} from './label';