UNPKG

@applicaster/zapp-react-native-utils

Version:

Applicaster Zapp React Native utilities package

547 lines (447 loc) • 14.2 kB
import { getAllSpecificStyles } from "../manifestKeyParser"; jest.mock("@applicaster/zapp-react-native-utils/reactUtils", () => ({ platformSelect: jest.fn((platforms) => platforms.samsung_tv), // Default to samsung for tests })); jest.mock("@applicaster/zapp-react-native-utils/stringUtils", () => ({ toCamelCase: jest.fn((str: string) => { // Simple camelCase implementation for testing return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()); }), })); describe("getAllSpecificStyles", () => { beforeEach(() => { jest.clearAllMocks(); }); describe("Basic functionality", () => { it("should throw error if outStyles is not provided", () => { expect(() => { getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration: {}, outStyles: null as any, }); }).toThrow("outStyles is required"); }); it("should throw error if componentName is not provided", () => { expect(() => { getAllSpecificStyles({ componentName: "", subComponentName: "", configuration: {}, outStyles: {}, }); }).toThrow("componentName is required"); }); it("should initialize default key if not present", () => { const outStyles = {}; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration: {}, outStyles, }); expect(outStyles).toHaveProperty("default"); expect(outStyles["default"]).toEqual({}); }); it("should handle empty configuration", () => { const outStyles = { default: {} }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration: {}, outStyles, }); expect(outStyles).toEqual({ default: {} }); }); }); describe("Style name parsing", () => { it("should parse basic style without state or platform", () => { const outStyles = {}; const configuration = { button_style_background_color: "#FF0000", button_style_border_width: 2, }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["default"]).toEqual({ backgroundColor: "#FF0000", borderWidth: 2, }); }); it("should handle subComponentName correctly", () => { const outStyles = {}; const configuration = { player_controls_style_button_background_color: "#FF0000", player_controls_style_button_text_size: 16, }; getAllSpecificStyles({ componentName: "player_controls", subComponentName: "button", configuration, outStyles, }); expect(outStyles["default"]).toEqual({ backgroundColor: "#FF0000", textSize: 16, }); }); it("should ignore keys that do not match the prefix", () => { const outStyles = {}; const configuration = { button_style_background_color: "#FF0000", other_component_style_text_color: "#00FF00", // Should be ignored random_key: "value", // Should be ignored }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["default"]).toEqual({ backgroundColor: "#FF0000", }); }); }); describe("State handling", () => { it("should handle pressed state", () => { const outStyles = {}; const configuration = { button_style_background_color: "#FF0000", button_style_pressed_background_color: "#00FF00", }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["default"]).toEqual({ backgroundColor: "#FF0000", }); expect(outStyles["pressed"]).toEqual({ backgroundColor: "#00FF00", }); }); it("should handle focused state", () => { const outStyles = {}; const configuration = { button_style_focused_border_width: 3, }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["focused"]).toEqual({ borderWidth: 3, }); }); it("should handle selected state", () => { const outStyles = {}; const configuration = { button_style_selected_opacity: 0.5, }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["selected"]).toEqual({ opacity: 0.5, }); }); it("should handle focused_selected state", () => { const outStyles = {}; const configuration = { button_style_focused_selected_scale: 1.2, }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["focused_selected"]).toEqual({ scale: 1.2, }); }); it("should merge default styles into other states", () => { const outStyles = {}; const configuration = { button_style_background_color: "#FF0000", button_style_border_width: 1, button_style_opacity: 1, button_style_pressed_background_color: "#00FF00", button_style_focused_opacity: 0.8, }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["default"]).toEqual({ backgroundColor: "#FF0000", borderWidth: 1, opacity: 1, }); // Pressed should have default styles merged with its specific override expect(outStyles["pressed"]).toEqual({ backgroundColor: "#00FF00", // Override borderWidth: 1, // From default opacity: 1, // From default }); // Focused should have default styles merged with its specific override expect(outStyles["focused"]).toEqual({ backgroundColor: "#FF0000", // From default borderWidth: 1, // From default opacity: 0.8, // Override }); }); it("should preserve existing state values when merging", () => { const outStyles = { pressed: { existingKey: "existingValue" }, }; const configuration = { button_style_background_color: "#FF0000", button_style_pressed_text_color: "#FFFFFF", }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["pressed"]).toEqual({ existingKey: "existingValue", // Should be preserved backgroundColor: "#FF0000", // From default textColor: "#FFFFFF", // New pressed style }); }); }); describe("Platform handling", () => { it("should include styles for current platform (samsung)", () => { const outStyles = {}; const configuration = { button_style_samsung_background_color: "#FF0000", button_style_background_color: "#00FF00", }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["default"]).toEqual({ backgroundColor: "#FF0000", // Samsung-specific should be included }); }); it("should skip styles for other platforms", () => { const outStyles = {}; const configuration = { button_style_ios_background_color: "#FF0000", button_style_android_text_color: "#00FF00", button_style_tvos_border_width: 2, button_style_lg_opacity: 0.5, button_style_background_color: "#FFFFFF", }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["default"]).toEqual({ backgroundColor: "#FFFFFF", // Only non-platform specific }); }); it("should handle platform in middle of style name", () => { const outStyles = {}; const configuration = { button_style_text_samsung_color: "#FF0000", }; getAllSpecificStyles({ componentName: "button", subComponentName: "text", configuration, outStyles, }); expect(outStyles["default"]).toEqual({ color: "#FF0000", }); }); it("should handle platform-specific styles with states", () => { const outStyles = {}; const configuration = { button_style_samsung_pressed_background_color: "#FF0000", button_style_ios_pressed_background_color: "#00FF00", // Should be ignored }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["pressed"]).toEqual({ backgroundColor: "#FF0000", // Only samsung style }); }); it("should work correctly when platform is Samsung", () => { const outStyles = {}; const configuration = { button_style_ios_background_color: "#FF0000", button_style_samsung_background_color: "#00FF00", button_style_background_color: "#FFFFFF", }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["default"]).toEqual({ backgroundColor: "#00FF00", // Samsung-specific should win }); }); }); describe("Complex scenarios", () => { it("should handle multiple states and platforms correctly", () => { const outStyles = {}; const configuration = { // Default styles button_style_background_color: "#FFFFFF", button_style_text_color: "#000000", button_style_border_width: 1, // Platform-specific default button_style_samsung_padding: 10, // State-specific button_style_pressed_background_color: "#EEEEEE", button_style_focused_scale: 1.1, // Platform + state specific button_style_samsung_pressed_opacity: 0.8, button_style_ios_pressed_opacity: 0.6, // Should be ignored }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["default"]).toEqual({ backgroundColor: "#FFFFFF", textColor: "#000000", borderWidth: 1, padding: 10, }); expect(outStyles["pressed"]).toEqual({ backgroundColor: "#EEEEEE", textColor: "#000000", borderWidth: 1, padding: 10, opacity: 0.8, }); expect(outStyles["focused"]).toEqual({ backgroundColor: "#FFFFFF", textColor: "#000000", borderWidth: 1, padding: 10, scale: 1.1, }); }); it("should handle edge case keys correctly", () => { const outStyles = {}; const configuration = { button_style_: "shouldBeIgnored", // Empty style name button_style_samsung_: "shouldBeIgnored", // Platform but no style button_style__pressed: "shouldBeIgnored", // No style name before state button_style_valid_key: "included", }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["default"]).toEqual({ validKey: "included", }); }); it("should handle all state suffixes in priority order", () => { const outStyles = {}; const configuration = { // Test that focused_selected is recognized before focused button_style_focused_selected_test: "focused_selected_value", button_style_focused_another: "focused_value", }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["focused_selected"]).toEqual({ test: "focused_selected_value", }); expect(outStyles["focused"]).toEqual({ another: "focused_value", }); }); }); describe("Immutability", () => { it("should not mutate configuration object", () => { const configuration = Object.freeze({ button_style_background_color: "#FF0000", }); const outStyles = {}; expect(() => { getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); }).not.toThrow(); }); it("platform pressed overrides generic pressed for same key", () => { const outStyles = {}; const configuration = { button_style_pressed_background_color: "#111111", // generic button_style_samsung_pressed_background_color: "#222222", // platform }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); expect(outStyles["pressed"]["backgroundColor"]).toBe("#222222"); }); it("should handle frozen outStyles properties", () => { const outStyles = { default: Object.freeze({ existingProp: "value" }), }; const configuration = { button_style_background_color: "#FF0000", }; getAllSpecificStyles({ componentName: "button", subComponentName: "", configuration, outStyles, }); // Should create new object instead of mutating frozen one expect(outStyles["default"]).toEqual({ existingProp: "value", backgroundColor: "#FF0000", }); }); }); });