feat: inject template arguments into context map for handler testability#1416
Open
bgurmendi wants to merge 6 commits into
Open
feat: inject template arguments into context map for handler testability#1416bgurmendi wants to merge 6 commits into
bgurmendi wants to merge 6 commits into
Conversation
added 6 commits
June 18, 2026 14:31
Writes a key/value pair into the map only if the key is not already present. This ensures that when components are nested, the outermost component's argument takes precedence over any inner component that happens to share the same parameter name.
…bility If the request context contains a map[string]any under the key "_templ_args_map", the generated code now calls templruntime.SetTemplArg() to store each parameter (and the receiver, if any) in that map at the start of execution. This allows tests to verify which arguments a handler passed to a template without parsing the rendered HTML. The map is only populated when the key is present, so production requests are not affected. Three helper functions are added to extract names from the raw expression string stored in HTMLTemplate.Expression.Value: - extractReceiverName: returns the receiver variable name if present - extractParamList: returns the parameter list from the last (...) group - extractParamNames: splits the list into individual variable names, handling nested types (func, map, slice, variadic)
All template_templ.go files in the generator test directories have been regenerated to reflect the new SetTemplArg calls. Templates with no parameters are unchanged.
…d code New test directory covering the _templ_args_map mechanism: - args_test.go: verifies that arguments are captured when the map key is present in the context, and that nothing is written when it isn't.
Runnable example showing the full pattern: - handler.go: a standard http.HandlerFunc that queries a dependency and renders a templ component, with the dependency as a replaceable package-level variable. - template.templ / template_templ.go: minimal templ component. - handler_test.go: injects "_templ_args_map" into the request context, calls the handler through a real mux, and asserts that the component received the correct User argument.
Adds a new subsection "Testing template arguments from a handler" to the testing guide explaining: - The opt-in mechanism: inject a map[string]any under the key "_templ_args_map" into the request context before calling the handler. - A worked example (handler + test) matching examples/testing-args/. - Nested component behaviour: when two components share a parameter name, the outermost component's value is kept (first write wins).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Testing an HTTP handler that renders a templ component requires parsing
the rendered HTML to verify which data was passed to the template. This
is fragile (depends on HTML structure) and couples the handler test to
the template output.
Solution
Add an opt-in mechanism: if the request context contains a
map[string]anyunder the key"_templ_args_map", the generated codestores each component argument in that map at the start of execution.
This lets handler tests inspect the arguments directly without touching
the HTML.
The map is only populated when the key is present in the context, so
production requests are unaffected.
Changes
runtime: newSetTemplArg(m, key, value)helper that writesinto the map only if the key is not already set.
generator: emitstemplruntime.SetTemplArg(...)calls at thestart of each generated component function, for every parameter and
for the receiver when present (
templ (this T) Render(...)).generator/test-args-map: new test case covering the mechanism.examples/testing-args: runnable end-to-end example with handlerdocs: new subsection in the testing guide explaining thepattern, including nested component behaviour.
Nested components
When components are nested and share a parameter name, the outermost
component's value is kept (first write wins). This is intentional:
handler tests call the top-level component, so those are the arguments
worth asserting on.
Test plan
go test ./runtime/...go test ./generator/...go test -C examples/testing-args ./...