Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
# Capability Spec Delta: testing-integration (testing-integration-build-fix)
**Package**: `@suaveplan/testing-integration`
**Status**: PROPOSED
## ADDED Requirements
### Requirement: globalSetup MUST resolve to a real on-disk file
`createIntegrationSetup()` returns an `IntegrationSetupResult.globalSetup: string` value. After `bun run build`, this string MUST be an absolute filesystem path that exists on disk and that `vitest` can load as a module. It MUST NOT contain a `data:` URL, an `import.meta.url`-derived expression that survives bundling, or any other URL scheme that Vitest cannot pass to `import()`.
The bug this requirement guards against: Vite library mode treats `new URL("../setup/global-setup.js", import.meta.url).pathname` as an asset reference and inlines the source file as a `data:video/mp2t;base64,<…>` URL during `vite build`. The published artifact at `dist/internal/create-integration-setup-internal.js` then literally returns `"data:video/mp2t;base64,…"` as the `globalSetup` field. Vitest crashes at startup with `ERR_LOAD_URL: Failed to load url <consumer-cwd>/video/mp2t;base64,…` and no consumer can use the public API.
The fix path declared by `testing-integration-build-fix` is to add `src/setup/global-setup.ts` as a second `lib.entry` in `vite.config.ts` (with `output.entryFileNames: "[name].js"` so `dist/setup/global-setup.js` is actually emitted) and to replace the asset-intercepted `new URL(...).pathname` expression in `src/internal/create-integration-setup-internal.ts` with a Vite-safe alternative — `path.join(fileURLToPath(import.meta.url), "..", "..", "setup", "global-setup.js")` — that Vite does not transform.
#### Scenario: globalSetup is an existing file path after build
- **WHEN** the package is built and `createIntegrationSetup({ x: stubFixture }).globalSetup` is read
- **THEN** the returned string is an absolute path AND `existsSync(globalSetup) === true`
#### Scenario: globalSetup is not a data: URL
- **WHEN** the package is built and `createIntegrationSetup({ x: stubFixture }).globalSetup` is read
- **THEN** the returned string does not start with `data:`, `blob:`, or any other non-`file://` URL scheme
#### Scenario: vitest can load the returned globalSetup
- **WHEN** a consumer wires `test.globalSetup = [createIntegrationSetup({...}).globalSetup]` in `vitest.config.ts` and runs `vitest run`
- **THEN** the runner reaches the global-setup phase without `ERR_LOAD_URL` or any `Failed to load url` error
**Verified by:** `tests/dist-asserts.test.ts` (added by this change) — loads `dist/index.js`, calls `createIntegrationSetup({ x: stubFixture })`, asserts `existsSync(globalSetup) === true` and that the path does not start with `data:`.
---
### Requirement: createIntegrationSetup public API is preserved
The shape of `createIntegrationSetup<TFixtures>(fixtures: TFixtures): IntegrationSetupResult<TFixtures>` MUST NOT change as part of this fix. Consumers continue to receive `{ globalSetup: string; inject: <K extends keyof TFixtures>(key: K) => InferConfig<TFixtures[K]> }`. The fix is a build-config and internal-resolution change only; no consumer call site needs to be modified.
#### Scenario: existing callers compile unchanged
- **WHEN** an existing consumer's `createIntegrationSetup({ surrealdb: new SurrealDBFixture() })` call is type-checked against the post-fix package
- **THEN** the call compiles without modification and `globalSetup` and `inject` are typed as before
**Verified by:** `src/setup/create-integration-setup.test.ts` (existing) AND `tests/dist-asserts.test.ts` (added by this change).
---
### Requirement: dist-asserts regression test
The package SHALL ship a `tests/dist-asserts.test.ts` that runs against the BUILT `dist/index.js` (not the `src/` source) and asserts the `globalSetup` resolution contract above. This test guards against any future refactor that re-introduces an asset-intercepted URL expression in the build output. The test MUST run after `build` so it exercises the published artifact, not the unbundled source.
#### Scenario: dist-asserts runs against the built artifact
- **WHEN** the test suite executes
- **THEN** the test imports from `../dist/index.js` (or the published entry resolved via `package.json` `exports."."`) and not from `../src/`
#### Scenario: dist-asserts fails fast when globalSetup is broken
- **WHEN** `globalSetup` is a `data:` URL or a non-existent path
- **THEN** the test fails with a message naming the actual offending value
**Verified by:** `tests/dist-asserts.test.ts` (added by this change).
---
### Requirement: Storage-s3 consumer migrates back to the public API
After this change ships, `packages/storage/storage-s3/tests/integration/setup.ts` and `packages/storage/storage-s3/tests/integration/global-setup.ts` MUST be migrated from their current hand-rolled `TestEnvironment` driver pattern (the rebel pattern that bypasses the broken `createIntegrationSetup` API) back to the public `createIntegrationSetup({ garageS3: new GarageS3Fixture() })` factory. No subsequent `testing-integration-*` consumer is permitted to ship the rebel pattern.
#### Scenario: storage-s3 setup uses the public factory
- **WHEN** `packages/storage/storage-s3/tests/integration/setup.ts` is read after this change ships
- **THEN** it imports `createIntegrationSetup` from `@suaveplan/testing-integration` and does not construct a `TestEnvironment` directly
**Verified by:** code-review against the migrated `setup.ts` and `global-setup.ts` files; the `set-partial.integration.test.ts` suite continues to pass via `bun run test:integration --filter=@suaveplan/storage-s3`.