@terreno/ui 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,137 @@
1
+ import {afterAll, afterEach, beforeEach, describe, expect, it, mock} from "bun:test";
2
+ import {fireEvent} from "@testing-library/react-native";
3
+
4
+ // Mock isNative to return false so the desktop/web path is rendered
5
+ mock.module("./Utilities", () => ({
6
+ isNative: () => false,
7
+ }));
8
+
9
+ import {HeightField} from "./HeightField";
10
+ import {renderWithTheme} from "./test-utils";
11
+
12
+ describe("HeightField (desktop/web path)", () => {
13
+ let mockOnChange: ReturnType<typeof mock>;
14
+
15
+ beforeEach(() => {
16
+ mockOnChange = mock(() => {});
17
+ });
18
+
19
+ afterEach(() => {});
20
+
21
+ afterAll(() => {
22
+ // Restore isNative to default native behavior so the mock doesn't leak to other test files
23
+ mock.module("./Utilities", () => ({
24
+ isNative: () => true,
25
+ }));
26
+ });
27
+
28
+ describe("rendering", () => {
29
+ it("renders two text inputs for feet and inches", () => {
30
+ const {getAllByLabelText} = renderWithTheme(<HeightField onChange={mockOnChange} value="" />);
31
+ expect(getAllByLabelText("ft input").length).toBe(1);
32
+ expect(getAllByLabelText("in input").length).toBe(1);
33
+ });
34
+
35
+ it("renders the correct initial feet and inches from value", () => {
36
+ const {getByDisplayValue} = renderWithTheme(
37
+ <HeightField onChange={mockOnChange} value="70" />
38
+ );
39
+ // 70 inches = 5ft 10in
40
+ expect(getByDisplayValue("5")).toBeTruthy();
41
+ expect(getByDisplayValue("10")).toBeTruthy();
42
+ });
43
+
44
+ it("renders title when provided", () => {
45
+ const {getByText} = renderWithTheme(
46
+ <HeightField onChange={mockOnChange} title="Height" value="" />
47
+ );
48
+ expect(getByText("Height")).toBeTruthy();
49
+ });
50
+
51
+ it("renders helper text", () => {
52
+ const {getByText} = renderWithTheme(
53
+ <HeightField helperText="Enter your height" onChange={mockOnChange} value="" />
54
+ );
55
+ expect(getByText("Enter your height")).toBeTruthy();
56
+ });
57
+
58
+ it("renders error text", () => {
59
+ const {getByText} = renderWithTheme(
60
+ <HeightField errorText="Invalid height" onChange={mockOnChange} value="" />
61
+ );
62
+ expect(getByText("Invalid height")).toBeTruthy();
63
+ });
64
+ });
65
+
66
+ describe("onChange behavior", () => {
67
+ it("calls onChange with correct total inches when feet changes", () => {
68
+ const {getAllByLabelText} = renderWithTheme(
69
+ <HeightField onChange={mockOnChange} value="70" />
70
+ );
71
+ const feetInput = getAllByLabelText("ft input")[0];
72
+ fireEvent.changeText(feetInput, "6");
73
+ // 6 feet + 10 inches (from value "70" = 5ft 10in, inches = 10) = 82 inches
74
+ expect(mockOnChange).toHaveBeenCalledWith("82");
75
+ });
76
+
77
+ it("calls onChange with correct total inches when inches changes", () => {
78
+ const {getAllByLabelText} = renderWithTheme(
79
+ <HeightField onChange={mockOnChange} value="70" />
80
+ );
81
+ const inchesInput = getAllByLabelText("in input")[0];
82
+ fireEvent.changeText(inchesInput, "0");
83
+ // 5 feet (from value "70" = 5ft 10in, feet = 5) + 0 inches = 60 inches
84
+ expect(mockOnChange).toHaveBeenCalledWith("60");
85
+ });
86
+
87
+ it("calls onChange with empty string when both inputs are cleared", () => {
88
+ const {getAllByLabelText} = renderWithTheme(
89
+ <HeightField onChange={mockOnChange} value="70" />
90
+ );
91
+ const feetInput = getAllByLabelText("ft input")[0];
92
+ const inchesInput = getAllByLabelText("in input")[0];
93
+ fireEvent.changeText(feetInput, "");
94
+ fireEvent.changeText(inchesInput, "");
95
+ expect(mockOnChange).toHaveBeenCalledWith("");
96
+ });
97
+
98
+ it("does not call onChange with values exceeding max feet", () => {
99
+ const {getAllByLabelText} = renderWithTheme(
100
+ <HeightField max={95} onChange={mockOnChange} value="" />
101
+ );
102
+ const feetInput = getAllByLabelText("ft input")[0];
103
+ // max is 95 inches = 7ft 11in, so maxFeet = 7
104
+ fireEvent.changeText(feetInput, "8");
105
+ expect(mockOnChange).not.toHaveBeenCalled();
106
+ });
107
+ });
108
+
109
+ describe("disabled state", () => {
110
+ it("renders text inputs as non-editable when disabled", () => {
111
+ const {getAllByLabelText} = renderWithTheme(
112
+ <HeightField disabled onChange={mockOnChange} value="70" />
113
+ );
114
+ const feetInput = getAllByLabelText("ft input")[0];
115
+ expect(feetInput.props.editable).toBe(false);
116
+ });
117
+ });
118
+
119
+ describe("snapshots", () => {
120
+ it("matches snapshot with default props", () => {
121
+ const component = renderWithTheme(<HeightField onChange={mockOnChange} value="" />);
122
+ expect(component.toJSON()).toMatchSnapshot();
123
+ });
124
+
125
+ it("matches snapshot with value", () => {
126
+ const component = renderWithTheme(<HeightField onChange={mockOnChange} value="70" />);
127
+ expect(component.toJSON()).toMatchSnapshot();
128
+ });
129
+
130
+ it("matches snapshot when disabled", () => {
131
+ const component = renderWithTheme(
132
+ <HeightField disabled onChange={mockOnChange} value="70" />
133
+ );
134
+ expect(component.toJSON()).toMatchSnapshot();
135
+ });
136
+ });
137
+ });