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"); }); }); });