You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CLAUDE.md
+41Lines changed: 41 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -207,6 +207,18 @@ ALWAYS use `cmd.NewTestKit(t)` for cmd tests. Auto-cleans RootCmd state (flags,
207
207
- No coverage theater
208
208
- Remove always-skipped tests
209
209
- Use `errors.Is()` for error checking
210
+
-**For aliasing/isolation tests, verify BOTH directions:** after a merge, mutate the result and confirm the original inputs are unchanged (result→src isolation); also mutate a source map before the merge and confirm the result is unaffected (src→result isolation).
211
+
-**For slice-result tests, assert element contents, not just length:**`require.Len` alone allows regressions that drop or corrupt contents. Assert at least the first and last element by value.
212
+
-**Never use platform-specific binaries in tests** (e.g., `false`, `true`, `sh` on Unix): these don't exist on Windows. Use Go-native test helpers: subprocess via `os.Executable()` + `TestMain`, temp files with cross-platform scripts, or DI to inject a fake command runner.
213
+
-**Safety guards must fail loudly:** any check that counts fixture files or validates test preconditions must use `require.Positive` (or equivalent) — never `if count > 0 { ... }` which silently disables the check when misconfigured.
214
+
-**Use absolute paths for fixture counting:** any `filepath.WalkDir` or file-count assertion must use an already-resolved absolute path (not a relative one) to be CWD-independent.
215
+
-**Add compile-time sentinels for schema field references in tests:** when a test uses a specific struct field (e.g., `schema.Provider{Kind: "azure"}`), add `var _ = schema.Provider{Kind: "azure"}` as a compile guard so a field rename immediately fails the build.
216
+
-**Add prerequisite sub-tests for subprocess behavior:** when a test depends on implicit env propagation (e.g., `ComponentEnvList` reaching a subprocess), add an explicit sub-test that confirms the behavior before the main test runs.
217
+
-**Contract vs. legacy behavior:** if a test says "matches mergo" (or any other library), add an opt-in cross-validation test behind a build tag (e.g., `//go:build compare_mergo`); otherwise state "defined contract" explicitly so it's clear the native implementation owns the behavior. Run cross-validation tests with: `go test -tags compare_mergo ./pkg/merge/... -run CompareMergo -v` (requires mergo v1.0.x installed).
218
+
-**Include negative-path tests for recovery logic:** whenever a test verifies that a recovery/fallback triggers under condition X, add a corresponding test that verifies the recovery does NOT trigger when condition X is absent (e.g., mismatched workspace name).
219
+
220
+
### Follow-up Tracking (MANDATORY)
221
+
When a PR defers work to a follow-up (e.g., migration, cleanup, refactor), **open a GitHub issue and link it by number** in the blog post, roadmap, and/or PR description before merging. Blog posts with "a follow-up issue will..." with no `#number` are incomplete — the work will never be tracked.
210
222
211
223
### Mock Generation (MANDATORY)
212
224
Use `go.uber.org/mock/mockgen` with `//go:generate` directives. Never manual mocks.
Use `viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK")` - ATMOS_ prefix required.
367
387
@@ -383,6 +403,27 @@ Search `internal/exec/` and `pkg/` before implementing. Extend, don't duplicate.
383
403
### Cross-Platform (MANDATORY)
384
404
Linux/macOS/Windows compatible. Use SDKs over binaries. Use `filepath.Join()` instead of hardcoded path separators.
385
405
406
+
**Subprocess helpers in tests (cross-platform):**
407
+
Instead of `exec.LookPath("false")` or other Unix-only binaries, use the test binary itself.
408
+
**Important:** If your package already has a `TestMain`, add the env-gate check **inside the existing `TestMain`** — do not add a second `TestMain` function (Go does not allow two in the same package).
409
+
410
+
```go
411
+
// In testmain_test.go — merge this check into the existing TestMain:
412
+
funcTestMain(m *testing.M) {
413
+
// If _ATMOS_TEST_EXIT_ONE is set, exit immediately with code 1.
414
+
// This lets tests use the test binary itself as a cross-platform "exit 1" command.
415
+
if os.Getenv("_ATMOS_TEST_EXIT_ONE") == "1" { os.Exit(1) }
416
+
os.Exit(m.Run())
417
+
}
418
+
// NOTE: If your package already defines TestMain, insert the _ATMOS_TEST_EXIT_ONE
419
+
// check at the top of the existing function rather than copying the whole snippet.
0 commit comments