Skip to content

Commit 2ca52f5

Browse files
committed
test: add comprehensive unit tests and CI workflow
Add unit tests for: - Branch name validation and sanitization (git adapter) - Session name sanitization (domain) - Git URL parsing and comparison (git adapter) - Notification service event handling and execution ID resolution - Token stats service caching and aggregation - Session service delete and rename operations - JSONL parser for token usage extraction Also includes: - GitHub Actions workflow for running tests on PRs - Updated mockery config with new interfaces - Updated testing.md with unit test guidelines
1 parent 3aa04f0 commit 2ca52f5

13 files changed

Lines changed: 2472 additions & 1 deletion

File tree

‎.claude/rules/testing.md‎

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,59 @@
1+
# Testing Guidelines
12

2-
This is a proof of concept, you don't need to implement unit tests.
3+
## Running Unit Tests
4+
5+
```bash
6+
# Run all unit tests
7+
go test ./internal/...
8+
9+
# Run tests with verbose output
10+
go test ./internal/... -v
11+
12+
# Run tests with coverage
13+
go test ./internal/... -cover
14+
15+
# Run specific test
16+
go test ./internal/services/... -run TestCreateSession
17+
```
18+
19+
## Test Patterns
20+
21+
Follow the established patterns from existing tests:
22+
23+
```go
24+
func TestFunctionName_Scenario(t *testing.T) {
25+
// Create mocks
26+
gitRepo := portsmocks.NewMockGitRepository(t)
27+
28+
// Setup expectations
29+
gitRepo.EXPECT().Method(mock.Anything).Return(value, nil)
30+
31+
// Create service
32+
service := NewService(gitRepo)
33+
34+
// Execute
35+
result, err := service.Method(...)
36+
37+
// Assert
38+
require.NoError(t, err)
39+
assert.Equal(t, expected, result)
40+
}
41+
```
42+
43+
## Mocks
44+
45+
Mocks are generated using mockery. Config is in `.mockery.yaml`.
46+
47+
```bash
48+
# Regenerate mocks after adding interfaces
49+
mockery
50+
```
51+
52+
## Test Coverage
53+
54+
Focus unit tests on:
55+
- Pure functions (validation, sanitization, parsing)
56+
- Service layer with mocked dependencies
57+
- Error handling paths
58+
59+
Integration tests run in Docker (see testing_safety.md).

‎.github/workflows/test.yml‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Test
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
push:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Set up Go
17+
uses: actions/setup-go@v5
18+
with:
19+
go-version: '1.25.6'
20+
21+
- name: Download dependencies
22+
run: go mod download
23+
24+
- name: Run tests
25+
run: go test ./internal/... -v -race -coverprofile=coverage.out
26+
27+
- name: Upload coverage
28+
uses: codecov/codecov-action@v4
29+
with:
30+
files: coverage.out
31+
fail_ci_if_error: false
32+
continue-on-error: true
33+
34+
lint:
35+
runs-on: ubuntu-latest
36+
steps:
37+
- name: Checkout code
38+
uses: actions/checkout@v4
39+
40+
- name: Set up Go
41+
uses: actions/setup-go@v5
42+
with:
43+
go-version: '1.25.6'
44+
45+
- name: Run golangci-lint
46+
uses: golangci/golangci-lint-action@v6
47+
with:
48+
version: latest
49+
50+
build:
51+
runs-on: ubuntu-latest
52+
steps:
53+
- name: Checkout code
54+
uses: actions/checkout@v4
55+
56+
- name: Set up Go
57+
uses: actions/setup-go@v5
58+
with:
59+
go-version: '1.25.6'
60+
61+
- name: Build
62+
run: go build -o rocha ./cmd

‎.mockery.yaml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ packages:
1212
ProcessInspector: {}
1313
SessionReader: {}
1414
SessionRepository: {}
15+
SessionStateUpdater: {}
1516
SessionWriter: {}
17+
SoundPlayer: {}
1618
TmuxClient: {}
1719
TmuxSessionLifecycle: {}
20+
TokenUsageReader: {}
1821
github.com/renato0307/rocha/internal/services:
1922
interfaces:
2023
ClaudeDirResolver: {}

0 commit comments

Comments
 (0)