vue-tui#214 ("macos zsh 开发模式 Text 组件颜色丢失") — `vue-tui dev` rendered
<Text color>/<Box borderColor> with no ANSI color while the built bundle showed
color — was fixed by the @vue-tui/cli -> @vue-tui/vite cutover (#215): the new
dev path runs the app in Vite's SSR runnable environment (Node resolve
conditions + externalized chalk) instead of bundling it in the browser-
conditioned client env, so chalk's #supports-color resolves to its node
implementation and does real TTY/FORCE_COLOR detection.
But the fix had no regression test (the old @vue-tui/cli color tests were
deleted with the package), and @vue-tui/vite's test config set no FORCE_COLOR,
so chalk was level 0 there and no color assertion could fire.
- Add test/fixtures/color (a <Text color="green"> app) + color.sequential.test.ts:
boots the live in-process dev server and asserts the green SGR
(\x1b[32mCOLORTEST\x1b[39m). Under the old browser-shim bug the codes never
appear, so this fails in exactly the #214 failure mode (verified by mutation).
- Add test.env { FORCE_COLOR:"3", CI:"false" } to packages/vite/vite.config.ts
(chalk locks its level at import time, so it must be set at the process level;
mirrors packages/runtime-tests/vite.config.ts).
vp run ready green (lint, type, 1290 + 129 PTY tests, build). No production code changed.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
// SEQUENTIAL: mutates globalThis.__VT_TEST_STDOUT__ (a process-global frame capture seam)
|
||||
// and starts a live Vite dev server that binds OS ports — see dev.sequential.test.ts's
|
||||
// header for the full rationale. Grouped with the other dev-server tests for the same reason.
|
||||
//
|
||||
// Regression for vue-tui#214 ("macos zsh 开发模式 Text 组件颜色丢失"): `vue-tui dev` rendered
|
||||
// <Text color>/<Box borderColor> with NO ANSI color even in a real terminal, while the built
|
||||
// bundle (`node dist/main.js`) showed color. Root cause was the old @vue-tui/cli dev path: it
|
||||
// bundled the app in Vite's CLIENT environment, whose resolve conditions omit "node", so chalk's
|
||||
// `#supports-color` import resolved to its BROWSER shim — hard-coded to level 0 under Node, so
|
||||
// chalk emitted no SGR regardless of FORCE_COLOR or a real TTY.
|
||||
//
|
||||
// The current @vue-tui/vite dev path runs the app in Vite's SSR runnable environment, which
|
||||
// resolves chalk with Node conditions (and externalizes it), so chalk does real TTY/FORCE_COLOR
|
||||
// detection and emits color. This test pins that: with FORCE_COLOR forced on (vite.config.ts
|
||||
// test.env, since chalk locks its level at import time), a dev-rendered <Text color="green">
|
||||
// must carry the green SGR. If chalk ever regressed to the browser shim, level would be 0 and the
|
||||
// SGR would vanish even with FORCE_COLOR set — exactly the #214 failure — and this test would catch it.
|
||||
import { test, expect, afterEach } from "vite-plus/test";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { createServer, type ViteDevServer } from "vite";
|
||||
import { vueTui } from "../src/index.ts";
|
||||
import { capture, waitFor } from "./helpers.ts";
|
||||
|
||||
// SGR escapes, matching the runtime-tests "\x1b[..m" convention. A NAMED chalk color is a fixed
|
||||
// ANSI-16 code even at level 3 (truecolor) — green fg is always ESC[32m … ESC[39m, never a 38;2;…
|
||||
// rgb sequence (only hex/rgb() inputs use those), so this literal is stable under FORCE_COLOR=3.
|
||||
const GREEN = "\x1b[32m";
|
||||
const FG_RESET = "\x1b[39m";
|
||||
const root = fileURLToPath(new URL("./fixtures/color", import.meta.url));
|
||||
let server: ViteDevServer | undefined;
|
||||
|
||||
afterEach(async () => {
|
||||
await server?.close();
|
||||
server = undefined;
|
||||
delete (globalThis as Record<string, unknown>).__VT_TEST_STDOUT__;
|
||||
});
|
||||
|
||||
test("#214: dev-mode <Text color> emits real ANSI color", async () => {
|
||||
const read = capture();
|
||||
server = await createServer({ root, logLevel: "silent", configFile: false, plugins: vueTui() });
|
||||
await server.listen();
|
||||
await waitFor(read, "COLORTEST");
|
||||
// Asserting the SGR (not just the text) is what distinguishes the fix from #214 — under the
|
||||
// browser-shim bug the escape codes never appear, leaving bare "COLORTEST".
|
||||
expect(read()).toContain(`${GREEN}COLORTEST${FG_RESET}`);
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { Box, Text } from "@vue-tui/runtime";
|
||||
</script>
|
||||
<template>
|
||||
<Box flexDirection="column">
|
||||
<Text color="green">COLORTEST</Text>
|
||||
</Box>
|
||||
</template>
|
||||
@@ -0,0 +1,5 @@
|
||||
import { createApp } from "@vue-tui/runtime";
|
||||
import App from "./app.vue";
|
||||
const stdout =
|
||||
(globalThis as { __VT_TEST_STDOUT__?: NodeJS.WriteStream }).__VT_TEST_STDOUT__ ?? process.stdout;
|
||||
createApp(App).mount({ debug: true, stdout });
|
||||
@@ -0,0 +1,3 @@
|
||||
import { defineConfig } from "vite";
|
||||
import { vueTui } from "../../../src/index.ts";
|
||||
export default defineConfig({ plugins: [vueTui()] });
|
||||
@@ -1,4 +1,11 @@
|
||||
import { defineConfig } from "vite-plus";
|
||||
export default defineConfig({
|
||||
pack: { entry: ["src/index.ts"], format: "esm", shims: true },
|
||||
test: {
|
||||
// chalk locks its color level at import time and disables color in non-TTY envs; force it on so
|
||||
// ANSI/color regressions (e.g. vue-tui#214 dev-mode color loss) can't hide from the dev-server
|
||||
// tests. CI:"false" because the runner sets CI=true, which flips vue-tui's interactive detection
|
||||
// (interactive = !isInCi && isTTY) off — matching the runtime-tests convention.
|
||||
env: { FORCE_COLOR: "3", CI: "false" },
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user