|
| 1 | +# bashunit - Bash Testing Framework |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +**bashunit** is a comprehensive, lightweight Bash testing framework (requires Bash 3.2+) focused on developer experience. It provides assertions, test doubles (spies/mocks), data providers, snapshots, and more. |
| 6 | + |
| 7 | +**Documentation:** https://bashunit.typeddevs.com |
| 8 | + |
| 9 | +## Claude Code Configuration |
| 10 | + |
| 11 | +This directory (`.claude/`) contains comprehensive Claude Code configuration: |
| 12 | +- **Custom skills**: `/tdd-cycle`, `/fix-test`, `/add-assertion`, `/check-coverage`, `/pre-release` |
| 13 | +- **Custom commands**: `/gh-issue` (complete GitHub issue → PR workflow) |
| 14 | +- **Modular rules**: Bash 3.2+ compatibility, testing patterns, TDD workflow |
| 15 | +- **Automation**: Agent SDK examples for CI/CD |
| 16 | + |
| 17 | +See `README.md` in this directory for complete documentation. |
| 18 | + |
| 19 | +## Core Principles |
| 20 | + |
| 21 | +### TDD by Default |
| 22 | +**RED → GREEN → REFACTOR** |
| 23 | + |
| 24 | +1. **RED** - Write failing test (fail for the RIGHT reason) |
| 25 | +2. **GREEN** - Minimal code to make it pass |
| 26 | +3. **REFACTOR** - Improve while keeping tests green |
| 27 | + |
| 28 | +Every change starts from a failing test. No exceptions. |
| 29 | + |
| 30 | +### Bash 3.2+ Compatible |
| 31 | + |
| 32 | +Works on macOS default bash. **Prohibited features:** |
| 33 | +- ❌ `declare -A` (associative arrays - Bash 4.0+) |
| 34 | +- ❌ `[[ ]]` (use `[ ]` instead) |
| 35 | +- ❌ `${var,,}` (case conversion - Bash 4.0+) |
| 36 | +- ❌ `${array[-1]}` (negative indexing - Bash 4.3+) |
| 37 | +- ❌ `&>>` redirect (Bash 4.0+) |
| 38 | + |
| 39 | +See `@.claude/rules/bash-style.md` for complete compatibility guide. |
| 40 | + |
| 41 | +### Quality Standards |
| 42 | + |
| 43 | +Every change must pass: |
| 44 | +```bash |
| 45 | +make sa # ShellCheck static analysis |
| 46 | +make lint # EditorConfig linting |
| 47 | +./bashunit tests/ # All tests passing |
| 48 | +shfmt -w . # Code formatting |
| 49 | +``` |
| 50 | + |
| 51 | +## Architecture |
| 52 | + |
| 53 | +``` |
| 54 | +bashunit/ |
| 55 | +├── src/ # Core framework code (Bash 3.2+ compatible) |
| 56 | +│ ├── bashunit.sh # Main entry point |
| 57 | +│ ├── assertions.sh # Assertion functions |
| 58 | +│ ├── assert_*.sh # Specialized assertions |
| 59 | +│ └── *.sh # Utilities (io, math, etc.) |
| 60 | +├── tests/ |
| 61 | +│ ├── unit/ # Unit tests for src/ (isolated, with mocks) |
| 62 | +│ ├── functional/ # Integration tests |
| 63 | +│ └── acceptance/ # End-to-end CLI tests |
| 64 | +├── .claude/ # Claude Code configuration |
| 65 | +│ ├── CLAUDE.md # This file (primary instructions) |
| 66 | +│ ├── skills/ # Custom workflows |
| 67 | +│ ├── commands/ # End-to-end commands |
| 68 | +│ └── rules/ # Modular guidelines |
| 69 | +├── .tasks/ # Optional task tracking files |
| 70 | +├── adrs/ # Architecture Decision Records |
| 71 | +└── bashunit # CLI entry point |
| 72 | +``` |
| 73 | + |
| 74 | +## Common Commands |
| 75 | + |
| 76 | +```bash |
| 77 | +# Testing |
| 78 | +./bashunit tests/ # Run all tests |
| 79 | +./bashunit --parallel tests/ # Parallel execution |
| 80 | +./bashunit tests/unit/ # Run unit tests only |
| 81 | +make test # Run full test suite |
| 82 | + |
| 83 | +# Quality checks |
| 84 | +make sa # ShellCheck static analysis |
| 85 | +make lint # EditorConfig checker |
| 86 | +shfmt -w . # Format all shell files |
| 87 | + |
| 88 | +# Documentation |
| 89 | +npm run docs:dev # Start docs dev server |
| 90 | +npm run docs:build # Build documentation |
| 91 | + |
| 92 | +# Releases |
| 93 | +./release.sh # Release new version |
| 94 | +``` |
| 95 | + |
| 96 | +## Test Patterns |
| 97 | + |
| 98 | +Study existing tests before writing new ones: |
| 99 | + |
| 100 | +- **Assertions**: `tests/unit/assert_test.sh` - Assertion patterns and failure testing |
| 101 | +- **Test Doubles**: `tests/functional/doubles_test.sh` - `mock`/`spy` + `assert_have_been_called*` |
| 102 | +- **Data Providers**: `tests/functional/provider_test.sh` - `@data_provider` syntax |
| 103 | +- **Lifecycle Hooks**: `tests/unit/setup_teardown_test.sh` - `set_up_before_script`, etc. |
| 104 | +- **CLI Testing**: `tests/acceptance/bashunit_test.sh` - Snapshot testing |
| 105 | + |
| 106 | +## Available Skills |
| 107 | + |
| 108 | +Invoke with `/skill-name`: |
| 109 | + |
| 110 | +### `/tdd-cycle` - Complete TDD Workflow |
| 111 | +Guides through RED → GREEN → REFACTOR cycle with quality checks. |
| 112 | +``` |
| 113 | +/tdd-cycle |
| 114 | +``` |
| 115 | + |
| 116 | +### `/fix-test` - Debug Failing Tests |
| 117 | +Systematically debugs and fixes test failures. |
| 118 | +``` |
| 119 | +/fix-test |
| 120 | +``` |
| 121 | + |
| 122 | +### `/add-assertion` - Add New Assertion |
| 123 | +Adds new assertion following TDD with comprehensive tests. |
| 124 | +``` |
| 125 | +/add-assertion |
| 126 | +``` |
| 127 | + |
| 128 | +### `/check-coverage` - Analyze Coverage |
| 129 | +Analyzes test coverage and identifies gaps. |
| 130 | +``` |
| 131 | +/check-coverage |
| 132 | +``` |
| 133 | + |
| 134 | +### `/pre-release` - Release Validation |
| 135 | +Comprehensive validation before releasing. |
| 136 | +``` |
| 137 | +/pre-release |
| 138 | +``` |
| 139 | + |
| 140 | +## Expert Agents |
| 141 | + |
| 142 | +Specialized agents you can consult using the Task tool: |
| 143 | + |
| 144 | +### Bash 3.2+ Expert |
| 145 | +**When to use:** Reviewing code for Bash 3.2+ compatibility |
| 146 | +**Expertise:** Identifying incompatible features, suggesting portable alternatives |
| 147 | +**Invoke:** Use Task tool with subagent_type="bash-3.2-expert" |
| 148 | + |
| 149 | +### Code Reviewer |
| 150 | +**When to use:** Before committing, for comprehensive code review |
| 151 | +**Expertise:** Project standards, quality, security, documentation |
| 152 | +**Invoke:** Use Task tool with subagent_type="code-reviewer" |
| 153 | + |
| 154 | +### TDD Coach |
| 155 | +**When to use:** Learning TDD, guidance through RED-GREEN-REFACTOR |
| 156 | +**Expertise:** TDD methodology, test design, avoiding common mistakes |
| 157 | +**Invoke:** Use Task tool with subagent_type="tdd-coach" |
| 158 | + |
| 159 | +### Test Architect |
| 160 | +**When to use:** Planning test strategy, organizing tests |
| 161 | +**Expertise:** Test categorization, coverage planning, testing patterns |
| 162 | +**Invoke:** Use Task tool with subagent_type="test-architect" |
| 163 | + |
| 164 | +### Performance Optimizer |
| 165 | +**When to use:** Optimizing slow code, improving test suite performance |
| 166 | +**Expertise:** Bash performance patterns, benchmarking, profiling |
| 167 | +**Invoke:** Use Task tool with subagent_type="performance-optimizer" |
| 168 | + |
| 169 | +## Available Commands |
| 170 | + |
| 171 | +### `/gh-issue` - GitHub Issue Workflow |
| 172 | +Complete end-to-end workflow from issue to PR: |
| 173 | +1. Fetches issue from GitHub |
| 174 | +2. Creates branch with proper naming |
| 175 | +3. Plans implementation |
| 176 | +4. Implements following TDD |
| 177 | +5. Runs quality checks |
| 178 | +6. Creates commit and PR |
| 179 | + |
| 180 | +``` |
| 181 | +/gh-issue 42 |
| 182 | +``` |
| 183 | + |
| 184 | +## Code Standards |
| 185 | + |
| 186 | +### Bash Style |
| 187 | +@.claude/rules/bash-style.md |
| 188 | +- Bash 3.2+ compatibility (critical!) |
| 189 | +- ShellCheck compliance |
| 190 | +- Function documentation |
| 191 | +- Naming conventions |
| 192 | + |
| 193 | +### Testing |
| 194 | +@.claude/rules/testing.md |
| 195 | +- Test organization (unit/functional/acceptance) |
| 196 | +- Assertion patterns |
| 197 | +- Test doubles (mocks/spies) |
| 198 | +- Data providers |
| 199 | +- Anti-patterns to avoid |
| 200 | + |
| 201 | +### TDD Workflow |
| 202 | +@.claude/rules/tdd-workflow.md |
| 203 | +- RED → GREEN → REFACTOR cycle |
| 204 | +- Quality gates |
| 205 | +- Definition of Done |
| 206 | + |
| 207 | +## Path-Scoped Guidelines |
| 208 | + |
| 209 | +### `src/**/*.sh` |
| 210 | +- Small, portable functions |
| 211 | +- Bash 3.2+ compatibility (no associative arrays, no `[[`, no `${var,,}`) |
| 212 | +- Proper namespacing (`bashunit::*`) |
| 213 | +- No external dependencies in core |
| 214 | +- Function documentation required |
| 215 | + |
| 216 | +### `tests/**/*_test.sh` |
| 217 | +- Behavior-focused tests |
| 218 | +- Use official assertions/doubles only |
| 219 | +- Avoid network calls |
| 220 | +- Use `temp_file`/`temp_dir` for isolation |
| 221 | +- Test both success and failure paths |
| 222 | + |
| 223 | +### `.tasks/YYYY-MM-DD-slug.md` (Optional) |
| 224 | +- Use for complex work to track progress |
| 225 | +- Include test inventory |
| 226 | +- Timestamped logbook entries |
| 227 | +- Not required for simple fixes |
| 228 | + |
| 229 | +### `adrs/*.md` |
| 230 | +- Read existing ADRs before major changes |
| 231 | +- Use template for new decisions |
| 232 | +- Match existing format |
| 233 | + |
| 234 | +## Guardrails |
| 235 | + |
| 236 | +### Never: |
| 237 | +- Invent commands/features not in the codebase |
| 238 | +- Break Bash 3.2+ compatibility |
| 239 | +- Skip tests or quality checks |
| 240 | +- Change public API without docs/CHANGELOG |
| 241 | +- Use speculative/unproven patterns |
| 242 | +- Commit without tests passing |
| 243 | +- Batch unrelated changes in one PR |
| 244 | + |
| 245 | +### Always: |
| 246 | +- Write tests before implementation |
| 247 | +- Use existing patterns from `tests/**` and `src/**` |
| 248 | +- Minimal code in GREEN phase |
| 249 | +- Keep tests passing during REFACTOR |
| 250 | +- Run quality checks before committing |
| 251 | +- Update CHANGELOG.md for user-visible changes |
| 252 | +- Maintain Bash 3.2+ compatibility |
| 253 | + |
| 254 | +## Definition of Done |
| 255 | + |
| 256 | +Before marking work complete: |
| 257 | +- ✅ All tests green for the **right reason** |
| 258 | +- ✅ `make sa` passes (ShellCheck) |
| 259 | +- ✅ `make lint` passes (EditorConfig) |
| 260 | +- ✅ Code formatted (`shfmt -w .`) |
| 261 | +- ✅ Bash 3.2+ compatible |
| 262 | +- ✅ Parallel tests passing (`./bashunit --parallel tests/`) |
| 263 | +- ✅ CHANGELOG.md updated (if user-facing changes) |
| 264 | +- ✅ Documentation updated (if needed) |
| 265 | +- ✅ ADR created/updated (if architectural decision) |
| 266 | + |
| 267 | +## Task Files (Optional) |
| 268 | + |
| 269 | +For complex work, consider creating `.tasks/YYYY-MM-DD-slug.md` to track: |
| 270 | +- Test inventory (which tests to write) |
| 271 | +- Progress logbook (timestamped entries) |
| 272 | +- Acceptance criteria |
| 273 | + |
| 274 | +Not required for simple fixes. See `.tasks/` for examples. |
| 275 | + |
| 276 | +## Prohibited Actions |
| 277 | + |
| 278 | +**Never do these without explicit user request:** |
| 279 | +- Commit secrets or sensitive data |
| 280 | +- Force push to main/master |
| 281 | +- Skip git hooks (--no-verify) |
| 282 | +- Amend published commits |
| 283 | +- Use destructive git commands (reset --hard, clean -f) |
| 284 | +- Delete branches |
| 285 | +- Push to remote without confirmation |
| 286 | + |
| 287 | +## ADRs (Architecture Decision Records) |
| 288 | + |
| 289 | +Read existing ADRs in `adrs/` before making architectural changes. Create new ADRs for significant decisions using the repo's template. |
| 290 | + |
| 291 | +## Commit Message Format |
| 292 | + |
| 293 | +Use [Conventional Commits](https://conventionalcommits.org/): |
| 294 | + |
| 295 | +``` |
| 296 | +<type>(<scope>): <description> |
| 297 | +
|
| 298 | +<optional body> |
| 299 | +``` |
| 300 | + |
| 301 | +**Types:** `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore` |
| 302 | + |
| 303 | +**Scopes:** `assert`, `runner`, `cli`, `docs`, etc. |
| 304 | + |
| 305 | +**Examples:** |
| 306 | +``` |
| 307 | +feat(assert): add assert_json_contains function |
| 308 | +
|
| 309 | +Adds new assertion to validate JSON key-value pairs. |
| 310 | +Supports nested keys and provides clear error messages. |
| 311 | +``` |
| 312 | + |
| 313 | +``` |
| 314 | +fix(runner): resolve parallel execution race condition |
| 315 | +
|
| 316 | +Fixed race condition when multiple tests write to temp files. |
| 317 | +``` |
| 318 | + |
| 319 | +## Help & Resources |
| 320 | + |
| 321 | +### Documentation |
| 322 | +- **Getting started:** @.claude/GETTING_STARTED.md (5-minute intro) |
| 323 | +- **Quick reference:** @.claude/QUICK_REFERENCE.md (one-page cheat sheet) |
| 324 | +- **Full docs:** https://bashunit.typeddevs.com |
| 325 | +- **Contributing:** @.github/CONTRIBUTING.md |
| 326 | + |
| 327 | +### Claude Code |
| 328 | +- **This directory:** @.claude/README.md (comprehensive guide) |
| 329 | +- **Skills:** See `.claude/skills/` directory |
| 330 | +- **Commands:** See `.claude/commands/` directory |
| 331 | +- **Automation:** See `.claude/agents/` directory |
| 332 | + |
| 333 | +### Community |
| 334 | +- **Issues:** https://github.com/TypedDevs/bashunit/issues |
| 335 | +- **Discussions:** https://github.com/TypedDevs/bashunit/discussions |
| 336 | + |
| 337 | +--- |
| 338 | + |
| 339 | +**Need help?** Start with `@.claude/GETTING_STARTED.md` for a quick introduction to the Claude Code configuration. |
0 commit comments