@shakenbake/react-native 0.0.1

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 (73) hide show
  1. package/dist/ShakeNbakeProvider.d.ts +26 -0
  2. package/dist/ShakeNbakeProvider.d.ts.map +1 -0
  3. package/dist/ShakeNbakeProvider.js +338 -0
  4. package/dist/ShakeNbakeProvider.js.map +1 -0
  5. package/dist/__tests__/capture.test.d.ts +2 -0
  6. package/dist/__tests__/capture.test.d.ts.map +1 -0
  7. package/dist/__tests__/capture.test.js +93 -0
  8. package/dist/__tests__/capture.test.js.map +1 -0
  9. package/dist/__tests__/collectors.test.d.ts +2 -0
  10. package/dist/__tests__/collectors.test.d.ts.map +1 -0
  11. package/dist/__tests__/collectors.test.js +212 -0
  12. package/dist/__tests__/collectors.test.js.map +1 -0
  13. package/dist/__tests__/drawing-canvas.test.d.ts +2 -0
  14. package/dist/__tests__/drawing-canvas.test.d.ts.map +1 -0
  15. package/dist/__tests__/drawing-canvas.test.js +503 -0
  16. package/dist/__tests__/drawing-canvas.test.js.map +1 -0
  17. package/dist/__tests__/provider.test.d.ts +2 -0
  18. package/dist/__tests__/provider.test.d.ts.map +1 -0
  19. package/dist/__tests__/provider.test.js +431 -0
  20. package/dist/__tests__/provider.test.js.map +1 -0
  21. package/dist/__tests__/report-form.test.d.ts +2 -0
  22. package/dist/__tests__/report-form.test.d.ts.map +1 -0
  23. package/dist/__tests__/report-form.test.js +178 -0
  24. package/dist/__tests__/report-form.test.js.map +1 -0
  25. package/dist/__tests__/triggers.test.d.ts +2 -0
  26. package/dist/__tests__/triggers.test.d.ts.map +1 -0
  27. package/dist/__tests__/triggers.test.js +53 -0
  28. package/dist/__tests__/triggers.test.js.map +1 -0
  29. package/dist/annotate/DrawingCanvas.d.ts +13 -0
  30. package/dist/annotate/DrawingCanvas.d.ts.map +1 -0
  31. package/dist/annotate/DrawingCanvas.js +475 -0
  32. package/dist/annotate/DrawingCanvas.js.map +1 -0
  33. package/dist/annotate/types.d.ts +72 -0
  34. package/dist/annotate/types.d.ts.map +1 -0
  35. package/dist/annotate/types.js +34 -0
  36. package/dist/annotate/types.js.map +1 -0
  37. package/dist/annotate/useDrawingOperations.d.ts +88 -0
  38. package/dist/annotate/useDrawingOperations.d.ts.map +1 -0
  39. package/dist/annotate/useDrawingOperations.js +186 -0
  40. package/dist/annotate/useDrawingOperations.js.map +1 -0
  41. package/dist/capture/screenshot.d.ts +31 -0
  42. package/dist/capture/screenshot.d.ts.map +1 -0
  43. package/dist/capture/screenshot.js +90 -0
  44. package/dist/capture/screenshot.js.map +1 -0
  45. package/dist/context/collectors.d.ts +25 -0
  46. package/dist/context/collectors.d.ts.map +1 -0
  47. package/dist/context/collectors.js +244 -0
  48. package/dist/context/collectors.js.map +1 -0
  49. package/dist/hooks/useShakeNbake.d.ts +28 -0
  50. package/dist/hooks/useShakeNbake.d.ts.map +1 -0
  51. package/dist/hooks/useShakeNbake.js +30 -0
  52. package/dist/hooks/useShakeNbake.js.map +1 -0
  53. package/dist/index.d.ts +19 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +49 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/triggers/shake.d.ts +16 -0
  58. package/dist/triggers/shake.d.ts.map +1 -0
  59. package/dist/triggers/shake.js +41 -0
  60. package/dist/triggers/shake.js.map +1 -0
  61. package/dist/ui/ReportForm.d.ts +33 -0
  62. package/dist/ui/ReportForm.d.ts.map +1 -0
  63. package/dist/ui/ReportForm.js +608 -0
  64. package/dist/ui/ReportForm.js.map +1 -0
  65. package/dist/ui/form-validation.d.ts +26 -0
  66. package/dist/ui/form-validation.d.ts.map +1 -0
  67. package/dist/ui/form-validation.js +44 -0
  68. package/dist/ui/form-validation.js.map +1 -0
  69. package/dist/ui/state-machine.d.ts +70 -0
  70. package/dist/ui/state-machine.d.ts.map +1 -0
  71. package/dist/ui/state-machine.js +107 -0
  72. package/dist/ui/state-machine.js.map +1 -0
  73. package/package.json +57 -0
@@ -0,0 +1,431 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // Tests for ShakeNbakeProvider, useShakeNbake, and flow state machine
4
+ //
5
+ // Since we cannot render React Native components in a vitest/node
6
+ // environment, we focus on:
7
+ // 1. Module exports are correctly shaped
8
+ // 2. Pure state machine logic (state-machine.ts)
9
+ // 3. Type shapes compile correctly
10
+ // ---------------------------------------------------------------------------
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const vitest_1 = require("vitest");
13
+ // ---------------------------------------------------------------------------
14
+ // Mock peer deps before imports
15
+ // ---------------------------------------------------------------------------
16
+ vitest_1.vi.mock('react-native', () => ({
17
+ View: 'View',
18
+ Text: 'Text',
19
+ TextInput: 'TextInput',
20
+ TouchableOpacity: 'TouchableOpacity',
21
+ ScrollView: 'ScrollView',
22
+ Modal: 'Modal',
23
+ Image: 'Image',
24
+ ActivityIndicator: 'ActivityIndicator',
25
+ KeyboardAvoidingView: 'KeyboardAvoidingView',
26
+ Platform: { OS: 'ios', Version: '17.0' },
27
+ StyleSheet: {
28
+ create: (styles) => styles,
29
+ },
30
+ Dimensions: {
31
+ get: () => ({ width: 390, height: 844, scale: 3, fontScale: 1 }),
32
+ },
33
+ PixelRatio: { get: () => 3, getFontScale: () => 1 },
34
+ PanResponder: {
35
+ create: () => ({ panHandlers: {} }),
36
+ },
37
+ Linking: { openURL: vitest_1.vi.fn() },
38
+ Alert: { alert: vitest_1.vi.fn() },
39
+ AccessibilityInfo: {
40
+ isScreenReaderEnabled: vitest_1.vi.fn().mockResolvedValue(false),
41
+ isReduceMotionEnabled: vitest_1.vi.fn().mockResolvedValue(false),
42
+ },
43
+ }));
44
+ vitest_1.vi.mock('react-native-shake', () => ({
45
+ default: {
46
+ addListener: vitest_1.vi.fn(() => ({ remove: vitest_1.vi.fn() })),
47
+ },
48
+ }));
49
+ vitest_1.vi.mock('react-native-view-shot', () => ({
50
+ captureRef: vitest_1.vi.fn().mockResolvedValue('mock-base64'),
51
+ }));
52
+ vitest_1.vi.mock('@shopify/react-native-skia', () => ({
53
+ Canvas: 'SkiaCanvas',
54
+ Image: 'SkiaImage',
55
+ Path: 'SkiaPath',
56
+ Rect: 'SkiaRect',
57
+ Circle: 'SkiaCircle',
58
+ Line: 'SkiaLine',
59
+ Skia: {
60
+ Path: { Make: () => ({ moveTo: vitest_1.vi.fn(), lineTo: vitest_1.vi.fn(), close: vitest_1.vi.fn(), reset: vitest_1.vi.fn(), copy: vitest_1.vi.fn() }) },
61
+ Data: { fromBase64: () => ({}) },
62
+ },
63
+ makeImageFromEncoded: () => ({
64
+ width: () => 390,
65
+ height: () => 844,
66
+ encodeToBase64: () => 'mock-base64-data',
67
+ }),
68
+ useCanvasRef: () => ({ current: null }),
69
+ }));
70
+ // ---------------------------------------------------------------------------
71
+ // Imports (after mocks)
72
+ // ---------------------------------------------------------------------------
73
+ const state_machine_js_1 = require("../ui/state-machine.js");
74
+ const ShakeNbakeProvider_js_1 = require("../ShakeNbakeProvider.js");
75
+ const useShakeNbake_js_1 = require("../hooks/useShakeNbake.js");
76
+ // ---------------------------------------------------------------------------
77
+ // 1. Module exports
78
+ // ---------------------------------------------------------------------------
79
+ (0, vitest_1.describe)('Provider module exports', () => {
80
+ (0, vitest_1.it)('ShakeNbakeProvider is a function component', () => {
81
+ (0, vitest_1.expect)(typeof ShakeNbakeProvider_js_1.ShakeNbakeProvider).toBe('function');
82
+ });
83
+ (0, vitest_1.it)('ShakeNbakeContext is a React context', () => {
84
+ (0, vitest_1.expect)(ShakeNbakeProvider_js_1.ShakeNbakeContext).toBeDefined();
85
+ (0, vitest_1.expect)(ShakeNbakeProvider_js_1.ShakeNbakeContext.Provider).toBeDefined();
86
+ (0, vitest_1.expect)(ShakeNbakeProvider_js_1.ShakeNbakeContext.Consumer).toBeDefined();
87
+ });
88
+ (0, vitest_1.it)('useShakeNbake is a function', () => {
89
+ (0, vitest_1.expect)(typeof useShakeNbake_js_1.useShakeNbake).toBe('function');
90
+ });
91
+ (0, vitest_1.it)('re-exports from index', async () => {
92
+ const index = await import('../index.js');
93
+ (0, vitest_1.expect)(typeof index.ShakeNbakeProvider).toBe('function');
94
+ (0, vitest_1.expect)(typeof index.useShakeNbake).toBe('function');
95
+ (0, vitest_1.expect)(index.ShakeNbakeContext).toBeDefined();
96
+ (0, vitest_1.expect)(typeof index.createFlowState).toBe('function');
97
+ (0, vitest_1.expect)(typeof index.flowReducer).toBe('function');
98
+ });
99
+ });
100
+ // ---------------------------------------------------------------------------
101
+ // 2. State machine — createFlowState
102
+ // ---------------------------------------------------------------------------
103
+ (0, vitest_1.describe)('createFlowState', () => {
104
+ (0, vitest_1.it)('returns idle state with empty data', () => {
105
+ const state = (0, state_machine_js_1.createFlowState)();
106
+ (0, vitest_1.expect)(state.step).toBe('idle');
107
+ (0, vitest_1.expect)(state.data).toEqual({});
108
+ });
109
+ });
110
+ // ---------------------------------------------------------------------------
111
+ // 3. State machine — flowReducer transitions
112
+ // ---------------------------------------------------------------------------
113
+ (0, vitest_1.describe)('flowReducer', () => {
114
+ // ---- TRIGGER ----
115
+ (0, vitest_1.it)('TRIGGER transitions idle -> triggered', () => {
116
+ const state = (0, state_machine_js_1.createFlowState)();
117
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'TRIGGER' });
118
+ (0, vitest_1.expect)(next.step).toBe('triggered');
119
+ });
120
+ (0, vitest_1.it)('TRIGGER from non-idle is a no-op', () => {
121
+ const state = { step: 'annotating', data: {} };
122
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'TRIGGER' });
123
+ (0, vitest_1.expect)(next).toBe(state);
124
+ });
125
+ // ---- CAPTURE_START ----
126
+ (0, vitest_1.it)('CAPTURE_START transitions triggered -> capturing', () => {
127
+ const state = { step: 'triggered', data: {} };
128
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'CAPTURE_START' });
129
+ (0, vitest_1.expect)(next.step).toBe('capturing');
130
+ });
131
+ (0, vitest_1.it)('CAPTURE_START from non-triggered is a no-op', () => {
132
+ const state = { step: 'idle', data: {} };
133
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'CAPTURE_START' });
134
+ (0, vitest_1.expect)(next).toBe(state);
135
+ });
136
+ // ---- CAPTURE_DONE ----
137
+ (0, vitest_1.it)('CAPTURE_DONE transitions capturing -> annotating with data', () => {
138
+ const state = { step: 'capturing', data: {} };
139
+ const captureResult = {
140
+ imageData: 'base64',
141
+ dimensions: { width: 390, height: 844 },
142
+ mimeType: 'image/png',
143
+ };
144
+ const context = { platform: { os: 'ios' } };
145
+ const next = (0, state_machine_js_1.flowReducer)(state, {
146
+ type: 'CAPTURE_DONE',
147
+ captureResult,
148
+ context,
149
+ });
150
+ (0, vitest_1.expect)(next.step).toBe('annotating');
151
+ (0, vitest_1.expect)(next.data.captureResult).toBe(captureResult);
152
+ (0, vitest_1.expect)(next.data.context).toBe(context);
153
+ });
154
+ // ---- CAPTURE_ERROR ----
155
+ (0, vitest_1.it)('CAPTURE_ERROR transitions capturing -> error', () => {
156
+ const state = { step: 'capturing', data: {} };
157
+ const next = (0, state_machine_js_1.flowReducer)(state, {
158
+ type: 'CAPTURE_ERROR',
159
+ error: 'No view ref',
160
+ });
161
+ (0, vitest_1.expect)(next.step).toBe('error');
162
+ (0, vitest_1.expect)(next.data.error).toBe('No view ref');
163
+ });
164
+ // ---- ANNOTATE_DONE ----
165
+ (0, vitest_1.it)('ANNOTATE_DONE transitions annotating -> form with screenshots', () => {
166
+ const state = {
167
+ step: 'annotating',
168
+ data: {
169
+ captureResult: {
170
+ imageData: 'base64',
171
+ dimensions: { width: 390, height: 844 },
172
+ mimeType: 'image/png',
173
+ },
174
+ context: { platform: { os: 'ios' } },
175
+ },
176
+ };
177
+ const next = (0, state_machine_js_1.flowReducer)(state, {
178
+ type: 'ANNOTATE_DONE',
179
+ annotatedScreenshot: 'annotated-base64',
180
+ originalScreenshot: 'original-base64',
181
+ });
182
+ (0, vitest_1.expect)(next.step).toBe('form');
183
+ (0, vitest_1.expect)(next.data.annotatedScreenshot).toBe('annotated-base64');
184
+ (0, vitest_1.expect)(next.data.originalScreenshot).toBe('original-base64');
185
+ // Preserves previous data
186
+ (0, vitest_1.expect)(next.data.captureResult).toBeDefined();
187
+ (0, vitest_1.expect)(next.data.context).toBeDefined();
188
+ });
189
+ // ---- ANNOTATE_CANCEL ----
190
+ (0, vitest_1.it)('ANNOTATE_CANCEL transitions annotating -> idle', () => {
191
+ const state = {
192
+ step: 'annotating',
193
+ data: { captureResult: { imageData: 'x', dimensions: { width: 0, height: 0 }, mimeType: 'image/png' } },
194
+ };
195
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'ANNOTATE_CANCEL' });
196
+ (0, vitest_1.expect)(next.step).toBe('idle');
197
+ (0, vitest_1.expect)(next.data).toEqual({});
198
+ });
199
+ // ---- RE_ANNOTATE ----
200
+ (0, vitest_1.it)('RE_ANNOTATE transitions form -> annotating, preserving capture data', () => {
201
+ const captureResult = {
202
+ imageData: 'base64',
203
+ dimensions: { width: 390, height: 844 },
204
+ mimeType: 'image/png',
205
+ };
206
+ const state = {
207
+ step: 'form',
208
+ data: {
209
+ captureResult,
210
+ context: { platform: { os: 'ios' } },
211
+ annotatedScreenshot: 'old-annotated',
212
+ originalScreenshot: 'old-original',
213
+ },
214
+ };
215
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'RE_ANNOTATE' });
216
+ (0, vitest_1.expect)(next.step).toBe('annotating');
217
+ (0, vitest_1.expect)(next.data.captureResult).toBe(captureResult);
218
+ // Screenshot data should be cleared (re-annotation will produce new ones)
219
+ (0, vitest_1.expect)(next.data.annotatedScreenshot).toBeUndefined();
220
+ });
221
+ // ---- SUBMIT_START ----
222
+ (0, vitest_1.it)('SUBMIT_START transitions form -> submitting', () => {
223
+ const state = {
224
+ step: 'form',
225
+ data: { annotatedScreenshot: 'a', originalScreenshot: 'b' },
226
+ };
227
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'SUBMIT_START' });
228
+ (0, vitest_1.expect)(next.step).toBe('submitting');
229
+ (0, vitest_1.expect)(next.data.annotatedScreenshot).toBe('a');
230
+ });
231
+ // ---- SUBMIT_DONE ----
232
+ (0, vitest_1.it)('SUBMIT_DONE transitions submitting -> success with result', () => {
233
+ const state = {
234
+ step: 'submitting',
235
+ data: { annotatedScreenshot: 'a', originalScreenshot: 'b' },
236
+ };
237
+ const result = { url: 'https://example.com', id: '1', success: true };
238
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'SUBMIT_DONE', result });
239
+ (0, vitest_1.expect)(next.step).toBe('success');
240
+ (0, vitest_1.expect)(next.data.submitResult).toBe(result);
241
+ });
242
+ // ---- SUBMIT_ERROR ----
243
+ (0, vitest_1.it)('SUBMIT_ERROR transitions submitting -> error', () => {
244
+ const state = {
245
+ step: 'submitting',
246
+ data: { annotatedScreenshot: 'a', originalScreenshot: 'b' },
247
+ };
248
+ const next = (0, state_machine_js_1.flowReducer)(state, {
249
+ type: 'SUBMIT_ERROR',
250
+ error: 'Upload failed',
251
+ });
252
+ (0, vitest_1.expect)(next.step).toBe('error');
253
+ (0, vitest_1.expect)(next.data.error).toBe('Upload failed');
254
+ // Preserves screenshot data for potential retry
255
+ (0, vitest_1.expect)(next.data.annotatedScreenshot).toBe('a');
256
+ });
257
+ // ---- RETRY ----
258
+ (0, vitest_1.it)('RETRY from error with form data goes back to form', () => {
259
+ const state = {
260
+ step: 'error',
261
+ data: {
262
+ annotatedScreenshot: 'a',
263
+ originalScreenshot: 'b',
264
+ error: 'Upload failed',
265
+ },
266
+ };
267
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'RETRY' });
268
+ (0, vitest_1.expect)(next.step).toBe('form');
269
+ (0, vitest_1.expect)(next.data.error).toBeUndefined();
270
+ (0, vitest_1.expect)(next.data.annotatedScreenshot).toBe('a');
271
+ });
272
+ (0, vitest_1.it)('RETRY from error without form data resets to idle', () => {
273
+ const state = {
274
+ step: 'error',
275
+ data: { error: 'Capture failed' },
276
+ };
277
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'RETRY' });
278
+ (0, vitest_1.expect)(next.step).toBe('idle');
279
+ (0, vitest_1.expect)(next.data).toEqual({});
280
+ });
281
+ (0, vitest_1.it)('RETRY from non-error is a no-op', () => {
282
+ const state = { step: 'form', data: {} };
283
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'RETRY' });
284
+ (0, vitest_1.expect)(next).toBe(state);
285
+ });
286
+ // ---- RESET ----
287
+ (0, vitest_1.it)('RESET always goes back to idle', () => {
288
+ const steps = [
289
+ 'idle',
290
+ 'triggered',
291
+ 'capturing',
292
+ 'annotating',
293
+ 'form',
294
+ 'submitting',
295
+ 'success',
296
+ 'error',
297
+ ];
298
+ for (const step of steps) {
299
+ const state = { step, data: { error: 'test' } };
300
+ const next = (0, state_machine_js_1.flowReducer)(state, { type: 'RESET' });
301
+ (0, vitest_1.expect)(next.step).toBe('idle');
302
+ (0, vitest_1.expect)(next.data).toEqual({});
303
+ }
304
+ });
305
+ });
306
+ // ---------------------------------------------------------------------------
307
+ // 4. Full flow scenario
308
+ // ---------------------------------------------------------------------------
309
+ (0, vitest_1.describe)('Full flow state machine scenario', () => {
310
+ (0, vitest_1.it)('follows complete happy path: idle -> triggered -> capturing -> annotating -> form -> submitting -> success -> idle', () => {
311
+ let state = (0, state_machine_js_1.createFlowState)();
312
+ // Step 1: Trigger
313
+ state = (0, state_machine_js_1.flowReducer)(state, { type: 'TRIGGER' });
314
+ (0, vitest_1.expect)(state.step).toBe('triggered');
315
+ // Step 2: Capture starts
316
+ state = (0, state_machine_js_1.flowReducer)(state, { type: 'CAPTURE_START' });
317
+ (0, vitest_1.expect)(state.step).toBe('capturing');
318
+ // Step 3: Capture completes
319
+ const captureResult = {
320
+ imageData: 'screenshot-base64',
321
+ dimensions: { width: 390, height: 844 },
322
+ mimeType: 'image/png',
323
+ };
324
+ state = (0, state_machine_js_1.flowReducer)(state, {
325
+ type: 'CAPTURE_DONE',
326
+ captureResult,
327
+ context: { platform: { os: 'ios' } },
328
+ });
329
+ (0, vitest_1.expect)(state.step).toBe('annotating');
330
+ (0, vitest_1.expect)(state.data.captureResult).toEqual(captureResult);
331
+ // Step 4: Annotation done
332
+ state = (0, state_machine_js_1.flowReducer)(state, {
333
+ type: 'ANNOTATE_DONE',
334
+ annotatedScreenshot: 'annotated-base64',
335
+ originalScreenshot: 'original-base64',
336
+ });
337
+ (0, vitest_1.expect)(state.step).toBe('form');
338
+ (0, vitest_1.expect)(state.data.annotatedScreenshot).toBe('annotated-base64');
339
+ // Step 5: Submit starts
340
+ state = (0, state_machine_js_1.flowReducer)(state, { type: 'SUBMIT_START' });
341
+ (0, vitest_1.expect)(state.step).toBe('submitting');
342
+ // Step 6: Submit succeeds
343
+ const result = { url: 'https://linear.app/123', id: '123', success: true };
344
+ state = (0, state_machine_js_1.flowReducer)(state, { type: 'SUBMIT_DONE', result });
345
+ (0, vitest_1.expect)(state.step).toBe('success');
346
+ (0, vitest_1.expect)(state.data.submitResult).toEqual(result);
347
+ // Step 7: Reset
348
+ state = (0, state_machine_js_1.flowReducer)(state, { type: 'RESET' });
349
+ (0, vitest_1.expect)(state.step).toBe('idle');
350
+ });
351
+ (0, vitest_1.it)('handles retry after submit error', () => {
352
+ let state = {
353
+ step: 'submitting',
354
+ data: {
355
+ annotatedScreenshot: 'a',
356
+ originalScreenshot: 'b',
357
+ captureResult: {
358
+ imageData: 'x',
359
+ dimensions: { width: 390, height: 844 },
360
+ mimeType: 'image/png',
361
+ },
362
+ },
363
+ };
364
+ // Submit fails
365
+ state = (0, state_machine_js_1.flowReducer)(state, {
366
+ type: 'SUBMIT_ERROR',
367
+ error: 'Network error',
368
+ });
369
+ (0, vitest_1.expect)(state.step).toBe('error');
370
+ (0, vitest_1.expect)(state.data.error).toBe('Network error');
371
+ // Retry goes back to form
372
+ state = (0, state_machine_js_1.flowReducer)(state, { type: 'RETRY' });
373
+ (0, vitest_1.expect)(state.step).toBe('form');
374
+ (0, vitest_1.expect)(state.data.annotatedScreenshot).toBe('a');
375
+ (0, vitest_1.expect)(state.data.error).toBeUndefined();
376
+ });
377
+ (0, vitest_1.it)('handles re-annotate from form', () => {
378
+ const captureResult = {
379
+ imageData: 'screenshot',
380
+ dimensions: { width: 390, height: 844 },
381
+ mimeType: 'image/png',
382
+ };
383
+ let state = {
384
+ step: 'form',
385
+ data: {
386
+ captureResult,
387
+ context: { platform: { os: 'ios' } },
388
+ annotatedScreenshot: 'old-annotation',
389
+ originalScreenshot: 'old-original',
390
+ },
391
+ };
392
+ // Re-annotate goes back to annotating
393
+ state = (0, state_machine_js_1.flowReducer)(state, { type: 'RE_ANNOTATE' });
394
+ (0, vitest_1.expect)(state.step).toBe('annotating');
395
+ (0, vitest_1.expect)(state.data.captureResult).toBe(captureResult);
396
+ // New annotation done
397
+ state = (0, state_machine_js_1.flowReducer)(state, {
398
+ type: 'ANNOTATE_DONE',
399
+ annotatedScreenshot: 'new-annotation',
400
+ originalScreenshot: 'new-original',
401
+ });
402
+ (0, vitest_1.expect)(state.step).toBe('form');
403
+ (0, vitest_1.expect)(state.data.annotatedScreenshot).toBe('new-annotation');
404
+ });
405
+ });
406
+ // ---------------------------------------------------------------------------
407
+ // 5. UseShakeNbakeResult type shape
408
+ // ---------------------------------------------------------------------------
409
+ (0, vitest_1.describe)('UseShakeNbakeResult type shape', () => {
410
+ (0, vitest_1.it)('compiles with correct shape', () => {
411
+ const mockResult = {
412
+ trigger: vitest_1.vi.fn(),
413
+ isOpen: false,
414
+ currentStep: 'idle',
415
+ config: {
416
+ enabled: true,
417
+ destination: {
418
+ name: 'mock',
419
+ uploadImage: vitest_1.vi.fn().mockResolvedValue('url'),
420
+ createIssue: vitest_1.vi.fn().mockResolvedValue({ url: '', id: '', success: true }),
421
+ testConnection: vitest_1.vi.fn().mockResolvedValue(true),
422
+ },
423
+ },
424
+ };
425
+ (0, vitest_1.expect)(typeof mockResult.trigger).toBe('function');
426
+ (0, vitest_1.expect)(mockResult.isOpen).toBe(false);
427
+ (0, vitest_1.expect)(mockResult.currentStep).toBe('idle');
428
+ (0, vitest_1.expect)(mockResult.config.enabled).toBe(true);
429
+ });
430
+ });
431
+ //# sourceMappingURL=provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.test.js","sourceRoot":"","sources":["../../src/__tests__/provider.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=report-form.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-form.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/report-form.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // Tests for ReportForm — module exports, validation logic, type shapes
4
+ //
5
+ // Since we cannot render React Native components in a vitest/node
6
+ // environment, we focus on:
7
+ // 1. Module exports are correctly shaped
8
+ // 2. Pure validation logic (form-validation.ts)
9
+ // 3. ReportFormProps type shapes compile correctly
10
+ // ---------------------------------------------------------------------------
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const vitest_1 = require("vitest");
13
+ // ---------------------------------------------------------------------------
14
+ // Mock peer deps before imports
15
+ // ---------------------------------------------------------------------------
16
+ vitest_1.vi.mock('react-native', () => ({
17
+ View: 'View',
18
+ Text: 'Text',
19
+ TextInput: 'TextInput',
20
+ TouchableOpacity: 'TouchableOpacity',
21
+ ScrollView: 'ScrollView',
22
+ Modal: 'Modal',
23
+ Image: 'Image',
24
+ ActivityIndicator: 'ActivityIndicator',
25
+ KeyboardAvoidingView: 'KeyboardAvoidingView',
26
+ Platform: { OS: 'ios' },
27
+ StyleSheet: {
28
+ create: (styles) => styles,
29
+ },
30
+ Linking: {
31
+ openURL: vitest_1.vi.fn(),
32
+ },
33
+ Alert: {
34
+ alert: vitest_1.vi.fn(),
35
+ },
36
+ }));
37
+ // ---------------------------------------------------------------------------
38
+ // Imports (after mocks)
39
+ // ---------------------------------------------------------------------------
40
+ const ReportForm_js_1 = require("../ui/ReportForm.js");
41
+ const form_validation_js_1 = require("../ui/form-validation.js");
42
+ // ---------------------------------------------------------------------------
43
+ // 1. Module exports
44
+ // ---------------------------------------------------------------------------
45
+ (0, vitest_1.describe)('ReportForm module exports', () => {
46
+ (0, vitest_1.it)('ReportForm is a function component', () => {
47
+ (0, vitest_1.expect)(typeof ReportForm_js_1.ReportForm).toBe('function');
48
+ });
49
+ (0, vitest_1.it)('re-exports from index', async () => {
50
+ const index = await import('../index.js');
51
+ (0, vitest_1.expect)(typeof index.ReportForm).toBe('function');
52
+ (0, vitest_1.expect)(typeof index.validateTitle).toBe('function');
53
+ (0, vitest_1.expect)(typeof index.validateForm).toBe('function');
54
+ (0, vitest_1.expect)(typeof index.isFormValid).toBe('function');
55
+ });
56
+ });
57
+ // ---------------------------------------------------------------------------
58
+ // 2. Form validation — validateTitle
59
+ // ---------------------------------------------------------------------------
60
+ (0, vitest_1.describe)('validateTitle', () => {
61
+ (0, vitest_1.it)('returns error for empty string', () => {
62
+ const error = (0, form_validation_js_1.validateTitle)('');
63
+ (0, vitest_1.expect)(error).not.toBeNull();
64
+ (0, vitest_1.expect)(error.field).toBe('title');
65
+ (0, vitest_1.expect)(error.message).toBe('Title is required');
66
+ });
67
+ (0, vitest_1.it)('returns error for whitespace-only string', () => {
68
+ const error = (0, form_validation_js_1.validateTitle)(' ');
69
+ (0, vitest_1.expect)(error).not.toBeNull();
70
+ (0, vitest_1.expect)(error.field).toBe('title');
71
+ (0, vitest_1.expect)(error.message).toBe('Title is required');
72
+ });
73
+ (0, vitest_1.it)('returns error for 1-2 character string', () => {
74
+ (0, vitest_1.expect)((0, form_validation_js_1.validateTitle)('ab')).not.toBeNull();
75
+ (0, vitest_1.expect)((0, form_validation_js_1.validateTitle)('ab').message).toBe('Title must be at least 3 characters');
76
+ });
77
+ (0, vitest_1.it)('returns error for 2 chars after trim', () => {
78
+ const error = (0, form_validation_js_1.validateTitle)(' ab ');
79
+ (0, vitest_1.expect)(error).not.toBeNull();
80
+ (0, vitest_1.expect)(error.message).toBe('Title must be at least 3 characters');
81
+ });
82
+ (0, vitest_1.it)('returns null for exactly 3 characters', () => {
83
+ (0, vitest_1.expect)((0, form_validation_js_1.validateTitle)('abc')).toBeNull();
84
+ });
85
+ (0, vitest_1.it)('returns null for longer strings', () => {
86
+ (0, vitest_1.expect)((0, form_validation_js_1.validateTitle)('This is a valid title')).toBeNull();
87
+ });
88
+ (0, vitest_1.it)('returns null for 3 chars with surrounding whitespace', () => {
89
+ (0, vitest_1.expect)((0, form_validation_js_1.validateTitle)(' abc ')).toBeNull();
90
+ });
91
+ });
92
+ // ---------------------------------------------------------------------------
93
+ // 3. Form validation — validateForm
94
+ // ---------------------------------------------------------------------------
95
+ (0, vitest_1.describe)('validateForm', () => {
96
+ (0, vitest_1.it)('returns empty array for valid form', () => {
97
+ const errors = (0, form_validation_js_1.validateForm)({ title: 'Valid title' });
98
+ (0, vitest_1.expect)(errors).toHaveLength(0);
99
+ });
100
+ (0, vitest_1.it)('returns array with title error for empty title', () => {
101
+ const errors = (0, form_validation_js_1.validateForm)({ title: '' });
102
+ (0, vitest_1.expect)(errors).toHaveLength(1);
103
+ (0, vitest_1.expect)(errors[0].field).toBe('title');
104
+ });
105
+ (0, vitest_1.it)('returns array with title error for short title', () => {
106
+ const errors = (0, form_validation_js_1.validateForm)({ title: 'ab' });
107
+ (0, vitest_1.expect)(errors).toHaveLength(1);
108
+ (0, vitest_1.expect)(errors[0].field).toBe('title');
109
+ });
110
+ });
111
+ // ---------------------------------------------------------------------------
112
+ // 4. Form validation — isFormValid
113
+ // ---------------------------------------------------------------------------
114
+ (0, vitest_1.describe)('isFormValid', () => {
115
+ (0, vitest_1.it)('returns true for valid title', () => {
116
+ (0, vitest_1.expect)((0, form_validation_js_1.isFormValid)({ title: 'Valid title' })).toBe(true);
117
+ });
118
+ (0, vitest_1.it)('returns false for empty title', () => {
119
+ (0, vitest_1.expect)((0, form_validation_js_1.isFormValid)({ title: '' })).toBe(false);
120
+ });
121
+ (0, vitest_1.it)('returns false for short title', () => {
122
+ (0, vitest_1.expect)((0, form_validation_js_1.isFormValid)({ title: 'ab' })).toBe(false);
123
+ });
124
+ });
125
+ // ---------------------------------------------------------------------------
126
+ // 5. Type shape validation (compile-time)
127
+ // ---------------------------------------------------------------------------
128
+ (0, vitest_1.describe)('ReportFormProps type shape', () => {
129
+ (0, vitest_1.it)('can construct a valid ReportFormProps object', () => {
130
+ const mockSubmit = vitest_1.vi.fn().mockResolvedValue({
131
+ url: 'https://linear.app/issue/123',
132
+ id: '123',
133
+ success: true,
134
+ });
135
+ const mockCancel = vitest_1.vi.fn();
136
+ const props = {
137
+ annotatedScreenshot: 'base64data',
138
+ originalScreenshot: 'base64data',
139
+ dimensions: { width: 390, height: 844 },
140
+ context: {
141
+ platform: { os: 'ios' },
142
+ device: { model: 'iPhone 15' },
143
+ },
144
+ onSubmit: mockSubmit,
145
+ onCancel: mockCancel,
146
+ onReAnnotate: vitest_1.vi.fn(),
147
+ theme: 'dark',
148
+ accentColor: '#007AFF',
149
+ };
150
+ (0, vitest_1.expect)(props.annotatedScreenshot).toBe('base64data');
151
+ (0, vitest_1.expect)(props.dimensions.width).toBe(390);
152
+ (0, vitest_1.expect)(props.theme).toBe('dark');
153
+ });
154
+ (0, vitest_1.it)('accepts minimal props (optional fields omitted)', () => {
155
+ const props = {
156
+ annotatedScreenshot: 'base64data',
157
+ originalScreenshot: 'base64data',
158
+ dimensions: { width: 390, height: 844 },
159
+ context: {},
160
+ onSubmit: vitest_1.vi.fn().mockResolvedValue({ url: '', id: '', success: true }),
161
+ onCancel: vitest_1.vi.fn(),
162
+ };
163
+ (0, vitest_1.expect)(props.theme).toBeUndefined();
164
+ (0, vitest_1.expect)(props.onReAnnotate).toBeUndefined();
165
+ (0, vitest_1.expect)(props.accentColor).toBeUndefined();
166
+ });
167
+ });
168
+ // ---------------------------------------------------------------------------
169
+ // 6. FieldError type shape
170
+ // ---------------------------------------------------------------------------
171
+ (0, vitest_1.describe)('FieldError type shape', () => {
172
+ (0, vitest_1.it)('has field and message properties', () => {
173
+ const error = { field: 'title', message: 'Title is required' };
174
+ (0, vitest_1.expect)(error.field).toBe('title');
175
+ (0, vitest_1.expect)(error.message).toBe('Title is required');
176
+ });
177
+ });
178
+ //# sourceMappingURL=report-form.test.js.map