@arbor-education/design-system.components 0.1.4 → 0.1.5

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.
Files changed (37) hide show
  1. package/.github/workflows/release.yml +17 -18
  2. package/CHANGELOG.md +6 -0
  3. package/dist/components/icon/Icon.test.js +6 -3
  4. package/dist/components/icon/Icon.test.js.map +1 -1
  5. package/dist/utils/hooks/useComponentDidMount.test.d.ts +2 -0
  6. package/dist/utils/hooks/useComponentDidMount.test.d.ts.map +1 -0
  7. package/dist/utils/hooks/useComponentDidMount.test.js +43 -0
  8. package/dist/utils/hooks/useComponentDidMount.test.js.map +1 -0
  9. package/dist/utils/hooks/useGridApi.test.d.ts +2 -0
  10. package/dist/utils/hooks/useGridApi.test.d.ts.map +1 -0
  11. package/dist/utils/hooks/useGridApi.test.js +48 -0
  12. package/dist/utils/hooks/useGridApi.test.js.map +1 -0
  13. package/dist/utils/hooks/useIsMounted.test.d.ts +2 -0
  14. package/dist/utils/hooks/useIsMounted.test.d.ts.map +1 -0
  15. package/dist/utils/hooks/useIsMounted.test.js +46 -0
  16. package/dist/utils/hooks/useIsMounted.test.js.map +1 -0
  17. package/dist/utils/hooks/useMemoGenerateUuid.d.ts +1 -1
  18. package/dist/utils/hooks/useMemoGenerateUuid.d.ts.map +1 -1
  19. package/dist/utils/hooks/useMemoGenerateUuid.js +1 -1
  20. package/dist/utils/hooks/useMemoGenerateUuid.js.map +1 -1
  21. package/dist/utils/hooks/useMemoGenerateUuid.test.d.ts +2 -0
  22. package/dist/utils/hooks/useMemoGenerateUuid.test.d.ts.map +1 -0
  23. package/dist/utils/hooks/useMemoGenerateUuid.test.js +55 -0
  24. package/dist/utils/hooks/useMemoGenerateUuid.test.js.map +1 -0
  25. package/dist/utils/hooks/usePubSub.test.d.ts +2 -0
  26. package/dist/utils/hooks/usePubSub.test.d.ts.map +1 -0
  27. package/dist/utils/hooks/usePubSub.test.js +81 -0
  28. package/dist/utils/hooks/usePubSub.test.js.map +1 -0
  29. package/package.json +2 -1
  30. package/src/components/icon/Icon.test.tsx +6 -3
  31. package/src/utils/hooks/useComponentDidMount.test.tsx +59 -0
  32. package/src/utils/hooks/useGridApi.test.tsx +79 -0
  33. package/src/utils/hooks/useIsMounted.test.tsx +63 -0
  34. package/src/utils/hooks/useMemoGenerateUuid.test.tsx +80 -0
  35. package/src/utils/hooks/useMemoGenerateUuid.ts +1 -1
  36. package/src/utils/hooks/usePubSub.test.tsx +100 -0
  37. package/vitest.config.ts +9 -0
@@ -8,18 +8,9 @@ permissions:
8
8
  id-token: write # Required for OIDC authentication
9
9
 
10
10
  on:
11
- push:
12
- branches:
13
- - DOPS-17000-fix-git-ops # Temporary: trigger on feature branch push
14
11
  schedule:
15
12
  - cron: '0 7 * * 1-5' # 7 AM UTC, Monday-Friday
16
- workflow_dispatch:
17
- inputs:
18
- force_publish:
19
- description: 'Force publish current version (skip changeset version step)'
20
- required: false
21
- default: false
22
- type: boolean
13
+ workflow_dispatch: # Allow manual trigger
23
14
 
24
15
  concurrency: ${{ github.workflow }}-${{ github.ref }}
25
16
 
@@ -55,7 +46,6 @@ jobs:
55
46
 
56
47
  - name: Version packages
57
48
  id: version
58
- if: ${{ !inputs.force_publish && github.event_name != 'push' }}
59
49
  env:
60
50
  GITHUB_TOKEN: ${{ secrets.ARBOR_AUTOMATION_ORG_GHA_TOKEN }}
61
51
  run: |
@@ -70,13 +60,12 @@ jobs:
70
60
  git commit -m "chore: version packages"
71
61
  git push
72
62
  fi
73
-
74
63
  - name: Publish to npm
75
- if: steps.version.outputs.changed == 'true' || inputs.force_publish || github.event_name == 'push'
64
+ if: steps.version.outputs.changed == 'true'
76
65
  run: npm publish
77
66
 
78
67
  - name: Get changelog for current release
79
- if: steps.version.outputs.changed == 'true' || inputs.force_publish || github.event_name == 'push'
68
+ if: steps.version.outputs.changed == 'true'
80
69
  id: get-changelog
81
70
  run: |
82
71
  changelog=$(python "${GITHUB_WORKSPACE}/.github/workflows/scripts/python/changelog_utils.py")
@@ -85,21 +74,21 @@ jobs:
85
74
  echo "EOF" >> $GITHUB_ENV
86
75
 
87
76
  - name: Get version
88
- if: steps.version.outputs.changed == 'true' || inputs.force_publish || github.event_name == 'push'
77
+ if: steps.version.outputs.changed == 'true'
89
78
  id: get-version
90
79
  run: |
91
80
  version=$(node -p "require('./package.json').version")
92
81
  echo "version=${version}" >> $GITHUB_OUTPUT
93
82
 
94
83
  - name: Create tarball
95
- if: steps.version.outputs.changed == 'true' || inputs.force_publish || github.event_name == 'push'
84
+ if: steps.version.outputs.changed == 'true'
96
85
  run: |
97
86
  mkdir -p release
98
87
  npm pack
99
88
  mv *.tgz release/design-system.components.tgz
100
89
 
101
90
  - name: Create GitHub Release
102
- if: steps.version.outputs.changed == 'true' || inputs.force_publish || github.event_name == 'push'
91
+ if: steps.version.outputs.changed == 'true'
103
92
  env:
104
93
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
105
94
  run: |
@@ -114,7 +103,7 @@ jobs:
114
103
  "./release/design-system.components.tgz"
115
104
 
116
105
  - name: Send Slack Success Message
117
- if: steps.version.outputs.changed == 'true' || inputs.force_publish || github.event_name == 'push'
106
+ if: steps.version.outputs.changed == 'true'
118
107
  uses: rtCamp/action-slack-notify@v2
119
108
  env:
120
109
  SLACK_COLOR: good
@@ -133,3 +122,13 @@ jobs:
133
122
  SLACK_LINK_NAMES: true
134
123
  MSG_MINIMAL: true
135
124
  SLACK_WEBHOOK: ${{ secrets.ARBOR_FRONTEND_RELEASE_SLACK_WEBHOOK }}
125
+
126
+ - name: Run component tests
127
+ if: steps.version.outputs.changed == 'true'
128
+ run: yarn test:coverage
129
+ - name: Coveralls
130
+ if: steps.version.outputs.changed == 'true'
131
+ uses: coverallsapp/github-action@v2
132
+ continue-on-error: true
133
+ with:
134
+ github-token: ${{ secrets.ARBOR_AUTOMATION_ORG_GHA_TOKEN }}
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## 0.1.4
2
2
 
3
+ ## 0.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [#93](https://github.com/arbor-education/design-system.components/pull/93) [`38e0e33`](https://github.com/arbor-education/design-system.components/commit/38e0e3315bb65becd546a5e6305f55ef7076bdab) Thanks [@AmeeMorris](https://github.com/AmeeMorris)! - MIS-67805 coveralls and add missing tests
8
+
3
9
  ### Patch Changes
4
10
 
5
11
  - [#80](https://github.com/arbor-education/design-system.components/pull/80) [`592c5b2`](https://github.com/arbor-education/design-system.components/commit/592c5b2a4a5f32d6da5d21c45c3a4d23ff935fea) Thanks [@AmeeMorris](https://github.com/AmeeMorris)! - MIS-66551 remove browser default margins from ds headings
@@ -3,10 +3,13 @@ import { describe, expect, test } from 'vitest';
3
3
  import { render, screen } from '@testing-library/react';
4
4
  import { Icon } from './Icon';
5
5
  import '@testing-library/jest-dom/vitest';
6
+ import { allowedIcons } from './allowedIcons';
6
7
  describe('Icon', () => {
7
- test('Icon renders', () => {
8
- render(_jsx(Icon, { name: "archive" }));
9
- expect(screen.getByRole('img', { hidden: true })).toBeInTheDocument();
8
+ Object.keys(allowedIcons).forEach((icon) => {
9
+ test(`Icon ${icon} renders`, () => {
10
+ render(_jsx(Icon, { name: icon }));
11
+ expect(screen.getByRole('img', { hidden: true })).toBeInTheDocument();
12
+ });
10
13
  });
11
14
  test('Screen reader text', () => {
12
15
  render(_jsx(Icon, { name: "arrow-right", screenReaderText: "foobar" }));
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.test.js","sourceRoot":"","sources":["../../../src/components/icon/Icon.test.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,kCAAkC,CAAC;AAE1C,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;IACpB,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE;QACxB,MAAM,CAAC,KAAC,IAAI,IAAC,IAAI,EAAC,SAAS,GAAG,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,KAAC,IAAI,IAAC,IAAI,EAAC,aAAa,EAAC,gBAAgB,EAAC,QAAQ,GAAG,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"Icon.test.js","sourceRoot":"","sources":["../../../src/components/icon/Icon.test.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,kCAAkC,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAiB,MAAM,gBAAgB,CAAC;AAE7D,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;IACpB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACzC,IAAI,CAAC,QAAQ,IAAI,UAAU,EAAE,GAAG,EAAE;YAChC,MAAM,CAAC,KAAC,IAAI,IAAC,IAAI,EAAE,IAAgB,GAAI,CAAC,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,KAAC,IAAI,IAAC,IAAI,EAAC,aAAa,EAAC,gBAAgB,EAAC,QAAQ,GAAG,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=useComponentDidMount.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useComponentDidMount.test.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useComponentDidMount.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { describe, expect, test, vi, beforeEach } from 'vitest';
3
+ import { render } from '@testing-library/react';
4
+ import { useComponentDidMount } from './useComponentDidMount';
5
+ describe('useComponentDidMount', () => {
6
+ beforeEach(() => {
7
+ vi.clearAllMocks();
8
+ });
9
+ test('calls callback on mount', () => {
10
+ const callback = vi.fn();
11
+ const TestComponent = () => {
12
+ useComponentDidMount(callback);
13
+ return _jsx("div", { children: "Test" });
14
+ };
15
+ render(_jsx(TestComponent, {}));
16
+ expect(callback).toHaveBeenCalledTimes(1);
17
+ });
18
+ test('does not call callback on re-render', () => {
19
+ const callback = vi.fn();
20
+ const TestComponent = ({ count }) => {
21
+ useComponentDidMount(callback);
22
+ return (_jsxs("div", { children: ["Test", count] }));
23
+ };
24
+ const { rerender } = render(_jsx(TestComponent, { count: 1 }));
25
+ expect(callback).toHaveBeenCalledTimes(1);
26
+ rerender(_jsx(TestComponent, { count: 2 }));
27
+ expect(callback).toHaveBeenCalledTimes(1);
28
+ });
29
+ test('calls cleanup function on unmount', () => {
30
+ const cleanup = vi.fn();
31
+ const callback = vi.fn(() => cleanup);
32
+ const TestComponent = () => {
33
+ useComponentDidMount(callback);
34
+ return _jsx("div", { children: "Test" });
35
+ };
36
+ const { unmount } = render(_jsx(TestComponent, {}));
37
+ expect(callback).toHaveBeenCalledTimes(1);
38
+ expect(cleanup).not.toHaveBeenCalled();
39
+ unmount();
40
+ expect(cleanup).toHaveBeenCalledTimes(1);
41
+ });
42
+ });
43
+ //# sourceMappingURL=useComponentDidMount.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useComponentDidMount.test.js","sourceRoot":"","sources":["../../../src/utils/hooks/useComponentDidMount.test.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACnC,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAEzB,MAAM,aAAa,GAAG,GAAG,EAAE;YACzB,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAC/B,OAAO,iCAAe,CAAC;QACzB,CAAC,CAAC;QAEF,MAAM,CAAC,KAAC,aAAa,KAAG,CAAC,CAAC;QAE1B,MAAM,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC/C,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAEzB,MAAM,aAAa,GAAG,CAAC,EAAE,KAAK,EAAqB,EAAE,EAAE;YACrD,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAC/B,OAAO,CACL,kCAEG,KAAK,IACF,CACP,CAAC;QACJ,CAAC,CAAC;QAEF,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,KAAC,aAAa,IAAC,KAAK,EAAE,CAAC,GAAI,CAAC,CAAC;QACzD,MAAM,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAE1C,QAAQ,CAAC,KAAC,aAAa,IAAC,KAAK,EAAE,CAAC,GAAI,CAAC,CAAC;QACtC,MAAM,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC7C,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;QAEtC,MAAM,aAAa,GAAG,GAAG,EAAE;YACzB,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAC/B,OAAO,iCAAe,CAAC;QACzB,CAAC,CAAC;QAEF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,KAAC,aAAa,KAAG,CAAC,CAAC;QAC9C,MAAM,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAEvC,OAAO,EAAE,CAAC;QACV,MAAM,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=useGridApi.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGridApi.test.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useGridApi.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, expect, test, vi } from 'vitest';
3
+ import { render } from '@testing-library/react';
4
+ import { useGridApi } from './useGridApi';
5
+ import { GridApiContext } from '../../components/table/GridApiContext';
6
+ describe('useGridApi', () => {
7
+ test('returns null gridApi and false isGridApiReady when context is null', () => {
8
+ let result = { gridApi: null, isGridApiReady: false };
9
+ const TestComponent = () => {
10
+ result = useGridApi();
11
+ return _jsx("div", { children: "Test" });
12
+ };
13
+ render(_jsx(GridApiContext.Provider, { value: null, children: _jsx(TestComponent, {}) }));
14
+ expect(result).not.toBeNull();
15
+ expect(result?.gridApi).toBeNull();
16
+ expect(result?.isGridApiReady).toBe(false);
17
+ });
18
+ test('returns gridApi and true isGridApiReady when context provides gridApi', () => {
19
+ const mockGridApi = {
20
+ getDisplayedRowCount: vi.fn(),
21
+ };
22
+ let result = { gridApi: null, isGridApiReady: false };
23
+ const TestComponent = () => {
24
+ result = useGridApi();
25
+ return _jsx("div", { children: "Test" });
26
+ };
27
+ render(_jsx(GridApiContext.Provider, { value: mockGridApi, children: _jsx(TestComponent, {}) }));
28
+ expect(result).not.toBeNull();
29
+ expect(result?.gridApi).toBe(mockGridApi);
30
+ expect(result?.isGridApiReady).toBe(true);
31
+ });
32
+ test('updates isGridApiReady when gridApi changes from null to provided', () => {
33
+ const mockGridApi = {
34
+ getDisplayedRowCount: vi.fn(),
35
+ };
36
+ let result = { gridApi: null, isGridApiReady: false };
37
+ const TestComponent = () => {
38
+ result = useGridApi();
39
+ return _jsx("div", { children: "Test" });
40
+ };
41
+ const { rerender } = render(_jsx(GridApiContext.Provider, { value: null, children: _jsx(TestComponent, {}) }));
42
+ expect(result?.isGridApiReady).toBe(false);
43
+ rerender(_jsx(GridApiContext.Provider, { value: mockGridApi, children: _jsx(TestComponent, {}) }));
44
+ expect(result?.isGridApiReady).toBe(true);
45
+ expect(result?.gridApi).toBe(mockGridApi);
46
+ });
47
+ });
48
+ //# sourceMappingURL=useGridApi.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGridApi.test.js","sourceRoot":"","sources":["../../../src/utils/hooks/useGridApi.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=useIsMounted.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIsMounted.test.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useIsMounted.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { describe, expect, test } from 'vitest';
3
+ import { render } from '@testing-library/react';
4
+ import { useIsMounted } from './useIsMounted';
5
+ describe('useIsMounted', () => {
6
+ test('returns a ref with current value true when component is mounted', () => {
7
+ let mountedRef = null;
8
+ const TestComponent = () => {
9
+ mountedRef = useIsMounted();
10
+ return _jsx("div", { children: "Test" });
11
+ };
12
+ render(_jsx(TestComponent, {}));
13
+ expect(mountedRef).not.toBeNull();
14
+ expect(mountedRef.current).toBe(true);
15
+ });
16
+ test('returns the same ref instance across re-renders', () => {
17
+ let mountedRef1 = null;
18
+ let mountedRef2 = null;
19
+ const TestComponent = ({ count }) => {
20
+ const ref = useIsMounted();
21
+ if (count === 1) {
22
+ mountedRef1 = ref;
23
+ }
24
+ else {
25
+ mountedRef2 = ref;
26
+ }
27
+ return (_jsxs("div", { children: ["Test", count] }));
28
+ };
29
+ const { rerender } = render(_jsx(TestComponent, { count: 1 }));
30
+ rerender(_jsx(TestComponent, { count: 2 }));
31
+ expect(mountedRef1).toBe(mountedRef2);
32
+ expect(mountedRef1.current).toBe(true);
33
+ });
34
+ test('sets current to false when component unmounts', () => {
35
+ let mountedRef = null;
36
+ const TestComponent = () => {
37
+ mountedRef = useIsMounted();
38
+ return _jsx("div", { children: "Test" });
39
+ };
40
+ const { unmount } = render(_jsx(TestComponent, {}));
41
+ expect(mountedRef.current).toBe(true);
42
+ unmount();
43
+ expect(mountedRef.current).toBe(false);
44
+ });
45
+ });
46
+ //# sourceMappingURL=useIsMounted.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIsMounted.test.js","sourceRoot":"","sources":["../../../src/utils/hooks/useIsMounted.test.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAI,CAAC,iEAAiE,EAAE,GAAG,EAAE;QAC3E,IAAI,UAAU,GAA2C,IAAI,CAAC;QAE9D,MAAM,aAAa,GAAG,GAAG,EAAE;YACzB,UAAU,GAAG,YAAY,EAAE,CAAC;YAC5B,OAAO,iCAAe,CAAC;QACzB,CAAC,CAAC;QAEF,MAAM,CAAC,KAAC,aAAa,KAAG,CAAC,CAAC;QAE1B,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,CAAC,UAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,iDAAiD,EAAE,GAAG,EAAE;QAC3D,IAAI,WAAW,GAA2C,IAAI,CAAC;QAC/D,IAAI,WAAW,GAA2C,IAAI,CAAC;QAE/D,MAAM,aAAa,GAAG,CAAC,EAAE,KAAK,EAAqB,EAAE,EAAE;YACrD,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;YAC3B,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,WAAW,GAAG,GAAG,CAAC;YACpB,CAAC;iBACI,CAAC;gBACJ,WAAW,GAAG,GAAG,CAAC;YACpB,CAAC;YACD,OAAO,CACL,kCAEG,KAAK,IACF,CACP,CAAC;QACJ,CAAC,CAAC;QAEF,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,KAAC,aAAa,IAAC,KAAK,EAAE,CAAC,GAAI,CAAC,CAAC;QACzD,QAAQ,CAAC,KAAC,aAAa,IAAC,KAAK,EAAE,CAAC,GAAI,CAAC,CAAC;QAEtC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtC,MAAM,CAAC,WAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACzD,IAAI,UAAU,GAA2C,IAAI,CAAC;QAE9D,MAAM,aAAa,GAAG,GAAG,EAAE;YACzB,UAAU,GAAG,YAAY,EAAE,CAAC;YAC5B,OAAO,iCAAe,CAAC;QACzB,CAAC,CAAC;QAEF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,KAAC,aAAa,KAAG,CAAC,CAAC;QAE9C,MAAM,CAAC,UAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEvC,OAAO,EAAE,CAAC;QAEV,MAAM,CAAC,UAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -3,6 +3,6 @@ type Args = {
3
3
  deps?: DependencyList;
4
4
  prefix?: string;
5
5
  };
6
- export declare const useMemoGenerateUuid: ({ deps, prefix }: Args) => string;
6
+ export declare const useMemoGenerateUuid: ({ deps, prefix }?: Args) => string;
7
7
  export {};
8
8
  //# sourceMappingURL=useMemoGenerateUuid.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useMemoGenerateUuid.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useMemoGenerateUuid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAGrD,KAAK,IAAI,GAAG;IACV,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,kBAAuB,IAAI,WAI9D,CAAC"}
1
+ {"version":3,"file":"useMemoGenerateUuid.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useMemoGenerateUuid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAGrD,KAAK,IAAI,GAAG;IACV,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,mBAAuB,IAAS,WAInE,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { useMemo } from 'react';
2
2
  import { generateUuid } from '../generateUuid';
3
- export const useMemoGenerateUuid = ({ deps = [], prefix }) => {
3
+ export const useMemoGenerateUuid = ({ deps = [], prefix } = {}) => {
4
4
  return useMemo(() => {
5
5
  return generateUuid(prefix);
6
6
  }, deps);
@@ -1 +1 @@
1
- {"version":3,"file":"useMemoGenerateUuid.js","sourceRoot":"","sources":["../../../src/utils/hooks/useMemoGenerateUuid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAuB,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAO/C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,MAAM,EAAQ,EAAE,EAAE;IACjE,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC,EAAE,IAAI,CAAC,CAAC;AACX,CAAC,CAAC"}
1
+ {"version":3,"file":"useMemoGenerateUuid.js","sourceRoot":"","sources":["../../../src/utils/hooks/useMemoGenerateUuid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAuB,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAO/C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,MAAM,KAAW,EAAE,EAAE,EAAE;IACtE,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC,EAAE,IAAI,CAAC,CAAC;AACX,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=useMemoGenerateUuid.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMemoGenerateUuid.test.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useMemoGenerateUuid.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { describe, expect, test, vi, beforeEach } from 'vitest';
3
+ import { render } from '@testing-library/react';
4
+ import { useMemoGenerateUuid } from './useMemoGenerateUuid';
5
+ import { generateUuid } from '../generateUuid';
6
+ vi.mock('../generateUuid', () => ({
7
+ generateUuid: vi.fn((prefix) => {
8
+ const uuid = '123e4567-e89b-12d3-a456-426614174000';
9
+ return prefix ? `${prefix}-${uuid}` : uuid;
10
+ }),
11
+ }));
12
+ describe('useMemoGenerateUuid', () => {
13
+ beforeEach(() => {
14
+ vi.clearAllMocks();
15
+ });
16
+ test('generates a UUID without prefix', () => {
17
+ let uuid = null;
18
+ const TestComponent = () => {
19
+ uuid = useMemoGenerateUuid();
20
+ return _jsx("div", { children: "Test" });
21
+ };
22
+ render(_jsx(TestComponent, {}));
23
+ expect(uuid).toBe('123e4567-e89b-12d3-a456-426614174000');
24
+ expect(generateUuid).toHaveBeenCalledWith(undefined);
25
+ });
26
+ test('generates a UUID with prefix', () => {
27
+ let uuid = null;
28
+ const TestComponent = () => {
29
+ uuid = useMemoGenerateUuid({ prefix: 'test' });
30
+ return _jsx("div", { children: "Test" });
31
+ };
32
+ render(_jsx(TestComponent, {}));
33
+ expect(uuid).toBe('test-123e4567-e89b-12d3-a456-426614174000');
34
+ expect(generateUuid).toHaveBeenCalledWith('test');
35
+ });
36
+ test('does not generate a new UUID when the dependencies do not change', () => {
37
+ const TestComponent = ({ count }) => {
38
+ const uuid = useMemoGenerateUuid();
39
+ return (_jsxs("div", { children: ["Test", count, uuid] }));
40
+ };
41
+ const { rerender } = render(_jsx(TestComponent, { count: 1 }));
42
+ rerender(_jsx(TestComponent, { count: 2 }));
43
+ expect(generateUuid).toHaveBeenCalledTimes(1);
44
+ });
45
+ test('generates a new UUID when the dependencies change', () => {
46
+ const TestComponent = ({ dep1, dep2 }) => {
47
+ const uuid = useMemoGenerateUuid({ deps: [dep1, dep2] });
48
+ return (_jsxs("div", { children: ["Test", uuid] }));
49
+ };
50
+ const { rerender } = render(_jsx(TestComponent, { dep1: 1, dep2: "a" }));
51
+ rerender(_jsx(TestComponent, { dep1: 2, dep2: "b" }));
52
+ expect(generateUuid).toHaveBeenCalledTimes(2);
53
+ });
54
+ });
55
+ //# sourceMappingURL=useMemoGenerateUuid.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMemoGenerateUuid.test.js","sourceRoot":"","sources":["../../../src/utils/hooks/useMemoGenerateUuid.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=usePubSub.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePubSub.test.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/usePubSub.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { describe, expect, test, vi, afterEach } from 'vitest';
3
+ import { render } from '@testing-library/react';
4
+ import { usePubSub } from './usePubSub';
5
+ import PubSub from '../PubSub';
6
+ import { generateUuid } from '../generateUuid';
7
+ const mockSubscriptions = {};
8
+ vi.mock('Utils/PubSub', () => {
9
+ return {
10
+ default: {
11
+ subscribe: vi.fn((eventName, handler) => {
12
+ const subscriptionId = generateUuid('pubsub-subscription');
13
+ if (!mockSubscriptions[eventName]) {
14
+ mockSubscriptions[eventName] = {};
15
+ }
16
+ mockSubscriptions[eventName][subscriptionId] = handler;
17
+ return subscriptionId;
18
+ }),
19
+ unsubscribe: vi.fn((eventName, subscriptionId) => {
20
+ if (mockSubscriptions[eventName]) {
21
+ delete mockSubscriptions[eventName][subscriptionId];
22
+ }
23
+ }),
24
+ publish: vi.fn((eventName, data) => {
25
+ if (mockSubscriptions[eventName]) {
26
+ Object.values(mockSubscriptions[eventName]).forEach((handler) => {
27
+ handler(data);
28
+ });
29
+ }
30
+ }),
31
+ // Helper to clear subscriptions for testing
32
+ _clearSubscriptions: () => {
33
+ Object.keys(mockSubscriptions).forEach((key) => {
34
+ delete mockSubscriptions[key];
35
+ });
36
+ },
37
+ },
38
+ };
39
+ });
40
+ describe('usePubSub', () => {
41
+ afterEach(() => {
42
+ // @ts-expect-error - Accessing private method for testing
43
+ PubSub._clearSubscriptions?.();
44
+ vi.clearAllMocks();
45
+ vi.resetAllMocks();
46
+ vi.restoreAllMocks();
47
+ });
48
+ test('subscribes to event on mount', () => {
49
+ const handler = vi.fn();
50
+ const TestComponent = () => {
51
+ usePubSub('test-event', handler);
52
+ return _jsx("div", { children: "Test" });
53
+ };
54
+ render(_jsx(TestComponent, {}));
55
+ expect(PubSub.subscribe).toHaveBeenCalledTimes(1);
56
+ expect(PubSub.subscribe).toHaveBeenCalledWith('test-event', handler);
57
+ });
58
+ test('unsubscribes from event on unmount', () => {
59
+ const handler = vi.fn();
60
+ const TestComponent = () => {
61
+ usePubSub('test-event', handler);
62
+ return _jsx("div", { children: "Test" });
63
+ };
64
+ const { unmount } = render(_jsx(TestComponent, {}));
65
+ expect(PubSub.subscribe).toHaveBeenCalledTimes(1);
66
+ unmount();
67
+ expect(PubSub.unsubscribe).toHaveBeenCalledWith('test-event', expect.any(String));
68
+ });
69
+ test('does not resubscribe on re-render', () => {
70
+ const handler = vi.fn();
71
+ const TestComponent = ({ count }) => {
72
+ usePubSub('test-event', handler);
73
+ return (_jsxs("div", { children: ["Test", count] }));
74
+ };
75
+ const { rerender } = render(_jsx(TestComponent, { count: 1 }));
76
+ expect(PubSub.subscribe).toHaveBeenCalledTimes(1);
77
+ rerender(_jsx(TestComponent, { count: 2 }));
78
+ expect(PubSub.subscribe).toHaveBeenCalledTimes(1);
79
+ });
80
+ });
81
+ //# sourceMappingURL=usePubSub.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePubSub.test.js","sourceRoot":"","sources":["../../../src/utils/hooks/usePubSub.test.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arbor-education/design-system.components",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "The component library for the design system (the baby)",
5
5
  "main": "dist/index.js",
6
6
  "repository": {
@@ -78,6 +78,7 @@
78
78
  "tsc-watch-command": "tsc-alias && yalc push --private --sig",
79
79
  "watch": "sass --watch src/index.scss dist/index.css & tsc-watch --onSuccess \"yarn tsc-watch-command\"",
80
80
  "test": "vitest",
81
+ "test:coverage": "vitest run --coverage",
81
82
  "create-component": "./bin/createComponent.sh",
82
83
  "prepare": "husky",
83
84
  "prepublishOnly": "yarn build",
@@ -2,11 +2,14 @@ import { describe, expect, test } from 'vitest';
2
2
  import { render, screen } from '@testing-library/react';
3
3
  import { Icon } from './Icon';
4
4
  import '@testing-library/jest-dom/vitest';
5
+ import { allowedIcons, type IconName } from './allowedIcons';
5
6
 
6
7
  describe('Icon', () => {
7
- test('Icon renders', () => {
8
- render(<Icon name="archive" />);
9
- expect(screen.getByRole('img', { hidden: true })).toBeInTheDocument();
8
+ Object.keys(allowedIcons).forEach((icon) => {
9
+ test(`Icon ${icon} renders`, () => {
10
+ render(<Icon name={icon as IconName} />);
11
+ expect(screen.getByRole('img', { hidden: true })).toBeInTheDocument();
12
+ });
10
13
  });
11
14
 
12
15
  test('Screen reader text', () => {
@@ -0,0 +1,59 @@
1
+ import { describe, expect, test, vi, beforeEach } from 'vitest';
2
+ import { render } from '@testing-library/react';
3
+ import { useComponentDidMount } from './useComponentDidMount';
4
+
5
+ describe('useComponentDidMount', () => {
6
+ beforeEach(() => {
7
+ vi.clearAllMocks();
8
+ });
9
+
10
+ test('calls callback on mount', () => {
11
+ const callback = vi.fn();
12
+
13
+ const TestComponent = () => {
14
+ useComponentDidMount(callback);
15
+ return <div>Test</div>;
16
+ };
17
+
18
+ render(<TestComponent />);
19
+
20
+ expect(callback).toHaveBeenCalledTimes(1);
21
+ });
22
+
23
+ test('does not call callback on re-render', () => {
24
+ const callback = vi.fn();
25
+
26
+ const TestComponent = ({ count }: { count: number }) => {
27
+ useComponentDidMount(callback);
28
+ return (
29
+ <div>
30
+ Test
31
+ {count}
32
+ </div>
33
+ );
34
+ };
35
+
36
+ const { rerender } = render(<TestComponent count={1} />);
37
+ expect(callback).toHaveBeenCalledTimes(1);
38
+
39
+ rerender(<TestComponent count={2} />);
40
+ expect(callback).toHaveBeenCalledTimes(1);
41
+ });
42
+
43
+ test('calls cleanup function on unmount', () => {
44
+ const cleanup = vi.fn();
45
+ const callback = vi.fn(() => cleanup);
46
+
47
+ const TestComponent = () => {
48
+ useComponentDidMount(callback);
49
+ return <div>Test</div>;
50
+ };
51
+
52
+ const { unmount } = render(<TestComponent />);
53
+ expect(callback).toHaveBeenCalledTimes(1);
54
+ expect(cleanup).not.toHaveBeenCalled();
55
+
56
+ unmount();
57
+ expect(cleanup).toHaveBeenCalledTimes(1);
58
+ });
59
+ });
@@ -0,0 +1,79 @@
1
+ import { describe, expect, test, vi } from 'vitest';
2
+ import { render } from '@testing-library/react';
3
+ import { useGridApi } from './useGridApi';
4
+ import { GridApiContext } from 'Components/table/GridApiContext';
5
+ import type { GridApi } from 'ag-grid-community';
6
+
7
+ describe('useGridApi', () => {
8
+ test('returns null gridApi and false isGridApiReady when context is null', () => {
9
+ let result: { gridApi: GridApi | null; isGridApiReady: boolean } = { gridApi: null, isGridApiReady: false };
10
+
11
+ const TestComponent = () => {
12
+ result = useGridApi();
13
+ return <div>Test</div>;
14
+ };
15
+
16
+ render(
17
+ <GridApiContext.Provider value={null}>
18
+ <TestComponent />
19
+ </GridApiContext.Provider>,
20
+ );
21
+
22
+ expect(result).not.toBeNull();
23
+ expect(result?.gridApi).toBeNull();
24
+ expect(result?.isGridApiReady).toBe(false);
25
+ });
26
+
27
+ test('returns gridApi and true isGridApiReady when context provides gridApi', () => {
28
+ const mockGridApi = {
29
+ getDisplayedRowCount: vi.fn(),
30
+ } as unknown as GridApi;
31
+
32
+ let result: { gridApi: GridApi | null; isGridApiReady: boolean } = { gridApi: null, isGridApiReady: false };
33
+
34
+ const TestComponent = () => {
35
+ result = useGridApi();
36
+ return <div>Test</div>;
37
+ };
38
+
39
+ render(
40
+ <GridApiContext.Provider value={mockGridApi}>
41
+ <TestComponent />
42
+ </GridApiContext.Provider>,
43
+ );
44
+
45
+ expect(result).not.toBeNull();
46
+ expect(result?.gridApi).toBe(mockGridApi);
47
+ expect(result?.isGridApiReady).toBe(true);
48
+ });
49
+
50
+ test('updates isGridApiReady when gridApi changes from null to provided', () => {
51
+ const mockGridApi = {
52
+ getDisplayedRowCount: vi.fn(),
53
+ } as unknown as GridApi;
54
+
55
+ let result: { gridApi: GridApi | null; isGridApiReady: boolean } = { gridApi: null, isGridApiReady: false };
56
+
57
+ const TestComponent = () => {
58
+ result = useGridApi();
59
+ return <div>Test</div>;
60
+ };
61
+
62
+ const { rerender } = render(
63
+ <GridApiContext.Provider value={null}>
64
+ <TestComponent />
65
+ </GridApiContext.Provider>,
66
+ );
67
+
68
+ expect(result?.isGridApiReady).toBe(false);
69
+
70
+ rerender(
71
+ <GridApiContext.Provider value={mockGridApi}>
72
+ <TestComponent />
73
+ </GridApiContext.Provider>,
74
+ );
75
+
76
+ expect(result?.isGridApiReady).toBe(true);
77
+ expect(result?.gridApi).toBe(mockGridApi);
78
+ });
79
+ });
@@ -0,0 +1,63 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { render } from '@testing-library/react';
3
+ import { useIsMounted } from './useIsMounted';
4
+
5
+ describe('useIsMounted', () => {
6
+ test('returns a ref with current value true when component is mounted', () => {
7
+ let mountedRef: ReturnType<typeof useIsMounted> | null = null;
8
+
9
+ const TestComponent = () => {
10
+ mountedRef = useIsMounted();
11
+ return <div>Test</div>;
12
+ };
13
+
14
+ render(<TestComponent />);
15
+
16
+ expect(mountedRef).not.toBeNull();
17
+ expect(mountedRef!.current).toBe(true);
18
+ });
19
+
20
+ test('returns the same ref instance across re-renders', () => {
21
+ let mountedRef1: ReturnType<typeof useIsMounted> | null = null;
22
+ let mountedRef2: ReturnType<typeof useIsMounted> | null = null;
23
+
24
+ const TestComponent = ({ count }: { count: number }) => {
25
+ const ref = useIsMounted();
26
+ if (count === 1) {
27
+ mountedRef1 = ref;
28
+ }
29
+ else {
30
+ mountedRef2 = ref;
31
+ }
32
+ return (
33
+ <div>
34
+ Test
35
+ {count}
36
+ </div>
37
+ );
38
+ };
39
+
40
+ const { rerender } = render(<TestComponent count={1} />);
41
+ rerender(<TestComponent count={2} />);
42
+
43
+ expect(mountedRef1).toBe(mountedRef2);
44
+ expect(mountedRef1!.current).toBe(true);
45
+ });
46
+
47
+ test('sets current to false when component unmounts', () => {
48
+ let mountedRef: ReturnType<typeof useIsMounted> | null = null;
49
+
50
+ const TestComponent = () => {
51
+ mountedRef = useIsMounted();
52
+ return <div>Test</div>;
53
+ };
54
+
55
+ const { unmount } = render(<TestComponent />);
56
+
57
+ expect(mountedRef!.current).toBe(true);
58
+
59
+ unmount();
60
+
61
+ expect(mountedRef!.current).toBe(false);
62
+ });
63
+ });
@@ -0,0 +1,80 @@
1
+ import { describe, expect, test, vi, beforeEach } from 'vitest';
2
+ import { render } from '@testing-library/react';
3
+ import { useMemoGenerateUuid } from './useMemoGenerateUuid';
4
+ import { generateUuid } from '../generateUuid';
5
+
6
+ vi.mock('../generateUuid', () => ({
7
+ generateUuid: vi.fn((prefix?: string) => {
8
+ const uuid = '123e4567-e89b-12d3-a456-426614174000';
9
+ return prefix ? `${prefix}-${uuid}` : uuid;
10
+ }),
11
+ }));
12
+
13
+ describe('useMemoGenerateUuid', () => {
14
+ beforeEach(() => {
15
+ vi.clearAllMocks();
16
+ });
17
+
18
+ test('generates a UUID without prefix', () => {
19
+ let uuid: string | null = null;
20
+
21
+ const TestComponent = () => {
22
+ uuid = useMemoGenerateUuid();
23
+ return <div>Test</div>;
24
+ };
25
+
26
+ render(<TestComponent />);
27
+
28
+ expect(uuid).toBe('123e4567-e89b-12d3-a456-426614174000');
29
+ expect(generateUuid).toHaveBeenCalledWith(undefined);
30
+ });
31
+
32
+ test('generates a UUID with prefix', () => {
33
+ let uuid: string | null = null;
34
+
35
+ const TestComponent = () => {
36
+ uuid = useMemoGenerateUuid({ prefix: 'test' });
37
+ return <div>Test</div>;
38
+ };
39
+
40
+ render(<TestComponent />);
41
+
42
+ expect(uuid).toBe('test-123e4567-e89b-12d3-a456-426614174000');
43
+ expect(generateUuid).toHaveBeenCalledWith('test');
44
+ });
45
+
46
+ test('does not generate a new UUID when the dependencies do not change', () => {
47
+ const TestComponent = ({ count }: { count: number }) => {
48
+ const uuid = useMemoGenerateUuid();
49
+ return (
50
+ <div>
51
+ Test
52
+ {count}
53
+ {uuid}
54
+ </div>
55
+ );
56
+ };
57
+
58
+ const { rerender } = render(<TestComponent count={1} />);
59
+ rerender(<TestComponent count={2} />);
60
+ expect(generateUuid).toHaveBeenCalledTimes(1);
61
+ });
62
+
63
+ test('generates a new UUID when the dependencies change', () => {
64
+ const TestComponent = ({ dep1, dep2 }: { dep1: number; dep2: string }) => {
65
+ const uuid = useMemoGenerateUuid({ deps: [dep1, dep2] });
66
+
67
+ return (
68
+ <div>
69
+ Test
70
+ {uuid}
71
+ </div>
72
+ );
73
+ };
74
+
75
+ const { rerender } = render(<TestComponent dep1={1} dep2="a" />);
76
+ rerender(<TestComponent dep1={2} dep2="b" />);
77
+
78
+ expect(generateUuid).toHaveBeenCalledTimes(2);
79
+ });
80
+ });
@@ -6,7 +6,7 @@ type Args = {
6
6
  prefix?: string;
7
7
  };
8
8
 
9
- export const useMemoGenerateUuid = ({ deps = [], prefix }: Args) => {
9
+ export const useMemoGenerateUuid = ({ deps = [], prefix }: Args = {}) => {
10
10
  return useMemo(() => {
11
11
  return generateUuid(prefix);
12
12
  }, deps);
@@ -0,0 +1,100 @@
1
+ import { describe, expect, test, vi, afterEach } from 'vitest';
2
+ import { render } from '@testing-library/react';
3
+ import { usePubSub } from './usePubSub';
4
+ import PubSub from 'Utils/PubSub';
5
+ import { generateUuid } from 'Utils/generateUuid';
6
+
7
+ const mockSubscriptions: Record<string, Record<string, (...args: unknown[]) => void>> = {};
8
+ vi.mock('Utils/PubSub', () => {
9
+ return {
10
+ default: {
11
+ subscribe: vi.fn((eventName: string, handler: (...args: unknown[]) => void) => {
12
+ const subscriptionId = generateUuid('pubsub-subscription');
13
+ if (!mockSubscriptions[eventName]) {
14
+ mockSubscriptions[eventName] = {};
15
+ }
16
+ mockSubscriptions[eventName][subscriptionId] = handler;
17
+ return subscriptionId;
18
+ }),
19
+ unsubscribe: vi.fn((eventName: string, subscriptionId: string) => {
20
+ if (mockSubscriptions[eventName]) {
21
+ delete mockSubscriptions[eventName][subscriptionId];
22
+ }
23
+ }),
24
+ publish: vi.fn((eventName: string, data?: unknown) => {
25
+ if (mockSubscriptions[eventName]) {
26
+ Object.values(mockSubscriptions[eventName]).forEach((handler) => {
27
+ handler(data);
28
+ });
29
+ }
30
+ }),
31
+ // Helper to clear subscriptions for testing
32
+ _clearSubscriptions: () => {
33
+ Object.keys(mockSubscriptions).forEach((key) => {
34
+ delete mockSubscriptions[key];
35
+ });
36
+ },
37
+ },
38
+ };
39
+ });
40
+
41
+ describe('usePubSub', () => {
42
+ afterEach(() => {
43
+ // @ts-expect-error - Accessing private method for testing
44
+ PubSub._clearSubscriptions?.();
45
+ vi.clearAllMocks();
46
+ vi.resetAllMocks();
47
+ vi.restoreAllMocks();
48
+ });
49
+
50
+ test('subscribes to event on mount', () => {
51
+ const handler = vi.fn();
52
+
53
+ const TestComponent = () => {
54
+ usePubSub('test-event', handler);
55
+ return <div>Test</div>;
56
+ };
57
+
58
+ render(<TestComponent />);
59
+
60
+ expect(PubSub.subscribe).toHaveBeenCalledTimes(1);
61
+ expect(PubSub.subscribe).toHaveBeenCalledWith('test-event', handler);
62
+ });
63
+
64
+ test('unsubscribes from event on unmount', () => {
65
+ const handler = vi.fn();
66
+
67
+ const TestComponent = () => {
68
+ usePubSub('test-event', handler);
69
+ return <div>Test</div>;
70
+ };
71
+
72
+ const { unmount } = render(<TestComponent />);
73
+
74
+ expect(PubSub.subscribe).toHaveBeenCalledTimes(1);
75
+
76
+ unmount();
77
+
78
+ expect(PubSub.unsubscribe).toHaveBeenCalledWith('test-event', expect.any(String));
79
+ });
80
+
81
+ test('does not resubscribe on re-render', () => {
82
+ const handler = vi.fn();
83
+
84
+ const TestComponent = ({ count }: { count: number }) => {
85
+ usePubSub('test-event', handler);
86
+ return (
87
+ <div>
88
+ Test
89
+ {count}
90
+ </div>
91
+ );
92
+ };
93
+
94
+ const { rerender } = render(<TestComponent count={1} />);
95
+ expect(PubSub.subscribe).toHaveBeenCalledTimes(1);
96
+
97
+ rerender(<TestComponent count={2} />);
98
+ expect(PubSub.subscribe).toHaveBeenCalledTimes(1);
99
+ });
100
+ });
package/vitest.config.ts CHANGED
@@ -8,6 +8,15 @@ export default defineConfig({
8
8
  environment: 'jsdom',
9
9
  globals: true,
10
10
  setupFiles: ['./setupTestRuntime.ts'],
11
+ coverage: {
12
+ reporter: ['lcov'],
13
+ include: ['src/**/*.{ts,tsx}'],
14
+ exclude: [
15
+ 'src/**/*.mdx',
16
+ 'src/**/*.{stories,story,test}.{ts,tsx}',
17
+ 'src/**/types.ts',
18
+ ],
19
+ },
11
20
  },
12
21
  resolve: {
13
22
  alias: {