|
| 1 | +# Contributing to OpenCode Smart Voice Notify |
| 2 | + |
| 3 | +Thank you for your interest in contributing to OpenCode Smart Voice Notify! This document provides guidelines for development, testing, and submitting contributions. |
| 4 | + |
| 5 | +## Development Environment Setup |
| 6 | + |
| 7 | +1. **Clone the repository**: |
| 8 | + ```bash |
| 9 | + git clone https://github.com/MasuRii/opencode-smart-voice-notify.git |
| 10 | + cd opencode-smart-voice-notify |
| 11 | + ``` |
| 12 | + |
| 13 | +2. **Install dependencies**: |
| 14 | + We recommend using [Bun](https://bun.sh) for the fastest development experience, but `npm` also works. |
| 15 | + ```bash |
| 16 | + bun install |
| 17 | + # or |
| 18 | + npm install |
| 19 | + ``` |
| 20 | + |
| 21 | +3. **Link to OpenCode**: |
| 22 | + Add the local path to your `~/.config/opencode/opencode.json`: |
| 23 | + ```json |
| 24 | + { |
| 25 | + "plugin": ["file:///path/to/opencode-smart-voice-notify"] |
| 26 | + } |
| 27 | + ``` |
| 28 | + |
| 29 | +## Testing Guidelines |
| 30 | + |
| 31 | +We take testing seriously. All new features and bug fixes should include appropriate tests. |
| 32 | + |
| 33 | +### Running Tests |
| 34 | + |
| 35 | +The project uses Bun's built-in test runner. |
| 36 | + |
| 37 | +```bash |
| 38 | +# Run all tests |
| 39 | +bun test |
| 40 | + |
| 41 | +# Run tests with coverage report |
| 42 | +bun test --coverage |
| 43 | + |
| 44 | +# Run tests in watch mode (useful during development) |
| 45 | +bun test --watch |
| 46 | + |
| 47 | +# Run a specific test file |
| 48 | +bun test tests/unit/config.test.js |
| 49 | +``` |
| 50 | + |
| 51 | +### Test File Naming & Location |
| 52 | + |
| 53 | +- **Unit Tests**: Place in `tests/unit/`. Name files as `[module].test.js`. |
| 54 | +- **E2E Tests**: Place in `tests/e2e/`. Name files as `[feature].test.js`. |
| 55 | +- **Integration Tests**: Place in `tests/integration/`. These tests use real API credentials. |
| 56 | + |
| 57 | +### Test Infrastructure |
| 58 | + |
| 59 | +We provide a comprehensive test setup in `tests/setup.js` which is preloaded for all tests. It includes utilities for: |
| 60 | + |
| 61 | +- **Filesystem Isolation**: `createTestTempDir()` creates a sandbox for each test. |
| 62 | +- **Config Mocks**: `createTestConfig()` and `createMinimalConfig()`. |
| 63 | +- **Shell Mocking**: `createMockShellRunner()` to intercept and verify shell commands. |
| 64 | +- **SDK Mocking**: `createMockClient()` to simulate the OpenCode SDK environment. |
| 65 | +- **Event Mocks**: `createMockEvent` and `mockEvents` factory for plugin events. |
| 66 | + |
| 67 | +### Coverage Requirements |
| 68 | + |
| 69 | +We maintain a high standard for code coverage. |
| 70 | +- **Minimum Requirement**: 70% line coverage for all new code. |
| 71 | +- **Ideal**: 90%+ function coverage. |
| 72 | +- PRs that significantly decrease overall coverage may be rejected or require additional tests. |
| 73 | + |
| 74 | +## Mock Usage Guidelines |
| 75 | + |
| 76 | +Avoid using real system calls or external APIs in unit and E2E tests. |
| 77 | + |
| 78 | +### Shell Commands |
| 79 | +Instead of using the real `$` shell runner, use `createMockShellRunner()`: |
| 80 | +```javascript |
| 81 | +import { createMockShellRunner } from '../setup.js'; |
| 82 | + |
| 83 | +const mockShell = createMockShellRunner({ |
| 84 | + handler: (command) => { |
| 85 | + if (command.includes('osascript')) return { stdout: Buffer.from('iTerm2') }; |
| 86 | + return { exitCode: 0 }; |
| 87 | + } |
| 88 | +}); |
| 89 | + |
| 90 | +// Use it in your tests |
| 91 | +await mockShell`echo "hello"`; |
| 92 | +expect(mockShell.getCallCount()).toBe(1); |
| 93 | +``` |
| 94 | + |
| 95 | +### OpenCode Client |
| 96 | +Use `createMockClient()` to verify interactions with the OpenCode TUI, sessions, and permissions: |
| 97 | +```javascript |
| 98 | +import { createMockClient } from '../setup.js'; |
| 99 | + |
| 100 | +const client = createMockClient(); |
| 101 | +await client.tui.showToast({ body: { message: 'Hello' } }); |
| 102 | +expect(client.tui.getToastCalls()[0].message).toBe('Hello'); |
| 103 | +``` |
| 104 | + |
| 105 | +## Integration Testing (Credentials) |
| 106 | + |
| 107 | +If you need to test real cloud APIs (ElevenLabs, OpenAI, etc.): |
| 108 | +1. Copy `tests/.env.example` to `tests/.env.local`. |
| 109 | +2. Fill in your real API keys. |
| 110 | +3. Run `bun test tests/integration/`. |
| 111 | + |
| 112 | +**NEVER** commit `tests/.env.local` to the repository. It is included in `.gitignore` by default. |
| 113 | + |
| 114 | +## Coding Standards |
| 115 | + |
| 116 | +- Use **ESM** (ECMAScript Modules) syntax (`import`/`export`). |
| 117 | +- Follow the existing code style (use 2 spaces for indentation). |
| 118 | +- Add JSDoc comments for all new functions and modules. |
| 119 | +- Ensure `bun run typecheck` (if available) or basic linting passes. |
| 120 | + |
| 121 | +## Pull Request Process |
| 122 | + |
| 123 | +1. Create a new branch for your feature or bug fix. |
| 124 | +2. Implement your changes and add tests. |
| 125 | +3. Verify all tests pass locally (`bun test`). |
| 126 | +4. Ensure your changes follow the existing architecture patterns. |
| 127 | +5. Submit a PR with a clear description of what changed and why. |
| 128 | + |
| 129 | +Thank you for contributing! |
0 commit comments