@teselagen/ui 0.9.4 → 0.9.6

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.
package/README.md CHANGED
@@ -4,12 +4,16 @@ This library was generated with [Nx](https://nx.dev).
4
4
 
5
5
  ## Running unit tests
6
6
 
7
- Run `nx test ui` to execute the unit tests via bun test
7
+ Run `bun test` from the root of the repo to execute all unit tests.
8
+
9
+ ## Running end-to-end tests locally
10
+
11
+ Run `nx run ui:launch-e2e` to launch the Cypress test runner locally
8
12
 
9
13
  ## Installation (react)
10
14
 
11
15
  ```
12
- yarn add @teselagen/ove react react-dom
16
+ yarn add @teselagen/ui react react-dom
13
17
  ```
14
18
 
15
19
  ## Running locally
package/index.cjs.js CHANGED
@@ -37093,6 +37093,9 @@ const defaultValidators = {
37093
37093
  }, "dropdownMulti"),
37094
37094
  number: /* @__PURE__ */ __name((newVal, field) => {
37095
37095
  if (isValueEmpty(newVal) && !field.isRequired) return;
37096
+ if (field.allowNaN && Number.isNaN(newVal)) {
37097
+ return;
37098
+ }
37096
37099
  if (isNaN(newVal) || !isNumber$1(newVal)) {
37097
37100
  return "Must be a number";
37098
37101
  }
package/index.es.js CHANGED
@@ -37075,6 +37075,9 @@ const defaultValidators = {
37075
37075
  }, "dropdownMulti"),
37076
37076
  number: /* @__PURE__ */ __name((newVal, field) => {
37077
37077
  if (isValueEmpty(newVal) && !field.isRequired) return;
37078
+ if (field.allowNaN && Number.isNaN(newVal)) {
37079
+ return;
37080
+ }
37078
37081
  if (isNaN(newVal) || !isNumber$1(newVal)) {
37079
37082
  return "Must be a number";
37080
37083
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teselagen/ui",
3
- "version": "0.9.4",
3
+ "version": "0.9.6",
4
4
  "main": "./src/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,26 +1,40 @@
1
1
  import React from "react";
2
2
  import { render, fireEvent } from "@testing-library/react";
3
+
3
4
  import AdvancedOptions from "./AdvancedOptions";
4
5
 
5
6
  describe("AdvancedOptions", () => {
7
+ // afterEach(() => {
8
+ // cleanup();
9
+ // });
10
+
6
11
  test("renders correctly with given props and default state", () => {
7
12
  const { queryByText, container } = render(
8
13
  <AdvancedOptions label="Test Label" content="Test Content" />
9
14
  );
10
- expect(queryByText("Test Label")).toBeInTheDocument();
11
- expect(queryByText("Test Content")).not.toBeInTheDocument();
15
+ // Check if label is rendered
16
+ expect(queryByText("Test Label")).not.toBeNull();
17
+ // Check if content is NOT rendered initially (collapsed state)
18
+ expect(queryByText("Test Content")).toBeNull();
12
19
 
13
- expect(
14
- container.querySelector(".bp3-icon-caret-right")
15
- ).toBeInTheDocument();
20
+ // Check if right caret icon is present (collapsed state)
21
+ expect(container.querySelector(".bp3-icon-caret-right")).not.toBeNull();
16
22
  });
17
23
 
18
24
  test("toggles content when clicked", () => {
19
- const { getByText, queryByText, container } = render(
20
- <AdvancedOptions label="Test Label" content="Test Content" />
25
+ const { container, queryByText } = render(
26
+ <AdvancedOptions label="Test Label 2" content="Test Content 2" />
21
27
  );
22
- fireEvent.click(getByText("Test Label"));
23
- expect(queryByText("Test Content")).toBeInTheDocument();
24
- expect(container.querySelector(".bp3-icon-caret-down")).toBeInTheDocument();
28
+
29
+ // Find and click the toggle button
30
+ const toggleButton = container.querySelector(".tg-toggle-advanced-options");
31
+ expect(toggleButton).not.toBeNull();
32
+
33
+ fireEvent.click(toggleButton);
34
+
35
+ // After click, content should be visible
36
+ expect(queryByText("Test Content 2")).not.toBeNull();
37
+ // After click, down caret icon should be present (expanded state)
38
+ expect(container.querySelector(".bp3-icon-caret-down")).not.toBeNull();
25
39
  });
26
40
  });
@@ -29,6 +29,10 @@ export const defaultValidators = {
29
29
  },
30
30
  number: (newVal, field) => {
31
31
  if (isValueEmpty(newVal) && !field.isRequired) return;
32
+ if (field.allowNaN && Number.isNaN(newVal)) {
33
+ // Allow actual NaN when explicitly permitted
34
+ return;
35
+ }
32
36
  if (isNaN(newVal) || !isNumber(newVal)) {
33
37
  return "Must be a number";
34
38
  }
@@ -0,0 +1,108 @@
1
+ // Basic unit tests without jest-dom setup
2
+ import { describe, test, expect } from "bun:test";
3
+ import { defaultValidators } from "./defaultValidators";
4
+
5
+ describe("defaultValidators", () => {
6
+ describe("number validator", () => {
7
+ const numberValidator = defaultValidators.number;
8
+
9
+ test("should validate valid numbers", () => {
10
+ expect(numberValidator(123, {})).toBeUndefined();
11
+ expect(numberValidator(0, {})).toBeUndefined();
12
+ expect(numberValidator(-123, {})).toBeUndefined();
13
+ expect(numberValidator(123.45, {})).toBeUndefined();
14
+ });
15
+
16
+ test("should reject non-numeric strings", () => {
17
+ expect(numberValidator("hello", {})).toBe("Must be a number");
18
+ expect(numberValidator("abc123", {})).toBe("Must be a number");
19
+ expect(numberValidator("", {})).toBeUndefined(); // empty values are allowed when not required
20
+ });
21
+
22
+ test("should reject NaN by default", () => {
23
+ expect(numberValidator(NaN, {})).toBe("Must be a number");
24
+ });
25
+
26
+ test("should allow NaN when allowNaN is true", () => {
27
+ expect(numberValidator(NaN, { allowNaN: true })).toBeUndefined();
28
+ });
29
+
30
+ test("should still reject non-numeric strings even with allowNaN", () => {
31
+ expect(numberValidator("hello", { allowNaN: true })).toBe("Must be a number");
32
+ expect(numberValidator("not a number", { allowNaN: true })).toBe("Must be a number");
33
+ });
34
+
35
+ test("should handle required field validation", () => {
36
+ expect(numberValidator("", { isRequired: true })).toBe("Must be a number");
37
+ expect(numberValidator(null, { isRequired: true })).toBe("Must be a number");
38
+ expect(numberValidator(undefined, { isRequired: true })).toBe("Must be a number");
39
+ });
40
+
41
+ test("should allow empty values for non-required fields", () => {
42
+ expect(numberValidator("", {})).toBeUndefined();
43
+ expect(numberValidator(null, {})).toBeUndefined();
44
+ expect(numberValidator(undefined, {})).toBeUndefined();
45
+ });
46
+
47
+ test("should reject numeric strings (only actual numbers allowed)", () => {
48
+ expect(numberValidator("123", {})).toBe("Must be a number");
49
+ expect(numberValidator("123.45", {})).toBe("Must be a number");
50
+ expect(numberValidator("-123", {})).toBe("Must be a number");
51
+ });
52
+
53
+ test("should combine allowNaN with required field validation", () => {
54
+ // Required field with allowNaN should still reject empty values
55
+ expect(numberValidator("", { isRequired: true, allowNaN: true })).toBe("Must be a number");
56
+ expect(numberValidator(null, { isRequired: true, allowNaN: true })).toBe("Must be a number");
57
+
58
+ // But should allow NaN
59
+ expect(numberValidator(NaN, { isRequired: true, allowNaN: true })).toBeUndefined();
60
+ });
61
+ });
62
+
63
+ describe("string validator", () => {
64
+ const stringValidator = defaultValidators.string;
65
+
66
+ test("should allow any string for non-required fields", () => {
67
+ expect(stringValidator("hello", {})).toBe(false);
68
+ expect(stringValidator("", {})).toBe(false);
69
+ });
70
+
71
+ test("should reject empty strings for required fields", () => {
72
+ expect(stringValidator("", { isRequired: true })).toBe("Please enter a value here");
73
+ expect(stringValidator(null, { isRequired: true })).toBe("Please enter a value here");
74
+ expect(stringValidator(undefined, { isRequired: true })).toBe("Please enter a value here");
75
+ });
76
+
77
+ test("should accept non-empty strings for required fields", () => {
78
+ expect(stringValidator("hello", { isRequired: true })).toBeUndefined();
79
+ expect(stringValidator("test", { isRequired: true })).toBeUndefined();
80
+ });
81
+ });
82
+
83
+ describe("dropdown validator", () => {
84
+ const dropdownValidator = defaultValidators.dropdown;
85
+ const field = { values: ["option1", "option2", "option3"] };
86
+
87
+ test("should accept valid dropdown values", () => {
88
+ expect(dropdownValidator("option1", field)).toBeUndefined();
89
+ expect(dropdownValidator("option2", field)).toBeUndefined();
90
+ expect(dropdownValidator("option3", field)).toBeUndefined();
91
+ });
92
+
93
+ test("should reject invalid dropdown values", () => {
94
+ expect(dropdownValidator("invalid", field)).toBe("Please choose one of the accepted values");
95
+ expect(dropdownValidator("option4", field)).toBe("Please choose one of the accepted values");
96
+ });
97
+
98
+ test("should handle required dropdown fields", () => {
99
+ expect(dropdownValidator("", { ...field, isRequired: true })).toBe("Please choose one of the accepted values");
100
+ expect(dropdownValidator(null, { ...field, isRequired: true })).toBe("Please choose one of the accepted values");
101
+ });
102
+
103
+ test("should allow empty values for non-required dropdown fields", () => {
104
+ expect(dropdownValidator("", field)).toBeUndefined();
105
+ expect(dropdownValidator(null, field)).toBeUndefined();
106
+ });
107
+ });
108
+ });