UNPKG

@letanure/resend-cli

Version:

A command-line interface for Resend email API

144 lines 7.22 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { render } from 'ink-testing-library'; import { describe, expect, it, vi } from 'vitest'; import { z } from 'zod'; import { SimpleForm } from './SimpleForm.js'; describe('SimpleForm', () => { const textFields = [ { name: 'email', label: 'Email', placeholder: 'user@example.com', helpText: 'Enter your email address', type: 'text', }, ]; const selectFields = [ { name: 'subscribed', label: 'Subscription', type: 'select', options: [ { value: true, label: 'Yes', color: 'green' }, { value: false, label: 'No', color: 'red' }, ], }, ]; const mixedFields = [...textFields, ...selectFields]; const mockOnSubmit = vi.fn(); const mockOnCancel = vi.fn(); it('should render text fields', () => { const { lastFrame } = render(_jsx(SimpleForm, { fields: textFields, onSubmit: mockOnSubmit, onCancel: mockOnCancel })); expect(lastFrame()).toContain('Email'); expect(lastFrame()).toContain('Enter your email address'); }); it('should render select fields', () => { const { lastFrame } = render(_jsx(SimpleForm, { fields: selectFields, onSubmit: mockOnSubmit, onCancel: mockOnCancel })); expect(lastFrame()).toContain('Subscription'); expect(lastFrame()).toContain('[✓] Yes'); expect(lastFrame()).toContain('[ ] No'); expect(lastFrame()).toContain('Use ←/→ or Space'); }); it('should render mixed field types', () => { const { lastFrame } = render(_jsx(SimpleForm, { fields: mixedFields, onSubmit: mockOnSubmit, onCancel: mockOnCancel })); expect(lastFrame()).toContain('Email'); expect(lastFrame()).toContain('Subscription'); expect(lastFrame()).toContain('[✓] Yes'); }); it('should show validation schema in action', () => { const schema = z.object({ email: z.string().email(), subscribed: z.boolean(), }); const { lastFrame } = render(_jsx(SimpleForm, { fields: mixedFields, validateWith: schema, onSubmit: mockOnSubmit, onCancel: mockOnCancel })); expect(lastFrame()).toContain('Email'); expect(lastFrame()).toContain('Subscription'); }); it('should handle select field default values', () => { const { lastFrame } = render(_jsx(SimpleForm, { fields: selectFields, onSubmit: mockOnSubmit, onCancel: mockOnCancel })); // First option should be selected by default expect(lastFrame()).toContain('[✓] Yes'); expect(lastFrame()).toContain('[ ] No'); }); it('should handle circular navigation with Tab key', async () => { const multipleFields = [ { name: 'field1', label: 'Field 1', type: 'text' }, { name: 'field2', label: 'Field 2', type: 'text' }, { name: 'field3', label: 'Field 3', type: 'text' }, ]; const { stdin } = render(_jsx(SimpleForm, { fields: multipleFields, onSubmit: mockOnSubmit, onCancel: mockOnCancel })); // Navigate to last field then press Tab to wrap to first stdin.write('\t'); // Go to field 2 await new Promise((resolve) => setTimeout(resolve, 10)); stdin.write('\t'); // Go to field 3 (last) await new Promise((resolve) => setTimeout(resolve, 10)); stdin.write('\t'); // Should wrap to field 1 (first) await new Promise((resolve) => setTimeout(resolve, 10)); // Test passes if no errors thrown and navigation works expect(true).toBe(true); }); it('should handle circular navigation with Shift+Tab key', async () => { const multipleFields = [ { name: 'field1', label: 'Field 1', type: 'text' }, { name: 'field2', label: 'Field 2', type: 'text' }, { name: 'field3', label: 'Field 3', type: 'text' }, ]; const { stdin } = render(_jsx(SimpleForm, { fields: multipleFields, onSubmit: mockOnSubmit, onCancel: mockOnCancel })); // Start at first field, press Shift+Tab to wrap to last stdin.write('\u001B[Z'); // Shift+Tab (should wrap to last field) await new Promise((resolve) => setTimeout(resolve, 10)); // Test passes if no errors thrown and navigation works expect(true).toBe(true); }); it('should handle circular navigation with arrow keys', async () => { const multipleFields = [ { name: 'field1', label: 'Field 1', type: 'text' }, { name: 'field2', label: 'Field 2', type: 'text' }, { name: 'field3', label: 'Field 3', type: 'text' }, ]; const { stdin } = render(_jsx(SimpleForm, { fields: multipleFields, onSubmit: mockOnSubmit, onCancel: mockOnCancel })); // Test down arrow from last field wraps to first stdin.write('\u001B[B'); // Down arrow to field 2 await new Promise((resolve) => setTimeout(resolve, 10)); stdin.write('\u001B[B'); // Down arrow to field 3 (last) await new Promise((resolve) => setTimeout(resolve, 10)); stdin.write('\u001B[B'); // Down arrow should wrap to field 1 (first) await new Promise((resolve) => setTimeout(resolve, 10)); // Test up arrow from first field wraps to last stdin.write('\u001B[A'); // Up arrow should wrap to field 3 (last) await new Promise((resolve) => setTimeout(resolve, 10)); // Test passes if no errors thrown and navigation works expect(true).toBe(true); }); it('should handle non-circular navigation with stacked select fields', async () => { const stackedSelectFields = [ { name: 'field1', label: 'Field 1', type: 'text' }, { name: 'priority', label: 'Priority', type: 'select', display: 'stacked', options: [ { value: 'low', label: 'Low' }, { value: 'medium', label: 'Medium' }, { value: 'high', label: 'High' }, ], }, { name: 'field3', label: 'Field 3', type: 'text' }, ]; const { stdin } = render(_jsx(SimpleForm, { fields: stackedSelectFields, onSubmit: mockOnSubmit, onCancel: mockOnCancel })); // Navigate to stacked select field stdin.write('\u001B[B'); // Go to select field await new Promise((resolve) => setTimeout(resolve, 10)); // Navigate to last option then down should move to next field (non-circular) stdin.write('\u001B[B'); // Go to medium option await new Promise((resolve) => setTimeout(resolve, 10)); stdin.write('\u001B[B'); // Go to high option (last) await new Promise((resolve) => setTimeout(resolve, 10)); stdin.write('\u001B[B'); // Should move to next field (non-circular) await new Promise((resolve) => setTimeout(resolve, 10)); // Test passes if no errors thrown and navigation works expect(true).toBe(true); }); }); //# sourceMappingURL=SimpleForm.test.js.map