feat(testkit): add test harness and kernel provider overrides#218
feat(testkit): add test harness and kernel provider overrides#218
Conversation
Introduce BootstrapWithOptions and token-level override validation in kernel, then add modkit/testkit with typed retrieval and lifecycle helpers for module tests. Update docs/examples and harden close/option edge cases with coverage for cancellation retries, nil options, and override conflicts.
Document modkit/testkit in the package list so users can discover the new testing harness alongside core packages.
📝 WalkthroughWalkthroughAdds a test harness package ( Changes
Sequence Diagram(s)sequenceDiagram
actor Test
participant Harness as "TestKit Harness"
participant Kernel as "kernel.Bootstrap/Container"
participant Module as "Module/Graph"
participant Provider as "ProviderEntry"
Test->>Harness: New(tb, root, WithOverrides(...))
Harness->>Harness: apply testkit Options
Harness->>Kernel: BootstrapWithOptions(root, opts...)
Kernel->>Kernel: validate options & build override map
Kernel->>Module: build provider graph
Kernel->>Provider: create entries (apply overrides where present)
Kernel-->>Harness: return *App
Harness->>Test: register auto-cleanup (optional)
Test->>Harness: Get[T](token)
Harness->>Kernel: Resolve(token)
Kernel->>Provider: return value
Provider-->>Harness: value
Harness-->>Test: typed T or TypeAssertionError
Test->>Harness: Close()
Harness->>Harness: run cleanup hooks
Harness->>Kernel: App.Close()
Harness-->>Test: aggregated HarnessCloseError (if errors)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 Comment |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Add targeted tests for wrapper fatal paths, override build helper usage, App accessor, controller type mismatch, and all testkit error string branches to raise patch/package coverage.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@modkit/kernel/bootstrap_options_test.go`:
- Around line 172-189: Update the test
TestBootstrapWithOptions_RejectsUnknownOverrideToken to use a module-qualified
provider token instead of "missing": change the module.Token value passed into
kernel.ProviderOverride to follow the "module.component" format (e.g.,
module.Token("root.missing") or another valid module-qualified name) so the test
aligns with production token format used by kernel.BootstrapWithOptions and
kernel.WithProviderOverrides.
- Around line 191-222: The test uses a non-qualified token name "hidden"; update
the token to follow the "module.component" format used across the codebase by
changing the hidden variable in
TestBootstrapWithOptions_RejectsOverrideTokenNotVisibleFromRoot to
module.Token("B.hidden") (so the provider in modB, the override in
kernel.WithProviderOverrides, and the visErr.Token comparison all reference the
same module-qualified token). Ensure the token string is changed wherever the
hidden symbol is declared/used so comparisons still match.
🧹 Nitpick comments (1)
docs/reference/api.md (1)
120-136: Clarify documentation for BootstrapWithOptions and Cleanup field.Two suggestions to improve clarity:
Line 126: The phrase "In v1,
WithProviderOverridesis the mutation option for tests" reads as an implementation detail. Consider rephrasing to focus on what it does: "UseWithProviderOverridesto replace provider implementations, typically for testing."Line 132: The
Cleanupfield lacks explanation. Add a brief note about when cleanup is invoked, e.g., "Optional cleanup function called when the harness is closed" or similar.📝 Suggested documentation improvements
-Bootstraps with explicit options. In v1, `WithProviderOverrides` is the mutation option for tests. +Bootstraps with explicit options. Use `WithProviderOverrides` to replace provider implementations, typically for testing. ```go type ProviderOverride struct { Token module.Token Build func(module.Resolver) (any, error) - Cleanup func(context.Context) error + Cleanup func(context.Context) error // Optional; called when harness is closed }
Align override validation tests with module.component token convention and clarify BootstrapWithOptions docs wording and ProviderOverride cleanup behavior.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@docs/reference/api.md`:
- Line 160: Remove the redundant horizontal rule: delete the duplicate line
containing '---' that follows the previous section separator so there is only a
single '---' between sections in the API reference document; simply remove the
extra '---' line to restore the established single-separator pattern.
🧹 Nitpick comments (3)
modkit/kernel/bootstrap_options_test.go (1)
166-170: Consider verifying the token in the error.For consistency with
TestBootstrapWithOptions_RejectsOptionConflictForSameToken(which checksconflictErr.Token), consider adding an assertion to verifydupErr.Token == token. This strengthens the test by ensuring the correct token is reported in the error.🔧 Optional improvement
var dupErr *kernel.DuplicateOverrideTokenError if !errors.As(err, &dupErr) { t.Fatalf("unexpected error type: %T", err) } + if dupErr.Token != token { + t.Fatalf("unexpected token in error: %q", dupErr.Token) + } }docs/reference/api.md (2)
120-136: Consider adding a dedicated kernel section for better clarity.While the content is accurate and follows the existing pattern of documenting kernel APIs (like
App.Get,App.Resolver) within the module section, a dedicated## kernelsection would make the package organization clearer to readers. This would be especially helpful as the bootstrap API surface grows with options.Note: This is a broader documentation structure suggestion and not specific to this PR.
216-266: Consider adding a testkit usage example to the Common Patterns section.The testkit API surface is well-documented with clear function signatures and descriptions. To further help users, consider adding a practical example in the Common Patterns section (starting at line 303) that demonstrates:
- Creating a test harness with
testkit.New- Using
WithOverridesto replace a provider- Retrieving providers with
testkit.Get[T]- Proper cleanup/close patterns
This would complement the existing bootstrap and serve examples and provide a complete picture of the testing workflow.
Drop redundant horizontal rule before the http API section to keep single-separator formatting in the reference.
Type
feat— New featurefix— Bug fixrefactor— Code restructure (no behavior change)docs— Documentation onlytest— Test coveragechore— Build, CI, toolingperf— Performance improvementSummary
Add a first-class
modkit/testkitpackage for module-level tests and extend kernel bootstrap with explicit provider override options. This reduces test boilerplate while preserving visibility, deterministic bootstrap behavior, and cleanup lifecycle guarantees.Changes
kernel.BootstrapWithOptionsandWithProviderOverrideswith strict override validation and typed errorsmodkit/testkit(Harness, override helpers, typedGet/Controllerhelpers, close lifecycle + error types)examples/hello-simpleand realistic override usage inexamples/hello-mysqlauth testsmodkit/testkitBreaking Changes
None
Validation
Checklist
make fmtpasses)make lint)make vuln)make test)make test-coverage)make cli-smoke-build && make cli-smoke-scaffold)Notes
No issue hierarchy is linked for this change set.
Summary by CodeRabbit
New Features
Documentation
Tests