@pyreon/rocketstyle 0.24.4 → 0.24.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.
Files changed (60) hide show
  1. package/package.json +8 -10
  2. package/src/__tests__/attrs-overloads.test.ts +0 -97
  3. package/src/__tests__/attrs.test.ts +0 -190
  4. package/src/__tests__/cache-key-boolean-collision.test.ts +0 -54
  5. package/src/__tests__/chaining.test.ts +0 -86
  6. package/src/__tests__/collection.test.ts +0 -35
  7. package/src/__tests__/compose.test.ts +0 -36
  8. package/src/__tests__/context.test.ts +0 -200
  9. package/src/__tests__/createLocalProvider.test.ts +0 -280
  10. package/src/__tests__/dimensions.test.ts +0 -183
  11. package/src/__tests__/e2e-styler.test.ts +0 -299
  12. package/src/__tests__/hooks.test.ts +0 -178
  13. package/src/__tests__/isRocketComponent.test.ts +0 -48
  14. package/src/__tests__/memo-cap.test.ts +0 -174
  15. package/src/__tests__/minimal-theme.test.ts +0 -62
  16. package/src/__tests__/misc.test.ts +0 -204
  17. package/src/__tests__/native-marker.test.ts +0 -9
  18. package/src/__tests__/providerConsumer.test.ts +0 -183
  19. package/src/__tests__/reactive-props-preservation.test.ts +0 -195
  20. package/src/__tests__/rocketstyle.browser.test.tsx +0 -481
  21. package/src/__tests__/rocketstyleIntegration.test.ts +0 -711
  22. package/src/__tests__/theme-integration.test.tsx +0 -254
  23. package/src/__tests__/themeUtils.test.ts +0 -463
  24. package/src/cache/LocalThemeManager.ts +0 -14
  25. package/src/cache/index.ts +0 -3
  26. package/src/constants/booleanTags.ts +0 -32
  27. package/src/constants/defaultDimensions.ts +0 -23
  28. package/src/constants/index.ts +0 -59
  29. package/src/context/context.ts +0 -70
  30. package/src/context/createLocalProvider.ts +0 -97
  31. package/src/context/localContext.ts +0 -37
  32. package/src/env.d.ts +0 -6
  33. package/src/hoc/index.ts +0 -3
  34. package/src/hoc/rocketstyleAttrsHoc.ts +0 -76
  35. package/src/hooks/index.ts +0 -4
  36. package/src/hooks/usePseudoState.ts +0 -79
  37. package/src/hooks/useTheme.ts +0 -48
  38. package/src/index.ts +0 -95
  39. package/src/init.ts +0 -93
  40. package/src/isRocketComponent.ts +0 -16
  41. package/src/rocketstyle.ts +0 -640
  42. package/src/types/attrs.ts +0 -23
  43. package/src/types/config.ts +0 -48
  44. package/src/types/configuration.ts +0 -69
  45. package/src/types/dimensions.ts +0 -109
  46. package/src/types/hoc.ts +0 -5
  47. package/src/types/pseudo.ts +0 -19
  48. package/src/types/rocketComponent.ts +0 -24
  49. package/src/types/rocketstyle.ts +0 -220
  50. package/src/types/styles.ts +0 -61
  51. package/src/types/theme.ts +0 -18
  52. package/src/types/utils.ts +0 -98
  53. package/src/utils/attrs.ts +0 -181
  54. package/src/utils/chaining.ts +0 -58
  55. package/src/utils/collection.ts +0 -9
  56. package/src/utils/compose.ts +0 -11
  57. package/src/utils/dimensions.ts +0 -126
  58. package/src/utils/statics.ts +0 -44
  59. package/src/utils/styles.ts +0 -18
  60. package/src/utils/theme.ts +0 -211
@@ -1,200 +0,0 @@
1
- import type { VNodeChild } from '@pyreon/core'
2
- import { h, useContext } from '@pyreon/core'
3
- import { Provider as CoreProvider } from '@pyreon/ui-core'
4
- import Provider from '../context/context'
5
-
6
- // Mock @pyreon/core useContext to return controlled values
7
- vi.mock('@pyreon/core', async (importOriginal) => {
8
- const original = await importOriginal<typeof import('@pyreon/core')>()
9
- return {
10
- ...original,
11
- useContext: vi.fn(() => (() => ({}))),
12
- }
13
- })
14
-
15
- // Mock @pyreon/ui-core Provider and context
16
- vi.mock('@pyreon/ui-core', async (importOriginal) => {
17
- const original = await importOriginal<typeof import('@pyreon/ui-core')>()
18
- return {
19
- ...original,
20
- Provider: vi.fn(((props: Record<string, unknown>) => ({
21
- type: 'div',
22
- props: { ...props, 'data-provider': 'core' },
23
- children: props.children,
24
- key: null,
25
- })) as any),
26
- context: original.context,
27
- }
28
- })
29
-
30
- const mockedUseContext = vi.mocked(useContext)
31
- const mockedCoreProvider = vi.mocked(CoreProvider)
32
-
33
- beforeEach(() => {
34
- vi.clearAllMocks()
35
- // Default: empty context
36
- mockedUseContext.mockReturnValue((() => ({})) as any)
37
- mockedCoreProvider.mockImplementation(((props: Record<string, unknown>) => ({
38
- type: 'div',
39
- props: { ...props, 'data-provider': 'core' },
40
- children: props.children as VNodeChild,
41
- key: null,
42
- })) as any)
43
- })
44
-
45
- describe('Provider (context)', () => {
46
- it('uses MODE_DEFAULT (light) when no mode is provided', () => {
47
- mockedUseContext.mockReturnValue((() => ({})) as any)
48
-
49
- const children = h('span', null, 'Hello')
50
- Provider({ children })
51
-
52
- expect(mockedCoreProvider).toHaveBeenCalledTimes(1)
53
- const callArgs = mockedCoreProvider.mock.calls[0]?.[0] as Record<string, unknown>
54
- expect(callArgs.mode).toBe('light')
55
- expect(callArgs.isLight).toBe(true)
56
- expect(callArgs.isDark).toBe(false)
57
- })
58
-
59
- it('passes mode directly when inversed is false', () => {
60
- mockedUseContext.mockReturnValue((() => ({ mode: 'dark' })) as any)
61
-
62
- const children = h('span', null, 'Hello')
63
- Provider({ children, mode: 'dark', inversed: false })
64
-
65
- const callArgs = mockedCoreProvider.mock.calls[0]?.[0] as Record<string, unknown>
66
- expect(callArgs.mode).toBe('dark')
67
- expect(callArgs.isDark).toBe(true)
68
- expect(callArgs.isLight).toBe(false)
69
- })
70
-
71
- it('passes mode directly when inversed is undefined', () => {
72
- const children = h('span', null, 'Hello')
73
- Provider({ children, mode: 'dark' })
74
-
75
- const callArgs = mockedCoreProvider.mock.calls[0]?.[0] as Record<string, unknown>
76
- expect(callArgs.mode).toBe('dark')
77
- expect(callArgs.isDark).toBe(true)
78
- expect(callArgs.isLight).toBe(false)
79
- })
80
-
81
- it('inverts light to dark when inversed is true', () => {
82
- const children = h('span', null, 'Hello')
83
- Provider({ children, mode: 'light', inversed: true })
84
-
85
- const callArgs = mockedCoreProvider.mock.calls[0]?.[0] as Record<string, unknown>
86
- expect(callArgs.mode).toBe('dark')
87
- expect(callArgs.isDark).toBe(true)
88
- expect(callArgs.isLight).toBe(false)
89
- })
90
-
91
- it('inverts dark to light when inversed is true', () => {
92
- const children = h('span', null, 'Hello')
93
- Provider({ children, mode: 'dark', inversed: true })
94
-
95
- const callArgs = mockedCoreProvider.mock.calls[0]?.[0] as Record<string, unknown>
96
- expect(callArgs.mode).toBe('light')
97
- expect(callArgs.isLight).toBe(true)
98
- expect(callArgs.isDark).toBe(false)
99
- })
100
-
101
- it('passes theme to provider when provided', () => {
102
- const theme = { rootSize: 16, breakpoints: { sm: 576 } }
103
- const children = h('span', null, 'Hello')
104
- Provider({ children, theme })
105
-
106
- const callArgs = mockedCoreProvider.mock.calls[0]?.[0] as Record<string, unknown>
107
- expect(callArgs.theme).toEqual(theme)
108
- })
109
-
110
- it('does not pass theme key when theme is undefined', () => {
111
- const children = h('span', null, 'Hello')
112
- Provider({ children })
113
-
114
- const callArgs = mockedCoreProvider.mock.calls[0]?.[0] as Record<string, unknown>
115
- expect('theme' in callArgs).toBe(false)
116
- })
117
-
118
- it('uses custom provider when specified', () => {
119
- const customProvider = vi.fn((props: Record<string, unknown>) => ({
120
- type: 'section',
121
- props,
122
- children: props.children as VNodeChild,
123
- key: null,
124
- }))
125
-
126
- const children = h('span', null, 'Hello')
127
- Provider({ children, provider: customProvider as any })
128
-
129
- expect(customProvider).toHaveBeenCalledTimes(1)
130
- // CoreProvider should NOT have been called
131
- expect(mockedCoreProvider).not.toHaveBeenCalled()
132
- })
133
-
134
- it('defaults to CoreProvider when no provider prop is given', () => {
135
- const children = h('span', null, 'Hello')
136
- Provider({ children })
137
-
138
- expect(mockedCoreProvider).toHaveBeenCalledTimes(1)
139
- })
140
-
141
- it('passes children through to the provider', () => {
142
- const children = { type: 'span', props: {}, children: ['Hello World'], key: null }
143
- Provider({ children })
144
-
145
- const callArgs = mockedCoreProvider.mock.calls[0]?.[0] as Record<string, unknown>
146
- expect(callArgs.children).toBe(children)
147
- })
148
-
149
- it('passes provider reference to the provider call', () => {
150
- const children = h('span', null, 'Hello')
151
- Provider({ children })
152
-
153
- const callArgs = mockedCoreProvider.mock.calls[0]?.[0] as Record<string, unknown>
154
- expect(callArgs.provider).toBe(CoreProvider)
155
- })
156
-
157
- it('returns null when provider returns null', () => {
158
- mockedCoreProvider.mockReturnValue(null as any)
159
-
160
- const children = h('span', null, 'Hello')
161
- const result = Provider({ children })
162
-
163
- expect(result).toBeNull()
164
- })
165
-
166
- it('returns null when provider returns undefined', () => {
167
- mockedCoreProvider.mockReturnValue(undefined as any)
168
-
169
- const children = h('span', null, 'Hello')
170
- const result = Provider({ children })
171
-
172
- expect(result).toBeNull()
173
- })
174
-
175
- it('merges context values with incoming props (props take precedence)', () => {
176
- mockedUseContext.mockReturnValue((() => ({
177
- mode: 'light',
178
- theme: { rootSize: 12 },
179
- })) as any)
180
-
181
- const overrideTheme = { rootSize: 20 }
182
- const children = h('span', null, 'Hello')
183
- Provider({ children, theme: overrideTheme, mode: 'dark' })
184
-
185
- const callArgs = mockedCoreProvider.mock.calls[0]?.[0] as Record<string, unknown>
186
- expect(callArgs.mode).toBe('dark')
187
- expect(callArgs.theme).toEqual(overrideTheme)
188
- })
189
-
190
- it('uses context mode when no mode prop is given', () => {
191
- mockedUseContext.mockReturnValue((() => ({ mode: 'dark' })) as any)
192
-
193
- const children = h('span', null, 'Hello')
194
- Provider({ children })
195
-
196
- const callArgs = mockedCoreProvider.mock.calls[0]?.[0] as Record<string, unknown>
197
- expect(callArgs.mode).toBe('dark')
198
- expect(callArgs.isDark).toBe(true)
199
- })
200
- })
@@ -1,280 +0,0 @@
1
- import { h, provide } from '@pyreon/core'
2
- import createLocalProvider from '../context/createLocalProvider'
3
-
4
- // Mock @pyreon/core provide
5
- vi.mock('@pyreon/core', async (importOriginal) => {
6
- const original = await importOriginal<typeof import('@pyreon/core')>()
7
- return {
8
- ...original,
9
- provide: vi.fn(),
10
- }
11
- })
12
-
13
- const mockedProvide = vi.mocked(provide)
14
-
15
- beforeEach(() => {
16
- vi.clearAllMocks()
17
- })
18
-
19
- /** Simple base component that returns its received props as a VNode for inspection. */
20
- const BaseComponent: any = vi.fn((props: Record<string, unknown>) => ({
21
- type: 'div',
22
- props,
23
- children: props.children,
24
- key: null,
25
- }))
26
-
27
- describe('createLocalProvider', () => {
28
- it('returns a component function', () => {
29
- const HOC = createLocalProvider(BaseComponent)
30
- expect(typeof HOC).toBe('function')
31
- })
32
-
33
- it('calls the wrapped component with forwarded props', () => {
34
- const HOC = createLocalProvider(BaseComponent)
35
-
36
- HOC({ 'data-testid': 'test', title: 'Hello', children: 'Content' } as any)
37
-
38
- expect(BaseComponent).toHaveBeenCalledTimes(1)
39
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
40
- expect(callProps['data-testid']).toBe('test')
41
- expect(callProps.title).toBe('Hello')
42
- expect(callProps.children).toBe('Content')
43
- })
44
-
45
- it('provides local context via provide()', () => {
46
- const HOC = createLocalProvider(BaseComponent)
47
-
48
- HOC({} as any)
49
-
50
- expect(mockedProvide).toHaveBeenCalledTimes(1)
51
- })
52
-
53
- it('initial pseudo state is all false', () => {
54
- const HOC = createLocalProvider(BaseComponent)
55
-
56
- HOC({} as any)
57
-
58
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
59
- const rocketstate = callProps.$rocketstate as Record<string, unknown>
60
- const pseudo = rocketstate?.pseudo as Record<string, boolean>
61
-
62
- expect(pseudo.hover).toBe(false)
63
- expect(pseudo.focus).toBe(false)
64
- expect(pseudo.pressed).toBe(false)
65
- })
66
-
67
- it('injects mouse and focus event handlers', () => {
68
- const HOC = createLocalProvider(BaseComponent)
69
-
70
- HOC({} as any)
71
-
72
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
73
- expect(typeof callProps.onMouseEnter).toBe('function')
74
- expect(typeof callProps.onMouseLeave).toBe('function')
75
- expect(typeof callProps.onMouseDown).toBe('function')
76
- expect(typeof callProps.onMouseUp).toBe('function')
77
- expect(typeof callProps.onFocus).toBe('function')
78
- expect(typeof callProps.onBlur).toBe('function')
79
- })
80
-
81
- it('forwards original onMouseEnter handler', () => {
82
- const HOC = createLocalProvider(BaseComponent)
83
- const originalHandler = vi.fn()
84
- const mockEvent = new MouseEvent('mouseenter')
85
-
86
- HOC({ onMouseEnter: originalHandler } as any)
87
-
88
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
89
- ;(callProps.onMouseEnter as (e: MouseEvent) => void)(mockEvent)
90
-
91
- expect(originalHandler).toHaveBeenCalledWith(mockEvent)
92
- })
93
-
94
- it('forwards original onMouseLeave handler', () => {
95
- const HOC = createLocalProvider(BaseComponent)
96
- const originalHandler = vi.fn()
97
- const mockEvent = new MouseEvent('mouseleave')
98
-
99
- HOC({ onMouseLeave: originalHandler } as any)
100
-
101
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
102
- ;(callProps.onMouseLeave as (e: MouseEvent) => void)(mockEvent)
103
-
104
- expect(originalHandler).toHaveBeenCalledWith(mockEvent)
105
- })
106
-
107
- it('forwards original onMouseDown handler', () => {
108
- const HOC = createLocalProvider(BaseComponent)
109
- const originalHandler = vi.fn()
110
- const mockEvent = new MouseEvent('mousedown')
111
-
112
- HOC({ onMouseDown: originalHandler } as any)
113
-
114
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
115
- ;(callProps.onMouseDown as (e: MouseEvent) => void)(mockEvent)
116
-
117
- expect(originalHandler).toHaveBeenCalledWith(mockEvent)
118
- })
119
-
120
- it('forwards original onMouseUp handler', () => {
121
- const HOC = createLocalProvider(BaseComponent)
122
- const originalHandler = vi.fn()
123
- const mockEvent = new MouseEvent('mouseup')
124
-
125
- HOC({ onMouseUp: originalHandler } as any)
126
-
127
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
128
- ;(callProps.onMouseUp as (e: MouseEvent) => void)(mockEvent)
129
-
130
- expect(originalHandler).toHaveBeenCalledWith(mockEvent)
131
- })
132
-
133
- it('forwards original onFocus handler', () => {
134
- const HOC = createLocalProvider(BaseComponent)
135
- const originalHandler = vi.fn()
136
- const mockEvent = new FocusEvent('focus')
137
-
138
- HOC({ onFocus: originalHandler } as any)
139
-
140
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
141
- ;(callProps.onFocus as (e: FocusEvent) => void)(mockEvent)
142
-
143
- expect(originalHandler).toHaveBeenCalledWith(mockEvent)
144
- })
145
-
146
- it('forwards original onBlur handler', () => {
147
- const HOC = createLocalProvider(BaseComponent)
148
- const originalHandler = vi.fn()
149
- const mockEvent = new FocusEvent('blur')
150
-
151
- HOC({ onBlur: originalHandler } as any)
152
-
153
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
154
- ;(callProps.onBlur as (e: FocusEvent) => void)(mockEvent)
155
-
156
- expect(originalHandler).toHaveBeenCalledWith(mockEvent)
157
- })
158
-
159
- it('does not forward event handlers that were not provided', () => {
160
- const HOC = createLocalProvider(BaseComponent)
161
-
162
- HOC({} as any)
163
-
164
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
165
- // The HOC event handlers should not throw when no original handler exists
166
- expect(() => {
167
- ;(callProps.onMouseEnter as (e: MouseEvent) => void)(new MouseEvent('mouseenter'))
168
- ;(callProps.onMouseLeave as (e: MouseEvent) => void)(new MouseEvent('mouseleave'))
169
- ;(callProps.onMouseDown as (e: MouseEvent) => void)(new MouseEvent('mousedown'))
170
- ;(callProps.onMouseUp as (e: MouseEvent) => void)(new MouseEvent('mouseup'))
171
- ;(callProps.onFocus as (e: FocusEvent) => void)(new FocusEvent('focus'))
172
- ;(callProps.onBlur as (e: FocusEvent) => void)(new FocusEvent('blur'))
173
- }).not.toThrow()
174
- })
175
-
176
- it('merges existing $rocketstate with pseudo state', () => {
177
- const HOC = createLocalProvider(BaseComponent)
178
-
179
- HOC({
180
- $rocketstate: { someExisting: 'value', pseudo: { disabled: true } },
181
- } as any)
182
-
183
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
184
- const rocketstate = callProps.$rocketstate as Record<string, unknown>
185
-
186
- expect(rocketstate.someExisting).toBe('value')
187
- const pseudo = rocketstate.pseudo as Record<string, unknown>
188
- expect(pseudo.disabled).toBe(true)
189
- expect(pseudo.hover).toBe(false)
190
- expect(pseudo.focus).toBe(false)
191
- expect(pseudo.pressed).toBe(false)
192
- })
193
-
194
- it('provides updated state to local context', () => {
195
- const HOC = createLocalProvider(BaseComponent)
196
-
197
- HOC({} as any)
198
-
199
- expect(mockedProvide).toHaveBeenCalledTimes(1)
200
- const [, providedValue] = mockedProvide.mock.calls[0] as [unknown, Record<string, unknown>]
201
- const pseudo = providedValue.pseudo as Record<string, boolean>
202
- expect(pseudo.hover).toBe(false)
203
- expect(pseudo.focus).toBe(false)
204
- expect(pseudo.pressed).toBe(false)
205
- })
206
-
207
- it('does not pass event handler props to wrapped component as original handler names', () => {
208
- const HOC = createLocalProvider(BaseComponent)
209
- const originalMouseEnter = vi.fn()
210
-
211
- HOC({ onMouseEnter: originalMouseEnter, customProp: 'keep' } as any)
212
-
213
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
214
- // The wrapped component should receive the HOC event handlers, not the original ones
215
- expect(callProps.customProp).toBe('keep')
216
- // The onMouseEnter on the component should be the HOC wrapper, not the original
217
- expect(callProps.onMouseEnter).not.toBe(originalMouseEnter)
218
- })
219
-
220
- it('strips $rocketstate from forwarded props and passes updated version', () => {
221
- const HOC = createLocalProvider(BaseComponent)
222
- const originalState = { existing: true }
223
-
224
- HOC({ $rocketstate: originalState } as any)
225
-
226
- const callProps = BaseComponent.mock.calls[0]?.[0] as Record<string, unknown>
227
- const rocketstate = callProps.$rocketstate as Record<string, unknown>
228
- // Should have merged pseudo state
229
- expect(rocketstate.pseudo).toBeDefined()
230
- // Original state is preserved
231
- expect(rocketstate.existing).toBe(true)
232
- })
233
-
234
- it('returns the result of the wrapped component', () => {
235
- const expectedResult = {
236
- type: 'div',
237
- props: { 'data-result': 'yes' },
238
- children: ['Result'],
239
- key: null,
240
- }
241
- const MockComponent = vi.fn(() => expectedResult)
242
- const HOC = createLocalProvider(MockComponent as any)
243
-
244
- const result = HOC({} as any)
245
-
246
- expect(result).toBe(expectedResult)
247
- })
248
- })
249
-
250
- // ─── createLocalProvider — real h() round-trip ──────────────────────
251
- //
252
- // The tests above use a `BaseComponent` mock that returns
253
- // `{ type, props, children, key }` literals and assert against the
254
- // shape. This block re-runs key contracts with a base component
255
- // that returns real h() output — same divergence guard as the
256
- // attrs / connector-document parallels.
257
-
258
- describe('createLocalProvider — real h() round-trip', () => {
259
- it('passes children through a real h() base component', () => {
260
- const BaseComponentH = vi.fn((props: Record<string, unknown>) =>
261
- h('div', { 'data-real-h': 'yes', ...props }, props.children as never),
262
- )
263
- const HOC = createLocalProvider(BaseComponentH as any)
264
- const result = HOC({ children: 'hello' } as any) as any
265
- expect(BaseComponentH).toHaveBeenCalled()
266
- expect(result.type).toBe('div')
267
- expect(result.props['data-real-h']).toBe('yes')
268
- })
269
-
270
- it('forwards arbitrary props through real h() output', () => {
271
- const BaseComponentH = vi.fn((props: Record<string, unknown>) =>
272
- h('button', props, props.label as never),
273
- )
274
- const HOC = createLocalProvider(BaseComponentH as any)
275
- const result = HOC({ label: 'Click', 'data-id': '42' } as any) as any
276
- expect(result.type).toBe('button')
277
- expect(result.props.label).toBe('Click')
278
- expect(result.props['data-id']).toBe('42')
279
- })
280
- })
@@ -1,183 +0,0 @@
1
- import {
2
- getDimensionsMap,
3
- getDimensionsValues,
4
- getKeys,
5
- getMultipleDimensions,
6
- getTransformDimensions,
7
- getValues,
8
- isMultiKey,
9
- isValidKey,
10
- } from '../utils/dimensions'
11
-
12
- describe('isValidKey', () => {
13
- it('returns true for truthy values', () => {
14
- expect(isValidKey('a')).toBe(true)
15
- expect(isValidKey(1)).toBe(true)
16
- expect(isValidKey(true)).toBe(true)
17
- expect(isValidKey(0)).toBe(true)
18
- expect(isValidKey('')).toBe(true)
19
- })
20
-
21
- it('returns false for undefined, null, false', () => {
22
- expect(isValidKey(undefined)).toBe(false)
23
- expect(isValidKey(null)).toBe(false)
24
- expect(isValidKey(false)).toBe(false)
25
- })
26
- })
27
-
28
- describe('isMultiKey', () => {
29
- it('returns [true, propName] for object with propName', () => {
30
- expect(isMultiKey({ propName: 'tags', multi: true })).toEqual([true, 'tags'])
31
- })
32
-
33
- it('returns [false, value] for string', () => {
34
- expect(isMultiKey('variant')).toEqual([false, 'variant'])
35
- })
36
- })
37
-
38
- describe('getKeys', () => {
39
- it('returns object keys', () => {
40
- expect(getKeys({ a: 1, b: 2 })).toEqual(['a', 'b'])
41
- })
42
-
43
- it('returns empty array for empty object', () => {
44
- expect(getKeys({})).toEqual([])
45
- })
46
- })
47
-
48
- describe('getValues', () => {
49
- it('returns object values', () => {
50
- expect(getValues({ a: 1, b: 2 })).toEqual([1, 2])
51
- })
52
- })
53
-
54
- describe('getDimensionsValues', () => {
55
- it('extracts string dimension values', () => {
56
- const dimensions = { size: 'size', variant: 'variant' }
57
- expect(getDimensionsValues(dimensions)).toEqual(['size', 'variant'])
58
- })
59
-
60
- it('extracts propName from object dimensions', () => {
61
- const dimensions = {
62
- size: 'size',
63
- tags: { propName: 'tags', multi: true },
64
- }
65
- expect(getDimensionsValues(dimensions)).toEqual(['size', 'tags'])
66
- })
67
- })
68
-
69
- describe('getMultipleDimensions', () => {
70
- it('identifies multi-key dimensions', () => {
71
- const dimensions = {
72
- size: 'size',
73
- tags: { propName: 'tags', multi: true },
74
- }
75
- expect(getMultipleDimensions(dimensions)).toEqual({ tags: true })
76
- })
77
-
78
- it('returns empty for no multi dimensions', () => {
79
- const dimensions = { size: 'size', variant: 'variant' }
80
- expect(getMultipleDimensions(dimensions)).toEqual({})
81
- })
82
-
83
- it('skips multi=false', () => {
84
- const dimensions = {
85
- tags: { propName: 'tags', multi: false },
86
- }
87
- expect(getMultipleDimensions(dimensions)).toEqual({})
88
- })
89
- })
90
-
91
- describe('getDimensionsMap', () => {
92
- it('builds keysMap and keywords from themes', () => {
93
- const themes = {
94
- size: { small: { fontSize: 12 }, large: { fontSize: 18 } },
95
- }
96
- const result = getDimensionsMap({ themes })
97
- expect(result.keysMap).toEqual({
98
- size: { small: true, large: true },
99
- })
100
- expect(result.keywords.size).toBe(true)
101
- })
102
-
103
- it('adds dimension keys to keywords when useBooleans', () => {
104
- const themes = {
105
- size: { small: { fontSize: 12 }, large: { fontSize: 18 } },
106
- }
107
- const result = getDimensionsMap({ themes, useBooleans: true })
108
- expect(result.keywords.small).toBe(true)
109
- expect(result.keywords.large).toBe(true)
110
- })
111
-
112
- it('skips invalid values (false, null, undefined)', () => {
113
- const themes = {
114
- size: { small: { fontSize: 12 }, disabled: false, hidden: null },
115
- }
116
- const result = getDimensionsMap({ themes })
117
- expect(result.keysMap.size).toEqual({ small: true })
118
- })
119
-
120
- it('returns empty for empty themes', () => {
121
- const result = getDimensionsMap({ themes: {} })
122
- expect(result.keysMap).toEqual({})
123
- expect(result.keywords).toEqual({})
124
- })
125
-
126
- it('includes function values (transform modifiers) as valid keys', () => {
127
- const themes = {
128
- modifier: {
129
- outlined: (theme: any) => ({ color: theme.bg }),
130
- ghost: () => ({ bg: 'transparent' }),
131
- },
132
- }
133
- const result = getDimensionsMap({ themes })
134
- expect(result.keysMap).toEqual({
135
- modifier: { outlined: true, ghost: true },
136
- })
137
- expect(result.keywords.modifier).toBe(true)
138
- })
139
-
140
- it('includes function values as boolean keywords when useBooleans', () => {
141
- const themes = {
142
- modifier: {
143
- outlined: (theme: any) => ({ color: theme.bg }),
144
- },
145
- }
146
- const result = getDimensionsMap({ themes, useBooleans: true })
147
- expect(result.keywords.outlined).toBe(true)
148
- })
149
- })
150
-
151
- describe('getTransformDimensions', () => {
152
- it('identifies transform dimensions', () => {
153
- const dimensions = {
154
- states: 'state',
155
- modifiers: { propName: 'modifier', multi: true, transform: true },
156
- }
157
- expect(getTransformDimensions(dimensions)).toEqual({ modifier: true })
158
- })
159
-
160
- it('returns empty when no transform dimensions exist', () => {
161
- const dimensions = {
162
- states: 'state',
163
- sizes: 'size',
164
- multiple: { propName: 'multiple', multi: true },
165
- }
166
- expect(getTransformDimensions(dimensions)).toEqual({})
167
- })
168
-
169
- it('skips dimensions without transform flag', () => {
170
- const dimensions = {
171
- states: 'state',
172
- tags: { propName: 'tags', multi: true },
173
- }
174
- expect(getTransformDimensions(dimensions)).toEqual({})
175
- })
176
-
177
- it('skips transform=false', () => {
178
- const dimensions = {
179
- modifiers: { propName: 'modifier', multi: true, transform: false },
180
- }
181
- expect(getTransformDimensions(dimensions)).toEqual({})
182
- })
183
- })