Skip to content

[#121] Add end-to-end lifecycle integration tests#259

Merged
bguidolim merged 8 commits intomainfrom
bruno/121-lifecycle-integration-tests
Mar 21, 2026
Merged

[#121] Add end-to-end lifecycle integration tests#259
bguidolim merged 8 commits intomainfrom
bruno/121-lifecycle-integration-tests

Conversation

@bguidolim
Copy link
Collaborator

@bguidolim bguidolim commented Mar 21, 2026

Summary

Add the main deliverable for #121: end-to-end lifecycle integration tests that exercise the full sync → state → doctor → remove pipeline. Each scenario chains Configurator.configure() with DoctorRunner.run() in a fully sandboxed environment, verifying cross-component interactions that were previously untested.

Final PR in the #121 stacked series (builds on #256, #261, #258).

Closes #121

Changes

  • Add LifecycleIntegrationTests.swift with LifecycleTestBed helper and 9 scenario tests:
    • Scenario 1 — Single-pack lifecycle: configure with hook + MCP + settings + template → doctor passes → introduce settings drift → doctor detects → re-sync fixes → remove pack (MCP removal, settings cleanup, template removal)
    • Scenario 2 — Multi-pack convergence: two packs with different settings/templates → verify merged state → remove one → verify only other remains → re-add → verify both restored
    • Scenario 3 — Pack update with template change: configure v1 → create v2 with new template → re-configure → verify content updated → doctor passes
    • Scenario 4 — Component exclusion lifecycle: configure both hooks → exclude one → verify removed → re-include → verify restored (PR Fix convergence gaps in sync engine #234 regression coverage)
    • Scenario 5 — Global scope sync + doctor: configure global scope → verify artifacts in ~/.claude/ → doctor passes
    • Scenario 6 — Stale artifact cleanup: v1 has skills A,B,C → v2 has A,D → verify B,C removed, D created, A unchanged
    • Scenario 7 — Template dependency filtering: exclude component → dependent template section removed → re-include → restored
    • Scenario 8 — Global scope exclusion + doctor: global-scope exclusion recorded → doctor completes
    • Scenario 9 — Section content restoration: tamper section content → re-sync restores original

Test plan

  • swift test passes locally (782 tests in 92 suites, 0 failures)
  • swiftformat --lint . and swiftlint pass without violations
  • Affected commands verified with a real pack (e.g. mcs sync, mcs doctor)

@bguidolim bguidolim force-pushed the bruno/121-doctor-runner-harness branch from d2bd9dc to cf04342 Compare March 21, 2026 15:40
@bguidolim bguidolim force-pushed the bruno/121-lifecycle-integration-tests branch from 301f1c7 to 7d37597 Compare March 21, 2026 15:40
@bguidolim bguidolim force-pushed the bruno/121-doctor-runner-harness branch from cf04342 to 39bbae3 Compare March 21, 2026 15:45
@bguidolim bguidolim force-pushed the bruno/121-lifecycle-integration-tests branch from 7d37597 to f544cec Compare March 21, 2026 15:45
@bguidolim bguidolim force-pushed the bruno/121-doctor-runner-harness branch from 39bbae3 to 0fd9d16 Compare March 21, 2026 15:56
@bguidolim bguidolim force-pushed the bruno/121-lifecycle-integration-tests branch from f544cec to 8af23f7 Compare March 21, 2026 15:56
@bguidolim bguidolim force-pushed the bruno/121-doctor-runner-harness branch from 0fd9d16 to 43538aa Compare March 21, 2026 16:00
@bguidolim bguidolim force-pushed the bruno/121-lifecycle-integration-tests branch 2 times, most recently from 4ed4d95 to bb29b5d Compare March 21, 2026 16:11
Base automatically changed from bruno/121-doctor-runner-harness to main March 21, 2026 16:13
- Add `environment` property to DoctorRunner and 10 check structs
  (CommandCheck, MCPServerCheck, PluginCheck, HookCheck, GitignoreCheck,
  ProjectIndexCheck, PackGitignoreCheck, ExternalCommandExistsCheck,
  ExternalHookEventExistsCheck, ExternalSettingsKeyEqualsCheck),
  replacing all hardcoded `Environment()` calls
- Add `projectRootOverride` to DoctorRunner to bypass
  ProjectDetector.findProjectRoot() in tests
- Flow environment through DerivedDoctorChecks and standaloneDoctorChecks
- Thread environment from DoctorCommand to DoctorRunner
- Pass environment to PackGitignoreCheck in artifactChecks()
- Remove redundant environment parameter from private standaloneDoctorChecks()
- Add `environment` property to DoctorRunner and 10 check structs
  (CommandCheck, MCPServerCheck, PluginCheck, HookCheck, GitignoreCheck,
  ProjectIndexCheck, PackGitignoreCheck, ExternalCommandExistsCheck,
  ExternalHookEventExistsCheck, ExternalSettingsKeyEqualsCheck),
  replacing all hardcoded `Environment()` calls
- Add `projectRootOverride` to DoctorRunner to bypass
  ProjectDetector.findProjectRoot() in tests
- Flow environment through DerivedDoctorChecks and standaloneDoctorChecks
- Thread environment from DoctorCommand to DoctorRunner
- Pass environment to PackGitignoreCheck in artifactChecks()
- Remove redundant environment parameter from private standaloneDoctorChecks()
- Add 6 lifecycle scenarios covering the full sync -> doctor -> remove
  pipeline with sandbox isolation
- Scenario 1: Single-pack configure/doctor/drift/fix/remove
- Scenario 2: Multi-pack convergence with selective removal
- Scenario 3: Pack update with template v1 -> v2 change
- Scenario 4: Component exclusion and re-inclusion
- Scenario 5: Global scope sync and doctor
- Scenario 6: Stale artifact cleanup on pack update (A,B,C -> A,D)
…x tests

- Add MCP server registration/removal assertions to scenario 1
- Add hook settings auto-derive verification to scenario 1
- Scenario 7: Template dependency filtering (exclude component removes
  dependent template sections, re-include restores)
- Scenario 8: Global scope exclusion + doctor
- Scenario 9: Doctor fix restores tampered section content via re-sync
@bguidolim bguidolim force-pushed the bruno/121-lifecycle-integration-tests branch from bb29b5d to fb49678 Compare March 21, 2026 16:23
- Add component factory methods (hookComponent, skillComponent,
  settingsComponent, mcpComponent) to LifecycleTestBed
- Add runDoctor/runGlobalDoctor convenience methods
- Add settingsEnv() helper to reduce JSON assertion boilerplate
- Add MCP scope assertion (local) in Scenario 1
- Rename Scenario 9 from "Doctor fix" to "Re-sync restores" to
  accurately reflect that re-sync (not doctor --fix) restores content
@bguidolim bguidolim merged commit 52cae67 into main Mar 21, 2026
4 checks passed
@bguidolim bguidolim deleted the bruno/121-lifecycle-integration-tests branch March 21, 2026 16:34
@bguidolim bguidolim mentioned this pull request Mar 22, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add end-to-end integration tests for full pack lifecycle

1 participant