Skip to content

fix(tests): corregir fallos de tests pre-existentes en entornos Windows#372

Merged
Alan-TheGentleman merged 8 commits into
Gentleman-Programming:mainfrom
Basparin:fix/103-windows-test-failures
Jun 11, 2026
Merged

fix(tests): corregir fallos de tests pre-existentes en entornos Windows#372
Alan-TheGentleman merged 8 commits into
Gentleman-Programming:mainfrom
Basparin:fix/103-windows-test-failures

Conversation

@Basparin

@Basparin Basparin commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

🔗 Linked Issue

Closes #103

🏷️ PR Type

  • type:bug — Bug fix (non-breaking change that fixes an issue)

🙏 Credit

Retoma el trabajo de @atarico en #104 (cerrado por un tema de proceso, no técnico). Su commit original se preserva con autoría intacta (Author: atarico).

📝 Summary

Al correr go test ./... en Windows hay fallos pre-existentes causados por incompatibilidades del entorno, no por errores de lógica. Tras el rebase sobre main actual (que ya arregló TestSkillPathForAgent por su cuenta con filepath.Join), este PR cubre dos categorías:

  1. CRLF en archivos trackeados — sin .gitattributes, Git en Windows convierte assets embebidos (go:embed) a CRLF en checkout, rompiendo los tests golden que esperan LF. Solución: .gitattributes con * text eol=lf.
  2. Tests OpenCode que requieren bun/npm — los tests de inyección SDD instalan el plugin de background-agents, que falla sin package manager. Solución: reusar el helper existente mockNoPackageManager() en los tests que NO testean el install path, y skipIfNoPkgManager() + skip por mensaje de error en los que sí lo ejercitan.

📂 Changes

File / Area What Changed
.gitattributes New: * text eol=lf para forzar LF en todos los sistemas
internal/components/golden_test.go t.Skipf en los 2 goldens OpenCode cuando el plugin install no está disponible en el entorno
internal/components/sdd/inject_test.go skipIfNoPkgManager() helper + mockNoPackageManager(t) aplicado a 17 tests de inyección que no testean el install path

Total: 3 files, +59/-0.

Cambios vs versión anterior del PR (review del 29-may):

  • Hunk de skills/inject_test.go eliminado — superseded por el fix de main con filepath.Join
  • disablePluginInstall eliminado — ahora reusa el helper existente mockNoPackageManager
  • Descripción actualizada para matchear el diff real ✅

🧪 Test Plan

Unit Tests (Windows 11 Pro local, tras rebase sobre main 03457e9)

go test ./internal/components/ ./internal/components/sdd/ ./internal/components/skills/
  • Los 3 paquetes PASS completos en Windows (antes: 10+ goldens FAIL por CRLF, 17 tests FAIL por bun/npm)
  • gofmt -l limpio en archivos tocados

E2E Tests (Docker required)

Not run

✅ Contributor Checklist

Summary by CodeRabbit

  • Chores

    • Enforced consistent LF line endings and excluded common binary/archive types from line-ending normalization.
  • Tests

    • Made tests more resilient when package managers or plugin installation are unavailable: added runtime detection and mocks to force no-package-manager mode in affected tests, and updated plugin-dependent and golden tests to gracefully skip on installation-related failures.

@Alan-TheGentleman Alan-TheGentleman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

La idea puede servir, pero falta ordenar el proceso y revisar solapamiento.

Sumá el label type:*, refrescá CI contra main y compará explícitamente este cambio con #490 para que no revisemos dos fixes de Windows que pisan el mismo problema.

@Basparin

Copy link
Copy Markdown
Contributor Author

@Alan-TheGentleman refreshed against current main + addressed the #490 comparison you asked for.

Refresh

Merge commit: 4af2c9c (clean, zero conflicts).

While running the suite against the merged tree I caught a new test introduced by main that the original PR pattern hadn't reached yet:

  • TestInjectCopiesNestedSDDSkillReferences — was missing disablePluginInstall(t), so it tried to install unique-names-generator into a temp dir on Windows and failed the post-install check.

Extension applied in commit 5553249 — one-line addition, same pattern this PR already uses across its sibling tests.

Local validation

go test ./internal/components/sdd/   -run "TestInjectCopiesNestedSDDSkillReferences|TestInjectCopiesAllFiles"
go test ./internal/components/skills/ -run TestSkillPathForAgent
go test ./internal/components/        -run TestGoldenEngram_Antigravity

All 3 previously-failing cases now PASS. The remaining unit-test failure on CI is from internal/cli/run_integration_test.go::TestRunInstallEngramForPiAndOpenCodeProvisionsBothMCPTargets — that's a Pi-feature regression that landed on main (last two fix(pi): commits left main red — see runs 25641715595, 25641492770). Same upstream issue blocking #374 right now — not anything this PR introduced.

Boundary vs #490 (tonyblu331)

You asked explicitly for this, so here it is concrete:

Aspect #490 (tonyblu331) #372 (this)
Scope internal/cli/ only internal/components/ (sdd + skills + golden)
Files touched 7, all under internal/cli/ 5, all under internal/components/ + .gitattributes
Failure category CLI test env contamination — real HOME / USERPROFILE / APPDATA bleeding into tests, Windows cmd.exe for shell capture, PATH normalization in CLI guidance CRLF in golden files (.gitattributes), path-separator hardcoded in SkillPathForAgent, opencode-plugin install requiring bun add unique-names-generator in test temp dirs
Helpers introduced isolateAgentDiscoveryEnv, ensureOpenCodeSDDNodeStub (in internal/cli/) skipIfNoPkgManager, disablePluginInstall (in internal/components/sdd/)
Overlap Zero files Zero files

Both PRs link Closes #103 because #103 is the umbrella "Windows test failures" issue. They are complementary slices, not duplicate fixes:

I checked both diffs file-by-file before refreshing — there is no shared symbol, no shared helper, and no shared test name. The two PRs can land in either order without rebase conflicts; whichever lands first the other will merge cleanly.

If you'd prefer them landed in a specific order or want me to align helper naming conventions across the two, happy to coordinate with @tonyblu331.

Pending maintainer action

  • Apply the type:bug label (the only blocker I can't unblock as an external contributor).

@Alan-TheGentleman Alan-TheGentleman added the type:bug Bug fix label May 22, 2026
@Alan-TheGentleman

Copy link
Copy Markdown
Contributor

@Basparin — friendly nudge: 10/12 checks green, only 2 failures left. Could you take another pass at the failing jobs and refresh against current main (we shipped v1.31.0 yesterday with 15+ PRs touching the install/upgrade/Windows paths — some test fixtures may need an update)? Once the last 2 are green I can review for merge. Thanks for sticking with it!

@Alan-TheGentleman

Copy link
Copy Markdown
Contributor

@Basparin — heads-up: this PR's Unit Tests failure is TestRunInstallEngramForPiAndOpenCodeProvisionsBothMCPTargets. That test was rewritten in main by PR #660 (fix(agents/pi): use positional pnpm dlx argument, landed in v1.31.0) to expect the new pnpm dlx gentle-engram@X pi-engram init form instead of the old pnpm dlx --package ... form.

Your branch still expects the old form, so the CI run uses the pre-#660 assertion and fails.

Fix: rebase against current main — the conflict should resolve cleanly (your changes are in different files than what #660 touched, but the integration test now has the new expectation). After the rebase, this specific failure goes away.

Pseudocode:

git fetch upstream main
git rebase upstream/main
# resolve any conflicts (likely none for this PR's scope)
git push --force-with-lease

The other PR you have open (and #371 + #374 + #372) all show the same failure for the same reason — same rebase fixes all three. Thanks for sticking with these.

@Alan-TheGentleman Alan-TheGentleman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking this up and preserving @atarico's authorship — the issue-first link (Closes #103, status:approved) and conventional commits are correct, and the approach is sound. .gitattributes eol=lf, filepath.FromSlash, and stubbing npmLookPath are genuine cross-platform fixes, not Windows-only t.Skips — so Linux/macOS coverage stays intact. Good.

Two things block merge:

  1. Stale / conflicting. The branch is currently conflicting against main (mergeStateStatus: DIRTY) and needs a rebase. merge-tree shows real conflicts in all three touched test files.
  2. Obsolete hunk. main already fixed TestSkillPathForAgent independently using filepath.Join(...), so the filepath.FromSlash hunk in skills/inject_test.go now conflicts and is redundant — please drop it on rebase.

Also: disablePluginInstall duplicates the existing mockNoPackageManager helper (both stub npmLookPath); please reuse mockNoPackageManager or drop the cases that call both. And the PR description references a golden_test.go "Windows helper" and a regenerated sdd-vscode golden that aren't in the final diff — please update it to match the actual change.

Rebase + drop the obsolete skills hunk and this is good to go.

atarico and others added 4 commits June 10, 2026 09:21
- Agregar .gitattributes con eol=lf para evitar conversión CRLF en golden files
- Regenerar golden files con terminaciones LF consistentes
- Usar filepath.FromSlash() en TestSkillPathForAgent para separadores de ruta
- Agregar skipIfNoPkgManager() y disablePluginInstall() para tests de OpenCode
  que requieren npm/bun — ahora hacen skip en lugar de fallar
These two tests exercised the OpenCode inject path without mocking the

package manager lookup, so they failed on Windows environments lacking

bun/npm with the same unique-names-generator post-install error that

atarico addressed for 15+ sibling tests. Applying the same helper keeps

the fix for Gentleman-Programming#103 consistent across the whole test file.
Previous regeneration contaminated the golden with persona.Inject output
(Rules, Personality, Engram Protocol) that does not belong to sdd.Inject.
Restoring to the baseline resolves TestGoldenSDD_VSCode on Linux CI.
…illReferences

Main introduced TestInjectCopiesNestedSDDSkillReferences after this PR
opened. It exercises the same opencode-plugin install path as its
TestInjectCopiesAllFiles* siblings and fails on Windows for the same
reason (no bun/npm to install unique-names-generator inside the test
temp dir).

Apply the same disablePluginInstall(t) helper this PR already uses for
the rest of the family. No behavior change in production code.
@Basparin Basparin force-pushed the fix/103-windows-test-failures branch from 5553249 to d80c72e Compare June 10, 2026 13:25
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0bf48d2a-733e-450b-ad3d-e2eebbbeeab1

📥 Commits

Reviewing files that changed from the base of the PR and between 2a4e7b0 and 42a8645.

📒 Files selected for processing (1)
  • internal/components/sdd/inject_test.go

📝 Walkthrough

Walkthrough

Adds .gitattributes to enforce LF line endings and updates OpenCode injection and golden tests with helpers and conditional skips so tests either disable plugin installation or skip when bun/npm are unavailable.

Changes

Test Environment Isolation

Layer / File(s) Summary
Git line-ending normalization
.gitattributes
Enforces LF line endings for text files and marks common binary formats (png, jpg, jpeg, gif, ico, zip, tar.gz) as binary to prevent Git EOL conversion.
Test helpers and imports
internal/components/sdd/inject_test.go
Adds os/exec import and skipIfNoPkgManager(t) helper to detect bun/npm and support disabling plugin installs in tests.
Golden test plugin-error skipping
internal/components/golden_test.go
TestGoldenSDD_OpenCode and TestGoldenSDD_OpenCode_Multi now detect plugin-install error substrings and call t.Skipf instead of failing when installation is unavailable.
Injection tests with plugin install disabled
internal/components/sdd/inject_test.go
Multiple OpenCode injection tests (command-file, idempotency, migrations, multi-mode, model-assignment, shared-file, and skill-copy assertions) now call the helper that disables plugin installation to isolate behavior from plugin-install side effects.
Plugin-install tests with package-manager checks
internal/components/sdd/inject_test.go
Plugin-writing/idempotency tests call skipIfNoPkgManager(t) and conditionally skip on installer error markers (unique-names-generator, post-install check).

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title in Spanish references fixing test failures on Windows, which aligns with the main changes: adding .gitattributes for LF line endings and updating tests to skip when environment dependencies are unavailable.
Linked Issues check ✅ Passed The PR addresses the primary coding requirements from issue #103: enforces LF line endings via .gitattributes (Category 1), and updates tests to skip when package managers are unavailable (Category 3). Category 2 (filepath separator) is not included but acknowledged as handled by separate PR #490.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing Windows test environment failures: .gitattributes for line endings, and test updates to handle missing package managers. No unrelated logic changes or refactoring outside the stated objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/components/sdd/inject_test.go`:
- Around line 3320-3323: Tests call skipIfNoPkgManager() to require a real
package manager but then immediately call mockNoPackageManager(), which
neutralizes that requirement and prevents exercising the install-capable path;
update the two affected tests in inject_test.go (the blocks that call
skipIfNoPkgManager and mockNoPackageManager around lines shown) so they do not
call mockNoPackageManager() before exercising install behavior (either remove
the mockNoPackageManager() call from those tests or move it to after the
install-capable assertions), and apply the same change to the second occurrence
around the other mentioned lines.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 01d7f880-9eba-4d4e-99f5-1bc666f58609

📥 Commits

Reviewing files that changed from the base of the PR and between 03457e9 and d80c72e.

📒 Files selected for processing (3)
  • .gitattributes
  • internal/components/golden_test.go
  • internal/components/sdd/inject_test.go

Comment thread internal/components/sdd/inject_test.go Outdated
@Basparin

Copy link
Copy Markdown
Contributor Author

@Alan-TheGentleman review del 29-may atendida completa:

  1. Rebase sobre main actual (03457e9) ✅ — conflictos resueltos, mergeStateStatus limpio.
  2. Hunk obsoleto de skills/inject_test.go eliminado ✅ — main ya lo había arreglado con filepath.Join; en el rebase tomé la versión de main y el archivo salió del diff.
  3. disablePluginInstall eliminado ✅ — los 17 call sites ahora reusan el helper existente mockNoPackageManager (commit e9e59e3).
  4. Descripción del PR actualizada ✅ — ahora matchea el diff real: 3 files, +59/-0 (.gitattributes, golden_test.go, sdd/inject_test.go).

Validación local Windows 11: go test ./internal/components/ ./internal/components/sdd/ ./internal/components/skills/ — los 3 paquetes PASS completos.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
internal/components/sdd/inject_test.go (1)

3307-3324: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

mockNoPackageManager neutralizes skipIfNoPkgManager in plugin tests (duplicate concern).

These plugin-focused tests first require a real package manager via skipIfNoPkgManager(t), then immediately mock it away with mockNoPackageManager(t). The result: they only run when bun/npm exist in PATH, but never exercise the install path because the mock forces a no-package-manager code path. This prevents regressions in the install logic from being caught.

Suggested fix

Remove mockNoPackageManager(t) from both tests so they exercise the real install path:

 func TestInjectOpenCodeSingleWritesPlugin(t *testing.T) {
 	skipIfNoPkgManager(t)
 	home := t.TempDir()
-	mockNoPackageManager(t)
 
 	_, err := Inject(home, opencodeAdapter(), "single")
 func TestInjectOpenCodePluginIdempotent(t *testing.T) {
 	skipIfNoPkgManager(t)
 	home := t.TempDir()
-	mockNoPackageManager(t)
 
 	// First run
 	first, err := Inject(home, opencodeAdapter(), "multi")

Also applies to: 3429-3454

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/components/sdd/inject_test.go` around lines 3307 - 3324, The test
setup calls skipIfNoPkgManager(t) to require a real package manager but then
immediately calls mockNoPackageManager(t), which neutralizes that requirement
and prevents exercising the install path; remove the mockNoPackageManager(t)
call from TestInjectOpenCodeSingleWritesPlugin (and the sibling test around
lines 3429-3454) so the tests run only when a package manager is present and
actually exercise Inject(..., opencodeAdapter(), "single") install logic instead
of the mocked no-package-manager path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/components/sdd/inject_test.go`:
- Around line 2246-2248: Remove the duplicated consecutive
mockNoPackageManager(t) call in each test; keep a single invocation to install
the mock and register cleanup (e.g., remove the second mockNoPackageManager(t)
after home := t.TempDir() so only the first call remains). Apply the same change
for the other occurrences mentioned (around the ranges referenced) and verify
each test still registers cleanup once and compiles.

---

Duplicate comments:
In `@internal/components/sdd/inject_test.go`:
- Around line 3307-3324: The test setup calls skipIfNoPkgManager(t) to require a
real package manager but then immediately calls mockNoPackageManager(t), which
neutralizes that requirement and prevents exercising the install path; remove
the mockNoPackageManager(t) call from TestInjectOpenCodeSingleWritesPlugin (and
the sibling test around lines 3429-3454) so the tests run only when a package
manager is present and actually exercise Inject(..., opencodeAdapter(),
"single") install logic instead of the mocked no-package-manager path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 97037546-026b-4a04-b15d-3cd19261a457

📥 Commits

Reviewing files that changed from the base of the PR and between d80c72e and e9e59e3.

📒 Files selected for processing (1)
  • internal/components/sdd/inject_test.go

Comment thread internal/components/sdd/inject_test.go Outdated
@Alan-TheGentleman

Copy link
Copy Markdown
Contributor

Good direction overall. The PR is now clean against current main, checks are green, and the scope makes sense for #103.

One small cleanup before merge: the final diff leaves duplicate mockNoPackageManager(t) calls in 5 tests, for example TestInjectOpenCodeMultiModeWithModelAssignments has one before home := t.TempDir() and another right after. Same pattern appears in the no-assignments, single-mode assignments, and the two pre-existing config tests.

Can you drop the redundant second call in those tests? It does not change behavior, but keeping one setup call per test avoids confusing future readers and makes the Windows-test hardening cleaner.

@Basparin

Copy link
Copy Markdown
Contributor Author

@Alan-TheGentleman done — the 5 duplicate mockNoPackageManager(t) calls are gone (commit 2a4e7b0). They were an artifact of the helper consolidation: those tests already had the mock from main, and the replace-all of disablePluginInstall left a second identical call. One setup call per test now. go test ./internal/components/sdd/ PASS local.

@Alan-TheGentleman Alan-TheGentleman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. The branch is refreshed against current main, the duplicate mock setup concern is resolved, and the fresh CI/E2E run is green across ubuntu, arch, and fedora.\n\nI also checked the final head locally with ok github.com/gentleman-programming/gentle-ai/internal/components 9.572s
ok github.com/gentleman-programming/gentle-ai/internal/components/sdd 42.816s; both pass. This is now a clean Windows test-hardening slice for #103.

@Alan-TheGentleman Alan-TheGentleman merged commit 6893438 into Gentleman-Programming:main Jun 11, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(tests): fallos de tests pre-existentes en entornos Windows

3 participants