Just a whole lot of crap
This commit is contained in:
161
tests/tui/windows/basicWindowsTest.test.js
Normal file
161
tests/tui/windows/basicWindowsTest.test.js
Normal file
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* Basic Windows Tests
|
||||
* Simple tests for Windows-specific functionality without complex imports
|
||||
*/
|
||||
|
||||
const {
|
||||
detectWindowsTerminal,
|
||||
getWindowsTerminalCapabilities,
|
||||
getWindowsColorSupport,
|
||||
getWindowsUnicodeSupport,
|
||||
} = require("../../../src/tui/utils/modernTerminal.js");
|
||||
|
||||
describe("Basic Windows Tests", () => {
|
||||
const originalEnv = process.env;
|
||||
const originalPlatform = process.platform;
|
||||
|
||||
beforeEach(() => {
|
||||
// Reset environment
|
||||
process.env = { ...originalEnv };
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: "win32",
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env = originalEnv;
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: originalPlatform,
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
|
||||
describe("Windows Terminal Detection", () => {
|
||||
test("should detect Windows Terminal with WT_SESSION", () => {
|
||||
process.env.WT_SESSION = "abc123-def456";
|
||||
process.env.TERM_PROGRAM = "Windows Terminal";
|
||||
|
||||
const isWindowsTerminal = detectWindowsTerminal();
|
||||
expect(isWindowsTerminal).toBe(true);
|
||||
});
|
||||
|
||||
test("should not detect Windows Terminal without proper env vars", () => {
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
|
||||
const isWindowsTerminal = detectWindowsTerminal();
|
||||
expect(isWindowsTerminal).toBe(false);
|
||||
});
|
||||
|
||||
test("should not detect Windows Terminal on non-Windows platforms", () => {
|
||||
Object.defineProperty(process, "platform", { value: "linux" });
|
||||
process.env.WT_SESSION = "test";
|
||||
|
||||
const isWindowsTerminal = detectWindowsTerminal();
|
||||
expect(isWindowsTerminal).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Windows Terminal Capabilities", () => {
|
||||
test("should detect Windows Terminal capabilities", () => {
|
||||
process.env.WT_SESSION = "test-session";
|
||||
process.env.COLORTERM = "truecolor";
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.isWindows).toBe(true);
|
||||
expect(capabilities.isWindowsTerminal).toBe(true);
|
||||
expect(capabilities.supportsUnicode).toBe(true);
|
||||
expect(capabilities.supportsTrueColor).toBe(true);
|
||||
});
|
||||
|
||||
test("should detect Command Prompt limitations", () => {
|
||||
process.env.COMSPEC = "C:\\Windows\\system32\\cmd.exe";
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.COLORTERM;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
delete process.env.PSModulePath;
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
|
||||
expect(capabilities.isCommandPrompt).toBe(true);
|
||||
expect(capabilities.supportsUnicode).toBe(false);
|
||||
expect(capabilities.supportsTrueColor).toBe(false);
|
||||
expect(capabilities.supportsColor).toBe(true);
|
||||
});
|
||||
|
||||
test("should detect PowerShell capabilities", () => {
|
||||
process.env.PSModulePath = "C:\\Program Files\\PowerShell\\Modules";
|
||||
delete process.env.WT_SESSION;
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.isPowerShell).toBe(true);
|
||||
expect(capabilities.supportsUnicode).toBe(true);
|
||||
expect(capabilities.supportsTrueColor).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Color Support Detection", () => {
|
||||
test("should detect true color support in Windows Terminal", () => {
|
||||
process.env.WT_SESSION = "test";
|
||||
process.env.COLORTERM = "truecolor";
|
||||
|
||||
const colorSupport = getWindowsColorSupport();
|
||||
expect(colorSupport.supportsTrueColor).toBe(true);
|
||||
expect(colorSupport.supports256Color).toBe(true);
|
||||
expect(colorSupport.supportsBasicColor).toBe(true);
|
||||
});
|
||||
|
||||
test("should detect limited color support in Command Prompt", () => {
|
||||
process.env.COMSPEC = "C:\\Windows\\system32\\cmd.exe";
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.COLORTERM;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
delete process.env.PSModulePath;
|
||||
|
||||
const colorSupport = getWindowsColorSupport();
|
||||
expect(colorSupport.supportsTrueColor).toBe(false);
|
||||
expect(colorSupport.supports256Color).toBe(false);
|
||||
expect(colorSupport.supportsBasicColor).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Unicode Support Detection", () => {
|
||||
test("should detect Unicode support in Windows Terminal", () => {
|
||||
process.env.WT_SESSION = "test";
|
||||
|
||||
const unicodeSupport = getWindowsUnicodeSupport();
|
||||
expect(unicodeSupport.supportsUnicode).toBe(true);
|
||||
expect(unicodeSupport.supportsEmoji).toBe(true);
|
||||
expect(unicodeSupport.supportsBoxDrawing).toBe(true);
|
||||
});
|
||||
|
||||
test("should detect limited Unicode support in Command Prompt", () => {
|
||||
process.env.COMSPEC = "C:\\Windows\\system32\\cmd.exe";
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.COLORTERM;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
delete process.env.PSModulePath;
|
||||
|
||||
const unicodeSupport = getWindowsUnicodeSupport();
|
||||
expect(unicodeSupport.supportsUnicode).toBe(false);
|
||||
expect(unicodeSupport.supportsEmoji).toBe(false);
|
||||
expect(unicodeSupport.supportsBoxDrawing).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Platform Detection", () => {
|
||||
test("should correctly identify Windows platform", () => {
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.isWindows).toBe(true);
|
||||
});
|
||||
|
||||
test("should handle non-Windows platforms", () => {
|
||||
Object.defineProperty(process, "platform", { value: "darwin" });
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.isWindows).toBe(false);
|
||||
expect(capabilities.isWindowsTerminal).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
266
tests/tui/windows/windowsCompatibility.test.js
Normal file
266
tests/tui/windows/windowsCompatibility.test.js
Normal file
@@ -0,0 +1,266 @@
|
||||
/**
|
||||
* Windows Compatibility Tests
|
||||
* Tests TUI functionality specifically on Windows systems including
|
||||
* Windows Terminal, Command Prompt, and PowerShell environments
|
||||
*/
|
||||
|
||||
import { render } from "ink-testing-library";
|
||||
import React from "react";
|
||||
import { Text, Box } from "ink";
|
||||
import { TuiApplication } from "../../../src/tui/TuiApplication.jsx";
|
||||
import {
|
||||
detectWindowsTerminal,
|
||||
getWindowsTerminalCapabilities,
|
||||
} from "../../../src/tui/utils/modernTerminal.js";
|
||||
|
||||
// Mock process.platform for Windows testing
|
||||
const originalPlatform = process.platform;
|
||||
|
||||
describe("Windows Compatibility Tests", () => {
|
||||
beforeAll(() => {
|
||||
// Mock Windows environment
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: "win32",
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
// Restore original platform
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: originalPlatform,
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
|
||||
describe("Windows Terminal Detection", () => {
|
||||
test("should detect Windows Terminal environment", () => {
|
||||
// Mock Windows Terminal environment variables
|
||||
const originalEnv = process.env;
|
||||
process.env = {
|
||||
...originalEnv,
|
||||
WT_SESSION: "test-session-id",
|
||||
TERM_PROGRAM: "Windows Terminal",
|
||||
};
|
||||
|
||||
const isWindowsTerminal = detectWindowsTerminal();
|
||||
expect(isWindowsTerminal).toBe(true);
|
||||
|
||||
process.env = originalEnv;
|
||||
});
|
||||
|
||||
test("should detect Command Prompt environment", () => {
|
||||
const originalEnv = process.env;
|
||||
process.env = {
|
||||
...originalEnv,
|
||||
PROMPT: "$P$G",
|
||||
COMSPEC: "C:\\Windows\\system32\\cmd.exe",
|
||||
};
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.isCommandPrompt).toBe(true);
|
||||
expect(capabilities.supportsUnicode).toBe(false);
|
||||
expect(capabilities.supportsTrueColor).toBe(false);
|
||||
|
||||
process.env = originalEnv;
|
||||
});
|
||||
|
||||
test("should detect PowerShell environment", () => {
|
||||
const originalEnv = process.env;
|
||||
process.env = {
|
||||
...originalEnv,
|
||||
PSModulePath: "C:\\Program Files\\PowerShell\\Modules",
|
||||
TERM_PROGRAM: "PowerShell",
|
||||
};
|
||||
delete process.env.WT_SESSION;
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.isPowerShell).toBe(true);
|
||||
expect(capabilities.supportsUnicode).toBe(true);
|
||||
expect(capabilities.supportsTrueColor).toBe(false);
|
||||
|
||||
process.env = originalEnv;
|
||||
});
|
||||
});
|
||||
|
||||
describe("Unicode Character Rendering", () => {
|
||||
test("should render basic Unicode characters on Windows", () => {
|
||||
const TestComponent = () => (
|
||||
<Box>
|
||||
<Text>Progress: ░░░░░░░░░░ 0%</Text>
|
||||
<Text>Status: ● Connected</Text>
|
||||
<Text>Arrow: ► Selected</Text>
|
||||
</Box>
|
||||
);
|
||||
|
||||
const { lastFrame } = render(<TestComponent />);
|
||||
const output = lastFrame();
|
||||
|
||||
// Test that Unicode characters are present (may be replaced with fallbacks)
|
||||
expect(output).toMatch(/Progress:.*0%/);
|
||||
expect(output).toMatch(/Status:.*Connected/);
|
||||
expect(output).toMatch(/Arrow:.*Selected/);
|
||||
});
|
||||
|
||||
test("should handle Unicode fallbacks for Command Prompt", () => {
|
||||
// Mock Command Prompt environment
|
||||
const originalEnv = process.env;
|
||||
process.env = {
|
||||
...originalEnv,
|
||||
COMSPEC: "C:\\Windows\\system32\\cmd.exe",
|
||||
};
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
|
||||
const TestComponent = () => {
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
return (
|
||||
<Box>
|
||||
<Text>
|
||||
Progress:{" "}
|
||||
{capabilities.supportsUnicode ? "░░░░░░░░░░" : "----------"} 0%
|
||||
</Text>
|
||||
<Text>
|
||||
Status: {capabilities.supportsUnicode ? "●" : "*"} Connected
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const { lastFrame } = render(<TestComponent />);
|
||||
const output = lastFrame();
|
||||
|
||||
expect(output).toContain("Progress: ---------- 0%");
|
||||
expect(output).toContain("Status: * Connected");
|
||||
|
||||
process.env = originalEnv;
|
||||
});
|
||||
});
|
||||
|
||||
describe("Color Support", () => {
|
||||
test("should detect color support in Windows Terminal", () => {
|
||||
const originalEnv = process.env;
|
||||
process.env = {
|
||||
...originalEnv,
|
||||
WT_SESSION: "test-session",
|
||||
COLORTERM: "truecolor",
|
||||
};
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.supportsTrueColor).toBe(true);
|
||||
expect(capabilities.supportsColor).toBe(true);
|
||||
|
||||
process.env = originalEnv;
|
||||
});
|
||||
|
||||
test("should handle limited color support in Command Prompt", () => {
|
||||
const originalEnv = process.env;
|
||||
process.env = {
|
||||
...originalEnv,
|
||||
COMSPEC: "C:\\Windows\\system32\\cmd.exe",
|
||||
};
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.COLORTERM;
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.supportsTrueColor).toBe(false);
|
||||
expect(capabilities.supportsColor).toBe(true); // Basic 16 colors
|
||||
|
||||
process.env = originalEnv;
|
||||
});
|
||||
});
|
||||
|
||||
describe("Keyboard Input Handling", () => {
|
||||
test("should handle Windows-specific key combinations", () => {
|
||||
const TestComponent = () => {
|
||||
const [keyPressed, setKeyPressed] = React.useState("");
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleInput = (input, key) => {
|
||||
if (key) {
|
||||
// Windows-specific key handling
|
||||
if (key.ctrl && key.name === "c") {
|
||||
setKeyPressed("ctrl+c");
|
||||
} else if (key.name === "escape") {
|
||||
setKeyPressed("escape");
|
||||
} else if (key.name === "return") {
|
||||
setKeyPressed("enter");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
process.stdin.on("keypress", handleInput);
|
||||
return () => process.stdin.off("keypress", handleInput);
|
||||
}, []);
|
||||
|
||||
return <Text>Last key: {keyPressed}</Text>;
|
||||
};
|
||||
|
||||
const { lastFrame, stdin } = render(<TestComponent />);
|
||||
|
||||
// Simulate Windows key events
|
||||
stdin.write("\x03"); // Ctrl+C
|
||||
expect(lastFrame()).toContain("Last key: ctrl+c");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Terminal Resizing", () => {
|
||||
test("should handle Windows terminal resize events", () => {
|
||||
const TestComponent = () => {
|
||||
const [size, setSize] = React.useState({ width: 80, height: 24 });
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleResize = () => {
|
||||
setSize({
|
||||
width: process.stdout.columns || 80,
|
||||
height: process.stdout.rows || 24,
|
||||
});
|
||||
};
|
||||
|
||||
process.stdout.on("resize", handleResize);
|
||||
return () => process.stdout.off("resize", handleResize);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Text>
|
||||
Terminal: {size.width}x{size.height}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
const { lastFrame } = render(<TestComponent />);
|
||||
expect(lastFrame()).toMatch(/Terminal: \d+x\d+/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("File Path Handling", () => {
|
||||
test("should handle Windows file paths correctly", () => {
|
||||
const windowsPath = "C:\\Users\\Test\\AppData\\Local\\Temp\\test.log";
|
||||
const normalizedPath = windowsPath.replace(/\\/g, "/");
|
||||
|
||||
expect(normalizedPath).toBe("C:/Users/Test/AppData/Local/Temp/test.log");
|
||||
});
|
||||
|
||||
test("should handle UNC paths", () => {
|
||||
const uncPath = "\\\\server\\share\\file.txt";
|
||||
const isUncPath = uncPath.startsWith("\\\\");
|
||||
|
||||
expect(isUncPath).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Process Management", () => {
|
||||
test("should handle Windows process signals", () => {
|
||||
const originalPlatform = process.platform;
|
||||
Object.defineProperty(process, "platform", { value: "win32" });
|
||||
|
||||
// Windows doesn't support SIGTERM the same way
|
||||
const supportsSigterm = process.platform !== "win32";
|
||||
expect(supportsSigterm).toBe(false);
|
||||
|
||||
Object.defineProperty(process, "platform", { value: originalPlatform });
|
||||
});
|
||||
});
|
||||
});
|
||||
269
tests/tui/windows/windowsIntegration.test.js
Normal file
269
tests/tui/windows/windowsIntegration.test.js
Normal file
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* Windows Integration Tests
|
||||
* Tests complete TUI workflows on Windows systems
|
||||
*/
|
||||
|
||||
import { render } from "ink-testing-library";
|
||||
import React from "react";
|
||||
import { TuiApplication } from "../../../src/tui/TuiApplication.jsx";
|
||||
import { MainMenuScreen } from "../../../src/tui/components/screens/MainMenuScreen.jsx";
|
||||
import { ConfigurationScreen } from "../../../src/tui/components/screens/ConfigurationScreen.jsx";
|
||||
import { AppProvider } from "../../../src/tui/providers/AppProvider.jsx";
|
||||
|
||||
// Mock Windows environment
|
||||
const mockWindowsEnvironment = () => {
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: "win32",
|
||||
writable: true,
|
||||
});
|
||||
|
||||
process.env = {
|
||||
...process.env,
|
||||
OS: "Windows_NT",
|
||||
USERPROFILE: "C:\\Users\\TestUser",
|
||||
APPDATA: "C:\\Users\\TestUser\\AppData\\Roaming",
|
||||
LOCALAPPDATA: "C:\\Users\\TestUser\\AppData\\Local",
|
||||
};
|
||||
};
|
||||
|
||||
describe("Windows Integration Tests", () => {
|
||||
beforeEach(() => {
|
||||
mockWindowsEnvironment();
|
||||
});
|
||||
|
||||
describe("Application Startup", () => {
|
||||
test("should start TUI application on Windows", async () => {
|
||||
const { lastFrame, unmount } = render(
|
||||
<AppProvider>
|
||||
<TuiApplication />
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
// Wait for initial render
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
const output = lastFrame();
|
||||
expect(output).toContain("Price Update Operations");
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
test("should handle Windows Terminal capabilities detection", async () => {
|
||||
// Mock Windows Terminal
|
||||
process.env.WT_SESSION = "test-session";
|
||||
process.env.COLORTERM = "truecolor";
|
||||
|
||||
const { lastFrame, unmount } = render(
|
||||
<AppProvider>
|
||||
<MainMenuScreen />
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
const output = lastFrame();
|
||||
// Should render with enhanced features in Windows Terminal
|
||||
expect(output).toBeTruthy();
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
test("should handle Command Prompt limitations", async () => {
|
||||
// Mock Command Prompt
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.COLORTERM;
|
||||
process.env.COMSPEC = "C:\\Windows\\system32\\cmd.exe";
|
||||
|
||||
const { lastFrame, unmount } = render(
|
||||
<AppProvider>
|
||||
<MainMenuScreen />
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
const output = lastFrame();
|
||||
// Should render with fallback characters
|
||||
expect(output).toBeTruthy();
|
||||
|
||||
unmount();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Navigation Flow", () => {
|
||||
test("should navigate between screens on Windows", async () => {
|
||||
const { lastFrame, stdin, unmount } = render(
|
||||
<AppProvider>
|
||||
<TuiApplication />
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
// Wait for initial render
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
// Navigate to configuration
|
||||
stdin.write("c");
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
const output = lastFrame();
|
||||
expect(output).toContain("Configuration") ||
|
||||
expect(output).toContain("Settings");
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
test("should handle Windows keyboard shortcuts", async () => {
|
||||
const { lastFrame, stdin, unmount } = render(
|
||||
<AppProvider>
|
||||
<MainMenuScreen />
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
// Test Escape key (common Windows pattern)
|
||||
stdin.write("\x1b"); // ESC
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
|
||||
// Test Enter key
|
||||
stdin.write("\r"); // Windows line ending
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
|
||||
expect(lastFrame()).toBeTruthy();
|
||||
|
||||
unmount();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Configuration Management", () => {
|
||||
test("should handle Windows file paths in configuration", async () => {
|
||||
const { lastFrame, unmount } = render(
|
||||
<AppProvider>
|
||||
<ConfigurationScreen />
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
const output = lastFrame();
|
||||
expect(output).toBeTruthy();
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
test("should validate Windows environment variables", () => {
|
||||
const windowsEnvVars = {
|
||||
SHOPIFY_SHOP_DOMAIN: "test-shop.myshopify.com",
|
||||
SHOPIFY_ACCESS_TOKEN: "shpat_test123",
|
||||
TARGET_TAG: "sale",
|
||||
PRICE_ADJUSTMENT_PERCENTAGE: "10",
|
||||
OPERATION_MODE: "update",
|
||||
};
|
||||
|
||||
Object.entries(windowsEnvVars).forEach(([key, value]) => {
|
||||
expect(typeof value).toBe("string");
|
||||
expect(value.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Error Handling", () => {
|
||||
test("should display Windows-friendly error messages", async () => {
|
||||
// Mock an error condition
|
||||
const ErrorComponent = () => {
|
||||
throw new Error("Test Windows error");
|
||||
};
|
||||
|
||||
const { lastFrame, unmount } = render(
|
||||
<AppProvider>
|
||||
<ErrorComponent />
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
// Should handle error gracefully
|
||||
expect(() => lastFrame()).not.toThrow();
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
test("should handle Windows file system errors", () => {
|
||||
const windowsError = new Error(
|
||||
"ENOENT: no such file or directory, open 'C:\\nonexistent\\file.txt'"
|
||||
);
|
||||
|
||||
expect(windowsError.message).toContain("ENOENT");
|
||||
expect(windowsError.message).toContain("C:\\");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Performance on Windows", () => {
|
||||
test("should render efficiently on Windows systems", async () => {
|
||||
const startTime = Date.now();
|
||||
|
||||
const { lastFrame, unmount } = render(
|
||||
<AppProvider>
|
||||
<TuiApplication />
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
const renderTime = Date.now() - startTime;
|
||||
expect(renderTime).toBeLessThan(1000); // Should render within 1 second
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
test("should handle Windows terminal refresh rates", async () => {
|
||||
let renderCount = 0;
|
||||
|
||||
const TestComponent = () => {
|
||||
React.useEffect(() => {
|
||||
renderCount++;
|
||||
});
|
||||
|
||||
return <div>Render count: {renderCount}</div>;
|
||||
};
|
||||
|
||||
const { unmount } = render(<TestComponent />);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
expect(renderCount).toBeGreaterThan(0);
|
||||
|
||||
unmount();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Memory Management on Windows", () => {
|
||||
test("should clean up resources properly on Windows", async () => {
|
||||
const { unmount } = render(
|
||||
<AppProvider>
|
||||
<TuiApplication />
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
// Unmount should not throw errors
|
||||
expect(() => unmount()).not.toThrow();
|
||||
});
|
||||
|
||||
test("should handle Windows process cleanup", () => {
|
||||
const cleanup = jest.fn();
|
||||
|
||||
// Mock Windows process cleanup
|
||||
process.on("SIGINT", cleanup);
|
||||
process.on("SIGTERM", cleanup);
|
||||
|
||||
// Windows uses different signals
|
||||
if (process.platform === "win32") {
|
||||
process.on("SIGBREAK", cleanup);
|
||||
}
|
||||
|
||||
expect(cleanup).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
378
tests/tui/windows/windowsOptimizations.test.js
Normal file
378
tests/tui/windows/windowsOptimizations.test.js
Normal file
@@ -0,0 +1,378 @@
|
||||
/**
|
||||
* Windows Optimizations Tests
|
||||
* Tests for Windows-specific performance optimizations
|
||||
*/
|
||||
|
||||
const {
|
||||
WindowsRenderingOptimizations,
|
||||
WindowsKeyboardOptimizations,
|
||||
WindowsFileSystemOptimizations,
|
||||
WindowsPerformanceMonitor,
|
||||
} = require("../../../src/tui/utils/windowsOptimizations.js");
|
||||
|
||||
const {
|
||||
WindowsKeyboardHandler,
|
||||
createWindowsKeyboardHandler,
|
||||
WindowsKeyboardUtils,
|
||||
} = require("../../../src/tui/utils/windowsKeyboardHandlers.js");
|
||||
|
||||
// Mock Windows environment
|
||||
const mockWindowsEnvironment = (terminalType = "windows-terminal") => {
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: "win32",
|
||||
writable: true,
|
||||
});
|
||||
|
||||
// Clear environment first
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
delete process.env.PSModulePath;
|
||||
delete process.env.COMSPEC;
|
||||
delete process.env.COLORTERM;
|
||||
|
||||
switch (terminalType) {
|
||||
case "windows-terminal":
|
||||
process.env.WT_SESSION = "test-session";
|
||||
process.env.TERM_PROGRAM = "Windows Terminal";
|
||||
process.env.COLORTERM = "truecolor";
|
||||
break;
|
||||
case "cmd":
|
||||
process.env.COMSPEC = "C:\\Windows\\system32\\cmd.exe";
|
||||
break;
|
||||
case "powershell":
|
||||
process.env.PSModulePath = "C:\\Program Files\\PowerShell\\Modules";
|
||||
process.env.TERM_PROGRAM = "PowerShell";
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
describe("Windows Optimizations Tests", () => {
|
||||
const originalPlatform = process.platform;
|
||||
const originalEnv = process.env;
|
||||
|
||||
afterEach(() => {
|
||||
process.env = originalEnv;
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: originalPlatform,
|
||||
writable: true,
|
||||
});
|
||||
|
||||
// Clear rendering cache
|
||||
WindowsRenderingOptimizations.clearCache();
|
||||
});
|
||||
|
||||
describe("Windows Rendering Optimizations", () => {
|
||||
test("should cache terminal capabilities for performance", () => {
|
||||
mockWindowsEnvironment("windows-terminal");
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
// First call should detect and cache
|
||||
const capabilities1 =
|
||||
WindowsRenderingOptimizations.getCachedCapabilities();
|
||||
const firstCallTime = Date.now() - startTime;
|
||||
|
||||
// Second call should use cache
|
||||
const cacheStartTime = Date.now();
|
||||
const capabilities2 =
|
||||
WindowsRenderingOptimizations.getCachedCapabilities();
|
||||
const cacheCallTime = Date.now() - cacheStartTime;
|
||||
|
||||
expect(capabilities1).toEqual(capabilities2);
|
||||
expect(cacheCallTime).toBeLessThan(10); // Cache should be very fast
|
||||
});
|
||||
|
||||
test("should provide optimized character sets for different terminals", () => {
|
||||
// Test Windows Terminal
|
||||
mockWindowsEnvironment("windows-terminal");
|
||||
const wtCharSet =
|
||||
WindowsRenderingOptimizations.getOptimizedCharacterSet();
|
||||
expect(wtCharSet.progress.filled).toBe("█");
|
||||
expect(wtCharSet.status.success).toBe("✅");
|
||||
|
||||
// Test Command Prompt
|
||||
mockWindowsEnvironment("cmd");
|
||||
WindowsRenderingOptimizations.clearCache();
|
||||
const cmdCharSet =
|
||||
WindowsRenderingOptimizations.getOptimizedCharacterSet();
|
||||
expect(cmdCharSet.progress.filled).toBe("#");
|
||||
expect(cmdCharSet.status.success).toBe("v");
|
||||
|
||||
// Test PowerShell
|
||||
mockWindowsEnvironment("powershell");
|
||||
WindowsRenderingOptimizations.clearCache();
|
||||
const psCharSet =
|
||||
WindowsRenderingOptimizations.getOptimizedCharacterSet();
|
||||
expect(psCharSet.progress.filled).toBe("█");
|
||||
expect(psCharSet.status.success).toBe("✓");
|
||||
});
|
||||
|
||||
test("should optimize strings for Command Prompt", () => {
|
||||
mockWindowsEnvironment("cmd");
|
||||
|
||||
const complexString = "█████░░░░░ ●✓ ►Test";
|
||||
const optimized =
|
||||
WindowsRenderingOptimizations.optimizeString(complexString);
|
||||
|
||||
expect(optimized).toBe("#####----- *v >Test");
|
||||
});
|
||||
|
||||
test("should provide appropriate update frequencies", () => {
|
||||
// Command Prompt should have lowest frequency
|
||||
mockWindowsEnvironment("cmd");
|
||||
WindowsRenderingOptimizations.clearCache();
|
||||
expect(WindowsRenderingOptimizations.getOptimalUpdateFrequency()).toBe(
|
||||
250
|
||||
);
|
||||
|
||||
// PowerShell should have medium frequency
|
||||
mockWindowsEnvironment("powershell");
|
||||
WindowsRenderingOptimizations.clearCache();
|
||||
expect(WindowsRenderingOptimizations.getOptimalUpdateFrequency()).toBe(
|
||||
100
|
||||
);
|
||||
|
||||
// Windows Terminal should have highest frequency
|
||||
mockWindowsEnvironment("windows-terminal");
|
||||
WindowsRenderingOptimizations.clearCache();
|
||||
expect(WindowsRenderingOptimizations.getOptimalUpdateFrequency()).toBe(
|
||||
50
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Windows Keyboard Optimizations", () => {
|
||||
test("should normalize Windows keyboard events", () => {
|
||||
const testCases = [
|
||||
{ input: "\r\n", expected: { name: "return" } },
|
||||
{ input: "\x03", expected: { name: "c", ctrl: true } },
|
||||
{ input: "\x1a", expected: { name: "z", ctrl: true } },
|
||||
{ input: "\x1b[1;5A", expected: { name: "up", ctrl: true } },
|
||||
];
|
||||
|
||||
testCases.forEach(({ input, expected }) => {
|
||||
const result = WindowsKeyboardOptimizations.normalizeKeyEvent(
|
||||
input,
|
||||
null
|
||||
);
|
||||
expect(result.key).toMatchObject(expected);
|
||||
});
|
||||
});
|
||||
|
||||
test("should create key debouncer", () => {
|
||||
const debouncer = WindowsKeyboardOptimizations.createKeyDebouncer(100);
|
||||
|
||||
// First call should pass through
|
||||
const result1 = debouncer("a", { name: "a" });
|
||||
expect(result1).toBeTruthy();
|
||||
|
||||
// Immediate second call with same key should be filtered
|
||||
const result2 = debouncer("a", { name: "a" });
|
||||
expect(result2).toBeNull();
|
||||
|
||||
// Different key should pass through
|
||||
const result3 = debouncer("b", { name: "b" });
|
||||
expect(result3).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Windows File System Optimizations", () => {
|
||||
test("should normalize Windows file paths", () => {
|
||||
const testPaths = [
|
||||
{
|
||||
input: "C:\\Users\\Test\\file.txt",
|
||||
expected: "C:/Users/Test/file.txt",
|
||||
},
|
||||
{
|
||||
input: "\\\\server\\share\\file.txt",
|
||||
expected: "//server/share/file.txt",
|
||||
},
|
||||
{
|
||||
input: "relative\\path\\file.txt",
|
||||
expected: "relative/path/file.txt",
|
||||
},
|
||||
];
|
||||
|
||||
testPaths.forEach(({ input, expected }) => {
|
||||
const result = WindowsFileSystemOptimizations.normalizePath(input);
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
test("should provide Windows user directories", () => {
|
||||
// Mock Windows environment variables
|
||||
process.env.USERPROFILE = "C:\\Users\\TestUser";
|
||||
process.env.APPDATA = "C:\\Users\\TestUser\\AppData\\Roaming";
|
||||
process.env.LOCALAPPDATA = "C:\\Users\\TestUser\\AppData\\Local";
|
||||
|
||||
const dirs = WindowsFileSystemOptimizations.getUserDirectories();
|
||||
|
||||
expect(dirs.home).toBe("C:\\Users\\TestUser");
|
||||
expect(dirs.appData).toBe("C:\\Users\\TestUser\\AppData\\Roaming");
|
||||
expect(dirs.localAppData).toBe("C:\\Users\\TestUser\\AppData\\Local");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Windows Performance Monitor", () => {
|
||||
test("should monitor rendering performance", () => {
|
||||
const monitor = WindowsPerformanceMonitor.createRenderingMonitor();
|
||||
|
||||
monitor.startFrame();
|
||||
|
||||
// Simulate some work
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < 10) {
|
||||
// Busy wait for 10ms
|
||||
}
|
||||
|
||||
const stats = monitor.endFrame();
|
||||
|
||||
expect(stats.frameTime).toBeGreaterThan(5);
|
||||
expect(stats.totalFrames).toBe(1);
|
||||
expect(stats.fps).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test("should monitor memory usage", () => {
|
||||
const usage = WindowsPerformanceMonitor.getMemoryUsage();
|
||||
|
||||
expect(typeof usage.heapUsed).toBe("number");
|
||||
expect(typeof usage.heapTotal).toBe("number");
|
||||
expect(typeof usage.external).toBe("number");
|
||||
expect(typeof usage.rss).toBe("number");
|
||||
|
||||
expect(usage.heapUsed).toBeGreaterThan(0);
|
||||
expect(usage.heapTotal).toBeGreaterThan(usage.heapUsed);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Windows Keyboard Handler", () => {
|
||||
test("should create keyboard handler with Windows optimizations", () => {
|
||||
mockWindowsEnvironment("windows-terminal");
|
||||
|
||||
const handler = createWindowsKeyboardHandler({
|
||||
debounceDelay: 25,
|
||||
enableEnhancedKeys: true,
|
||||
});
|
||||
|
||||
expect(handler).toBeInstanceOf(WindowsKeyboardHandler);
|
||||
expect(handler.debounceDelay).toBe(25);
|
||||
expect(handler.enableEnhancedKeys).toBe(true);
|
||||
});
|
||||
|
||||
test("should parse Windows Terminal enhanced keys", () => {
|
||||
mockWindowsEnvironment("windows-terminal");
|
||||
|
||||
const handler = new WindowsKeyboardHandler();
|
||||
|
||||
const testKeys = [
|
||||
{ input: "\x1b[1;5A", expected: { name: "up", ctrl: true } },
|
||||
{ input: "\x1b[1;2B", expected: { name: "down", shift: true } },
|
||||
{ input: "\x1b[1;3C", expected: { name: "right", meta: true } },
|
||||
];
|
||||
|
||||
testKeys.forEach(({ input, expected }) => {
|
||||
const result = handler.parseWindowsTerminalKeys(input);
|
||||
expect(result.key).toMatchObject(expected);
|
||||
});
|
||||
});
|
||||
|
||||
test("should handle Command Prompt key limitations", () => {
|
||||
mockWindowsEnvironment("cmd");
|
||||
|
||||
const handler = new WindowsKeyboardHandler();
|
||||
|
||||
const testKeys = [
|
||||
{ input: "\x03", expected: { name: "c", ctrl: true } },
|
||||
{ input: "\r", expected: { name: "return" } },
|
||||
{ input: "\x08", expected: { name: "backspace" } },
|
||||
];
|
||||
|
||||
testKeys.forEach(({ input, expected }) => {
|
||||
const result = handler.parseCommandPromptKeys(input);
|
||||
expect(result.key).toMatchObject(expected);
|
||||
});
|
||||
});
|
||||
|
||||
test("should provide keyboard handler statistics", () => {
|
||||
const handler = new WindowsKeyboardHandler();
|
||||
const stats = handler.getStats();
|
||||
|
||||
expect(stats).toHaveProperty("isActive");
|
||||
expect(stats).toHaveProperty("capabilities");
|
||||
expect(stats).toHaveProperty("debounceDelay");
|
||||
expect(stats).toHaveProperty("enableEnhancedKeys");
|
||||
expect(stats).toHaveProperty("listenerCount");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Windows Keyboard Utils", () => {
|
||||
test("should identify system shortcuts", () => {
|
||||
const systemShortcuts = [
|
||||
{ input: "\x03", key: { name: "c", ctrl: true } }, // Ctrl+C
|
||||
{ input: "v", key: { name: "v", ctrl: true } }, // Ctrl+V
|
||||
{ input: "z", key: { name: "z", ctrl: true } }, // Ctrl+Z
|
||||
];
|
||||
|
||||
systemShortcuts.forEach(({ input, key }) => {
|
||||
const isSystem = WindowsKeyboardUtils.isSystemShortcut(input, key);
|
||||
expect(isSystem).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test("should generate Windows-friendly key descriptions", () => {
|
||||
const testKeys = [
|
||||
{ input: "a", key: { name: "a", ctrl: true }, expected: "Ctrl+A" },
|
||||
{ input: "f4", key: { name: "f4", meta: true }, expected: "Alt+F4" },
|
||||
{
|
||||
input: "tab",
|
||||
key: { name: "tab", ctrl: true, shift: true },
|
||||
expected: "Ctrl+Shift+Tab",
|
||||
},
|
||||
];
|
||||
|
||||
testKeys.forEach(({ input, key, expected }) => {
|
||||
const description = WindowsKeyboardUtils.getKeyDescription(input, key);
|
||||
expect(description).toBe(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Performance Benchmarks", () => {
|
||||
test("should perform character optimization efficiently", () => {
|
||||
mockWindowsEnvironment("cmd");
|
||||
|
||||
const testString =
|
||||
"█████░░░░░ ●✓ ►Test with lots of Unicode characters ▶️🔵";
|
||||
const iterations = 1000;
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
WindowsRenderingOptimizations.optimizeString(testString);
|
||||
}
|
||||
|
||||
const totalTime = Date.now() - startTime;
|
||||
const avgTime = totalTime / iterations;
|
||||
|
||||
expect(avgTime).toBeLessThan(1); // Should average less than 1ms per optimization
|
||||
});
|
||||
|
||||
test("should handle rapid capability checks efficiently", () => {
|
||||
const terminals = ["windows-terminal", "cmd", "powershell"];
|
||||
const iterations = 100;
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
const terminalType = terminals[i % terminals.length];
|
||||
mockWindowsEnvironment(terminalType);
|
||||
WindowsRenderingOptimizations.clearCache();
|
||||
WindowsRenderingOptimizations.getCachedCapabilities();
|
||||
}
|
||||
|
||||
const totalTime = Date.now() - startTime;
|
||||
|
||||
expect(totalTime).toBeLessThan(500); // Should complete in less than 500ms
|
||||
});
|
||||
});
|
||||
});
|
||||
316
tests/tui/windows/windowsPerformance.test.js
Normal file
316
tests/tui/windows/windowsPerformance.test.js
Normal file
@@ -0,0 +1,316 @@
|
||||
/**
|
||||
* Windows Performance Tests
|
||||
* Tests TUI performance specifically on Windows systems
|
||||
*/
|
||||
|
||||
const {
|
||||
detectWindowsTerminal,
|
||||
getWindowsTerminalCapabilities,
|
||||
} = require("../../../src/tui/utils/modernTerminal.js");
|
||||
|
||||
// Mock Windows environment
|
||||
const mockWindowsEnvironment = (terminalType = "windows-terminal") => {
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: "win32",
|
||||
writable: true,
|
||||
});
|
||||
|
||||
// Clear environment first
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
delete process.env.PSModulePath;
|
||||
delete process.env.COMSPEC;
|
||||
delete process.env.COLORTERM;
|
||||
|
||||
switch (terminalType) {
|
||||
case "windows-terminal":
|
||||
process.env.WT_SESSION = "test-session";
|
||||
process.env.TERM_PROGRAM = "Windows Terminal";
|
||||
process.env.COLORTERM = "truecolor";
|
||||
break;
|
||||
case "cmd":
|
||||
process.env.COMSPEC = "C:\\Windows\\system32\\cmd.exe";
|
||||
break;
|
||||
case "powershell":
|
||||
process.env.PSModulePath = "C:\\Program Files\\PowerShell\\Modules";
|
||||
process.env.TERM_PROGRAM = "PowerShell";
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
describe("Windows Performance Tests", () => {
|
||||
const originalPlatform = process.platform;
|
||||
const originalEnv = process.env;
|
||||
|
||||
afterEach(() => {
|
||||
process.env = originalEnv;
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: originalPlatform,
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
|
||||
describe("Terminal Detection Performance", () => {
|
||||
test("should detect Windows Terminal capabilities quickly", () => {
|
||||
mockWindowsEnvironment("windows-terminal");
|
||||
|
||||
const startTime = Date.now();
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
const detectionTime = Date.now() - startTime;
|
||||
|
||||
expect(detectionTime).toBeLessThan(10); // Should detect within 10ms
|
||||
expect(capabilities.isWindowsTerminal).toBe(true);
|
||||
expect(capabilities.supportsUnicode).toBe(true);
|
||||
expect(capabilities.supportsTrueColor).toBe(true);
|
||||
});
|
||||
|
||||
test("should detect Command Prompt capabilities efficiently", () => {
|
||||
mockWindowsEnvironment("cmd");
|
||||
|
||||
const startTime = Date.now();
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
const detectionTime = Date.now() - startTime;
|
||||
|
||||
expect(detectionTime).toBeLessThan(10);
|
||||
expect(capabilities.isCommandPrompt).toBe(true);
|
||||
expect(capabilities.supportsUnicode).toBe(false);
|
||||
expect(capabilities.supportsTrueColor).toBe(false);
|
||||
});
|
||||
|
||||
test("should detect PowerShell capabilities quickly", () => {
|
||||
mockWindowsEnvironment("powershell");
|
||||
|
||||
const startTime = Date.now();
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
const detectionTime = Date.now() - startTime;
|
||||
|
||||
expect(detectionTime).toBeLessThan(10);
|
||||
expect(capabilities.isPowerShell).toBe(true);
|
||||
expect(capabilities.supportsUnicode).toBe(true);
|
||||
expect(capabilities.supports256Color).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Memory Usage", () => {
|
||||
test("should not leak memory during Windows Terminal detection", () => {
|
||||
mockWindowsEnvironment("windows-terminal");
|
||||
|
||||
const initialMemory = process.memoryUsage().heapUsed;
|
||||
|
||||
// Run detection multiple times
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
detectWindowsTerminal();
|
||||
getWindowsTerminalCapabilities();
|
||||
}
|
||||
|
||||
// Force garbage collection if available
|
||||
if (global.gc) {
|
||||
global.gc();
|
||||
}
|
||||
|
||||
const finalMemory = process.memoryUsage().heapUsed;
|
||||
const memoryIncrease = finalMemory - initialMemory;
|
||||
|
||||
// Memory increase should be minimal (less than 1MB)
|
||||
expect(memoryIncrease).toBeLessThan(1024 * 1024);
|
||||
});
|
||||
|
||||
test("should handle rapid terminal capability checks", () => {
|
||||
const terminals = ["windows-terminal", "cmd", "powershell"];
|
||||
const startTime = Date.now();
|
||||
|
||||
// Rapidly switch between terminal types
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const terminalType = terminals[i % terminals.length];
|
||||
mockWindowsEnvironment(terminalType);
|
||||
getWindowsTerminalCapabilities();
|
||||
}
|
||||
|
||||
const totalTime = Date.now() - startTime;
|
||||
|
||||
// Should complete 300 operations in less than 1 second
|
||||
expect(totalTime).toBeLessThan(1000);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Character Rendering Performance", () => {
|
||||
test("should generate character fallbacks efficiently", () => {
|
||||
mockWindowsEnvironment("cmd");
|
||||
|
||||
const startTime = Date.now();
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
|
||||
// Generate character mappings
|
||||
const chars = {
|
||||
progress: capabilities.supportsUnicode ? "█" : "#",
|
||||
empty: capabilities.supportsUnicode ? "░" : "-",
|
||||
status: capabilities.supportsUnicode ? "●" : "*",
|
||||
arrow: capabilities.supportsUnicode ? "►" : ">",
|
||||
check: capabilities.supportsUnicode ? "✓" : "v",
|
||||
cross: capabilities.supportsUnicode ? "✗" : "x",
|
||||
};
|
||||
|
||||
// Generate progress bar strings
|
||||
const progressBars = [];
|
||||
for (let i = 0; i <= 100; i += 10) {
|
||||
const filled = Math.round((i / 100) * 20);
|
||||
progressBars.push(
|
||||
chars.progress.repeat(filled) + chars.empty.repeat(20 - filled)
|
||||
);
|
||||
}
|
||||
|
||||
const generationTime = Date.now() - startTime;
|
||||
|
||||
expect(generationTime).toBeLessThan(50);
|
||||
expect(progressBars).toHaveLength(11);
|
||||
expect(progressBars[0]).toBe("--------------------"); // 0% with fallback chars
|
||||
expect(progressBars[10]).toBe("####################"); // 100% with fallback chars
|
||||
});
|
||||
|
||||
test("should handle Unicode character generation efficiently", () => {
|
||||
mockWindowsEnvironment("windows-terminal");
|
||||
|
||||
const startTime = Date.now();
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
|
||||
// Generate Unicode character strings
|
||||
const unicodeStrings = [];
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const progressChar = capabilities.supportsUnicode ? "█" : "#";
|
||||
const emptyChar = capabilities.supportsUnicode ? "░" : "-";
|
||||
unicodeStrings.push(progressChar.repeat(10) + emptyChar.repeat(10));
|
||||
}
|
||||
|
||||
const generationTime = Date.now() - startTime;
|
||||
|
||||
expect(generationTime).toBeLessThan(50);
|
||||
expect(unicodeStrings).toHaveLength(100);
|
||||
expect(unicodeStrings[0]).toBe("██████████░░░░░░░░░░");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Windows-Specific Optimizations", () => {
|
||||
test("should optimize for Windows file path handling", () => {
|
||||
const windowsPaths = [
|
||||
"C:\\Users\\Test\\AppData\\Local\\Temp\\test.log",
|
||||
"D:\\Projects\\MyApp\\logs\\error.log",
|
||||
"\\\\server\\share\\file.txt",
|
||||
"C:\\Program Files\\App\\config.json",
|
||||
];
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
const normalizedPaths = windowsPaths.map((path) => {
|
||||
// Simulate path normalization
|
||||
return path.replace(/\\/g, "/");
|
||||
});
|
||||
|
||||
const processingTime = Date.now() - startTime;
|
||||
|
||||
expect(processingTime).toBeLessThan(10);
|
||||
expect(normalizedPaths).toEqual([
|
||||
"C:/Users/Test/AppData/Local/Temp/test.log",
|
||||
"D:/Projects/MyApp/logs/error.log",
|
||||
"//server/share/file.txt",
|
||||
"C:/Program Files/App/config.json",
|
||||
]);
|
||||
});
|
||||
|
||||
test("should handle Windows environment variable processing efficiently", () => {
|
||||
const windowsEnvVars = {
|
||||
USERPROFILE: "C:\\Users\\TestUser",
|
||||
APPDATA: "C:\\Users\\TestUser\\AppData\\Roaming",
|
||||
LOCALAPPDATA: "C:\\Users\\TestUser\\AppData\\Local",
|
||||
PROGRAMFILES: "C:\\Program Files",
|
||||
SYSTEMROOT: "C:\\Windows",
|
||||
};
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
// Simulate environment variable processing
|
||||
Object.entries(windowsEnvVars).forEach(([key, value]) => {
|
||||
expect(typeof value).toBe("string");
|
||||
expect(value.length).toBeGreaterThan(0);
|
||||
expect(value).toMatch(/^[A-Z]:\\/); // Windows path format
|
||||
});
|
||||
|
||||
const processingTime = Date.now() - startTime;
|
||||
expect(processingTime).toBeLessThan(10);
|
||||
});
|
||||
|
||||
test("should efficiently detect Windows version compatibility", () => {
|
||||
const startTime = Date.now();
|
||||
|
||||
// Simulate Windows version detection
|
||||
const isWindows = process.platform === "win32";
|
||||
const hasModernTerminal = Boolean(process.env.WT_SESSION);
|
||||
const hasLegacyTerminal = Boolean(process.env.COMSPEC);
|
||||
|
||||
const detectionTime = Date.now() - startTime;
|
||||
|
||||
expect(detectionTime).toBeLessThan(5);
|
||||
expect(typeof isWindows).toBe("boolean");
|
||||
expect(typeof hasModernTerminal).toBe("boolean");
|
||||
expect(typeof hasLegacyTerminal).toBe("boolean");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Stress Testing", () => {
|
||||
test("should handle repeated terminal type switching", () => {
|
||||
const terminals = ["windows-terminal", "cmd", "powershell"];
|
||||
const results = [];
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
const terminalType = terminals[i % terminals.length];
|
||||
mockWindowsEnvironment(terminalType);
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
results.push(capabilities.terminalType);
|
||||
}
|
||||
|
||||
const totalTime = Date.now() - startTime;
|
||||
|
||||
expect(totalTime).toBeLessThan(500); // 1000 switches in less than 500ms
|
||||
expect(results).toHaveLength(1000);
|
||||
|
||||
// Verify correct distribution
|
||||
const windowsTerminalCount = results.filter(
|
||||
(t) => t === "windows-terminal"
|
||||
).length;
|
||||
const cmdCount = results.filter((t) => t === "cmd").length;
|
||||
const powershellCount = results.filter((t) => t === "powershell").length;
|
||||
|
||||
expect(windowsTerminalCount).toBeGreaterThan(300);
|
||||
expect(windowsTerminalCount).toBeLessThan(350);
|
||||
expect(cmdCount).toBeGreaterThan(300);
|
||||
expect(cmdCount).toBeLessThan(350);
|
||||
expect(powershellCount).toBeGreaterThan(300);
|
||||
expect(powershellCount).toBeLessThan(350);
|
||||
});
|
||||
|
||||
test("should maintain performance under concurrent capability checks", async () => {
|
||||
mockWindowsEnvironment("windows-terminal");
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
// Simulate concurrent capability checks
|
||||
const promises = Array.from({ length: 100 }, () =>
|
||||
Promise.resolve(getWindowsTerminalCapabilities())
|
||||
);
|
||||
|
||||
const results = await Promise.all(promises);
|
||||
const totalTime = Date.now() - startTime;
|
||||
|
||||
expect(totalTime).toBeLessThan(100);
|
||||
expect(results).toHaveLength(100);
|
||||
|
||||
// All results should be identical
|
||||
results.forEach((result) => {
|
||||
expect(result.isWindowsTerminal).toBe(true);
|
||||
expect(result.supportsUnicode).toBe(true);
|
||||
expect(result.supportsTrueColor).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
341
tests/tui/windows/windowsTerminal.test.js
Normal file
341
tests/tui/windows/windowsTerminal.test.js
Normal file
@@ -0,0 +1,341 @@
|
||||
/**
|
||||
* Windows Terminal Specific Tests
|
||||
* Tests for Windows Terminal, Command Prompt, and PowerShell environments
|
||||
*/
|
||||
|
||||
import { render } from "ink-testing-library";
|
||||
import React from "react";
|
||||
import { Text, Box } from "ink";
|
||||
import {
|
||||
detectWindowsTerminal,
|
||||
getWindowsTerminalCapabilities,
|
||||
getWindowsColorSupport,
|
||||
getWindowsUnicodeSupport,
|
||||
} from "../../../src/tui/utils/modernTerminal.js";
|
||||
|
||||
describe("Windows Terminal Environment Tests", () => {
|
||||
const originalEnv = process.env;
|
||||
const originalPlatform = process.platform;
|
||||
|
||||
beforeEach(() => {
|
||||
// Reset environment
|
||||
process.env = { ...originalEnv };
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: "win32",
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env = originalEnv;
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: originalPlatform,
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
|
||||
describe("Windows Terminal Detection", () => {
|
||||
test("should detect Windows Terminal with WT_SESSION", () => {
|
||||
process.env.WT_SESSION = "abc123-def456";
|
||||
process.env.TERM_PROGRAM = "Windows Terminal";
|
||||
|
||||
const isWindowsTerminal = detectWindowsTerminal();
|
||||
expect(isWindowsTerminal).toBe(true);
|
||||
});
|
||||
|
||||
test("should detect Windows Terminal Preview", () => {
|
||||
process.env.WT_SESSION = "preview-session";
|
||||
process.env.TERM_PROGRAM = "Windows Terminal Preview";
|
||||
|
||||
const isWindowsTerminal = detectWindowsTerminal();
|
||||
expect(isWindowsTerminal).toBe(true);
|
||||
});
|
||||
|
||||
test("should not detect Windows Terminal without proper env vars", () => {
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
|
||||
const isWindowsTerminal = detectWindowsTerminal();
|
||||
expect(isWindowsTerminal).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Command Prompt Detection", () => {
|
||||
test("should detect Command Prompt environment", () => {
|
||||
process.env.COMSPEC = "C:\\Windows\\system32\\cmd.exe";
|
||||
process.env.PROMPT = "$P$G";
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
delete process.env.PSModulePath;
|
||||
delete process.env.COLORTERM;
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.isCommandPrompt).toBe(true);
|
||||
expect(capabilities.terminalType).toBe("cmd");
|
||||
});
|
||||
|
||||
test("should handle Command Prompt limitations", () => {
|
||||
process.env.COMSPEC = "C:\\Windows\\system32\\cmd.exe";
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.COLORTERM;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
delete process.env.PSModulePath;
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.supportsUnicode).toBe(false);
|
||||
expect(capabilities.supportsTrueColor).toBe(false);
|
||||
expect(capabilities.supportsColor).toBe(true); // Basic colors only
|
||||
});
|
||||
});
|
||||
|
||||
describe("PowerShell Detection", () => {
|
||||
test("should detect PowerShell environment", () => {
|
||||
process.env.PSModulePath = "C:\\Program Files\\PowerShell\\Modules";
|
||||
process.env.TERM_PROGRAM = "PowerShell";
|
||||
delete process.env.WT_SESSION;
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.isPowerShell).toBe(true);
|
||||
expect(capabilities.terminalType).toBe("powershell");
|
||||
});
|
||||
|
||||
test("should detect PowerShell Core", () => {
|
||||
process.env.PSModulePath = "C:\\Program Files\\PowerShell\\7\\Modules";
|
||||
process.env.TERM_PROGRAM = "PowerShell Core";
|
||||
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
expect(capabilities.isPowerShell).toBe(true);
|
||||
expect(capabilities.supportsUnicode).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Color Support Detection", () => {
|
||||
test("should detect true color support in Windows Terminal", () => {
|
||||
process.env.WT_SESSION = "test";
|
||||
process.env.COLORTERM = "truecolor";
|
||||
|
||||
const colorSupport = getWindowsColorSupport();
|
||||
expect(colorSupport.supportsTrueColor).toBe(true);
|
||||
expect(colorSupport.supports256Color).toBe(true);
|
||||
expect(colorSupport.supportsBasicColor).toBe(true);
|
||||
});
|
||||
|
||||
test("should detect limited color support in Command Prompt", () => {
|
||||
process.env.COMSPEC = "C:\\Windows\\system32\\cmd.exe";
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.COLORTERM;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
delete process.env.PSModulePath;
|
||||
|
||||
const colorSupport = getWindowsColorSupport();
|
||||
expect(colorSupport.supportsTrueColor).toBe(false);
|
||||
expect(colorSupport.supports256Color).toBe(false);
|
||||
expect(colorSupport.supportsBasicColor).toBe(true);
|
||||
});
|
||||
|
||||
test("should detect 256 color support in PowerShell", () => {
|
||||
process.env.PSModulePath = "C:\\Program Files\\PowerShell\\Modules";
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.COLORTERM;
|
||||
|
||||
const colorSupport = getWindowsColorSupport();
|
||||
expect(colorSupport.supportsTrueColor).toBe(false);
|
||||
expect(colorSupport.supports256Color).toBe(true);
|
||||
expect(colorSupport.supportsBasicColor).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Unicode Support Detection", () => {
|
||||
test("should detect Unicode support in Windows Terminal", () => {
|
||||
process.env.WT_SESSION = "test";
|
||||
|
||||
const unicodeSupport = getWindowsUnicodeSupport();
|
||||
expect(unicodeSupport.supportsUnicode).toBe(true);
|
||||
expect(unicodeSupport.supportsEmoji).toBe(true);
|
||||
expect(unicodeSupport.supportsBoxDrawing).toBe(true);
|
||||
});
|
||||
|
||||
test("should detect limited Unicode support in Command Prompt", () => {
|
||||
process.env.COMSPEC = "C:\\Windows\\system32\\cmd.exe";
|
||||
delete process.env.WT_SESSION;
|
||||
delete process.env.COLORTERM;
|
||||
delete process.env.TERM_PROGRAM;
|
||||
delete process.env.PSModulePath;
|
||||
|
||||
const unicodeSupport = getWindowsUnicodeSupport();
|
||||
expect(unicodeSupport.supportsUnicode).toBe(false);
|
||||
expect(unicodeSupport.supportsEmoji).toBe(false);
|
||||
expect(unicodeSupport.supportsBoxDrawing).toBe(false);
|
||||
});
|
||||
|
||||
test("should detect partial Unicode support in PowerShell", () => {
|
||||
process.env.PSModulePath = "C:\\Program Files\\PowerShell\\Modules";
|
||||
delete process.env.WT_SESSION;
|
||||
|
||||
const unicodeSupport = getWindowsUnicodeSupport();
|
||||
expect(unicodeSupport.supportsUnicode).toBe(true);
|
||||
expect(unicodeSupport.supportsEmoji).toBe(false);
|
||||
expect(unicodeSupport.supportsBoxDrawing).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Character Generation Tests", () => {
|
||||
test("should render progress bars correctly in Windows Terminal", () => {
|
||||
process.env.WT_SESSION = "test";
|
||||
process.env.COLORTERM = "truecolor";
|
||||
|
||||
const ProgressComponent = () => {
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
const progressChar = capabilities.supportsUnicode ? "█" : "#";
|
||||
const emptyChar = capabilities.supportsUnicode ? "░" : "-";
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Text>
|
||||
Progress: {progressChar.repeat(5)}
|
||||
{emptyChar.repeat(5)} 50%
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const { lastFrame } = render(<ProgressComponent />);
|
||||
expect(lastFrame()).toContain("Progress: █████░░░░░ 50%");
|
||||
});
|
||||
|
||||
test("should render progress bars with fallbacks in Command Prompt", () => {
|
||||
process.env.COMSPEC = "C:\\Windows\\system32\\cmd.exe";
|
||||
delete process.env.WT_SESSION;
|
||||
|
||||
const ProgressComponent = () => {
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
const progressChar = capabilities.supportsUnicode ? "█" : "#";
|
||||
const emptyChar = capabilities.supportsUnicode ? "░" : "-";
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Text>
|
||||
Progress: {progressChar.repeat(5)}
|
||||
{emptyChar.repeat(5)} 50%
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const { lastFrame } = render(<ProgressComponent />);
|
||||
expect(lastFrame()).toContain("Progress: #####----- 50%");
|
||||
});
|
||||
|
||||
test("should render status indicators correctly across terminals", () => {
|
||||
const testTerminals = [
|
||||
{ env: { WT_SESSION: "test" }, expected: "●" },
|
||||
{ env: { COMSPEC: "C:\\Windows\\system32\\cmd.exe" }, expected: "*" },
|
||||
{
|
||||
env: { PSModulePath: "C:\\Program Files\\PowerShell\\Modules" },
|
||||
expected: "●",
|
||||
},
|
||||
];
|
||||
|
||||
testTerminals.forEach(({ env, expected }) => {
|
||||
// Set environment
|
||||
Object.keys(env).forEach((key) => {
|
||||
process.env[key] = env[key];
|
||||
});
|
||||
|
||||
const StatusComponent = () => {
|
||||
const capabilities = getWindowsTerminalCapabilities();
|
||||
const statusChar = capabilities.supportsUnicode ? "●" : "*";
|
||||
|
||||
return <Text>Status: {statusChar} Connected</Text>;
|
||||
};
|
||||
|
||||
const { lastFrame } = render(<StatusComponent />);
|
||||
expect(lastFrame()).toContain(`Status: ${expected} Connected`);
|
||||
|
||||
// Clean up
|
||||
Object.keys(env).forEach((key) => {
|
||||
delete process.env[key];
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Keyboard Input Handling", () => {
|
||||
test("should handle Windows-specific key codes", () => {
|
||||
const keyMappings = {
|
||||
"\x03": "ctrl+c",
|
||||
"\x1a": "ctrl+z",
|
||||
"\x1b": "escape",
|
||||
"\r": "enter",
|
||||
"\r\n": "enter", // Windows line ending
|
||||
"\x08": "backspace",
|
||||
"\x7f": "delete",
|
||||
};
|
||||
|
||||
Object.entries(keyMappings).forEach(([keyCode, expectedKey]) => {
|
||||
// Test key code recognition
|
||||
expect(keyCode).toBeDefined();
|
||||
expect(expectedKey).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
test("should handle Windows Terminal enhanced keyboard input", () => {
|
||||
process.env.WT_SESSION = "test";
|
||||
|
||||
// Windows Terminal supports enhanced keyboard sequences
|
||||
const enhancedKeys = [
|
||||
"\x1b[1;5A", // Ctrl+Up
|
||||
"\x1b[1;5B", // Ctrl+Down
|
||||
"\x1b[1;2A", // Shift+Up
|
||||
"\x1b[1;2B", // Shift+Down
|
||||
];
|
||||
|
||||
enhancedKeys.forEach((keySequence) => {
|
||||
expect(keySequence).toMatch(/\x1b\[/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Terminal Size Handling", () => {
|
||||
test("should handle Windows terminal resize events", () => {
|
||||
const originalColumns = process.stdout.columns;
|
||||
const originalRows = process.stdout.rows;
|
||||
|
||||
// Mock terminal size
|
||||
Object.defineProperty(process.stdout, "columns", {
|
||||
value: 120,
|
||||
writable: true,
|
||||
});
|
||||
Object.defineProperty(process.stdout, "rows", {
|
||||
value: 30,
|
||||
writable: true,
|
||||
});
|
||||
|
||||
const SizeComponent = () => {
|
||||
const [size, setSize] = React.useState({
|
||||
width: process.stdout.columns || 80,
|
||||
height: process.stdout.rows || 24,
|
||||
});
|
||||
|
||||
return (
|
||||
<Text>
|
||||
Size: {size.width}x{size.height}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
const { lastFrame } = render(<SizeComponent />);
|
||||
expect(lastFrame()).toContain("Size: 120x30");
|
||||
|
||||
// Restore original values
|
||||
Object.defineProperty(process.stdout, "columns", {
|
||||
value: originalColumns,
|
||||
writable: true,
|
||||
});
|
||||
Object.defineProperty(process.stdout, "rows", {
|
||||
value: originalRows,
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user