From 8feb763482cc036bee6e1e14245fbb7ca20e6d46 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Mon, 28 Oct 2024 14:33:04 +0100 Subject: [PATCH] some more changes to make it actually pass --- packages/playwright/src/reporters/base.ts | 50 +++++++++++++--------- tests/playwright-test/fit-to-width.spec.ts | 38 +--------------- 2 files changed, 31 insertions(+), 57 deletions(-) diff --git a/packages/playwright/src/reporters/base.ts b/packages/playwright/src/reporters/base.ts index ae8079e9e4..45c4c5a938 100644 --- a/packages/playwright/src/reporters/base.ts +++ b/packages/playwright/src/reporters/base.ts @@ -489,43 +489,51 @@ export function stripAnsiEscapes(str: string): string { return str.replace(ansiRegex, ''); } +function characterWidth(c: string) { + return /[\u4e00-\u9fff]/.test(c) ? 2 : 1; +} + +function stringWidth(v: string) { + let width = 0; + for (let i = 0; i < v.length; ++i) + width += characterWidth(v[i]); + return width; +} + +function suffixOfWidth(v: string, width: number) { + let i = v.length - 1; + for (; i > 0; --i) { + const c = v[i]; + const cWidth = characterWidth(c); + if (cWidth >= width) + break; + width -= cWidth; + } + return v.substring(i); +} + // Leaves enough space for the "prefix" to also fit. export function fitToWidth(line: string, width: number, prefix?: string): string { const prefixLength = prefix ? stripAnsiEscapes(prefix).length : 0; width -= prefixLength; - if (line.length <= width) + if (stringWidth(line) <= width) return line; // Even items are plain text, odd items are control sequences. const parts = line.split(ansiRegex); const taken: string[] = []; - for (let i = parts.length - 1; i >= 0; i--) { if (i % 2) { // Include all control sequences to preserve formatting. taken.push(parts[i]); } else { - let part = parts[i]; - let partLength = 0; - for (let j = part.length - 1; j >= 0; j--) { - const char = part[j]; - // Check if the character is a Chinese character - if (/[\u4e00-\u9fff]/.test(char)) - partLength += 2; // Chinese characters take 2 spaces - else - partLength += 1; - - if (partLength > width) { - part = part.substring(j + 1); - if (part.length > 0) { - // Add ellipsis if we are truncating. - part = '\u2026' + part.substring(1); - } - break; - } + let part = suffixOfWidth(parts[i], width); + if (part.length < parts[i].length && part.length > 0) { + // Add ellipsis if we are truncating. + part = '\u2026' + part.substring(1); } taken.push(part); - width -= partLength; + width -= stringWidth(part); } } return taken.reverse().join(''); diff --git a/tests/playwright-test/fit-to-width.spec.ts b/tests/playwright-test/fit-to-width.spec.ts index acb118142c..c118e6687f 100644 --- a/tests/playwright-test/fit-to-width.spec.ts +++ b/tests/playwright-test/fit-to-width.spec.ts @@ -18,40 +18,6 @@ import { fitToWidth } from 'packages/playwright/lib/reporters/base'; import { test, expect } from './playwright-test-fixtures'; test('chinese characters', () => { - expect(fitToWidth('你好', 2)).toBe('你\n好'); - expect(fitToWidth('你好你好', 4)).toBe('你好\n你好'); -}); - -test('mixed characters', () => { - expect(fitToWidth('hello你好', 5)).toBe('hello\n你好'); - expect(fitToWidth('你好hello', 5)).toBe('你好h\nello'); -}); - -test('special characters', () => { - expect(fitToWidth('hello@world', 5)).toBe('hello\n@worl\nd'); - expect(fitToWidth('你好@世界', 3)).toBe('你\n好@\n世\n界'); -}); - -test('long words', () => { - expect(fitToWidth('supercalifragilisticexpialidocious', 10)).toBe('supercalif\nragilistic\nexpialidoc\nious'); - expect(fitToWidth('你好超级长的词', 5)).toBe('你好\n超级\n长的\n词'); -}); - -test('empty string', () => { - expect(fitToWidth('', 5)).toBe(''); - expect(fitToWidth('', 5)).toBe(''); -}); - -test('single character', () => { - expect(fitToWidth('a', 1)).toBe('a'); - expect(fitToWidth('a', 1)).toBe('a'); -}); - -test('spaces', () => { - expect(fitToWidth('hello world', 5)).toBe('hello\nworld'); - expect(fitToWidth('hello world', 5)).toBe('hello\nworld'); -}); - -test('prefix', () => { - expect(fitToWidth('hello world', 5, '~>')).toBe('hel\nlo\nwor\nld'); + expect(fitToWidth('你你好', 3)).toBe('…好'); + expect(fitToWidth('你好你好', 4)).toBe('…好'); });