Just a whole lot of crap

This commit is contained in:
2025-08-14 16:36:12 -05:00
parent 66b7e42275
commit 62f6d6f279
144 changed files with 41421 additions and 2458 deletions

View File

@@ -0,0 +1,331 @@
/**
* Unit tests for keyboard handlers utilities
* Tests global keyboard shortcuts and help system integration
* Requirements: 9.1, 9.3, 9.4, 9.2, 9.5
*/
describe("Keyboard Handlers Utilities", () => {
test("should have keyboardHandlers module available", () => {
const keyboardHandlers = require("../../../src/tui/utils/keyboardHandlers.js");
expect(typeof keyboardHandlers).toBe("object");
});
test("should export required functions", () => {
const keyboardHandlers = require("../../../src/tui/utils/keyboardHandlers.js");
expect(typeof keyboardHandlers.handleGlobalShortcuts).toBe("function");
expect(typeof keyboardHandlers.createKeyboardHandler).toBe("function");
expect(typeof keyboardHandlers.navigationKeys).toBe("object");
expect(typeof keyboardHandlers.helpSystem).toBe("object");
});
test("should define handleGlobalShortcuts function", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
expect(keyboardHandlersContent).toContain("handleGlobalShortcuts");
expect(keyboardHandlersContent).toContain("input, key, context");
expect(keyboardHandlersContent).toContain("toggleHelp");
expect(keyboardHandlersContent).toContain("navigateBack");
});
test("should handle help toggle shortcut", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
expect(keyboardHandlersContent).toContain('input === "h"');
expect(keyboardHandlersContent).toContain('input === "H"');
expect(keyboardHandlersContent).toContain("toggleHelp()");
});
test("should handle escape key for back navigation", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
expect(keyboardHandlersContent).toContain("key.escape");
expect(keyboardHandlersContent).toContain("appState.uiState.helpVisible");
expect(keyboardHandlersContent).toContain("context.hideHelp()");
expect(keyboardHandlersContent).toContain("navigateBack()");
});
test("should handle exit shortcuts", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
expect(keyboardHandlersContent).toContain('key.ctrl && input === "c"');
expect(keyboardHandlersContent).toContain('input === "q"');
expect(keyboardHandlersContent).toContain('input === "Q"');
expect(keyboardHandlersContent).toContain("process.exit(0)");
});
test("should define createKeyboardHandler function", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
expect(keyboardHandlersContent).toContain("createKeyboardHandler");
expect(keyboardHandlersContent).toContain("screenHandler, context");
expect(keyboardHandlersContent).toContain("handleGlobalShortcuts");
expect(keyboardHandlersContent).toContain("wasHandledGlobally");
});
});
describe("Navigation Keys Utilities", () => {
test("should define navigationKeys object", () => {
const keyboardHandlers = require("../../../src/tui/utils/keyboardHandlers.js");
expect(typeof keyboardHandlers.navigationKeys.handleMenuNavigation).toBe(
"function"
);
expect(typeof keyboardHandlers.navigationKeys.handleFormNavigation).toBe(
"function"
);
expect(typeof keyboardHandlers.navigationKeys.handlePagination).toBe(
"function"
);
});
test("should define handleMenuNavigation function", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
expect(keyboardHandlersContent).toContain("handleMenuNavigation:");
expect(keyboardHandlersContent).toContain("key.upArrow");
expect(keyboardHandlersContent).toContain("key.downArrow");
expect(keyboardHandlersContent).toContain("Math.max(0, currentIndex - 1)");
expect(keyboardHandlersContent).toContain(
"Math.min(maxIndex, currentIndex + 1)"
);
});
test("should define handleFormNavigation function", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
expect(keyboardHandlersContent).toContain("handleFormNavigation:");
expect(keyboardHandlersContent).toContain("key.tab");
expect(keyboardHandlersContent).toContain(
"(currentIndex + 1) % (maxIndex + 1)"
);
});
test("should define handlePagination function", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
expect(keyboardHandlersContent).toContain("handlePagination:");
expect(keyboardHandlersContent).toContain("key.pageUp");
expect(keyboardHandlersContent).toContain("key.pageDown");
expect(keyboardHandlersContent).toContain("Math.max(0, currentPage - 1)");
expect(keyboardHandlersContent).toContain(
"Math.min(totalPages - 1, currentPage + 1)"
);
});
});
describe("Help System Utilities", () => {
test("should define helpSystem object", () => {
const keyboardHandlers = require("../../../src/tui/utils/keyboardHandlers.js");
expect(typeof keyboardHandlers.helpSystem.getScreenShortcuts).toBe(
"function"
);
expect(typeof keyboardHandlers.helpSystem.getGlobalShortcuts).toBe(
"function"
);
});
test("should define screen shortcuts mapping", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
expect(keyboardHandlersContent).toContain("getScreenShortcuts:");
expect(keyboardHandlersContent).toContain('"main-menu":');
expect(keyboardHandlersContent).toContain("configuration:");
expect(keyboardHandlersContent).toContain("operation:");
expect(keyboardHandlersContent).toContain("scheduling:");
expect(keyboardHandlersContent).toContain("logs:");
expect(keyboardHandlersContent).toContain('"tag-analysis":');
});
test("should define common shortcuts for each screen", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
// Main menu shortcuts
expect(keyboardHandlersContent).toContain(
'"↑/↓", description: "Navigate menu"'
);
expect(keyboardHandlersContent).toContain(
'"Enter", description: "Select item"'
);
// Configuration shortcuts
expect(keyboardHandlersContent).toContain(
'"Tab", description: "Next field"'
);
expect(keyboardHandlersContent).toContain('"Ctrl+S", description: "Save"');
// Operation shortcuts
expect(keyboardHandlersContent).toContain(
'"Ctrl+C", description: "Cancel"'
);
// Logs shortcuts
expect(keyboardHandlersContent).toContain('"/", description: "Search"');
expect(keyboardHandlersContent).toContain(
'"PgUp/PgDn", description: "Page"'
);
});
test("should define global shortcuts", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
expect(keyboardHandlersContent).toContain("getGlobalShortcuts:");
expect(keyboardHandlersContent).toContain(
'"h", description: "Toggle help"'
);
expect(keyboardHandlersContent).toContain(
'"Esc", description: "Back/Close"'
);
expect(keyboardHandlersContent).toContain('"Ctrl+C", description: "Exit"');
});
test("should have fallback for unknown screens", () => {
const fs = require("fs");
const path = require("path");
const keyboardHandlersPath = path.join(
__dirname,
"../../../src/tui/utils/keyboardHandlers.js"
);
const keyboardHandlersContent = fs.readFileSync(
keyboardHandlersPath,
"utf8"
);
expect(keyboardHandlersContent).toContain("shortcuts[screenName] || []");
});
});
describe("Keyboard Handlers Integration", () => {
test("should be used by MainMenuScreen", () => {
const fs = require("fs");
const path = require("path");
const mainMenuPath = path.join(
__dirname,
"../../../src/tui/components/screens/MainMenuScreen.jsx"
);
const mainMenuContent = fs.readFileSync(mainMenuPath, "utf8");
expect(mainMenuContent).toContain(
'require("../../utils/keyboardHandlers.js")'
);
expect(mainMenuContent).toContain("createKeyboardHandler");
expect(mainMenuContent).toContain("navigationKeys");
});
test("should provide context to keyboard handlers", () => {
const fs = require("fs");
const path = require("path");
const mainMenuPath = path.join(
__dirname,
"../../../src/tui/components/screens/MainMenuScreen.jsx"
);
const mainMenuContent = fs.readFileSync(mainMenuPath, "utf8");
expect(mainMenuContent).toContain("appState,");
expect(mainMenuContent).toContain("navigateTo,");
expect(mainMenuContent).toContain("navigateBack,");
expect(mainMenuContent).toContain("toggleHelp,");
expect(mainMenuContent).toContain("showHelp,");
expect(mainMenuContent).toContain("hideHelp,");
});
});

View File

@@ -0,0 +1,239 @@
const {
getResponsiveDimensions,
getColumnLayout,
getScrollableDimensions,
getTextTruncationLength,
getResponsiveSpacing,
shouldHideOnSmallScreen,
getAdaptiveFontStyle,
} = require("../../../src/tui/utils/responsiveLayout.js");
describe("responsiveLayout utilities", () => {
const smallLayoutConfig = {
isSmall: true,
isMedium: false,
isLarge: false,
maxContentWidth: 76,
maxContentHeight: 20,
columnsCount: 1,
};
const mediumLayoutConfig = {
isSmall: false,
isMedium: true,
isLarge: false,
maxContentWidth: 116,
maxContentHeight: 30,
columnsCount: 2,
};
const largeLayoutConfig = {
isSmall: false,
isMedium: false,
isLarge: true,
maxContentWidth: 120,
maxContentHeight: 40,
columnsCount: 3,
};
describe("getResponsiveDimensions", () => {
test("should return appropriate menu dimensions for small screen", () => {
const dimensions = getResponsiveDimensions(smallLayoutConfig, "menu");
expect(dimensions.width).toBe(76);
expect(dimensions.height).toBe(16); // 20 * 0.8
});
test("should return appropriate menu dimensions for medium screen", () => {
const dimensions = getResponsiveDimensions(mediumLayoutConfig, "menu");
expect(dimensions.width).toBe(81); // Math.floor(116 * 0.7)
expect(dimensions.height).toBe(28); // 30 - 2
});
test("should return appropriate menu dimensions for large screen", () => {
const dimensions = getResponsiveDimensions(largeLayoutConfig, "menu");
expect(dimensions.width).toBe(72); // Math.floor(120 * 0.6)
expect(dimensions.height).toBe(38); // 40 - 2
});
test("should return form dimensions", () => {
const smallDimensions = getResponsiveDimensions(
smallLayoutConfig,
"form"
);
const largeDimensions = getResponsiveDimensions(
largeLayoutConfig,
"form"
);
expect(smallDimensions.width).toBe(76);
expect(largeDimensions.width).toBe(60); // Math.min(60, 120)
});
test("should return default dimensions for unknown component type", () => {
const dimensions = getResponsiveDimensions(smallLayoutConfig, "unknown");
expect(dimensions.width).toBe(76);
expect(dimensions.height).toBe(20);
});
});
describe("getColumnLayout", () => {
test("should return single column for small screen", () => {
const layout = getColumnLayout(smallLayoutConfig, 5);
expect(layout.columns).toBe(1);
expect(layout.itemWidth).toBe(74); // Math.floor(76 / 1) - 2
expect(layout.rows).toBe(5);
});
test("should return multiple columns for medium screen", () => {
const layout = getColumnLayout(mediumLayoutConfig, 5);
expect(layout.columns).toBe(2);
expect(layout.itemWidth).toBe(56); // Math.floor(116 / 2) - 2
expect(layout.rows).toBe(3); // Math.ceil(5 / 2)
});
test("should handle fewer items than columns", () => {
const layout = getColumnLayout(largeLayoutConfig, 2);
expect(layout.columns).toBe(2);
expect(layout.itemWidth).toBe(58); // Math.floor(120 / 2) - 2
expect(layout.rows).toBeUndefined();
});
});
describe("getScrollableDimensions", () => {
test("should calculate scrollable dimensions correctly", () => {
const dimensions = getScrollableDimensions(smallLayoutConfig, 30, 2);
expect(dimensions.visibleItems).toBe(8); // Math.floor((20 - 4) / 2)
expect(dimensions.totalItems).toBe(30);
expect(dimensions.needsScrolling).toBe(true);
expect(dimensions.scrollHeight).toBe(16);
expect(dimensions.itemHeight).toBe(2);
});
test("should handle case where scrolling is not needed", () => {
const dimensions = getScrollableDimensions(largeLayoutConfig, 10, 1);
expect(dimensions.visibleItems).toBe(36); // Math.floor((40 - 4) / 1)
expect(dimensions.needsScrolling).toBe(false);
});
});
describe("getTextTruncationLength", () => {
test("should return appropriate truncation length for small screen", () => {
const length = getTextTruncationLength(smallLayoutConfig, 50);
expect(length).toBe(40); // Math.max(20, 50 - 10)
});
test("should return appropriate truncation length for medium screen", () => {
const length = getTextTruncationLength(mediumLayoutConfig, 80);
expect(length).toBe(72); // Math.max(40, 80 - 8)
});
test("should return appropriate truncation length for large screen", () => {
const length = getTextTruncationLength(largeLayoutConfig, 100);
expect(length).toBe(94); // Math.max(60, 100 - 6)
});
test("should enforce minimum lengths", () => {
const smallLength = getTextTruncationLength(smallLayoutConfig, 10);
const mediumLength = getTextTruncationLength(mediumLayoutConfig, 10);
const largeLength = getTextTruncationLength(largeLayoutConfig, 10);
expect(smallLength).toBe(20);
expect(mediumLength).toBe(40);
expect(largeLength).toBe(60);
});
});
describe("getResponsiveSpacing", () => {
test("should return small spacing for small screens", () => {
const spacing = getResponsiveSpacing(smallLayoutConfig);
expect(spacing.padding).toBe(1);
expect(spacing.margin).toBe(0);
expect(spacing.gap).toBe(0);
});
test("should return larger spacing for medium/large screens", () => {
const spacing = getResponsiveSpacing(mediumLayoutConfig);
expect(spacing.padding).toBe(2);
expect(spacing.margin).toBe(1);
expect(spacing.gap).toBe(1);
});
});
describe("shouldHideOnSmallScreen", () => {
test("should hide sidebar on small screens", () => {
expect(shouldHideOnSmallScreen(smallLayoutConfig, "sidebar")).toBe(true);
expect(shouldHideOnSmallScreen(mediumLayoutConfig, "sidebar")).toBe(
false
);
});
test("should hide secondary info on small screens", () => {
expect(shouldHideOnSmallScreen(smallLayoutConfig, "secondary-info")).toBe(
true
);
expect(shouldHideOnSmallScreen(largeLayoutConfig, "secondary-info")).toBe(
false
);
});
test("should not hide main components on small screens", () => {
expect(shouldHideOnSmallScreen(smallLayoutConfig, "main-content")).toBe(
false
);
});
});
describe("getAdaptiveFontStyle", () => {
test("should return appropriate title styles", () => {
const smallStyle = getAdaptiveFontStyle(smallLayoutConfig, "title");
const largeStyle = getAdaptiveFontStyle(largeLayoutConfig, "title");
expect(smallStyle.bold).toBe(true);
expect(smallStyle.color).toBe("white");
expect(largeStyle.color).toBe("blue");
});
test("should return appropriate subtitle styles", () => {
const smallStyle = getAdaptiveFontStyle(smallLayoutConfig, "subtitle");
const largeStyle = getAdaptiveFontStyle(largeLayoutConfig, "subtitle");
expect(smallStyle.bold).toBe(false);
expect(largeStyle.bold).toBe(true);
expect(smallStyle.color).toBe("gray");
});
test("should return error styles", () => {
const style = getAdaptiveFontStyle(smallLayoutConfig, "error");
expect(style.bold).toBe(true);
expect(style.color).toBe("red");
});
test("should return success styles", () => {
const style = getAdaptiveFontStyle(largeLayoutConfig, "success");
expect(style.bold).toBe(true);
expect(style.color).toBe("green");
});
test("should return default styles for unknown type", () => {
const style = getAdaptiveFontStyle(smallLayoutConfig, "unknown");
expect(style.color).toBe("white");
});
});
});