303 lines
8.4 KiB
JavaScript
303 lines
8.4 KiB
JavaScript
/**
|
|
* Integration tests for responsive layout functionality
|
|
* Tests different screen size scenarios and component behavior
|
|
* Requirements: 10.2, 10.3, 10.4
|
|
*/
|
|
|
|
const {
|
|
getResponsiveDimensions,
|
|
getColumnLayout,
|
|
getScrollableDimensions,
|
|
getTextTruncationLength,
|
|
getResponsiveSpacing,
|
|
shouldHideOnSmallScreen,
|
|
getAdaptiveFontStyle,
|
|
} = require("../../../src/tui/utils/responsiveLayout.js");
|
|
|
|
describe("Responsive Layout Integration", () => {
|
|
// Test scenarios for different screen sizes
|
|
const screenSizes = {
|
|
small: {
|
|
width: 80,
|
|
height: 20,
|
|
layoutConfig: {
|
|
isSmall: true,
|
|
isMedium: false,
|
|
isLarge: false,
|
|
maxContentWidth: 76,
|
|
maxContentHeight: 16,
|
|
columnsCount: 1,
|
|
showSidebar: false,
|
|
},
|
|
},
|
|
medium: {
|
|
width: 120,
|
|
height: 30,
|
|
layoutConfig: {
|
|
isSmall: false,
|
|
isMedium: true,
|
|
isLarge: false,
|
|
maxContentWidth: 116,
|
|
maxContentHeight: 26,
|
|
columnsCount: 2,
|
|
showSidebar: true,
|
|
},
|
|
},
|
|
large: {
|
|
width: 160,
|
|
height: 40,
|
|
layoutConfig: {
|
|
isSmall: false,
|
|
isMedium: false,
|
|
isLarge: true,
|
|
maxContentWidth: 120, // Limited to max 120
|
|
maxContentHeight: 36,
|
|
columnsCount: 3,
|
|
showSidebar: true,
|
|
},
|
|
},
|
|
};
|
|
|
|
describe("Small Screen Behavior", () => {
|
|
const { layoutConfig } = screenSizes.small;
|
|
|
|
test("should provide appropriate dimensions for small screens", () => {
|
|
const menuDimensions = getResponsiveDimensions(layoutConfig, "menu");
|
|
const formDimensions = getResponsiveDimensions(layoutConfig, "form");
|
|
|
|
expect(menuDimensions.width).toBe(76);
|
|
expect(menuDimensions.height).toBe(12); // 16 * 0.8 = 12.8, floored to 12
|
|
expect(formDimensions.width).toBe(76);
|
|
});
|
|
|
|
test("should use single column layout", () => {
|
|
const columnLayout = getColumnLayout(layoutConfig, 10);
|
|
|
|
expect(columnLayout.columns).toBe(1);
|
|
expect(columnLayout.rows).toBe(10);
|
|
});
|
|
|
|
test("should hide secondary components", () => {
|
|
expect(shouldHideOnSmallScreen(layoutConfig, "sidebar")).toBe(true);
|
|
expect(shouldHideOnSmallScreen(layoutConfig, "secondary-info")).toBe(
|
|
true
|
|
);
|
|
expect(shouldHideOnSmallScreen(layoutConfig, "main-content")).toBe(false);
|
|
});
|
|
|
|
test("should use compact spacing", () => {
|
|
const spacing = getResponsiveSpacing(layoutConfig);
|
|
|
|
expect(spacing.padding).toBe(1);
|
|
expect(spacing.margin).toBe(0);
|
|
expect(spacing.gap).toBe(0);
|
|
});
|
|
|
|
test("should truncate text appropriately", () => {
|
|
const truncationLength = getTextTruncationLength(layoutConfig, 50);
|
|
|
|
expect(truncationLength).toBe(40); // Math.max(20, 50 - 10)
|
|
});
|
|
|
|
test("should use adaptive font styles", () => {
|
|
const titleStyle = getAdaptiveFontStyle(layoutConfig, "title");
|
|
const subtitleStyle = getAdaptiveFontStyle(layoutConfig, "subtitle");
|
|
|
|
expect(titleStyle.color).toBe("white"); // Different from large screens
|
|
expect(subtitleStyle.bold).toBe(false); // Different from large screens
|
|
});
|
|
});
|
|
|
|
describe("Medium Screen Behavior", () => {
|
|
const { layoutConfig } = screenSizes.medium;
|
|
|
|
test("should provide appropriate dimensions for medium screens", () => {
|
|
const menuDimensions = getResponsiveDimensions(layoutConfig, "menu");
|
|
|
|
expect(menuDimensions.width).toBe(81); // Math.floor(116 * 0.7)
|
|
expect(menuDimensions.height).toBe(24); // 26 - 2
|
|
});
|
|
|
|
test("should use two column layout", () => {
|
|
const columnLayout = getColumnLayout(layoutConfig, 10);
|
|
|
|
expect(columnLayout.columns).toBe(2);
|
|
expect(columnLayout.rows).toBe(5); // Math.ceil(10 / 2)
|
|
});
|
|
|
|
test("should show sidebar components", () => {
|
|
expect(shouldHideOnSmallScreen(layoutConfig, "sidebar")).toBe(false);
|
|
expect(shouldHideOnSmallScreen(layoutConfig, "secondary-info")).toBe(
|
|
false
|
|
);
|
|
});
|
|
|
|
test("should use normal spacing", () => {
|
|
const spacing = getResponsiveSpacing(layoutConfig);
|
|
|
|
expect(spacing.padding).toBe(2);
|
|
expect(spacing.margin).toBe(1);
|
|
expect(spacing.gap).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe("Large Screen Behavior", () => {
|
|
const { layoutConfig } = screenSizes.large;
|
|
|
|
test("should provide appropriate dimensions for large screens", () => {
|
|
const menuDimensions = getResponsiveDimensions(layoutConfig, "menu");
|
|
|
|
expect(menuDimensions.width).toBe(72); // Math.floor(120 * 0.6)
|
|
expect(menuDimensions.height).toBe(34); // 36 - 2
|
|
});
|
|
|
|
test("should use three column layout", () => {
|
|
const columnLayout = getColumnLayout(layoutConfig, 10);
|
|
|
|
expect(columnLayout.columns).toBe(3);
|
|
expect(columnLayout.rows).toBe(4); // Math.ceil(10 / 3)
|
|
});
|
|
|
|
test("should show all components", () => {
|
|
expect(shouldHideOnSmallScreen(layoutConfig, "sidebar")).toBe(false);
|
|
expect(shouldHideOnSmallScreen(layoutConfig, "secondary-info")).toBe(
|
|
false
|
|
);
|
|
expect(shouldHideOnSmallScreen(layoutConfig, "decorative-elements")).toBe(
|
|
false
|
|
);
|
|
});
|
|
|
|
test("should use enhanced font styles", () => {
|
|
const titleStyle = getAdaptiveFontStyle(layoutConfig, "title");
|
|
const subtitleStyle = getAdaptiveFontStyle(layoutConfig, "subtitle");
|
|
|
|
expect(titleStyle.color).toBe("blue");
|
|
expect(subtitleStyle.bold).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("Scrollable Content Behavior", () => {
|
|
test("should calculate scrolling needs correctly for different screen sizes", () => {
|
|
const totalItems = 50;
|
|
const itemHeight = 2;
|
|
|
|
// Small screen
|
|
const smallScrollDimensions = getScrollableDimensions(
|
|
screenSizes.small.layoutConfig,
|
|
totalItems,
|
|
itemHeight
|
|
);
|
|
expect(smallScrollDimensions.visibleItems).toBe(6); // Math.floor((16 - 4) / 2)
|
|
expect(smallScrollDimensions.needsScrolling).toBe(true);
|
|
|
|
// Large screen
|
|
const largeScrollDimensions = getScrollableDimensions(
|
|
screenSizes.large.layoutConfig,
|
|
totalItems,
|
|
itemHeight
|
|
);
|
|
expect(largeScrollDimensions.visibleItems).toBe(16); // Math.floor((36 - 4) / 2)
|
|
expect(largeScrollDimensions.needsScrolling).toBe(true);
|
|
});
|
|
|
|
test("should handle cases where scrolling is not needed", () => {
|
|
const totalItems = 5;
|
|
const itemHeight = 1;
|
|
|
|
const scrollDimensions = getScrollableDimensions(
|
|
screenSizes.large.layoutConfig,
|
|
totalItems,
|
|
itemHeight
|
|
);
|
|
expect(scrollDimensions.needsScrolling).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("Text Truncation Behavior", () => {
|
|
test("should provide different truncation lengths for different screen sizes", () => {
|
|
const containerWidth = 60;
|
|
|
|
const smallTruncation = getTextTruncationLength(
|
|
screenSizes.small.layoutConfig,
|
|
containerWidth
|
|
);
|
|
const mediumTruncation = getTextTruncationLength(
|
|
screenSizes.medium.layoutConfig,
|
|
containerWidth
|
|
);
|
|
const largeTruncation = getTextTruncationLength(
|
|
screenSizes.large.layoutConfig,
|
|
containerWidth
|
|
);
|
|
|
|
expect(smallTruncation).toBe(50); // Math.max(20, 60 - 10)
|
|
expect(mediumTruncation).toBe(52); // Math.max(40, 60 - 8)
|
|
expect(largeTruncation).toBe(60); // Math.max(60, 60 - 6)
|
|
});
|
|
|
|
test("should enforce minimum truncation lengths", () => {
|
|
const smallContainerWidth = 5;
|
|
|
|
const smallTruncation = getTextTruncationLength(
|
|
screenSizes.small.layoutConfig,
|
|
smallContainerWidth
|
|
);
|
|
const mediumTruncation = getTextTruncationLength(
|
|
screenSizes.medium.layoutConfig,
|
|
smallContainerWidth
|
|
);
|
|
const largeTruncation = getTextTruncationLength(
|
|
screenSizes.large.layoutConfig,
|
|
smallContainerWidth
|
|
);
|
|
|
|
expect(smallTruncation).toBe(20); // Minimum enforced
|
|
expect(mediumTruncation).toBe(40); // Minimum enforced
|
|
expect(largeTruncation).toBe(60); // Minimum enforced
|
|
});
|
|
});
|
|
|
|
describe("Component Visibility Rules", () => {
|
|
test("should hide appropriate components on small screens", () => {
|
|
const componentsToHide = [
|
|
"sidebar",
|
|
"secondary-info",
|
|
"decorative-elements",
|
|
];
|
|
const componentsToShow = [
|
|
"main-content",
|
|
"primary-navigation",
|
|
"essential-info",
|
|
];
|
|
|
|
componentsToHide.forEach((component) => {
|
|
expect(
|
|
shouldHideOnSmallScreen(screenSizes.small.layoutConfig, component)
|
|
).toBe(true);
|
|
});
|
|
|
|
componentsToShow.forEach((component) => {
|
|
expect(
|
|
shouldHideOnSmallScreen(screenSizes.small.layoutConfig, component)
|
|
).toBe(false);
|
|
});
|
|
});
|
|
|
|
test("should show all components on large screens", () => {
|
|
const allComponents = [
|
|
"sidebar",
|
|
"secondary-info",
|
|
"decorative-elements",
|
|
"main-content",
|
|
];
|
|
|
|
allComponents.forEach((component) => {
|
|
expect(
|
|
shouldHideOnSmallScreen(screenSizes.large.layoutConfig, component)
|
|
).toBe(false);
|
|
});
|
|
});
|
|
});
|
|
});
|