|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Flutter Hooks Test is a testing utility library for Flutter hooks, inspired by React's `react-hooks-testing-library`. It provides a simple API to test custom hooks in isolation. |
| 8 | + |
| 9 | +## Development Commands |
| 10 | + |
| 11 | +### Essential Commands |
| 12 | + |
| 13 | +```bash |
| 14 | +# Install dependencies |
| 15 | +melos get |
| 16 | +bun install |
| 17 | + |
| 18 | +# Run tests |
| 19 | +melos test |
| 20 | + |
| 21 | +# Run code analysis |
| 22 | +melos analyze |
| 23 | + |
| 24 | +# Format code (Dart + Prettier) |
| 25 | +melos format |
| 26 | + |
| 27 | +# Run all checks (analyze + format + test) |
| 28 | +melos analyze && melos format && melos test |
| 29 | + |
| 30 | +# Run a single test file |
| 31 | +flutter test test/flutter_hooks_test_test.dart |
| 32 | + |
| 33 | +# Run tests with coverage |
| 34 | +flutter test --coverage |
| 35 | +``` |
| 36 | + |
| 37 | +### Additional Commands |
| 38 | + |
| 39 | +```bash |
| 40 | +# Upgrade dependencies |
| 41 | +melos upgrade |
| 42 | + |
| 43 | +# Clean build artifacts |
| 44 | +melos clean |
| 45 | + |
| 46 | +# Format with Prettier only |
| 47 | +bun run format |
| 48 | + |
| 49 | +# Setup git hooks |
| 50 | +bun run prepare |
| 51 | +``` |
| 52 | + |
| 53 | +## Architecture and Code Structure |
| 54 | + |
| 55 | +### Core API |
| 56 | + |
| 57 | +The library exports a single file `lib/flutter_hooks_test.dart` containing: |
| 58 | + |
| 59 | +1. **`buildHook<T, P>`** - Main function to test hooks |
| 60 | + |
| 61 | + - Generic `T`: Return type of the hook |
| 62 | + - Generic `P`: Props type for parameterized hooks |
| 63 | + - Returns `_HookTestingAction<T>` with methods: |
| 64 | + - `current`: Access current hook value |
| 65 | + - `rebuild([props])`: Trigger rebuild with optional new props |
| 66 | + - `unmount()`: Unmount the hook |
| 67 | + |
| 68 | +2. **`act`** - Wraps state changes to ensure proper Flutter test lifecycle |
| 69 | + - Similar to React's `act` function |
| 70 | + - Required when changing hook state |
| 71 | + |
| 72 | +### Testing Pattern |
| 73 | + |
| 74 | +```dart |
| 75 | +// Basic hook test structure |
| 76 | +final result = await buildHook((_) => useMyHook()); |
| 77 | +await act(() => result.current.doSomething()); |
| 78 | +expect(result.current.value, expectedValue); |
| 79 | +
|
| 80 | +// With wrapper widget |
| 81 | +final result = await buildHook( |
| 82 | + (_) => useMyHook(), |
| 83 | + wrapper: (child) => Provider(child: child), |
| 84 | +); |
| 85 | +``` |
| 86 | + |
| 87 | +### Internal Implementation |
| 88 | + |
| 89 | +- Uses `TestWidgetsFlutterBinding` for test environment |
| 90 | +- Creates a minimal widget tree with `HookBuilder` |
| 91 | +- Manages completer-based async operations for mount/unmount |
| 92 | +- Preserves hook state across rebuilds using keys |
| 93 | + |
| 94 | +## Testing Approach |
| 95 | + |
| 96 | +- All tests go in `test/` directory |
| 97 | +- Example hooks in `test/hooks/` demonstrate testable patterns |
| 98 | +- Use `testWidgets` for widget-based tests |
| 99 | +- Use Mockito for mocking dependencies |
| 100 | + |
| 101 | +## Code Quality |
| 102 | + |
| 103 | +- Flutter lints are enforced via `analysis_options.yaml` |
| 104 | +- Example directory is excluded from analysis |
| 105 | +- Pre-commit hooks format code automatically |
| 106 | +- CI runs on Ubuntu with asdf version management |
| 107 | + |
| 108 | +## Important Conventions |
| 109 | + |
| 110 | +1. **Type Safety**: Always specify generic types when using `buildHook` |
| 111 | +2. **Act Wrapper**: Always wrap state changes in `act()` |
| 112 | +3. **Async Handling**: Most operations return Futures - use `await` |
| 113 | +4. **Testing**: Test both happy paths and edge cases (mount/unmount/rebuild) |
| 114 | + |
| 115 | +## Version Requirements |
| 116 | + |
| 117 | +- Dart SDK: `>=2.17.0 <4.0.0` |
| 118 | +- Flutter: `>=3.20.0` |
| 119 | +- Uses Flutter hooks `^0.21.2` |
| 120 | + |
| 121 | +## Release Process |
| 122 | + |
| 123 | +Releases are fully automated via GitHub Actions: |
| 124 | + |
| 125 | +### Creating a Release |
| 126 | + |
| 127 | +1. **Update version**: Update version in `pubspec.yaml` |
| 128 | +2. **Update changelog**: Run `git cliff --unreleased --tag v1.0.1 --output CHANGELOG.md` |
| 129 | +3. **Commit changes**: `git commit -am "chore(release): prepare for v1.0.1"` |
| 130 | +4. **Create tag**: `git tag v1.0.1` |
| 131 | +5. **Push**: `git push origin main --tags` |
| 132 | + |
| 133 | +### Automated Release Steps |
| 134 | + |
| 135 | +When a tag matching `v[0-9]+.[0-9]+.[0-9]+*` is pushed: |
| 136 | + |
| 137 | +1. **CI Validation**: All tests, formatting, and analysis must pass |
| 138 | +2. **Dry Run**: Package publication is tested |
| 139 | +3. **Release Notes**: Auto-generated using git-cliff from conventional commits |
| 140 | +4. **GitHub Release**: Created with generated release notes |
| 141 | +5. **pub.dev Publication**: Package is published automatically |
| 142 | + |
| 143 | +### Commit Convention |
| 144 | + |
| 145 | +Use [Conventional Commits](https://www.conventionalcommits.org/) for automatic release note generation: |
| 146 | + |
| 147 | +- `feat:` - New features |
| 148 | +- `fix:` - Bug fixes |
| 149 | +- `docs:` - Documentation changes |
| 150 | +- `test:` - Test improvements |
| 151 | +- `refactor:` - Code refactoring |
| 152 | +- `perf:` - Performance improvements |
0 commit comments