Skip to content

Commit b3409ae

Browse files
committed
test as design guide principles
1 parent fa305d9 commit b3409ae

File tree

4 files changed

+106
-2
lines changed

4 files changed

+106
-2
lines changed

docs/CODING_GUIDELINES.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ This pattern is foundational, not mandatory—direct store access is fine for si
4343
- **Naming:** Use clear, consistent names. Prefer `handleSubmit` over `onClick` for handlers passed as props; keep event handlers and callbacks obvious.
4444
- **File length:** If a file grows past roughly 200–300 lines, consider splitting (e.g. by component, by feature, or into a small folder).
4545
- **Comments:** Comment *why* when it’s not obvious from the code; avoid restating what the code does.
46-
- **Tests:** New behavior should have unit tests where practical. Follow existing patterns in `tests/unit/` and use the test helpers (e.g. `renderWithProviders`, `createTestStore`).
46+
- **Tests:** Unit tests are **required** for all features—not optional. Follow existing patterns in `tests/unit/` and use the test helpers (e.g. `renderWithProviders`, `createTestStore`). If a test is hard to write, refactor the code rather than writing a complex test. See [TEST_PLAN.md](TEST_PLAN.md#testing-requirements).
47+
- **Tests guide design:** Use testability as feedback on your design. If you can't imagine a simple test for something, simplify the design before implementation gets complicated. Easy to test = easy to understand and maintain.
48+
- **Exception for performance-critical code:** Code optimized for performance may be harder to test due to its structure. This is acceptable **only if** the code is: (1) explicitly marked as performance-critical with a comment explaining why, (2) well bounded—small and focused on one thing, and (3) isolated—minimal dependencies, clear interface. Such code still needs tests, but they may test at the boundary rather than internals.
4749

4850
## Dependencies
4951

docs/PRINCIPLES_AND_GOALS.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,36 @@ We simulate Solid concepts locally; adding a sync target gives full Solid protoc
242242

243243
---
244244

245+
## Technical Principles: Testability and Maintainability
246+
247+
**If it's hard to test, it's hard to maintain.** These principles enable the project to live for a long time with minimal cost, and make it feasible for new participants to make changes without high levels of risk.
248+
249+
### Testability Drives Design
250+
251+
1. **Unit tests required for all features.** Every feature must have unit tests. No exceptions.
252+
2. **Refactor over complex tests.** If a test requires extensive setup, mocking, or is hard to write, that's a signal to refactor the code—not to write a more complex test.
253+
3. **Small, isolated units.** Code that's easy to test in isolation is easy to understand, change, and reuse.
254+
4. **Tests as documentation.** Tests show how code is meant to be used. If the test is hard to read, the API is probably hard to use.
255+
256+
### Maintainability Enables Longevity
257+
258+
1. **Low barrier to change.** New contributors should be able to make changes confidently. Good tests catch mistakes before they ship.
259+
2. **Refactoring is safe.** Comprehensive tests let you restructure code without fear. If you can't refactor safely, the project calcifies.
260+
3. **Cost stays low over time.** Projects without tests accumulate risk with every change. Projects with tests can grow indefinitely.
261+
262+
### How This Connects to Project Goals
263+
264+
| Goal | How Testability/Maintainability Supports It |
265+
|------|---------------------------------------------|
266+
| **Vibe coding friendly** | New contributors can experiment knowing tests will catch regressions |
267+
| **Agent-ready** | AI agents can modify code and verify correctness via tests |
268+
| **Minimal setup for app authors** | Well-tested library code means fewer bugs for consumers to work around |
269+
| **CLI as composable building blocks** | Commands tested in isolation work reliably when composed |
270+
271+
See [TEST_PLAN.md](TEST_PLAN.md) for testing requirements and [SDLC_PROCESS.md](SDLC_PROCESS.md) for the verification workflow.
272+
273+
---
274+
245275
## What We Commit To
246276

247277
| Commitment | What It Means |
@@ -278,6 +308,7 @@ See [SHORTCOMINGS.md](SHORTCOMINGS.md) for the full list.
278308
| **Minimal setup** | One install, no backend, use what you need. |
279309
| **Vibe coding friendly** | Experiment, hack, use AI tools—vision over polish. |
280310
| **Unified CLI** | Same commands in browser, terminal, and AI agents. |
311+
| **Testability = maintainability** | If it's hard to test, refactor. Tests enable safe change. |
281312

282313
TinyBase makes local-first reactive and practical. Solid provides the vision for user-owned, interoperable data. The unified CLI gives humans and AI agents the same command surface in browser and terminal. Together, they let users start immediately and grow into full data sovereignty—whether you're a seasoned developer, someone with an idea and an AI assistant, or an AI agent driving the library programmatically.
283314

docs/SDLC_PROCESS.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,18 @@ The process flows from **feature/requirements** → **design/selection** → **i
3838

3939
The Feature Checklist serves two purposes: verifying new work and **defining behavior to preserve**. Before making changes, review affected checklist items—they represent working functionality that should not regress.
4040

41-
For **code features**, “Documenting Changes” and “Verification Workflow” below apply. For **planning and documentation** (e.g. before or after a major phase), use the **Documentation review process** so design and docs stay coherent and gaps are tracked to closure.
41+
### Testability = Maintainability
42+
43+
**If code is hard to test, it's hard to maintain.** This is a core technical principle (see [PRINCIPLES_AND_GOALS.md](PRINCIPLES_AND_GOALS.md#technical-principles-testability-and-maintainability)).
44+
45+
- **Unit tests required for all features.** No exceptions. See [TEST_PLAN.md](TEST_PLAN.md#testing-requirements).
46+
- **Refactor over complex tests.** If a test needs extensive setup or mocking, refactor the code instead.
47+
- **Tests enable safe change.** New contributors can modify code confidently when tests catch regressions.
48+
- **Cost stays low.** Projects without tests accumulate risk. Projects with tests can grow indefinitely.
49+
50+
This is what makes it feasible for new participants to make changes without high levels of risk, and what enables the project to live for a long time with minimal cost.
51+
52+
For **code features**, "Documenting Changes" and "Verification Workflow" below apply. For **planning and documentation** (e.g. before or after a major phase), use the **Documentation review process** so design and docs stay coherent and gaps are tracked to closure.
4253

4354
---
4455

docs/TEST_PLAN.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,65 @@
11
# Test Suite Implementation Plan
22

3+
## Testing Requirements
4+
5+
**Unit tests are required for all features.** This is not optional. See [PRINCIPLES_AND_GOALS.md](PRINCIPLES_AND_GOALS.md#technical-principles-testability-and-maintainability) for why.
6+
7+
### Core Rules
8+
9+
1. **Every feature must have unit tests.** Before a feature is considered complete, it must have tests that verify its behavior.
10+
11+
2. **Refactor over complex tests.** If writing a test requires:
12+
- Extensive mocking or setup
13+
- Deep knowledge of unrelated systems
14+
- More than a few lines of boilerplate
15+
16+
...then **refactor the code**, don't write a more complex test. Hard-to-test code is hard-to-maintain code.
17+
18+
3. **Tests document behavior.** Tests show how code is meant to be used. If a test is hard to read, the API is probably hard to use.
19+
20+
4. **Tests enable safe refactoring.** The test suite should give confidence that changes don't break existing behavior. If you can't refactor safely, add more tests first.
21+
22+
### What to Test
23+
24+
| Layer | What to test | Example |
25+
|-------|--------------|---------|
26+
| **Schemas** | Validation, factory functions, edge cases | `PersonaSchema.safeParse()`, `createPersona()` |
27+
| **Utilities** | Pure functions, transformations | `resolvePath()`, `findPersona()` |
28+
| **CLI commands** | Command execution, structured results | `executeCommandLine('ls')` returns expected result |
29+
| **Components** | Rendering, user interactions | ContactList renders items, handles selection |
30+
31+
### Use Tests as a Design Guide
32+
33+
**Unit tests are feedback on your design.** If code is hard to test, that's a signal the design is getting too complex or convoluted. Use this feedback:
34+
35+
- Easy to test → probably easy to understand, change, and reuse
36+
- Hard to test → probably too coupled, doing too much, or poorly factored
37+
38+
Write the test first (or at least think about how you'd test it) before the implementation gets complicated. If you can't imagine a simple test, simplify the design.
39+
40+
### When Tests Are Hard to Write
41+
42+
If you find yourself struggling to test something, ask:
43+
44+
- **Is this unit doing too much?** Split it into smaller pieces.
45+
- **Are there too many dependencies?** Inject them or extract pure logic.
46+
- **Is the state management tangled?** Separate state from behavior.
47+
- **Am I testing implementation details?** Test behavior, not internals.
48+
49+
The answer is almost always "refactor the code" rather than "write a more elaborate test."
50+
51+
### Exception: Performance-Critical Code
52+
53+
Code optimized for performance may have a structure that's harder to test (e.g., inlined logic, avoiding allocations). This is acceptable **only if**:
54+
55+
1. **Explicitly marked** — Comment explains why this code is performance-critical
56+
2. **Well bounded** — Small and focused on one thing
57+
3. **Isolated** — Minimal dependencies, clear interface
58+
59+
Such code still needs tests, but they may test at the boundary (inputs → outputs) rather than internals. The isolation requirement ensures that hard-to-test performance code doesn't spread throughout the codebase.
60+
61+
---
62+
363
## Status: Complete
464

565
### Completed

0 commit comments

Comments
 (0)