From e9f73c02934ad74faeaa95a68f3dd0990ca32d09 Mon Sep 17 00:00:00 2001 From: Srirang Kalantri Date: Wed, 16 Sep 2026 18:38:01 +0530 Subject: [PATCH 1/2] chore: add style contracts tests --- .../src/__tests__/backgroundGradient.spec.tsx | 6 ++++++ .../src/utils/__tests__/StyleUtils.spec.ts | 9 ++++++++- .../src/__tests__/BarcodeScanner.spec.tsx | 6 ++++++ .../src/__tests__/Carousel.spec.tsx | 7 ++++++- .../src/__tests__/ColorPicker.spec.tsx | 6 ++++++ .../src/utils/__tests__/StyleUtils.spec.ts | 9 ++++++++- .../src/__tests__/Feedback.spec.tsx | 17 ++++++++++++++++- .../src/utils/__tests__/StyleUtils.spec.ts | 9 ++++++++- .../src/__tests__/PieDoughnutChart.spec.tsx | 5 +++++ .../src/__tests__/ProgressBar.spec.tsx | 6 ++++++ .../src/__tests__/ProgressCircle.spec.tsx | 6 ++++++ .../src/__tests__/ToggleButtons.spec.tsx | 14 ++++++++++++++ 12 files changed, 95 insertions(+), 5 deletions(-) diff --git a/packages/pluggableWidgets/background-gradient-native/src/__tests__/backgroundGradient.spec.tsx b/packages/pluggableWidgets/background-gradient-native/src/__tests__/backgroundGradient.spec.tsx index eef3e4035..d3d0e95ed 100644 --- a/packages/pluggableWidgets/background-gradient-native/src/__tests__/backgroundGradient.spec.tsx +++ b/packages/pluggableWidgets/background-gradient-native/src/__tests__/backgroundGradient.spec.tsx @@ -3,6 +3,7 @@ import { render, fireEvent } from "@testing-library/react-native"; import Big from "big.js"; import { ActionValue } from "mendix"; import { BackgroundGradient, props } from "../BackgroundGradient"; +import defaultStyle from "../ui/Styles"; describe("Background gradient", () => { let defaultProps: props; @@ -110,4 +111,9 @@ describe("Background gradient", () => { fireEvent.press(pressable); expect(actionExecution).toHaveBeenCalled(); }); + + it("preserves expected style key set", () => { + const keys = Object.keys(defaultStyle).sort(); + expect(keys).toEqual(["angle", "colorList", "container", "opacity"]); + }); }); diff --git a/packages/pluggableWidgets/bar-chart-native/src/utils/__tests__/StyleUtils.spec.ts b/packages/pluggableWidgets/bar-chart-native/src/utils/__tests__/StyleUtils.spec.ts index 53fbaa648..bb426e936 100644 --- a/packages/pluggableWidgets/bar-chart-native/src/utils/__tests__/StyleUtils.spec.ts +++ b/packages/pluggableWidgets/bar-chart-native/src/utils/__tests__/StyleUtils.spec.ts @@ -1,5 +1,5 @@ import { aggregateGridPadding, mapToAxisStyle, mapToGridStyle, mapToBarStyles } from "../StyleUtils"; -import { BarChartAxisStyle, BarChartGridStyle, BarChartStyle } from "../../ui/Styles"; +import { BarChartAxisStyle, BarChartGridStyle, BarChartStyle, defaultBarChartStyle } from "../../ui/Styles"; describe("StyleMappers", () => { describe("mapToGridStyle", () => { @@ -210,3 +210,10 @@ describe("aggregateGridPadding", () => { expect(aggregateGridPadding(undefined)).toBeUndefined(); }); }); + +describe("Style schema guardrail", () => { + it("preserves expected style key set", () => { + const keys = Object.keys(defaultBarChartStyle).sort(); + expect(keys).toEqual(["chart", "container", "errorMessage", "grid", "legend", "xAxis"]); + }); +}); diff --git a/packages/pluggableWidgets/barcode-scanner-native/src/__tests__/BarcodeScanner.spec.tsx b/packages/pluggableWidgets/barcode-scanner-native/src/__tests__/BarcodeScanner.spec.tsx index 4774fd46e..1eb1920f1 100644 --- a/packages/pluggableWidgets/barcode-scanner-native/src/__tests__/BarcodeScanner.spec.tsx +++ b/packages/pluggableWidgets/barcode-scanner-native/src/__tests__/BarcodeScanner.spec.tsx @@ -3,6 +3,7 @@ import { actionValue, EditableValueBuilder } from "@mendix/piw-utils-internal"; import { render } from "@testing-library/react-native"; import { View } from "react-native"; import { BarcodeScanner, Props } from "../BarcodeScanner"; +import { defaultBarcodeScannerStyle } from "../ui/styles"; let mockOnCodeScanned: ((codes: Array<{ value: string }>) => void) | undefined; @@ -68,4 +69,9 @@ describe("BarcodeScanner", () => { expect(defaultProps.barcode.setValue).toHaveBeenCalledWith("value1"); expect(onDetectAction.execute).toHaveBeenCalledTimes(2); }); + + it("preserves expected style key set", () => { + const keys = Object.keys(defaultBarcodeScannerStyle).sort(); + expect(keys).toEqual(["container", "mask"]); + }); }); diff --git a/packages/pluggableWidgets/carousel-native/src/__tests__/Carousel.spec.tsx b/packages/pluggableWidgets/carousel-native/src/__tests__/Carousel.spec.tsx index bbab1c98c..3702096d1 100644 --- a/packages/pluggableWidgets/carousel-native/src/__tests__/Carousel.spec.tsx +++ b/packages/pluggableWidgets/carousel-native/src/__tests__/Carousel.spec.tsx @@ -1,5 +1,5 @@ import { CarouselProps } from "../../typings/CarouselProps"; -import { CarouselStyle } from "../ui/styles"; +import { CarouselStyle, defaultCarouselStyle } from "../ui/styles"; import { render } from "@testing-library/react-native"; import { Text, View } from "react-native"; import { buildWidgetValue, ListValueBuilder } from "@mendix/piw-utils-internal"; @@ -47,4 +47,9 @@ describe("Carousel", () => { // }; // expect(render().toJSON()).toMatchSnapshot(); // }); + + it("preserves expected style key set", () => { + const keys = Object.keys(defaultCarouselStyle).sort(); + expect(keys).toEqual(["cardLayout", "container", "fullWidthLayout"]); + }); }); diff --git a/packages/pluggableWidgets/color-picker-native/src/__tests__/ColorPicker.spec.tsx b/packages/pluggableWidgets/color-picker-native/src/__tests__/ColorPicker.spec.tsx index f46abbe62..a3b9197d2 100644 --- a/packages/pluggableWidgets/color-picker-native/src/__tests__/ColorPicker.spec.tsx +++ b/packages/pluggableWidgets/color-picker-native/src/__tests__/ColorPicker.spec.tsx @@ -4,6 +4,7 @@ import Slider from "react-native-slider"; import { fireEvent, render, RenderAPI } from "@testing-library/react-native"; import { ReactTestInstance } from "react-test-renderer"; import { ColorPicker, Props } from "../ColorPicker"; +import { defaultColorPickerStyle } from "../ui/Styles"; describe("Color Picker", () => { let defaultProps: Props; @@ -177,6 +178,11 @@ describe("Color Picker", () => { function getSliders(component: RenderAPI): ReactTestInstance[] { return component.UNSAFE_getAllByType(Slider); } + + it("preserves expected style key set", () => { + const keys = Object.keys(defaultColorPickerStyle).sort(); + expect(keys).toEqual(["container", "preview"]); + }); }); function responderMove(dx: number): any { diff --git a/packages/pluggableWidgets/column-chart-native/src/utils/__tests__/StyleUtils.spec.ts b/packages/pluggableWidgets/column-chart-native/src/utils/__tests__/StyleUtils.spec.ts index ad17ffc1a..d9097e18f 100644 --- a/packages/pluggableWidgets/column-chart-native/src/utils/__tests__/StyleUtils.spec.ts +++ b/packages/pluggableWidgets/column-chart-native/src/utils/__tests__/StyleUtils.spec.ts @@ -1,5 +1,5 @@ import { aggregateGridPadding, mapToAxisStyle, mapToGridStyle, mapToColumnStyles } from "../StyleUtils"; -import { ColumnChartAxisStyle, ColumnChartGridStyle, ColumnChartStyle } from "../../ui/Styles"; +import { ColumnChartAxisStyle, ColumnChartGridStyle, ColumnChartStyle, defaultColumnChartStyle } from "../../ui/Styles"; describe("StyleMappers", () => { describe("mapToGridStyle", () => { @@ -210,3 +210,10 @@ describe("aggregateGridPadding", () => { expect(aggregateGridPadding(undefined)).toBeUndefined(); }); }); + +describe("Style schema guardrail", () => { + it("preserves expected style key set", () => { + const keys = Object.keys(defaultColumnChartStyle).sort(); + expect(keys).toEqual(["chart", "container", "errorMessage", "legend", "xAxis"]); + }); +}); diff --git a/packages/pluggableWidgets/feedback-native/src/__tests__/Feedback.spec.tsx b/packages/pluggableWidgets/feedback-native/src/__tests__/Feedback.spec.tsx index a9797ba66..61a941103 100644 --- a/packages/pluggableWidgets/feedback-native/src/__tests__/Feedback.spec.tsx +++ b/packages/pluggableWidgets/feedback-native/src/__tests__/Feedback.spec.tsx @@ -1,4 +1,4 @@ -import { FeedbackStyle } from "../ui/styles"; +import { FeedbackStyle, defaultFeedbackStyle } from "../ui/styles"; import { render, cleanup, fireEvent, waitFor } from "@testing-library/react-native"; import { FeedbackProps } from "../../typings/FeedbackProps"; import { Feedback } from "../Feedback"; @@ -95,4 +95,19 @@ describe("Feedback", () => { expect(typeof body.metadata.screenWidth).toBe("number"); expect(typeof body.metadata.screenHeight).toBe("number"); }, 15000); + + it("preserves expected style key set", () => { + const keys = Object.keys(defaultFeedbackStyle).sort(); + expect(keys).toEqual([ + "activityIndicator", + "button", + "buttonDisabled", + "dialog", + "floatingButton", + "switchInput", + "switchLabel", + "textAreaInput", + "title" + ]); + }); }); diff --git a/packages/pluggableWidgets/line-chart-native/src/utils/__tests__/StyleUtils.spec.ts b/packages/pluggableWidgets/line-chart-native/src/utils/__tests__/StyleUtils.spec.ts index 5c3ca0810..7103ee39a 100644 --- a/packages/pluggableWidgets/line-chart-native/src/utils/__tests__/StyleUtils.spec.ts +++ b/packages/pluggableWidgets/line-chart-native/src/utils/__tests__/StyleUtils.spec.ts @@ -1,5 +1,5 @@ import { aggregateGridPadding, mapToAxisStyle, mapToGridStyle, mapToLineStyle, mapToMarkerStyle } from "../StyleUtils"; -import { LineChartAxisStyle, LineChartGridStyle, LineChartLineStyle } from "../../ui/Styles"; +import { LineChartAxisStyle, LineChartGridStyle, LineChartLineStyle, defaultLineChartStyle } from "../../ui/Styles"; describe("StyleMappers", () => { describe("mapToGridStyle", () => { @@ -183,3 +183,10 @@ describe("aggregateGridPadding", () => { expect(aggregateGridPadding(undefined)).toBeUndefined(); }); }); + +describe("Style schema guardrail", () => { + it("preserves expected style key set", () => { + const keys = Object.keys(defaultLineChartStyle).sort(); + expect(keys).toEqual(["chart", "container", "errorMessage", "grid", "legend", "xAxis"]); + }); +}); diff --git a/packages/pluggableWidgets/pie-doughnut-chart-native/src/__tests__/PieDoughnutChart.spec.tsx b/packages/pluggableWidgets/pie-doughnut-chart-native/src/__tests__/PieDoughnutChart.spec.tsx index 21ec108d8..9999ce118 100644 --- a/packages/pluggableWidgets/pie-doughnut-chart-native/src/__tests__/PieDoughnutChart.spec.tsx +++ b/packages/pluggableWidgets/pie-doughnut-chart-native/src/__tests__/PieDoughnutChart.spec.tsx @@ -334,6 +334,11 @@ describe("PieDoughnutChart", () => { }); }); }); + + it("preserves expected style key set", () => { + const keys = Object.keys(defaultStyle).sort(); + expect(keys).toEqual(["container", "slices"]); + }); }); function createProps(opts: Partial> = {}): PieDoughnutChartProps { diff --git a/packages/pluggableWidgets/progress-bar-native/src/__tests__/ProgressBar.spec.tsx b/packages/pluggableWidgets/progress-bar-native/src/__tests__/ProgressBar.spec.tsx index db964902e..2b8dba97d 100644 --- a/packages/pluggableWidgets/progress-bar-native/src/__tests__/ProgressBar.spec.tsx +++ b/packages/pluggableWidgets/progress-bar-native/src/__tests__/ProgressBar.spec.tsx @@ -5,6 +5,7 @@ import { Bar } from "react-native-progress"; import { render } from "@testing-library/react-native"; import { ProgressBar, Props } from "../ProgressBar"; +import { defaultProgressBarStyle } from "../ui/Styles"; describe("ProgressBar", () => { it("renders", () => { @@ -45,6 +46,11 @@ describe("ProgressBar", () => { expect(component.UNSAFE_getByType(Bar).props.progress).toBe(0.7); expect(component.UNSAFE_queryByType(Text)).toBeNull(); }); + + it("preserves expected style key set", () => { + const keys = Object.keys(defaultProgressBarStyle).sort(); + expect(keys).toEqual(["bar", "container", "fill", "validationMessage"]); + }); }); function createProps(progressValue?: number, minimumValue?: number, maximumValue?: number): Props { diff --git a/packages/pluggableWidgets/progress-circle-native/src/__tests__/ProgressCircle.spec.tsx b/packages/pluggableWidgets/progress-circle-native/src/__tests__/ProgressCircle.spec.tsx index b67837724..ea2cf41e9 100644 --- a/packages/pluggableWidgets/progress-circle-native/src/__tests__/ProgressCircle.spec.tsx +++ b/packages/pluggableWidgets/progress-circle-native/src/__tests__/ProgressCircle.spec.tsx @@ -5,6 +5,7 @@ import { Circle } from "react-native-progress"; import { render } from "@testing-library/react-native"; import { ProgressCircle, Props } from "../ProgressCircle"; +import { defaultProgressCircleStyle } from "../ui/Styles"; describe("ProgressCircle", () => { it("renders", () => { @@ -80,6 +81,11 @@ No current value provided.` const component = render(); expect(component.UNSAFE_queryByType(Text)).toBeNull(); }); + + it("preserves expected style key set", () => { + const keys = Object.keys(defaultProgressCircleStyle).sort(); + expect(keys).toEqual(["circle", "container", "fill", "text", "validationMessage"]); + }); }); function createProps(progressValue?: number, minimumValue?: number, maximumValue?: number): Props { diff --git a/packages/pluggableWidgets/toggle-buttons-native/src/__tests__/ToggleButtons.spec.tsx b/packages/pluggableWidgets/toggle-buttons-native/src/__tests__/ToggleButtons.spec.tsx index 0ada19173..b339619be 100644 --- a/packages/pluggableWidgets/toggle-buttons-native/src/__tests__/ToggleButtons.spec.tsx +++ b/packages/pluggableWidgets/toggle-buttons-native/src/__tests__/ToggleButtons.spec.tsx @@ -3,6 +3,7 @@ import { Text } from "react-native"; import { fireEvent, render } from "@testing-library/react-native"; import { Props, ToggleButtons } from "../ToggleButtons"; +import { defaultToggleButtonsStyle } from "../ui/Styles"; describe("ToggleButtons", () => { let defaultProps: Props; @@ -68,4 +69,17 @@ describe("ToggleButtons", () => { expect(defaultProps.enum.setValue).not.toHaveBeenCalled(); }); + + it("preserves expected style key set", () => { + const keys = Object.keys(defaultToggleButtonsStyle).sort(); + expect(keys).toEqual([ + "activeButton", + "activeButtonText", + "button", + "container", + "containerDisabled", + "text", + "validationMessage" + ]); + }); }); From 50c62e9b7f43a453897b7df8da2b582b93f4002c Mon Sep 17 00:00:00 2001 From: Srirang Kalantri Date: Mon, 28 Sep 2026 12:52:22 +0530 Subject: [PATCH 2/2] fix: add nested style contracts --- .../bar-chart-native/src/ui/Styles.ts | 3 ++ .../src/utils/__tests__/StyleUtils.spec.ts | 12 +++++++- .../src/__tests__/BarcodeScanner.spec.tsx | 5 ++++ .../column-chart-native/src/ui/Styles.ts | 4 +++ .../src/utils/__tests__/StyleUtils.spec.ts | 12 +++++++- .../line-chart-native/src/ui/Styles.ts | 2 ++ .../src/utils/__tests__/StyleUtils.spec.ts | 2 +- .../src/__tests__/PieDoughnutChart.spec.tsx | 8 ++++++ .../src/__tests__/PopupMenu.spec.tsx | 28 ++++++++++++++++++- .../popup-menu-native/src/ui/Styles.ts | 7 +++++ .../src/__tests__/ProgressBar.spec.tsx | 5 ++++ .../src/__tests__/ProgressCircle.spec.tsx | 10 +++++++ 12 files changed, 94 insertions(+), 4 deletions(-) diff --git a/packages/pluggableWidgets/bar-chart-native/src/ui/Styles.ts b/packages/pluggableWidgets/bar-chart-native/src/ui/Styles.ts index 80c3c0f04..56826bbaf 100644 --- a/packages/pluggableWidgets/bar-chart-native/src/ui/Styles.ts +++ b/packages/pluggableWidgets/bar-chart-native/src/ui/Styles.ts @@ -93,6 +93,9 @@ export const defaultBarChartStyle: BarChartStyle = { alignSelf: "center" } }, + yAxis: {}, + domain: {}, + bars: {}, legend: { container: { flexDirection: "row", diff --git a/packages/pluggableWidgets/bar-chart-native/src/utils/__tests__/StyleUtils.spec.ts b/packages/pluggableWidgets/bar-chart-native/src/utils/__tests__/StyleUtils.spec.ts index bb426e936..1c63c65c9 100644 --- a/packages/pluggableWidgets/bar-chart-native/src/utils/__tests__/StyleUtils.spec.ts +++ b/packages/pluggableWidgets/bar-chart-native/src/utils/__tests__/StyleUtils.spec.ts @@ -214,6 +214,16 @@ describe("aggregateGridPadding", () => { describe("Style schema guardrail", () => { it("preserves expected style key set", () => { const keys = Object.keys(defaultBarChartStyle).sort(); - expect(keys).toEqual(["chart", "container", "errorMessage", "grid", "legend", "xAxis"]); + expect(keys).toEqual([ + "bars", + "chart", + "container", + "domain", + "errorMessage", + "grid", + "legend", + "xAxis", + "yAxis" + ]); }); }); diff --git a/packages/pluggableWidgets/barcode-scanner-native/src/__tests__/BarcodeScanner.spec.tsx b/packages/pluggableWidgets/barcode-scanner-native/src/__tests__/BarcodeScanner.spec.tsx index 1eb1920f1..256765ee9 100644 --- a/packages/pluggableWidgets/barcode-scanner-native/src/__tests__/BarcodeScanner.spec.tsx +++ b/packages/pluggableWidgets/barcode-scanner-native/src/__tests__/BarcodeScanner.spec.tsx @@ -74,4 +74,9 @@ describe("BarcodeScanner", () => { const keys = Object.keys(defaultBarcodeScannerStyle).sort(); expect(keys).toEqual(["container", "mask"]); }); + + it("preserves expected mask style key set", () => { + const keys = Object.keys(defaultBarcodeScannerStyle.mask).sort(); + expect(keys).toEqual(["backgroundColor", "color"]); + }); }); diff --git a/packages/pluggableWidgets/column-chart-native/src/ui/Styles.ts b/packages/pluggableWidgets/column-chart-native/src/ui/Styles.ts index 22b620062..aa2c05c6a 100644 --- a/packages/pluggableWidgets/column-chart-native/src/ui/Styles.ts +++ b/packages/pluggableWidgets/column-chart-native/src/ui/Styles.ts @@ -82,11 +82,15 @@ export const defaultColumnChartStyle: ColumnChartStyle = { chart: { flex: 1 }, + grid: {}, xAxis: { label: { alignSelf: "center" } }, + yAxis: {}, + domain: {}, + columns: {}, legend: { container: { flexDirection: "row", diff --git a/packages/pluggableWidgets/column-chart-native/src/utils/__tests__/StyleUtils.spec.ts b/packages/pluggableWidgets/column-chart-native/src/utils/__tests__/StyleUtils.spec.ts index d9097e18f..c679e575e 100644 --- a/packages/pluggableWidgets/column-chart-native/src/utils/__tests__/StyleUtils.spec.ts +++ b/packages/pluggableWidgets/column-chart-native/src/utils/__tests__/StyleUtils.spec.ts @@ -214,6 +214,16 @@ describe("aggregateGridPadding", () => { describe("Style schema guardrail", () => { it("preserves expected style key set", () => { const keys = Object.keys(defaultColumnChartStyle).sort(); - expect(keys).toEqual(["chart", "container", "errorMessage", "legend", "xAxis"]); + expect(keys).toEqual([ + "chart", + "columns", + "container", + "domain", + "errorMessage", + "grid", + "legend", + "xAxis", + "yAxis" + ]); }); }); diff --git a/packages/pluggableWidgets/line-chart-native/src/ui/Styles.ts b/packages/pluggableWidgets/line-chart-native/src/ui/Styles.ts index 0ea16b165..6df619443 100644 --- a/packages/pluggableWidgets/line-chart-native/src/ui/Styles.ts +++ b/packages/pluggableWidgets/line-chart-native/src/ui/Styles.ts @@ -89,6 +89,8 @@ export const defaultLineChartStyle: LineChartStyle = { alignSelf: "center" } }, + yAxis: {}, + lines: {}, legend: { container: { flexDirection: "row", diff --git a/packages/pluggableWidgets/line-chart-native/src/utils/__tests__/StyleUtils.spec.ts b/packages/pluggableWidgets/line-chart-native/src/utils/__tests__/StyleUtils.spec.ts index 7103ee39a..075c66391 100644 --- a/packages/pluggableWidgets/line-chart-native/src/utils/__tests__/StyleUtils.spec.ts +++ b/packages/pluggableWidgets/line-chart-native/src/utils/__tests__/StyleUtils.spec.ts @@ -187,6 +187,6 @@ describe("aggregateGridPadding", () => { describe("Style schema guardrail", () => { it("preserves expected style key set", () => { const keys = Object.keys(defaultLineChartStyle).sort(); - expect(keys).toEqual(["chart", "container", "errorMessage", "grid", "legend", "xAxis"]); + expect(keys).toEqual(["chart", "container", "errorMessage", "grid", "legend", "lines", "xAxis", "yAxis"]); }); }); diff --git a/packages/pluggableWidgets/pie-doughnut-chart-native/src/__tests__/PieDoughnutChart.spec.tsx b/packages/pluggableWidgets/pie-doughnut-chart-native/src/__tests__/PieDoughnutChart.spec.tsx index 9999ce118..e698a06f4 100644 --- a/packages/pluggableWidgets/pie-doughnut-chart-native/src/__tests__/PieDoughnutChart.spec.tsx +++ b/packages/pluggableWidgets/pie-doughnut-chart-native/src/__tests__/PieDoughnutChart.spec.tsx @@ -339,6 +339,14 @@ describe("PieDoughnutChart", () => { const keys = Object.keys(defaultStyle).sort(); expect(keys).toEqual(["container", "slices"]); }); + + it("preserves expected slices.customStyles entry key set", () => { + const entry: NonNullable["customStyles"]>[string] = { + slice: {}, + label: {} + }; + expect(Object.keys(entry).sort()).toEqual(["label", "slice"]); + }); }); function createProps(opts: Partial> = {}): PieDoughnutChartProps { diff --git a/packages/pluggableWidgets/popup-menu-native/src/__tests__/PopupMenu.spec.tsx b/packages/pluggableWidgets/popup-menu-native/src/__tests__/PopupMenu.spec.tsx index ab99b21f5..70a230428 100644 --- a/packages/pluggableWidgets/popup-menu-native/src/__tests__/PopupMenu.spec.tsx +++ b/packages/pluggableWidgets/popup-menu-native/src/__tests__/PopupMenu.spec.tsx @@ -1,5 +1,5 @@ import { PopupMenuProps } from "../../typings/PopupMenuProps"; -import { PopupMenuStyle } from "../ui/Styles"; +import { defaultPopupMenuStyle, PopupMenuStyle } from "../ui/Styles"; import { Text, View } from "react-native"; import { actionValue } from "@mendix/piw-utils-internal"; import { act, fireEvent, render, within } from "@testing-library/react-native"; @@ -145,4 +145,30 @@ describe("Popup menu", () => { expect(within(secondView).getByText("Yolo")).not.toBeNull(); }); }); + + describe("Style schema guardrail", () => { + it("preserves expected style key set", () => { + const keys = Object.keys(defaultPopupMenuStyle).sort(); + expect(keys).toEqual(["basic", "buttonContainer", "container", "custom"]); + }); + + it("preserves expected basic.itemStyle key set", () => { + const itemStyle: NonNullable["itemStyle"] = { + rippleColor: "", + ellipsizeMode: "tail", + defaultStyle: {}, + primaryStyle: {}, + dangerStyle: {}, + customStyle: {} + }; + expect(Object.keys(itemStyle).sort()).toEqual([ + "customStyle", + "dangerStyle", + "defaultStyle", + "ellipsizeMode", + "primaryStyle", + "rippleColor" + ]); + }); + }); }); diff --git a/packages/pluggableWidgets/popup-menu-native/src/ui/Styles.ts b/packages/pluggableWidgets/popup-menu-native/src/ui/Styles.ts index 415de25bf..bd9219c7e 100644 --- a/packages/pluggableWidgets/popup-menu-native/src/ui/Styles.ts +++ b/packages/pluggableWidgets/popup-menu-native/src/ui/Styles.ts @@ -7,6 +7,13 @@ export interface PopupMenuStyle { buttonContainer?: ViewStyle; } +export const defaultPopupMenuStyle: PopupMenuStyle = { + container: {}, + basic: {}, + custom: {}, + buttonContainer: {} +}; + export interface CustomItemStyle extends ViewStyle { container?: ViewStyle; itemStyle?: { rippleColor?: string }; diff --git a/packages/pluggableWidgets/progress-bar-native/src/__tests__/ProgressBar.spec.tsx b/packages/pluggableWidgets/progress-bar-native/src/__tests__/ProgressBar.spec.tsx index 2b8dba97d..6b03cee7e 100644 --- a/packages/pluggableWidgets/progress-bar-native/src/__tests__/ProgressBar.spec.tsx +++ b/packages/pluggableWidgets/progress-bar-native/src/__tests__/ProgressBar.spec.tsx @@ -51,6 +51,11 @@ describe("ProgressBar", () => { const keys = Object.keys(defaultProgressBarStyle).sort(); expect(keys).toEqual(["bar", "container", "fill", "validationMessage"]); }); + + it("preserves expected fill style key set", () => { + const keys = Object.keys(defaultProgressBarStyle.fill).sort(); + expect(keys).toEqual(["backgroundColor"]); + }); }); function createProps(progressValue?: number, minimumValue?: number, maximumValue?: number): Props { diff --git a/packages/pluggableWidgets/progress-circle-native/src/__tests__/ProgressCircle.spec.tsx b/packages/pluggableWidgets/progress-circle-native/src/__tests__/ProgressCircle.spec.tsx index ea2cf41e9..fef764eaf 100644 --- a/packages/pluggableWidgets/progress-circle-native/src/__tests__/ProgressCircle.spec.tsx +++ b/packages/pluggableWidgets/progress-circle-native/src/__tests__/ProgressCircle.spec.tsx @@ -86,6 +86,16 @@ No current value provided.` const keys = Object.keys(defaultProgressCircleStyle).sort(); expect(keys).toEqual(["circle", "container", "fill", "text", "validationMessage"]); }); + + it("preserves expected fill style key set", () => { + const keys = Object.keys(defaultProgressCircleStyle.fill).sort(); + expect(keys).toEqual(["backgroundColor", "lineCapRounded", "width"]); + }); + + it("preserves expected circle style key set", () => { + const keys = Object.keys(defaultProgressCircleStyle.circle).sort(); + expect(keys).toEqual(["borderColor", "borderWidth", "size"]); + }); }); function createProps(progressValue?: number, minimumValue?: number, maximumValue?: number): Props {