@navios/commander-tui 1.3.0 โ†’ 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/{src/__tests__/mocks/scm-mock.ts โ†’ dist/base/src/__tests__/mocks/scm-mock.d.ts} +3 -1
  3. package/dist/base/src/__tests__/mocks/scm-mock.d.ts.map +1 -0
  4. package/dist/base/src/__tests__/setup.d.ts +2 -0
  5. package/dist/base/src/__tests__/setup.d.ts.map +1 -0
  6. package/dist/base/src/__tests__/utils/factories.d.ts +67 -0
  7. package/dist/base/src/__tests__/utils/factories.d.ts.map +1 -0
  8. package/dist/base/src/__tests__/utils/render-utils.d.ts +21 -0
  9. package/dist/base/src/__tests__/utils/render-utils.d.ts.map +1 -0
  10. package/dist/base/src/__tests__/utils/test-container.d.ts +20 -0
  11. package/dist/base/src/__tests__/utils/test-container.d.ts.map +1 -0
  12. package/dist/base/src/adapters/interface.d.ts +9 -2
  13. package/dist/base/src/adapters/interface.d.ts.map +1 -1
  14. package/dist/base/src/overrides/missing-adapter.override.d.ts +10 -0
  15. package/dist/base/src/overrides/missing-adapter.override.d.ts.map +1 -1
  16. package/dist/base/src/schemas/logger-options.d.ts +1 -1
  17. package/dist/base/src/services/index.d.ts +1 -0
  18. package/dist/base/src/services/index.d.ts.map +1 -1
  19. package/dist/base/src/services/logger.d.ts.map +1 -1
  20. package/dist/base/src/services/readline_prompt.d.ts +27 -0
  21. package/dist/base/src/services/readline_prompt.d.ts.map +1 -0
  22. package/dist/base/src/services/screen.d.ts +14 -8
  23. package/dist/base/src/services/screen.d.ts.map +1 -1
  24. package/dist/base/src/services/screen_manager.d.ts +62 -12
  25. package/dist/base/src/services/screen_manager.d.ts.map +1 -1
  26. package/dist/base/src/types/events.types.d.ts +40 -0
  27. package/dist/base/src/types/events.types.d.ts.map +1 -0
  28. package/dist/base/src/types/index.d.ts +1 -0
  29. package/dist/base/src/types/index.d.ts.map +1 -1
  30. package/dist/base/src/types/screen.types.d.ts +28 -0
  31. package/dist/base/src/types/screen.types.d.ts.map +1 -1
  32. package/dist/base/src/utils/colors/helpers.d.ts +0 -16
  33. package/dist/base/src/utils/colors/helpers.d.ts.map +1 -1
  34. package/dist/base/src/utils/index.d.ts +2 -0
  35. package/dist/base/src/utils/index.d.ts.map +1 -1
  36. package/dist/base/src/utils/prompt.d.ts +7 -0
  37. package/dist/base/src/utils/prompt.d.ts.map +1 -0
  38. package/dist/base/src/utils/runtime.d.ts +10 -0
  39. package/dist/base/src/utils/runtime.d.ts.map +1 -0
  40. package/dist/base/src/utils/stdout-printer.d.ts +5 -0
  41. package/dist/base/src/utils/stdout-printer.d.ts.map +1 -1
  42. package/dist/base/tsconfig.base.tsbuildinfo +1 -1
  43. package/dist/base/tsconfig.tsbuildinfo +1 -0
  44. package/dist/ink/src/adapters/ink/components/file/file_log.d.ts +28 -0
  45. package/dist/ink/src/adapters/ink/components/file/file_log.d.ts.map +1 -0
  46. package/dist/ink/src/adapters/ink/components/file/index.d.ts +2 -0
  47. package/dist/ink/src/adapters/ink/components/file/index.d.ts.map +1 -0
  48. package/dist/ink/src/adapters/ink/components/filter/filter_bar.d.ts +7 -0
  49. package/dist/ink/src/adapters/ink/components/filter/filter_bar.d.ts.map +1 -0
  50. package/dist/ink/src/adapters/ink/components/filter/index.d.ts +2 -0
  51. package/dist/ink/src/adapters/ink/components/filter/index.d.ts.map +1 -0
  52. package/dist/ink/src/adapters/ink/components/help/help_overlay.d.ts +6 -0
  53. package/dist/ink/src/adapters/ink/components/help/help_overlay.d.ts.map +1 -0
  54. package/dist/ink/src/adapters/ink/components/help/index.d.ts +2 -0
  55. package/dist/ink/src/adapters/ink/components/help/index.d.ts.map +1 -0
  56. package/dist/ink/src/adapters/ink/components/index.d.ts +9 -0
  57. package/dist/ink/src/adapters/ink/components/index.d.ts.map +1 -0
  58. package/dist/ink/src/adapters/ink/components/log/index.d.ts +2 -0
  59. package/dist/ink/src/adapters/ink/components/log/index.d.ts.map +1 -0
  60. package/dist/ink/src/adapters/ink/components/log/log_message.d.ts +15 -0
  61. package/dist/ink/src/adapters/ink/components/log/log_message.d.ts.map +1 -0
  62. package/dist/ink/src/adapters/ink/components/prompt/index.d.ts +2 -0
  63. package/dist/ink/src/adapters/ink/components/prompt/index.d.ts.map +1 -0
  64. package/dist/ink/src/adapters/ink/components/prompt/prompt_renderer.d.ts +6 -0
  65. package/dist/ink/src/adapters/ink/components/prompt/prompt_renderer.d.ts.map +1 -0
  66. package/dist/ink/src/adapters/ink/components/screen/group_renderer.d.ts +14 -0
  67. package/dist/ink/src/adapters/ink/components/screen/group_renderer.d.ts.map +1 -0
  68. package/dist/ink/src/adapters/ink/components/screen/index.d.ts +7 -0
  69. package/dist/ink/src/adapters/ink/components/screen/index.d.ts.map +1 -0
  70. package/dist/ink/src/adapters/ink/components/screen/loading_message.d.ts +6 -0
  71. package/dist/ink/src/adapters/ink/components/screen/loading_message.d.ts.map +1 -0
  72. package/dist/ink/src/adapters/ink/components/screen/message_renderer.d.ts +6 -0
  73. package/dist/ink/src/adapters/ink/components/screen/message_renderer.d.ts.map +1 -0
  74. package/dist/ink/src/adapters/ink/components/screen/progress_message.d.ts +6 -0
  75. package/dist/ink/src/adapters/ink/components/screen/progress_message.d.ts.map +1 -0
  76. package/dist/ink/src/adapters/ink/components/screen/screen_bridge.d.ts +14 -0
  77. package/dist/ink/src/adapters/ink/components/screen/screen_bridge.d.ts.map +1 -0
  78. package/dist/ink/src/adapters/ink/components/screen/table_message.d.ts +6 -0
  79. package/dist/ink/src/adapters/ink/components/screen/table_message.d.ts.map +1 -0
  80. package/dist/ink/src/adapters/ink/components/screen_manager_bridge.d.ts +8 -0
  81. package/dist/ink/src/adapters/ink/components/screen_manager_bridge.d.ts.map +1 -0
  82. package/dist/ink/src/adapters/ink/components/sidebar/index.d.ts +4 -0
  83. package/dist/ink/src/adapters/ink/components/sidebar/index.d.ts.map +1 -0
  84. package/dist/ink/src/adapters/ink/components/sidebar/sidebar.d.ts +11 -0
  85. package/dist/ink/src/adapters/ink/components/sidebar/sidebar.d.ts.map +1 -0
  86. package/dist/ink/src/adapters/ink/components/sidebar/sidebar_item.d.ts +9 -0
  87. package/dist/ink/src/adapters/ink/components/sidebar/sidebar_item.d.ts.map +1 -0
  88. package/dist/ink/src/adapters/ink/components/sidebar/sidebar_separator.d.ts +2 -0
  89. package/dist/ink/src/adapters/ink/components/sidebar/sidebar_separator.d.ts.map +1 -0
  90. package/dist/ink/src/adapters/ink/context/index.d.ts +2 -0
  91. package/dist/ink/src/adapters/ink/context/index.d.ts.map +1 -0
  92. package/dist/ink/src/adapters/ink/context/logger_context.d.ts +33 -0
  93. package/dist/ink/src/adapters/ink/context/logger_context.d.ts.map +1 -0
  94. package/dist/ink/src/adapters/ink/hooks/index.d.ts +2 -0
  95. package/dist/ink/src/adapters/ink/hooks/index.d.ts.map +1 -0
  96. package/dist/ink/src/adapters/ink/hooks/use_theme.d.ts +7 -0
  97. package/dist/ink/src/adapters/ink/hooks/use_theme.d.ts.map +1 -0
  98. package/dist/ink/src/adapters/ink/index.d.ts +18 -0
  99. package/dist/ink/src/adapters/ink/index.d.ts.map +1 -0
  100. package/dist/ink/src/adapters/react-shared/hooks/index.d.ts +4 -0
  101. package/dist/ink/src/adapters/react-shared/hooks/index.d.ts.map +1 -0
  102. package/dist/ink/src/adapters/react-shared/hooks/use_filter_state.d.ts +18 -0
  103. package/dist/ink/src/adapters/react-shared/hooks/use_filter_state.d.ts.map +1 -0
  104. package/dist/ink/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts +26 -0
  105. package/dist/ink/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts.map +1 -0
  106. package/dist/ink/src/adapters/react-shared/hooks/use_manager_subscription.d.ts +7 -0
  107. package/dist/ink/src/adapters/react-shared/hooks/use_manager_subscription.d.ts.map +1 -0
  108. package/dist/ink/src/adapters/react-shared/index.d.ts +2 -0
  109. package/dist/ink/src/adapters/react-shared/index.d.ts.map +1 -0
  110. package/dist/ink/tsconfig.ink.tsbuildinfo +1 -0
  111. package/dist/react/src/adapters/react-shared/hooks/index.d.ts +4 -0
  112. package/dist/react/src/adapters/react-shared/hooks/index.d.ts.map +1 -0
  113. package/dist/react/src/adapters/react-shared/hooks/use_filter_state.d.ts +18 -0
  114. package/dist/react/src/adapters/react-shared/hooks/use_filter_state.d.ts.map +1 -0
  115. package/dist/react/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts +26 -0
  116. package/dist/react/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts.map +1 -0
  117. package/dist/react/src/adapters/react-shared/hooks/use_manager_subscription.d.ts +7 -0
  118. package/dist/react/src/adapters/react-shared/hooks/use_manager_subscription.d.ts.map +1 -0
  119. package/dist/react/src/adapters/react-shared/index.d.ts +2 -0
  120. package/dist/react/src/adapters/react-shared/index.d.ts.map +1 -0
  121. package/dist/react/tsconfig.react.tsbuildinfo +1 -1
  122. package/dist/solid/tsconfig.solid.tsbuildinfo +1 -1
  123. package/lib/index.cjs +2177 -178
  124. package/lib/index.cjs.map +1 -1
  125. package/lib/index.d.cts +942 -78
  126. package/lib/index.d.cts.map +1 -0
  127. package/lib/index.d.mts +902 -38
  128. package/lib/index.d.mts.map +1 -0
  129. package/lib/index.mjs +2098 -135
  130. package/lib/index.mjs.map +1 -1
  131. package/package.json +1 -31
  132. package/src/__tests__/services/logger.spec.ts +32 -0
  133. package/src/__tests__/services/screen.spec.ts +106 -95
  134. package/src/__tests__/utils/factories.ts +2 -0
  135. package/src/adapters/interface.ts +10 -2
  136. package/src/overrides/missing-adapter.override.ts +16 -6
  137. package/src/services/index.ts +1 -0
  138. package/src/services/logger.ts +7 -1
  139. package/src/services/readline_prompt.ts +194 -0
  140. package/src/services/screen.ts +106 -54
  141. package/src/services/screen_manager.ts +282 -74
  142. package/src/types/events.types.ts +84 -0
  143. package/src/types/index.ts +3 -0
  144. package/src/types/screen.types.ts +34 -0
  145. package/src/utils/colors/helpers.ts +0 -25
  146. package/src/utils/index.ts +6 -0
  147. package/src/utils/prompt.ts +18 -0
  148. package/src/utils/runtime.ts +14 -0
  149. package/src/utils/stdout-printer.ts +16 -5
  150. package/tsconfig.base.json +1 -17
  151. package/tsconfig.json +1 -6
  152. package/tsdown.config.mts +13 -70
  153. package/lib/adapters/react/index.cjs +0 -1768
  154. package/lib/adapters/react/index.cjs.map +0 -1
  155. package/lib/adapters/react/index.d.cts +0 -80
  156. package/lib/adapters/react/index.d.mts +0 -80
  157. package/lib/adapters/react/index.mjs +0 -1760
  158. package/lib/adapters/react/index.mjs.map +0 -1
  159. package/lib/adapters/solid/index.cjs +0 -3855
  160. package/lib/adapters/solid/index.cjs.map +0 -1
  161. package/lib/adapters/solid/index.d.cts +0 -74
  162. package/lib/adapters/solid/index.d.mts +0 -74
  163. package/lib/adapters/solid/index.mjs +0 -3847
  164. package/lib/adapters/solid/index.mjs.map +0 -1
  165. package/lib/filter_engine-DXqu9Vaq.cjs +0 -1836
  166. package/lib/filter_engine-DXqu9Vaq.cjs.map +0 -1
  167. package/lib/filter_engine-DmqhEhpA.mjs +0 -1609
  168. package/lib/filter_engine-DmqhEhpA.mjs.map +0 -1
  169. package/lib/interface-CTHQ08aY.d.mts +0 -699
  170. package/lib/interface-DQEIz9Mb.d.cts +0 -699
  171. package/src/__tests__/components/__snapshots__/filter_bar.spec.tsx.snap +0 -2293
  172. package/src/__tests__/components/__snapshots__/loading_message.spec.tsx.snap +0 -1414
  173. package/src/__tests__/components/__snapshots__/log_message.spec.tsx.snap +0 -3245
  174. package/src/__tests__/components/__snapshots__/progress_message.spec.tsx.snap +0 -1783
  175. package/src/__tests__/components/__snapshots__/prompt_renderer.spec.tsx.snap +0 -3203
  176. package/src/__tests__/components/__snapshots__/sidebar.spec.tsx.snap +0 -2857
  177. package/src/__tests__/components/filter_bar.spec.tsx +0 -190
  178. package/src/__tests__/components/loading_message.spec.tsx +0 -110
  179. package/src/__tests__/components/log_message.spec.tsx +0 -166
  180. package/src/__tests__/components/progress_message.spec.tsx +0 -147
  181. package/src/__tests__/components/prompt_renderer.spec.tsx +0 -274
  182. package/src/__tests__/components/sidebar.spec.tsx +0 -322
  183. package/src/__tests__/utils/render-utils.tsx +0 -39
  184. package/src/adapters/react/components/file/file_log.tsx +0 -241
  185. package/src/adapters/react/components/file/index.ts +0 -1
  186. package/src/adapters/react/components/filter/filter_bar.tsx +0 -79
  187. package/src/adapters/react/components/filter/index.ts +0 -1
  188. package/src/adapters/react/components/help/help_overlay.tsx +0 -100
  189. package/src/adapters/react/components/help/index.ts +0 -1
  190. package/src/adapters/react/components/log/index.ts +0 -1
  191. package/src/adapters/react/components/log/log_message.tsx +0 -102
  192. package/src/adapters/react/components/prompt/index.ts +0 -2
  193. package/src/adapters/react/components/prompt/prompt_renderer.tsx +0 -346
  194. package/src/adapters/react/components/screen/group_renderer.tsx +0 -64
  195. package/src/adapters/react/components/screen/index.ts +0 -6
  196. package/src/adapters/react/components/screen/loading_message.tsx +0 -43
  197. package/src/adapters/react/components/screen/message_renderer.tsx +0 -108
  198. package/src/adapters/react/components/screen/progress_message.tsx +0 -60
  199. package/src/adapters/react/components/screen/screen_bridge.tsx +0 -149
  200. package/src/adapters/react/components/screen/table_message.tsx +0 -57
  201. package/src/adapters/react/components/screen_manager_bridge.tsx +0 -245
  202. package/src/adapters/react/components/sidebar/index.ts +0 -3
  203. package/src/adapters/react/components/sidebar/sidebar.tsx +0 -102
  204. package/src/adapters/react/components/sidebar/sidebar_item.tsx +0 -50
  205. package/src/adapters/react/components/sidebar/sidebar_separator.tsx +0 -13
  206. package/src/adapters/react/context/index.ts +0 -1
  207. package/src/adapters/react/context/logger_context.tsx +0 -109
  208. package/src/adapters/react/hooks/index.ts +0 -1
  209. package/src/adapters/react/hooks/use_theme.ts +0 -12
  210. package/src/adapters/react/index.ts +0 -39
  211. package/src/adapters/solid/components/file/file_log.tsx +0 -221
  212. package/src/adapters/solid/components/file/index.ts +0 -1
  213. package/src/adapters/solid/components/filter/filter_bar.tsx +0 -84
  214. package/src/adapters/solid/components/filter/index.ts +0 -1
  215. package/src/adapters/solid/components/help/help_overlay.tsx +0 -106
  216. package/src/adapters/solid/components/help/index.ts +0 -1
  217. package/src/adapters/solid/components/log/index.ts +0 -1
  218. package/src/adapters/solid/components/log/log_message.tsx +0 -92
  219. package/src/adapters/solid/components/prompt/index.ts +0 -2
  220. package/src/adapters/solid/components/prompt/prompt_renderer.tsx +0 -350
  221. package/src/adapters/solid/components/screen/group_renderer.tsx +0 -61
  222. package/src/adapters/solid/components/screen/index.ts +0 -6
  223. package/src/adapters/solid/components/screen/loading_message.tsx +0 -39
  224. package/src/adapters/solid/components/screen/message_renderer.tsx +0 -122
  225. package/src/adapters/solid/components/screen/progress_message.tsx +0 -61
  226. package/src/adapters/solid/components/screen/screen_bridge.tsx +0 -155
  227. package/src/adapters/solid/components/screen/table_message.tsx +0 -58
  228. package/src/adapters/solid/components/screen_manager_bridge.tsx +0 -243
  229. package/src/adapters/solid/components/sidebar/index.ts +0 -3
  230. package/src/adapters/solid/components/sidebar/sidebar.tsx +0 -108
  231. package/src/adapters/solid/components/sidebar/sidebar_item.tsx +0 -55
  232. package/src/adapters/solid/components/sidebar/sidebar_separator.tsx +0 -13
  233. package/src/adapters/solid/context/index.ts +0 -2
  234. package/src/adapters/solid/context/logger_context.tsx +0 -95
  235. package/src/adapters/solid/hooks/index.ts +0 -1
  236. package/src/adapters/solid/hooks/use_theme.ts +0 -12
  237. package/src/adapters/solid/index.tsx +0 -43
  238. package/src/adapters/solid/jsx.d.ts +0 -98
  239. package/tsconfig.react.json +0 -16
  240. package/tsconfig.solid.json +0 -16
@@ -1,274 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
-
3
- import { PromptRenderer } from '../../adapters/react/components/prompt/prompt_renderer.tsx'
4
- import {
5
- createChoicePrompt,
6
- createConfirmPrompt,
7
- createInputPrompt,
8
- createMultiChoicePrompt,
9
- STABLE_TIMESTAMP,
10
- } from '../utils/factories.ts'
11
- import { wrapWithContext } from '../utils/render-utils.tsx'
12
-
13
- describe('PromptRenderer', () => {
14
- describe('choice prompt', () => {
15
- it('should render choice prompt with options', () => {
16
- const prompt = createChoicePrompt({
17
- question: 'Select an option',
18
- choices: [
19
- { label: 'Option A', value: 'a' },
20
- { label: 'Option B', value: 'b' },
21
- { label: 'Option C', value: 'c' },
22
- ],
23
- selectedIndex: 0,
24
- })
25
-
26
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
27
-
28
- expect(component).toMatchSnapshot()
29
- })
30
-
31
- it('should render selected option highlighted', () => {
32
- const prompt = createChoicePrompt({
33
- question: 'Choose wisely',
34
- choices: [
35
- { label: 'First', value: '1' },
36
- { label: 'Second', value: '2' },
37
- { label: 'Third', value: '3' },
38
- ],
39
- selectedIndex: 1,
40
- })
41
-
42
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
43
-
44
- expect(component).toMatchSnapshot()
45
- })
46
-
47
- it('should render choice with input mode', () => {
48
- const prompt = createChoicePrompt({
49
- question: 'Select or type',
50
- choices: [
51
- { label: 'Option A', value: 'a' },
52
- { label: 'Other', value: 'other', input: true },
53
- ],
54
- selectedIndex: 1,
55
- inputMode: true,
56
- inputValue: 'custom value',
57
- })
58
-
59
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
60
-
61
- expect(component).toMatchSnapshot()
62
- })
63
-
64
- it('should render choice with timeout', () => {
65
- const prompt = createChoicePrompt({
66
- question: 'Quick! Select one',
67
- choices: [{ label: 'Default', value: 'default' }],
68
- timeout: 10000,
69
- timeoutStarted: STABLE_TIMESTAMP.getTime() - 5000, // 5 seconds elapsed from stable timestamp
70
- })
71
-
72
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
73
-
74
- expect(component).toMatchSnapshot()
75
- })
76
-
77
- it('should render resolved choice prompt', () => {
78
- const prompt = createChoicePrompt({
79
- question: 'Already answered',
80
- choices: [
81
- { label: 'Yes', value: 'yes' },
82
- { label: 'No', value: 'no' },
83
- ],
84
- selectedIndex: 0,
85
- resolved: true,
86
- resolvedValue: 'yes',
87
- })
88
-
89
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
90
-
91
- expect(component).toMatchSnapshot()
92
- })
93
- })
94
-
95
- describe('confirm prompt', () => {
96
- it('should render confirm prompt (Yes/No)', () => {
97
- const prompt = createConfirmPrompt({
98
- question: 'Are you sure?',
99
- confirmText: 'Yes',
100
- cancelText: 'No',
101
- selectedValue: true,
102
- })
103
-
104
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
105
-
106
- expect(component).toMatchSnapshot()
107
- })
108
-
109
- it('should render with No selected', () => {
110
- const prompt = createConfirmPrompt({
111
- question: 'Continue?',
112
- confirmText: 'Yes',
113
- cancelText: 'No',
114
- selectedValue: false,
115
- })
116
-
117
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
118
-
119
- expect(component).toMatchSnapshot()
120
- })
121
-
122
- it('should render with custom button labels', () => {
123
- const prompt = createConfirmPrompt({
124
- question: 'Delete this file?',
125
- confirmText: 'Delete',
126
- cancelText: 'Keep',
127
- selectedValue: true,
128
- })
129
-
130
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
131
-
132
- expect(component).toMatchSnapshot()
133
- })
134
-
135
- it('should render resolved confirm prompt', () => {
136
- const prompt = createConfirmPrompt({
137
- question: 'Already confirmed',
138
- resolved: true,
139
- resolvedValue: true,
140
- })
141
-
142
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
143
-
144
- expect(component).toMatchSnapshot()
145
- })
146
- })
147
-
148
- describe('input prompt', () => {
149
- it('should render input prompt with placeholder', () => {
150
- const prompt = createInputPrompt({
151
- question: 'Enter your name',
152
- placeholder: 'John Doe',
153
- value: '',
154
- })
155
-
156
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
157
-
158
- expect(component).toMatchSnapshot()
159
- })
160
-
161
- it('should render input with entered value', () => {
162
- const prompt = createInputPrompt({
163
- question: 'Enter your email',
164
- placeholder: 'user@example.com',
165
- value: 'test@test.com',
166
- })
167
-
168
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
169
-
170
- expect(component).toMatchSnapshot()
171
- })
172
-
173
- it('should render resolved input prompt', () => {
174
- const prompt = createInputPrompt({
175
- question: 'Already answered',
176
- value: 'My answer',
177
- resolved: true,
178
- resolvedValue: 'My answer',
179
- })
180
-
181
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
182
-
183
- expect(component).toMatchSnapshot()
184
- })
185
- })
186
-
187
- describe('multiChoice prompt', () => {
188
- it('should render multiChoice with checkboxes', () => {
189
- const prompt = createMultiChoicePrompt({
190
- question: 'Select all that apply',
191
- choices: [
192
- { label: 'Option A', value: 'a' },
193
- { label: 'Option B', value: 'b' },
194
- { label: 'Option C', value: 'c' },
195
- ],
196
- selectedIndices: new Set(),
197
- focusedIndex: 0,
198
- })
199
-
200
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
201
-
202
- expect(component).toMatchSnapshot()
203
- })
204
-
205
- it('should render with some options selected', () => {
206
- const prompt = createMultiChoicePrompt({
207
- question: 'Choose features',
208
- choices: [
209
- { label: 'Feature A', value: 'a' },
210
- { label: 'Feature B', value: 'b' },
211
- { label: 'Feature C', value: 'c' },
212
- ],
213
- selectedIndices: new Set([0, 2]),
214
- focusedIndex: 1,
215
- })
216
-
217
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
218
-
219
- expect(component).toMatchSnapshot()
220
- })
221
-
222
- it('should show selection count', () => {
223
- const prompt = createMultiChoicePrompt({
224
- question: 'Select up to 3',
225
- choices: [
226
- { label: 'A', value: 'a' },
227
- { label: 'B', value: 'b' },
228
- { label: 'C', value: 'c' },
229
- { label: 'D', value: 'd' },
230
- ],
231
- selectedIndices: new Set([0, 2]),
232
- maxSelect: 3,
233
- })
234
-
235
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
236
-
237
- expect(component).toMatchSnapshot()
238
- })
239
-
240
- it('should show minSelect warning when not met', () => {
241
- const prompt = createMultiChoicePrompt({
242
- question: 'Select at least 2',
243
- choices: [
244
- { label: 'A', value: 'a' },
245
- { label: 'B', value: 'b' },
246
- { label: 'C', value: 'c' },
247
- ],
248
- selectedIndices: new Set([0]), // Only 1 selected
249
- minSelect: 2,
250
- })
251
-
252
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
253
-
254
- expect(component).toMatchSnapshot()
255
- })
256
-
257
- it('should render resolved multiChoice prompt', () => {
258
- const prompt = createMultiChoicePrompt({
259
- question: 'Already selected',
260
- choices: [
261
- { label: 'A', value: 'a' },
262
- { label: 'B', value: 'b' },
263
- ],
264
- selectedIndices: new Set([0, 1]),
265
- resolved: true,
266
- resolvedValues: ['a', 'b'],
267
- })
268
-
269
- const component = wrapWithContext(<PromptRenderer prompt={prompt} />)
270
-
271
- expect(component).toMatchSnapshot()
272
- })
273
- })
274
- })
@@ -1,322 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest'
2
-
3
- import { Sidebar } from '../../adapters/react/components/sidebar/sidebar.tsx'
4
- import { wrapWithContext } from '../utils/render-utils.tsx'
5
-
6
- import type { ScreenInstance } from '../../services/screen.ts'
7
- import type { ScreenStatus } from '../../types/index.ts'
8
-
9
- // Create mock ScreenInstance
10
- function createMockScreen(overrides: {
11
- id?: string
12
- name?: string
13
- icon?: string
14
- badgeCount?: number
15
- status?: ScreenStatus
16
- }): ScreenInstance {
17
- return {
18
- getId: vi.fn(() => overrides.id ?? 'screen-1'),
19
- getName: vi.fn(() => overrides.name ?? 'Test Screen'),
20
- getIcon: vi.fn(() => overrides.icon),
21
- getBadgeCount: vi.fn(() => overrides.badgeCount ?? 0),
22
- getStatus: vi.fn(() => overrides.status ?? 'pending'),
23
- isHidden: vi.fn(() => false),
24
- } as unknown as ScreenInstance
25
- }
26
-
27
- describe('Sidebar', () => {
28
- describe('screen list', () => {
29
- it('should render screen list', () => {
30
- const screens = [
31
- createMockScreen({ id: '1', name: 'Screen 1' }),
32
- createMockScreen({ id: '2', name: 'Screen 2' }),
33
- createMockScreen({ id: '3', name: 'Screen 3' }),
34
- ]
35
-
36
- const component = wrapWithContext(
37
- <Sidebar
38
- screens={screens}
39
- selectedIndex={0}
40
- activeScreenId="1"
41
- focused={true}
42
- width={30}
43
- title="Screens"
44
- />,
45
- )
46
-
47
- expect(component).toMatchSnapshot()
48
- })
49
-
50
- it('should render active screen highlighted', () => {
51
- const screens = [
52
- createMockScreen({ id: '1', name: 'Screen 1' }),
53
- createMockScreen({ id: '2', name: 'Screen 2' }),
54
- ]
55
-
56
- const component = wrapWithContext(
57
- <Sidebar
58
- screens={screens}
59
- selectedIndex={1}
60
- activeScreenId="2"
61
- focused={true}
62
- width={30}
63
- title="Screens"
64
- />,
65
- )
66
-
67
- expect(component).toMatchSnapshot()
68
- })
69
- })
70
-
71
- describe('pending vs completed screens', () => {
72
- it('should separate pending from other screens', () => {
73
- const screens = [
74
- createMockScreen({ id: '1', name: 'Pending 1', status: 'pending' }),
75
- createMockScreen({ id: '2', name: 'Success', status: 'success' }),
76
- createMockScreen({ id: '3', name: 'Pending 2', status: 'pending' }),
77
- createMockScreen({ id: '4', name: 'Failed', status: 'fail' }),
78
- ]
79
-
80
- const component = wrapWithContext(
81
- <Sidebar
82
- screens={screens}
83
- selectedIndex={0}
84
- activeScreenId="1"
85
- focused={true}
86
- width={30}
87
- title="Tasks"
88
- />,
89
- )
90
-
91
- expect(component).toMatchSnapshot()
92
- })
93
-
94
- it('should show separator between pending and completed', () => {
95
- const screens = [
96
- createMockScreen({ id: '1', name: 'Active Task', status: 'pending' }),
97
- createMockScreen({ id: '2', name: 'Completed Task', status: 'success' }),
98
- ]
99
-
100
- const component = wrapWithContext(
101
- <Sidebar
102
- screens={screens}
103
- selectedIndex={0}
104
- activeScreenId="1"
105
- focused={true}
106
- width={30}
107
- title="Tasks"
108
- />,
109
- )
110
-
111
- expect(component).toMatchSnapshot()
112
- })
113
-
114
- it('should not show separator if no mix', () => {
115
- const screens = [
116
- createMockScreen({ id: '1', name: 'Task 1', status: 'pending' }),
117
- createMockScreen({ id: '2', name: 'Task 2', status: 'pending' }),
118
- ]
119
-
120
- const component = wrapWithContext(
121
- <Sidebar
122
- screens={screens}
123
- selectedIndex={0}
124
- activeScreenId="1"
125
- focused={true}
126
- width={30}
127
- title="Tasks"
128
- />,
129
- )
130
-
131
- expect(component).toMatchSnapshot()
132
- })
133
- })
134
-
135
- describe('status indicators', () => {
136
- it('should render waiting status', () => {
137
- const screens = [createMockScreen({ id: '1', name: 'Waiting', status: 'waiting' })]
138
-
139
- const component = wrapWithContext(
140
- <Sidebar
141
- screens={screens}
142
- selectedIndex={0}
143
- activeScreenId="1"
144
- focused={true}
145
- width={30}
146
- title="Screens"
147
- />,
148
- )
149
-
150
- expect(component).toMatchSnapshot()
151
- })
152
-
153
- it('should render pending status', () => {
154
- const screens = [createMockScreen({ id: '1', name: 'In Progress', status: 'pending' })]
155
-
156
- const component = wrapWithContext(
157
- <Sidebar
158
- screens={screens}
159
- selectedIndex={0}
160
- activeScreenId="1"
161
- focused={true}
162
- width={30}
163
- title="Screens"
164
- />,
165
- )
166
-
167
- expect(component).toMatchSnapshot()
168
- })
169
-
170
- it('should render success status', () => {
171
- const screens = [createMockScreen({ id: '1', name: 'Completed', status: 'success' })]
172
-
173
- const component = wrapWithContext(
174
- <Sidebar
175
- screens={screens}
176
- selectedIndex={0}
177
- activeScreenId="1"
178
- focused={true}
179
- width={30}
180
- title="Screens"
181
- />,
182
- )
183
-
184
- expect(component).toMatchSnapshot()
185
- })
186
-
187
- it('should render fail status', () => {
188
- const screens = [createMockScreen({ id: '1', name: 'Failed', status: 'fail' })]
189
-
190
- const component = wrapWithContext(
191
- <Sidebar
192
- screens={screens}
193
- selectedIndex={0}
194
- activeScreenId="1"
195
- focused={true}
196
- width={30}
197
- title="Screens"
198
- />,
199
- )
200
-
201
- expect(component).toMatchSnapshot()
202
- })
203
-
204
- it('should render static status', () => {
205
- const screens = [createMockScreen({ id: '1', name: 'Static', status: 'static' })]
206
-
207
- const component = wrapWithContext(
208
- <Sidebar
209
- screens={screens}
210
- selectedIndex={0}
211
- activeScreenId="1"
212
- focused={true}
213
- width={30}
214
- title="Screens"
215
- />,
216
- )
217
-
218
- expect(component).toMatchSnapshot()
219
- })
220
- })
221
-
222
- describe('badge counts', () => {
223
- it('should render badge counts', () => {
224
- const screens = [
225
- createMockScreen({ id: '1', name: 'Messages', badgeCount: 5 }),
226
- createMockScreen({ id: '2', name: 'Notifications', badgeCount: 12 }),
227
- createMockScreen({ id: '3', name: 'Empty', badgeCount: 0 }),
228
- ]
229
-
230
- const component = wrapWithContext(
231
- <Sidebar
232
- screens={screens}
233
- selectedIndex={0}
234
- activeScreenId="1"
235
- focused={true}
236
- width={30}
237
- title="Screens"
238
- />,
239
- )
240
-
241
- expect(component).toMatchSnapshot()
242
- })
243
- })
244
-
245
- describe('icons', () => {
246
- it('should render icons', () => {
247
- const screens = [
248
- createMockScreen({ id: '1', name: 'Build', icon: '๐Ÿ”จ' }),
249
- createMockScreen({ id: '2', name: 'Test', icon: '๐Ÿงช' }),
250
- createMockScreen({ id: '3', name: 'Deploy', icon: '๐Ÿš€' }),
251
- ]
252
-
253
- const component = wrapWithContext(
254
- <Sidebar
255
- screens={screens}
256
- selectedIndex={0}
257
- activeScreenId="1"
258
- focused={true}
259
- width={30}
260
- title="Pipeline"
261
- />,
262
- )
263
-
264
- expect(component).toMatchSnapshot()
265
- })
266
- })
267
-
268
- describe('focus state', () => {
269
- it('should render focused state', () => {
270
- const screens = [createMockScreen({ id: '1', name: 'Test' })]
271
-
272
- const component = wrapWithContext(
273
- <Sidebar
274
- screens={screens}
275
- selectedIndex={0}
276
- activeScreenId="1"
277
- focused={true}
278
- width={30}
279
- title="Screens"
280
- />,
281
- )
282
-
283
- expect(component).toMatchSnapshot()
284
- })
285
-
286
- it('should render unfocused state', () => {
287
- const screens = [createMockScreen({ id: '1', name: 'Test' })]
288
-
289
- const component = wrapWithContext(
290
- <Sidebar
291
- screens={screens}
292
- selectedIndex={0}
293
- activeScreenId="1"
294
- focused={false}
295
- width={30}
296
- title="Screens"
297
- />,
298
- )
299
-
300
- expect(component).toMatchSnapshot()
301
- })
302
- })
303
-
304
- describe('title', () => {
305
- it('should render custom title', () => {
306
- const screens = [createMockScreen({ id: '1', name: 'Test' })]
307
-
308
- const component = wrapWithContext(
309
- <Sidebar
310
- screens={screens}
311
- selectedIndex={0}
312
- activeScreenId="1"
313
- focused={true}
314
- width={30}
315
- title="Custom Title"
316
- />,
317
- )
318
-
319
- expect(component).toMatchSnapshot()
320
- })
321
- })
322
- })
@@ -1,39 +0,0 @@
1
- import { LoggerProvider } from '../../adapters/react/context/index.ts'
2
- import { darkTheme } from '../../themes/index.ts'
3
-
4
- import type { ReactNode } from 'react'
5
- import type { Theme, LogLevelColorMap } from '../../types/index.ts'
6
-
7
- export interface RenderContextOptions {
8
- theme?: Theme
9
- levelColors?: Partial<LogLevelColorMap>
10
- }
11
-
12
- /**
13
- * Wrap a component with LoggerProvider for testing.
14
- * Returns the wrapped component tree.
15
- */
16
- export function wrapWithContext(
17
- component: ReactNode,
18
- options: RenderContextOptions = {},
19
- ): ReactNode {
20
- const { theme = darkTheme, levelColors } = options
21
-
22
- return (
23
- <LoggerProvider theme={theme} levelColors={levelColors}>
24
- {component}
25
- </LoggerProvider>
26
- )
27
- }
28
-
29
- /**
30
- * Create a default context value for testing components outside LoggerProvider.
31
- */
32
- export function createMockContextValue(overrides: Partial<RenderContextOptions> = {}) {
33
- return {
34
- syntaxStyle: undefined,
35
- treeSitterClient: undefined,
36
- levelColors: darkTheme.logLevels,
37
- theme: overrides.theme ?? darkTheme,
38
- }
39
- }