@shohojdhara/atomix 0.3.13 → 0.3.15

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 (249) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +2 -0
  3. package/build-tools/EXAMPLES.md +372 -0
  4. package/build-tools/README.md +242 -0
  5. package/build-tools/__tests__/error-handler.test.js +230 -0
  6. package/build-tools/__tests__/index.test.js +141 -0
  7. package/build-tools/__tests__/rollup-plugin.test.js +194 -0
  8. package/build-tools/__tests__/utils.test.js +161 -0
  9. package/build-tools/__tests__/vite-plugin.test.js +129 -0
  10. package/build-tools/__tests__/webpack-loader.test.js +190 -0
  11. package/build-tools/error-handler.js +308 -0
  12. package/build-tools/index.d.ts +43 -0
  13. package/build-tools/index.js +88 -0
  14. package/build-tools/package.json +67 -0
  15. package/build-tools/rollup-plugin.js +236 -0
  16. package/build-tools/types.d.ts +163 -0
  17. package/build-tools/utils.js +203 -0
  18. package/build-tools/vite-plugin.js +161 -0
  19. package/build-tools/webpack-loader.js +123 -0
  20. package/dist/atomix.css +298 -167
  21. package/dist/atomix.css.map +1 -1
  22. package/dist/atomix.min.css +3 -3
  23. package/dist/atomix.min.css.map +1 -1
  24. package/dist/build-tools/EXAMPLES.md +372 -0
  25. package/dist/build-tools/README.md +242 -0
  26. package/dist/build-tools/__tests__/error-handler.test.js +230 -0
  27. package/dist/build-tools/__tests__/index.test.js +141 -0
  28. package/dist/build-tools/__tests__/rollup-plugin.test.js +194 -0
  29. package/dist/build-tools/__tests__/utils.test.js +161 -0
  30. package/dist/build-tools/__tests__/vite-plugin.test.js +129 -0
  31. package/dist/build-tools/__tests__/webpack-loader.test.js +190 -0
  32. package/dist/build-tools/error-handler.js +308 -0
  33. package/dist/build-tools/index.d.ts +43 -0
  34. package/dist/build-tools/index.js +88 -0
  35. package/dist/build-tools/package.json +67 -0
  36. package/dist/build-tools/rollup-plugin.js +236 -0
  37. package/dist/build-tools/types.d.ts +163 -0
  38. package/dist/build-tools/utils.js +203 -0
  39. package/dist/build-tools/vite-plugin.js +161 -0
  40. package/dist/build-tools/webpack-loader.js +123 -0
  41. package/dist/charts.d.ts +2 -2
  42. package/dist/charts.js +87 -58
  43. package/dist/charts.js.map +1 -1
  44. package/dist/core.d.ts +42 -12
  45. package/dist/core.js +175 -135
  46. package/dist/core.js.map +1 -1
  47. package/dist/forms.d.ts +30 -16
  48. package/dist/forms.js +146 -131
  49. package/dist/forms.js.map +1 -1
  50. package/dist/heavy.d.ts +2 -2
  51. package/dist/heavy.js +151 -118
  52. package/dist/heavy.js.map +1 -1
  53. package/dist/index.d.ts +130 -106
  54. package/dist/index.esm.js +1083 -465
  55. package/dist/index.esm.js.map +1 -1
  56. package/dist/index.js +1102 -483
  57. package/dist/index.js.map +1 -1
  58. package/dist/index.min.js +1 -1
  59. package/dist/index.min.js.map +1 -1
  60. package/dist/theme.d.ts +27 -2
  61. package/dist/theme.js +721 -108
  62. package/dist/theme.js.map +1 -1
  63. package/package.json +23 -8
  64. package/scripts/atomix-cli.js +749 -1153
  65. package/scripts/cli/__tests__/README.md +81 -0
  66. package/scripts/cli/__tests__/basic.test.js +115 -0
  67. package/scripts/cli/__tests__/component-generator.test.js +332 -0
  68. package/scripts/cli/__tests__/integration.test.js +327 -0
  69. package/scripts/cli/__tests__/test-setup.js +133 -0
  70. package/scripts/cli/__tests__/token-manager.test.js +251 -0
  71. package/scripts/cli/__tests__/utils.test.js +78 -118
  72. package/scripts/cli/component-generator.js +564 -0
  73. package/scripts/cli/dependency-checker.js +355 -0
  74. package/scripts/cli/documentation-sync.js +542 -0
  75. package/scripts/cli/interactive-init.js +129 -292
  76. package/scripts/cli/mappings.js +211 -0
  77. package/scripts/cli/migration-tools.js +95 -288
  78. package/scripts/cli/template-manager.js +105 -0
  79. package/scripts/cli/templates/README.md +123 -0
  80. package/scripts/cli/templates/common-templates.js +636 -0
  81. package/scripts/cli/templates/composable-templates.js +171 -0
  82. package/scripts/cli/templates/config-templates.js +126 -0
  83. package/scripts/cli/templates/index.js +102 -0
  84. package/scripts/cli/templates/project-templates.js +342 -0
  85. package/scripts/cli/templates/react-templates.js +331 -0
  86. package/scripts/cli/templates/scss-templates.js +155 -0
  87. package/scripts/cli/templates/storybook-templates.js +236 -0
  88. package/scripts/cli/templates/testing-templates.js +224 -0
  89. package/scripts/cli/templates/testing-utils.js +278 -0
  90. package/scripts/cli/templates/token-templates.js +447 -0
  91. package/scripts/cli/templates/types-templates.js +147 -0
  92. package/scripts/cli/templates.js +35 -0
  93. package/scripts/cli/theme-bridge.js +28 -16
  94. package/scripts/cli/token-manager.js +432 -247
  95. package/scripts/cli/utils.js +37 -26
  96. package/src/components/Accordion/Accordion.stories.tsx +369 -870
  97. package/src/components/Accordion/Accordion.test.tsx +57 -0
  98. package/src/components/Accordion/Accordion.tsx +4 -0
  99. package/src/components/AtomixGlass/AtomixGlass.tsx +80 -39
  100. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +103 -81
  101. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +8 -7
  102. package/src/components/AtomixGlass/glass-utils.ts +2 -2
  103. package/src/components/AtomixGlass/shader-utils.ts +5 -0
  104. package/src/components/AtomixGlass/stories/Customization.stories.tsx +131 -0
  105. package/src/components/AtomixGlass/stories/Examples.stories.tsx +2965 -2861
  106. package/src/components/AtomixGlass/stories/Modes.stories.tsx +1 -1
  107. package/src/components/AtomixGlass/stories/Overview.stories.tsx +348 -0
  108. package/src/components/AtomixGlass/stories/Performance.stories.tsx +103 -0
  109. package/src/components/AtomixGlass/stories/Playground.stories.tsx +73 -59
  110. package/src/components/AtomixGlass/stories/{ShaderVariants.stories.tsx → Shaders.stories.tsx} +1 -1
  111. package/src/components/AtomixGlass/stories/shared-components.tsx +90 -190
  112. package/src/components/Avatar/Avatar.stories.tsx +239 -27
  113. package/src/components/Badge/Badge.stories.tsx +132 -373
  114. package/src/components/Badge/Badge.test.tsx +51 -0
  115. package/src/components/Badge/Badge.tsx +20 -1
  116. package/src/components/Block/Block.stories.tsx +26 -17
  117. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +141 -23
  118. package/src/components/Breadcrumb/Breadcrumb.tsx +2 -2
  119. package/src/components/Button/Button.stories.tsx +463 -1126
  120. package/src/components/Button/Button.test.tsx +107 -0
  121. package/src/components/Button/Button.tsx +50 -54
  122. package/src/components/Button/ButtonGroup.stories.tsx +373 -217
  123. package/src/components/Button/README.md +5 -0
  124. package/src/components/Callout/Callout.stories.tsx +299 -644
  125. package/src/components/Callout/Callout.test.tsx +10 -10
  126. package/src/components/Callout/Callout.tsx +7 -7
  127. package/src/components/Callout/README.md +9 -8
  128. package/src/components/Card/Card.stories.tsx +248 -68
  129. package/src/components/Card/Card.tsx +2 -2
  130. package/src/components/Chart/Chart.stories.tsx +156 -14
  131. package/src/components/Chart/Chart.tsx +1 -1
  132. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +151 -69
  133. package/src/components/Countdown/Countdown.stories.tsx +115 -8
  134. package/src/components/DataTable/DataTable.stories.tsx +346 -146
  135. package/src/components/DataTable/DataTable.tsx +14 -12
  136. package/src/components/DatePicker/DatePicker.stories.tsx +325 -1066
  137. package/src/components/Dropdown/Dropdown.stories.tsx +157 -37
  138. package/src/components/EdgePanel/EdgePanel.stories.tsx +230 -21
  139. package/src/components/Footer/Footer.stories.tsx +392 -328
  140. package/src/components/Form/Checkbox.stories.tsx +143 -9
  141. package/src/components/Form/Checkbox.test.tsx +63 -0
  142. package/src/components/Form/Checkbox.tsx +90 -52
  143. package/src/components/Form/Form.stories.tsx +121 -22
  144. package/src/components/Form/FormGroup.stories.tsx +128 -5
  145. package/src/components/Form/Input.stories.tsx +28 -16
  146. package/src/components/Form/Input.test.tsx +59 -0
  147. package/src/components/Form/Input.tsx +97 -95
  148. package/src/components/Form/Radio.stories.tsx +232 -97
  149. package/src/components/Form/Radio.tsx +2 -2
  150. package/src/components/Form/Select.stories.tsx +144 -12
  151. package/src/components/Form/Select.tsx +2 -2
  152. package/src/components/Form/Textarea.stories.tsx +171 -13
  153. package/src/components/Form/Textarea.test.tsx +45 -0
  154. package/src/components/Form/Textarea.tsx +88 -86
  155. package/src/components/Hero/Hero.stories.tsx +333 -32
  156. package/src/components/List/List.stories.tsx +143 -5
  157. package/src/components/Modal/Modal.stories.tsx +185 -46
  158. package/src/components/Navigation/Navbar/Navbar.stories.tsx +5 -5
  159. package/src/components/Navigation/Navbar/Navbar.tsx +1 -1
  160. package/src/components/Navigation/README.md +1 -1
  161. package/src/components/Pagination/Pagination.stories.tsx +5 -2
  162. package/src/components/Pagination/Pagination.tsx +1 -1
  163. package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -10
  164. package/src/components/Popover/Popover.stories.tsx +449 -99
  165. package/src/components/ProductReview/ProductReview.tsx +1 -1
  166. package/src/components/Progress/Progress.stories.tsx +167 -5
  167. package/src/components/Progress/Progress.tsx +46 -46
  168. package/src/components/Rating/Rating.stories.tsx +4 -4
  169. package/src/components/Rating/Rating.tsx +8 -8
  170. package/src/components/River/River.stories.tsx +1 -1
  171. package/src/components/SectionIntro/SectionIntro.stories.tsx +240 -48
  172. package/src/components/Slider/Slider.stories.tsx +63 -63
  173. package/src/components/Spinner/Spinner.stories.tsx +104 -10
  174. package/src/components/Spinner/Spinner.test.tsx +35 -0
  175. package/src/components/Spinner/Spinner.tsx +9 -2
  176. package/src/components/Steps/Steps.stories.tsx +172 -43
  177. package/src/components/Tabs/Tabs.stories.tsx +136 -10
  178. package/src/components/Testimonial/Testimonial.stories.tsx +121 -4
  179. package/src/components/Todo/Todo.stories.tsx +198 -9
  180. package/src/components/Toggle/Toggle.stories.tsx +153 -43
  181. package/src/components/Toggle/Toggle.test.tsx +91 -0
  182. package/src/components/Toggle/Toggle.tsx +44 -27
  183. package/src/components/Tooltip/Tooltip.stories.tsx +194 -104
  184. package/src/components/Tooltip/Tooltip.tsx +1 -1
  185. package/src/components/Upload/Upload.stories.tsx +113 -24
  186. package/src/layouts/Grid/Grid.stories.tsx +49 -49
  187. package/src/layouts/MasonryGrid/MasonryGrid.stories.tsx +2 -2
  188. package/src/lib/README.md +2 -2
  189. package/src/lib/__tests__/theme-tools.test.ts +193 -0
  190. package/src/lib/composables/index.ts +2 -2
  191. package/src/lib/composables/useAccordion.ts +12 -3
  192. package/src/lib/composables/useAtomixGlass.ts +28 -56
  193. package/src/lib/composables/useBreadcrumb.ts +2 -2
  194. package/src/lib/composables/useCallout.ts +7 -7
  195. package/src/lib/composables/useChartExport.ts +2 -7
  196. package/src/lib/composables/useDataTable.ts +46 -29
  197. package/src/lib/composables/useNavbar.ts +1 -1
  198. package/src/lib/constants/components.ts +10 -33
  199. package/src/lib/storybook/InteractiveDemo.tsx +113 -0
  200. package/src/lib/storybook/PreviewContainer.tsx +36 -0
  201. package/src/lib/storybook/VariantsGrid.tsx +21 -0
  202. package/src/lib/storybook/index.ts +3 -0
  203. package/src/lib/theme/core/createThemeObject.ts +9 -5
  204. package/src/lib/theme/devtools/CLI.ts +155 -0
  205. package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +213 -0
  206. package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +566 -0
  207. package/src/lib/theme/devtools/LiveEditor.tsx +2 -1
  208. package/src/lib/theme/devtools/index.ts +3 -0
  209. package/src/lib/theme/errors/errors.ts +8 -0
  210. package/src/lib/theme/runtime/ThemeProvider.tsx +117 -57
  211. package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +305 -0
  212. package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +588 -0
  213. package/src/lib/theme/utils/__tests__/themeValidation.test.ts +264 -0
  214. package/src/lib/theme/utils/index.ts +1 -0
  215. package/src/lib/theme/utils/themeValidation.ts +501 -0
  216. package/src/lib/theme-tools.ts +32 -3
  217. package/src/lib/types/components.ts +82 -27
  218. package/src/lib/utils/__tests__/csv.test.ts +45 -0
  219. package/src/lib/utils/csv.ts +17 -0
  220. package/src/lib/utils/dataTableExport.ts +1 -10
  221. package/src/lib/utils/themeNaming.ts +1 -1
  222. package/src/styles/01-settings/_index.scss +2 -1
  223. package/src/styles/01-settings/_settings.accordion.scss +28 -7
  224. package/src/styles/01-settings/_settings.colors.scss +11 -11
  225. package/src/styles/01-settings/_settings.typography.scss +5 -5
  226. package/src/styles/02-tools/_tools.utility-api.scss +14 -0
  227. package/src/styles/06-components/_components.accordion.scss +56 -14
  228. package/src/styles/06-components/_components.callout.scss +29 -33
  229. package/src/styles/06-components/_components.checkbox.scss +23 -17
  230. package/src/styles/06-components/_index.scss +1 -1
  231. package/src/styles/99-utilities/_index.scss +2 -0
  232. package/src/styles/99-utilities/_utilities.display.scss +14 -3
  233. package/src/styles/99-utilities/_utilities.flex.scss +10 -10
  234. package/src/styles/99-utilities/_utilities.scss +3 -1
  235. package/src/styles/99-utilities/_utilities.text-gradient.scss +45 -0
  236. package/src/styles/99-utilities/_utilities.text.scss +28 -8
  237. package/themes/dark-complementary/README.md +98 -0
  238. package/themes/dark-complementary/index.scss +158 -0
  239. package/themes/default-light/README.md +81 -0
  240. package/themes/default-light/index.scss +154 -0
  241. package/themes/high-contrast/README.md +105 -0
  242. package/themes/high-contrast/index.scss +172 -0
  243. package/themes/test-theme/README.md +38 -0
  244. package/themes/test-theme/index.scss +47 -0
  245. package/scripts/cli/__tests__/cli-commands.test.js +0 -204
  246. package/scripts/cli/__tests__/vitest.config.js +0 -26
  247. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +0 -1438
  248. package/src/lib/composables/useButton.ts +0 -93
  249. package/src/lib/composables/useCheckbox.ts +0 -70
@@ -0,0 +1,230 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { AtomixBuildError, Validator, ErrorHandler } from '../error-handler.js';
3
+
4
+ describe('Atomix Build Error Handler', () => {
5
+ describe('AtomixBuildError', () => {
6
+ it('should create error with proper properties', () => {
7
+ const error = new AtomixBuildError(
8
+ 'Test error message',
9
+ 'TEST_ERROR',
10
+ { detail: 'test' },
11
+ ['Suggestion 1', 'Suggestion 2']
12
+ );
13
+
14
+ expect(error).toBeInstanceOf(Error);
15
+ expect(error.name).toBe('AtomixBuildError');
16
+ expect(error.message).toBe('Test error message');
17
+ expect(error.code).toBe('TEST_ERROR');
18
+ expect(error.details).toEqual({ detail: 'test' });
19
+ expect(error.suggestions).toEqual(['Suggestion 1', 'Suggestion 2']);
20
+ expect(error.timestamp).toBeDefined();
21
+ });
22
+
23
+ it('should format error message correctly', () => {
24
+ const error = new AtomixBuildError(
25
+ 'Simple error',
26
+ 'SIMPLE_ERROR'
27
+ );
28
+
29
+ const formatted = error.toString();
30
+ expect(formatted).toContain('[AtomixBuildError:SIMPLE_ERROR]');
31
+ expect(formatted).toContain('Simple error');
32
+ });
33
+ });
34
+
35
+ describe('Validator', () => {
36
+ describe('validateTheme', () => {
37
+ it('should validate valid theme', () => {
38
+ expect(() => {
39
+ Validator.validateTheme('default', ['default', 'dark']);
40
+ }).not.toThrow();
41
+ });
42
+
43
+ it('should throw error for invalid theme type', () => {
44
+ expect(() => {
45
+ Validator.validateTheme(123);
46
+ }).toThrow(AtomixBuildError);
47
+ });
48
+
49
+ it('should throw error for empty theme', () => {
50
+ expect(() => {
51
+ Validator.validateTheme('');
52
+ }).toThrow(AtomixBuildError);
53
+ });
54
+
55
+ it('should throw error for non-existent theme', () => {
56
+ expect(() => {
57
+ Validator.validateTheme('nonexistent', ['default', 'dark']);
58
+ }).toThrow(AtomixBuildError);
59
+ });
60
+ });
61
+
62
+ describe('validateComponents', () => {
63
+ it('should validate valid components array', () => {
64
+ expect(() => {
65
+ Validator.validateComponents(['Button', 'Card'], ['Button', 'Card', 'Input']);
66
+ }).not.toThrow();
67
+ });
68
+
69
+ it('should throw error for non-array components', () => {
70
+ expect(() => {
71
+ Validator.validateComponents('Button');
72
+ }).toThrow(AtomixBuildError);
73
+ });
74
+
75
+ it('should throw error for non-string component names', () => {
76
+ expect(() => {
77
+ Validator.validateComponents(['Button', 123]);
78
+ }).toThrow(AtomixBuildError);
79
+ });
80
+
81
+ it('should throw error for missing components', () => {
82
+ expect(() => {
83
+ Validator.validateComponents(['Button', 'Missing'], ['Button']);
84
+ }).toThrow(AtomixBuildError);
85
+ });
86
+ });
87
+
88
+ describe('validateBoolean', () => {
89
+ it('should validate valid boolean', () => {
90
+ expect(() => {
91
+ Validator.validateBoolean(true, 'testOption');
92
+ }).not.toThrow();
93
+ });
94
+
95
+ it('should throw error for non-boolean value', () => {
96
+ expect(() => {
97
+ Validator.validateBoolean('true', 'testOption');
98
+ }).toThrow(AtomixBuildError);
99
+ });
100
+ });
101
+
102
+ describe('validateString', () => {
103
+ it('should validate valid string', () => {
104
+ expect(() => {
105
+ Validator.validateString('test', 'testOption');
106
+ }).not.toThrow();
107
+ });
108
+
109
+ it('should throw error for non-string value', () => {
110
+ expect(() => {
111
+ Validator.validateString(123, 'testOption');
112
+ }).toThrow(AtomixBuildError);
113
+ });
114
+
115
+ it('should throw error for empty string when not allowed', () => {
116
+ expect(() => {
117
+ Validator.validateString('', 'testOption');
118
+ }).toThrow(AtomixBuildError);
119
+ });
120
+
121
+ it('should allow empty string when permitted', () => {
122
+ expect(() => {
123
+ Validator.validateString('', 'testOption', true);
124
+ }).not.toThrow();
125
+ });
126
+ });
127
+
128
+ describe('validateOptions', () => {
129
+ it('should validate complete options object', () => {
130
+ const options = {
131
+ theme: 'default',
132
+ components: ['Button'],
133
+ optimizeCss: true,
134
+ includeAtoms: false,
135
+ verbose: false
136
+ };
137
+
138
+ expect(() => {
139
+ Validator.validateOptions(options);
140
+ }).not.toThrow();
141
+ });
142
+
143
+ it('should throw error for invalid options object', () => {
144
+ expect(() => {
145
+ Validator.validateOptions('invalid');
146
+ }).toThrow(AtomixBuildError);
147
+ });
148
+
149
+ it('should warn about unknown options', () => {
150
+ const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
151
+
152
+ const options = {
153
+ theme: 'default',
154
+ unknownOption: 'value'
155
+ };
156
+
157
+ Validator.validateOptions(options);
158
+ expect(consoleSpy).toHaveBeenCalledWith('[AtomixBuildWarning] Unknown options provided: unknownOption');
159
+
160
+ consoleSpy.mockRestore();
161
+ });
162
+ });
163
+ });
164
+
165
+ describe('ErrorHandler', () => {
166
+ describe('withErrorHandling', () => {
167
+ it('should wrap function and handle errors', () => {
168
+ const failingFn = () => {
169
+ throw new Error('Original error');
170
+ };
171
+
172
+ const wrappedFn = ErrorHandler.withErrorHandling(failingFn, 'Test Context');
173
+
174
+ expect(() => {
175
+ wrappedFn();
176
+ }).toThrow(AtomixBuildError);
177
+ });
178
+
179
+ it('should preserve AtomixBuildError instances', () => {
180
+ const atomixError = new AtomixBuildError('Test', 'TEST_CODE');
181
+ const failingFn = () => {
182
+ throw atomixError;
183
+ };
184
+
185
+ const wrappedFn = ErrorHandler.withErrorHandling(failingFn, 'Test Context');
186
+
187
+ try {
188
+ wrappedFn();
189
+ expect.fail('Should have thrown');
190
+ } catch (error) {
191
+ expect(error).toBe(atomixError);
192
+ }
193
+ });
194
+ });
195
+
196
+ describe('logError', () => {
197
+ it('should log AtomixBuildError properly', () => {
198
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
199
+ const error = new AtomixBuildError('Test error', 'TEST_CODE');
200
+
201
+ ErrorHandler.logError(error);
202
+ expect(consoleSpy).toHaveBeenCalled();
203
+
204
+ consoleSpy.mockRestore();
205
+ });
206
+
207
+ it('should log regular Error properly', () => {
208
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
209
+ const error = new Error('Regular error');
210
+
211
+ ErrorHandler.logError(error);
212
+ expect(consoleSpy).toHaveBeenCalledWith('[Error] Regular error');
213
+
214
+ consoleSpy.mockRestore();
215
+ });
216
+ });
217
+
218
+ describe('getErrorCode', () => {
219
+ it('should get error code from AtomixBuildError', () => {
220
+ const error = new AtomixBuildError('Test', 'TEST_CODE');
221
+ expect(ErrorHandler.getErrorCode(error)).toBe('TEST_CODE');
222
+ });
223
+
224
+ it('should return null for regular Error', () => {
225
+ const error = new Error('Test');
226
+ expect(ErrorHandler.getErrorCode(error)).toBeNull();
227
+ });
228
+ });
229
+ });
230
+ });
@@ -0,0 +1,141 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { detectBuildTool, getIntegration, initAutoIntegration } from '../index.js';
3
+ import fs from 'fs';
4
+
5
+ // Mock fs for detectBuildTool tests
6
+ vi.mock('fs', async (importOriginal) => {
7
+ const actual = await importOriginal();
8
+ return {
9
+ ...actual,
10
+ default: {
11
+ ...actual.default,
12
+ existsSync: vi.fn(),
13
+ readFileSync: vi.fn(),
14
+ },
15
+ existsSync: vi.fn(),
16
+ readFileSync: vi.fn(),
17
+ };
18
+ });
19
+
20
+ describe('Build-Tools Index (index.js)', () => {
21
+ beforeEach(() => {
22
+ vi.clearAllMocks();
23
+ });
24
+
25
+ afterEach(() => {
26
+ vi.restoreAllMocks();
27
+ });
28
+
29
+ describe('detectBuildTool', () => {
30
+ it('should detect vite when it is in devDependencies', () => {
31
+ fs.existsSync.mockReturnValue(true);
32
+ fs.readFileSync.mockReturnValue(JSON.stringify({
33
+ devDependencies: { vite: '^5.0.0' },
34
+ }));
35
+
36
+ expect(detectBuildTool()).toBe('vite');
37
+ });
38
+
39
+ it('should detect webpack when it is in dependencies', () => {
40
+ fs.existsSync.mockReturnValue(true);
41
+ fs.readFileSync.mockReturnValue(JSON.stringify({
42
+ dependencies: { webpack: '^5.0.0' },
43
+ }));
44
+
45
+ expect(detectBuildTool()).toBe('webpack');
46
+ });
47
+
48
+ it('should detect rollup', () => {
49
+ fs.existsSync.mockReturnValue(true);
50
+ fs.readFileSync.mockReturnValue(JSON.stringify({
51
+ devDependencies: { rollup: '^4.0.0' },
52
+ }));
53
+
54
+ expect(detectBuildTool()).toBe('rollup');
55
+ });
56
+
57
+ it('should return null when no build tool is detected', () => {
58
+ fs.existsSync.mockReturnValue(true);
59
+ fs.readFileSync.mockReturnValue(JSON.stringify({
60
+ dependencies: { react: '^18.0.0' },
61
+ }));
62
+
63
+ expect(detectBuildTool()).toBeNull();
64
+ });
65
+
66
+ it('should return null when package.json does not exist', () => {
67
+ fs.existsSync.mockReturnValue(false);
68
+
69
+ expect(detectBuildTool()).toBeNull();
70
+ });
71
+
72
+ it('should prioritize vite over webpack when both exist', () => {
73
+ fs.existsSync.mockReturnValue(true);
74
+ fs.readFileSync.mockReturnValue(JSON.stringify({
75
+ devDependencies: { vite: '^5.0.0', webpack: '^5.0.0' },
76
+ }));
77
+
78
+ expect(detectBuildTool()).toBe('vite');
79
+ });
80
+
81
+ it('should handle malformed package.json gracefully', () => {
82
+ fs.existsSync.mockReturnValue(true);
83
+ fs.readFileSync.mockReturnValue('not valid json');
84
+
85
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
86
+ expect(detectBuildTool()).toBeNull();
87
+ consoleSpy.mockRestore();
88
+ });
89
+ });
90
+
91
+ describe('getIntegration', () => {
92
+ it('should return a plugin object for "vite"', () => {
93
+ const result = getIntegration('vite');
94
+ expect(result).toBeDefined();
95
+ expect(result.name).toBe('atomix');
96
+ });
97
+
98
+ it('should return a function for "webpack"', () => {
99
+ const result = getIntegration('webpack');
100
+ expect(typeof result).toBe('function');
101
+ });
102
+
103
+ it('should return a plugin object for "rollup"', () => {
104
+ const result = getIntegration('rollup');
105
+ expect(result).toBeDefined();
106
+ expect(result.name).toBe('atomix');
107
+ });
108
+
109
+ it('should return null for unknown build tool', () => {
110
+ const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
111
+ const result = getIntegration('parcel');
112
+ expect(result).toBeNull();
113
+ consoleSpy.mockRestore();
114
+ });
115
+
116
+ it('should return null for null build tool', () => {
117
+ const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
118
+ const result = getIntegration(null);
119
+ expect(result).toBeNull();
120
+ consoleSpy.mockRestore();
121
+ });
122
+
123
+ it('should be case-insensitive', () => {
124
+ const result = getIntegration('VITE');
125
+ expect(result).toBeDefined();
126
+ expect(result.name).toBe('atomix');
127
+ });
128
+ });
129
+
130
+ describe('initAutoIntegration', () => {
131
+ it('should return null when no build tool detected', () => {
132
+ fs.existsSync.mockReturnValue(false);
133
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
134
+
135
+ const result = initAutoIntegration();
136
+ expect(result).toBeNull();
137
+
138
+ warnSpy.mockRestore();
139
+ });
140
+ });
141
+ });
@@ -0,0 +1,194 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import atomixRollupPlugin, { getAvailableThemes, getAtomixPackageLocation } from '../rollup-plugin.js';
3
+
4
+ describe('Atomix Rollup Plugin', () => {
5
+ beforeEach(() => {
6
+ vi.clearAllMocks();
7
+ });
8
+
9
+ afterEach(() => {
10
+ vi.restoreAllMocks();
11
+ });
12
+
13
+ describe('Plugin Creation', () => {
14
+ it('should create plugin with default options', () => {
15
+ const plugin = atomixRollupPlugin();
16
+ expect(plugin.name).toBe('atomix');
17
+ expect(typeof plugin.transform).toBe('function');
18
+ expect(typeof plugin.resolveId).toBe('function');
19
+ expect(typeof plugin.load).toBe('function');
20
+ });
21
+
22
+ it('should create plugin with custom options', () => {
23
+ const options = {
24
+ theme: 'dark-complementary',
25
+ components: ['Button', 'Card'],
26
+ optimize: false,
27
+ includeAtoms: true,
28
+ verbose: true
29
+ };
30
+
31
+ const plugin = atomixRollupPlugin(options);
32
+ expect(plugin.name).toBe('atomix');
33
+ });
34
+
35
+ it('should throw error for invalid theme type', () => {
36
+ expect(() => {
37
+ atomixRollupPlugin({ theme: 123 });
38
+ }).toThrow('Theme must be a string');
39
+ });
40
+
41
+ it('should throw error for invalid components type', () => {
42
+ expect(() => {
43
+ atomixRollupPlugin({ components: 'Button' });
44
+ }).toThrow('Components must be an array');
45
+ });
46
+ });
47
+
48
+ describe('Transform Hook', () => {
49
+ it('should process Atomix files', () => {
50
+ const plugin = atomixRollupPlugin();
51
+ const testCode = `
52
+ import { Button, Card } from '@shohojdhara/atomix/components';
53
+ import { AtomButton } from '@shohojdhara/atomix/atoms';
54
+ export default function Test() {
55
+ return <Button>Hello</Button>;
56
+ }
57
+ `;
58
+
59
+ const result = plugin.transform(testCode, '/test/node_modules/@shohojdhara/atomix/Button.js');
60
+
61
+ expect(result).toBeDefined();
62
+ expect(result.code).toContain('Button');
63
+ expect(result.map).toBeNull();
64
+ });
65
+
66
+ it('should filter components when specified', () => {
67
+ const plugin = atomixRollupPlugin({
68
+ components: ['Button'],
69
+ optimize: true
70
+ });
71
+
72
+ const testCode = `
73
+ import { Button, Card, Input } from '@shohojdhara/atomix/components';
74
+ export default function Test() {
75
+ return <Button>Hello</Button>;
76
+ }
77
+ `;
78
+
79
+ const result = plugin.transform(testCode, '/test/file.js');
80
+ expect(result.code).toContain('Button');
81
+ // Should filter out Card and Input
82
+ });
83
+
84
+ it('should remove atom imports when includeAtoms is false', () => {
85
+ const plugin = atomixRollupPlugin({
86
+ includeAtoms: false,
87
+ optimize: true
88
+ });
89
+
90
+ const testCode = `
91
+ import { Button } from '@shohojdhara/atomix/components';
92
+ import { AtomButton } from '@shohojdhara/atomix/atoms';
93
+ `;
94
+
95
+ const result = plugin.transform(testCode, '/test/file.js');
96
+ expect(result.code).not.toContain('AtomButton');
97
+ });
98
+
99
+ it('should return null for non-Atomix files', () => {
100
+ const plugin = atomixRollupPlugin();
101
+ const result = plugin.transform('console.log("hello");', '/test/other.js');
102
+ expect(result).toBeNull();
103
+ });
104
+ });
105
+
106
+ describe('ResolveId Hook', () => {
107
+ it('should resolve theme imports', () => {
108
+ const plugin = atomixRollupPlugin();
109
+ const result = plugin.resolveId('@shohojdhara/atomix/theme', '/test/importer.js');
110
+ // Should return null or the import path
111
+ expect(result === null || typeof result === 'string').toBe(true);
112
+ });
113
+
114
+ it('should resolve component imports', () => {
115
+ const plugin = atomixRollupPlugin();
116
+ const result = plugin.resolveId('@shohojdhara/atomix/components/Button', '/test/importer.js');
117
+ expect(result === null || typeof result === 'string').toBe(true);
118
+ });
119
+
120
+ it('should return null for non-Atomix imports', () => {
121
+ const plugin = atomixRollupPlugin();
122
+ const result = plugin.resolveId('react', '/test/importer.js');
123
+ expect(result).toBeNull();
124
+ });
125
+ });
126
+
127
+ describe('Load Hook', () => {
128
+ it('should load virtual theme modules', () => {
129
+ const plugin = atomixRollupPlugin();
130
+ const result = plugin.load('virtual:atomix-theme');
131
+ expect(typeof result).toBe('string');
132
+ });
133
+
134
+ it('should return null for unknown virtual modules', () => {
135
+ const plugin = atomixRollupPlugin();
136
+ const result = plugin.load('virtual:unknown');
137
+ expect(result).toBeNull();
138
+ });
139
+ });
140
+
141
+ describe('GenerateBundle Hook', () => {
142
+ it('should process CSS assets', () => {
143
+ const plugin = atomixRollupPlugin({ optimize: true });
144
+ const bundle = {
145
+ 'styles.css': {
146
+ type: 'asset',
147
+ fileName: 'atomix-styles.css',
148
+ source: 'body { color: red; }'
149
+ }
150
+ };
151
+
152
+ // This should not throw an error
153
+ expect(() => {
154
+ plugin.generateBundle({}, bundle);
155
+ }).not.toThrow();
156
+ });
157
+
158
+ it('should skip non-CSS assets', () => {
159
+ const plugin = atomixRollupPlugin({ optimize: true });
160
+ const bundle = {
161
+ 'script.js': {
162
+ type: 'chunk',
163
+ fileName: 'script.js',
164
+ code: 'console.log("hello");'
165
+ }
166
+ };
167
+
168
+ expect(() => {
169
+ plugin.generateBundle({}, bundle);
170
+ }).not.toThrow();
171
+ });
172
+ });
173
+
174
+ describe('BuildStart Hook', () => {
175
+ it('should have buildStart function', () => {
176
+ const plugin = atomixRollupPlugin();
177
+ expect(typeof plugin.buildStart).toBe('function');
178
+ });
179
+ });
180
+
181
+ describe('Helper Functions', () => {
182
+ it('should get available themes', () => {
183
+ const themes = getAvailableThemes(null);
184
+ expect(Array.isArray(themes)).toBe(true);
185
+ expect(themes).toEqual([]);
186
+ });
187
+
188
+ it('should get Atomix package location', () => {
189
+ const location = getAtomixPackageLocation();
190
+ // Should return null or valid path
191
+ expect(location === null || typeof location === 'string').toBe(true);
192
+ });
193
+ });
194
+ });