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

Print colors in tests 🎨 #6327

Merged
merged 9 commits into from
Jul 31, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type {
} from '../types';
import { DescribeDecorator, TestDecorator } from '../types';
import { TestComponent } from '../TestComponent';
import { applyMarkdown, formatString } from '../utils/stringFormatUtils';
import { applyMarkdown, formatTestName } from '../utils/stringFormatUtils';
import type {
LayoutAnimationStartFunction,
LayoutAnimationType,
Expand Down Expand Up @@ -157,10 +157,10 @@ export class TestRunner {
await testCase(example, index);
};
this.test(
formatString(name, example, index),
formatTestName(name, example, index),
currentTestCase,
decorator,
formatString(expectedWarning, example, index),
formatTestName(expectedWarning, example, index),
);
});
};
Expand All @@ -172,7 +172,7 @@ export class TestRunner {
const currentTestCase = async () => {
await testCase(example, index);
};
this.test(formatString(name, example, index), currentTestCase, decorator);
this.test(formatTestName(name, example, index), currentTestCase, decorator);
});
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export class TestSummaryLogger {
private _skipped: number = 0;
private _failedTests: Array<string> = [];
private _startTime: number = Date.now();
private _endTime: number = 0;

public logRunningTestSuite(testSuite: TestSuite) {
console.log(`${indentNestingLevel(testSuite.nestingLevel)}${testSuite.name}`);
Expand Down Expand Up @@ -44,7 +43,8 @@ export class TestSummaryLogger {
}

public printSummary() {
this._endTime = Date.now();
const endTime = Date.now();
const timeInSeconds = Math.round((endTime - this._startTime) / 1000);

console.log('End of tests run 🏁');
console.log('\n');
Expand All @@ -54,7 +54,8 @@ export class TestSummaryLogger {
'orange',
)} skipped`,
);
console.log(`⏱️ Total time: ${Math.round(((this._endTime - this._startTime) / 1000) * 100) / 100}s`);
console.log(`⏱️ Total time: ${Math.floor(timeInSeconds / 60)} minutes ${timeInSeconds % 60} s`);

if (this._failed > 0) {
console.log('❌ Failed tests:');
for (const failedTest of this._failedTests) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { formatSnapshotMismatch, green, red, yellow } from '../utils/stringFormatUtils';
import { green, red, yellow } from '../utils/stringFormatUtils';
import type { OperationUpdate, Mismatch } from '../types';
import { ComparisonMode, isValidPropName } from '../types';
import { getComparator, getComparisonModeForProp } from './Comparators';
import type { SingleViewSnapshot } from '../TestRunner/UpdatesContainer';
import { formatSnapshotMismatch } from '../utils/drawSnapshotTable';

function compareSnapshot(
expectedSnapshot: OperationUpdate,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { isColor } from 'react-native-reanimated';
import type { Mismatch, TestValue } from '../types';
import { green, red, color, getColorSquare } from './stringFormatUtils';

const VALUE_COLUMN_WIDTH = 15;
const INDEX_COLUMN_WIDTH = 7;

const VERTICAL_LINE = '│';
const VERTICAL_LINE_DOUBLE = '┃';
const HORIZONTAL_LINE = '━';

function prepareValueToTableCell(message: TestValue): string {
if (message === undefined) {
return 'undefined';
} else if (message === null) {
return 'null';
} else if (typeof message === 'object') {
return JSON.stringify(message);
} else if (typeof message === 'number' || (typeof message === 'string' && Number(message) !== null)) {
const messageNum = Number(message);
const digitsAfterDot = messageNum.toString().split('.')?.[1]?.length || 0;
for (let i = 0; i < digitsAfterDot; i++) {
if (Math.abs(messageNum - Number(messageNum.toFixed(i))) < 0.00001) {
return '≈' + messageNum.toFixed(i);
}
}
return String(message);
} else {
return message?.toString();
}
}

function adjustValueToLength(value: TestValue, length: number, valueKey?: string) {
let valueStr = prepareValueToTableCell(value);
let messageLen = valueStr.length;

if (isColor(valueStr) && valueKey === 'backgroundColor' && messageLen + 3 <= VALUE_COLUMN_WIDTH) {
valueStr += ' ' + getColorSquare(valueStr);
messageLen += 3;
}
if (length > messageLen) {
const indentSize = length - messageLen;
return `${valueStr}${' '.repeat(indentSize)}`;
} else {
return valueStr.slice(0, length);
}
}

function getBorderLine(keys: Array<string>, type: 'top' | 'bottom' | 'mid') {
const leftEdge = { top: '╭', mid: '├', bottom: '╰' };
const rightEdge = { top: '╮', mid: '┤', bottom: '╯' };
const boldLineJoint = { top: '┳', mid: '╋', bottom: '┻' };
const singleLineJoint = { top: '┯', mid: '┷', bottom: HORIZONTAL_LINE };

return (
leftEdge[type] +
HORIZONTAL_LINE.repeat(INDEX_COLUMN_WIDTH) +
boldLineJoint[type] +
keys
.map(
_key =>
HORIZONTAL_LINE.repeat(VALUE_COLUMN_WIDTH) +
singleLineJoint[type] +
HORIZONTAL_LINE.repeat(VALUE_COLUMN_WIDTH),
)
.join(boldLineJoint[type]) +
rightEdge[type]
);
}

function getUpperTableHeader(keys: Array<string>) {
return (
' '.repeat(INDEX_COLUMN_WIDTH) +
VERTICAL_LINE_DOUBLE +
keys
.map(
key =>
adjustValueToLength(key, VALUE_COLUMN_WIDTH) + VERTICAL_LINE + adjustValueToLength(key, VALUE_COLUMN_WIDTH),
)
.join(VERTICAL_LINE_DOUBLE)
);
}

function getLowerTableHeader(keys: Array<string>, native: boolean) {
const columnPair =
adjustValueToLength(native ? 'native' : 'expected', VALUE_COLUMN_WIDTH) +
VERTICAL_LINE +
adjustValueToLength(native ? 'js' : 'captured', VALUE_COLUMN_WIDTH);

return (
adjustValueToLength('index', INDEX_COLUMN_WIDTH) +
VERTICAL_LINE_DOUBLE +
keys.map(_ => columnPair).join(VERTICAL_LINE_DOUBLE)
);
}

function withSideBorders(line: string) {
return VERTICAL_LINE + line + VERTICAL_LINE;
}

function getComparisonRow(mismatch: Mismatch, keys: Array<string>) {
const { index, capturedSnapshot, expectedSnapshot } = mismatch;
const indexColumn = adjustValueToLength(index.toString(), INDEX_COLUMN_WIDTH);
const formattedCells = keys.map(key => {
const expectedValue = expectedSnapshot[key as keyof typeof expectedSnapshot];
const capturedValue = capturedSnapshot[key as keyof typeof capturedSnapshot];

const match = expectedValue === capturedValue;

const expectedAdjusted = adjustValueToLength(expectedValue, VALUE_COLUMN_WIDTH, key);
const capturedAdjusted = adjustValueToLength(capturedValue, VALUE_COLUMN_WIDTH, key);

const expectedColored = match ? expectedAdjusted : green(expectedAdjusted);
const capturedColored = match ? capturedAdjusted : red(capturedAdjusted);

return expectedColored + color(VERTICAL_LINE, 'gray') + capturedColored;
});

return indexColumn + VERTICAL_LINE_DOUBLE + formattedCells.join(VERTICAL_LINE_DOUBLE);
}

export function formatSnapshotMismatch(mismatches: Array<Mismatch>, native: boolean) {
const keysToPrint: Array<string> = [];
mismatches.forEach(({ expectedSnapshot, capturedSnapshot }) => {
Object.keys(expectedSnapshot).forEach(key => {
if (!keysToPrint.includes(key)) {
keysToPrint.push(key);
}
});
Object.keys(capturedSnapshot).forEach(key => {
if (!keysToPrint.includes(key)) {
keysToPrint.push(key);
}
});
});

const topLine = getBorderLine(keysToPrint, 'top');
const upperHeader = withSideBorders(getUpperTableHeader(keysToPrint));
const lowerHeader = withSideBorders(getLowerTableHeader(keysToPrint, native));
const separatorLine = getBorderLine(keysToPrint, 'mid');
const mismatchRows = mismatches.map(mismatch => withSideBorders(getComparisonRow(mismatch, keysToPrint)));
const bottomLine = getBorderLine(keysToPrint, 'bottom');

return [topLine, upperHeader, lowerHeader, separatorLine, ...mismatchRows, bottomLine].join('\n');
}
Loading