Current State
- File:
pkg/workflow/tools_timeout_validation_test.go (104 LOC, 1 test function, 3 sub-cases) - Source pair:
pkg/workflow/frontmatter_extraction_metadata.go (extractToolsStartupTimeout, timeout extraction logic in extractToolTimeouts) - Testify usage: none — file imports no testify packages; all assertions use raw
t.Fatalf/t.Errorf.
Strengths
- Table-driven structure with clear
name/workflowMd/shouldCompile/errorContains fields. - Covers a valid case, an invalid
timeout: 0 case, and a combined timeout + startup-timeout valid case. - Proper temp-file cleanup via
defer os.Remove(...).
Prioritized Improvements
1. Missing/high-value tests
The source (extractToolsStartupTimeout in frontmatter_extraction_metadata.go) validates several cases the test file never exercises:
startup-timeout: 0 or negative → error "must be at least 1 second, got %d"startup-timeout as a non-integer string that isn't a GitHub Actions expression → error "must be an integer or a GitHub Actions expression ... got string"startup-timeout as a valid GHA expression string (e.g. "${{ inputs.startup-timeout }}") → should compile successfullystartup-timeout provided with an invalid type (e.g. a list/map) → error "got %T"- Negative
tools.timeout value (only 0 is currently tested)
Suggested additional table cases
{
name: "invalid startup-timeout - zero",
workflowMd: `---on: workflow_dispatchengine: claudetools: startup-timeout: 0 github:---# Test`,
shouldCompile: false,
errorContains: "must be at least 1 second, got 0",
},
{
name: "startup-timeout as GitHub Actions expression",
workflowMd: `---on: workflow_dispatch: inputs: startup-timeout: default: "120"engine: claudetools: startup-timeout: "${{ inputs.startup-timeout }}" github:---# Test`,
shouldCompile: true,
},
{
name: "startup-timeout as invalid string",
workflowMd: `---on: workflow_dispatchengine: claudetools: startup-timeout: "not-a-number" github:---# Test`,
shouldCompile: false,
errorContains: "must be an integer or a GitHub Actions expression",
},2. Testify assertion upgrades
Replace manual if err != nil { t.Fatalf/Errorf } checks with require/assert for consistency with the rest of the pkg/workflow suite (see labels_validation_test.go for the pattern already used nearby).
Before / after
Before:
tmpFile, err:=os.CreateTemp("", "test-timeout-validation-*.md")
iferr!=nil {
t.Fatalf("Failed to create temp file: %v", err)
}
...iftt.shouldCompile {
iferr!=nil {
t.Errorf("Expected workflow to compile successfully, but got error: %v", err)
}
} else {
iferr==nil {
t.Errorf("Expected workflow compilation to fail, but it succeeded")
} elseif!strings.Contains(err.Error(), tt.errorContains) {
t.Errorf("Expected error to contain '%s', but got: %v", tt.errorContains, err)
}
}After:
tmpFile, err:=os.CreateTemp("", "test-timeout-validation-*.md")
require.NoError(t, err, "Failed to create temp file")
...iftt.shouldCompile {
assert.NoError(t, err, "Expected workflow to compile successfully")
} else {
require.Error(t, err, "Expected workflow compilation to fail")
assert.Contains(t, err.Error(), tt.errorContains)
}3. Table-driven refactors
The table is already good; no structural refactor needed beyond adding the missing cases above. Consider adding a startupTimeout field alongside errorContains if timeout and startup-timeout cases grow enough to warrant separating into two tables (TestToolsTimeoutValidation / TestToolsStartupTimeoutValidation) for clearer failure attribution.
4. Organization/readability
- Rename the single test function's sub-cases so timeout vs. startup-timeout intent is unambiguous (e.g.
"invalid timeout - zero" vs. a to-be-added "invalid startup-timeout - zero" — already distinguishable, but keep this naming convention as more cases are added). - Add a short comment above the test explaining that this test exercises the frontmatter
tools.timeout / tools.startup-timeout schema+extraction validation end-to-end via full compilation, since a reader unfamiliar with the compiler pipeline may not realize why a full CompileWorkflow call is needed instead of calling extractToolTimeouts directly.
Acceptance Checklist
Generated by 🧪 Daily Testify Uber Super Expert · auto · 23 AIC · ⌖ 6.82 AIC · ⊞ 7.3K · ◷
Current State
pkg/workflow/tools_timeout_validation_test.go(104 LOC, 1 test function, 3 sub-cases)pkg/workflow/frontmatter_extraction_metadata.go(extractToolsStartupTimeout, timeout extraction logic inextractToolTimeouts)t.Fatalf/t.Errorf.Strengths
name/workflowMd/shouldCompile/errorContainsfields.timeout: 0case, and a combinedtimeout+startup-timeoutvalid case.defer os.Remove(...).Prioritized Improvements
1. Missing/high-value tests
The source (
extractToolsStartupTimeoutinfrontmatter_extraction_metadata.go) validates several cases the test file never exercises:startup-timeout: 0or negative → error "must be at least 1 second, got %d"startup-timeoutas a non-integer string that isn't a GitHub Actions expression → error "must be an integer or a GitHub Actions expression ... got string"startup-timeoutas a valid GHA expression string (e.g."${{ inputs.startup-timeout }}") → should compile successfullystartup-timeoutprovided with an invalid type (e.g. a list/map) → error "got %T"tools.timeoutvalue (only0is currently tested)Suggested additional table cases
{ name: "invalid startup-timeout - zero", workflowMd: `---on: workflow_dispatchengine: claudetools: startup-timeout: 0 github:---# Test`, shouldCompile: false, errorContains: "must be at least 1 second, got 0", }, { name: "startup-timeout as GitHub Actions expression", workflowMd: `---on: workflow_dispatch: inputs: startup-timeout: default: "120"engine: claudetools: startup-timeout: "${{ inputs.startup-timeout }}" github:---# Test`, shouldCompile: true, }, { name: "startup-timeout as invalid string", workflowMd: `---on: workflow_dispatchengine: claudetools: startup-timeout: "not-a-number" github:---# Test`, shouldCompile: false, errorContains: "must be an integer or a GitHub Actions expression", },2. Testify assertion upgrades
Replace manual
if err != nil { t.Fatalf/Errorf }checks withrequire/assertfor consistency with the rest of thepkg/workflowsuite (seelabels_validation_test.gofor the pattern already used nearby).Before / after
Before:
After:
3. Table-driven refactors
The table is already good; no structural refactor needed beyond adding the missing cases above. Consider adding a
startupTimeoutfield alongsideerrorContainsif timeout and startup-timeout cases grow enough to warrant separating into two tables (TestToolsTimeoutValidation/TestToolsStartupTimeoutValidation) for clearer failure attribution.4. Organization/readability
"invalid timeout - zero"vs. a to-be-added"invalid startup-timeout - zero"— already distinguishable, but keep this naming convention as more cases are added).tools.timeout/tools.startup-timeoutschema+extraction validation end-to-end via full compilation, since a reader unfamiliar with the compiler pipeline may not realize why a fullCompileWorkflowcall is needed instead of callingextractToolTimeoutsdirectly.Acceptance Checklist
startup-timeoutzero/negative valuestartup-timeoutas valid GitHub Actions expressionstartup-timeoutas invalid non-numeric stringt.Fatalf/t.Errorfwithrequire/assertfrom testifymake test-unitand confirm all tests passmake fmtafter edits