Summary
packages/testing/src/setupEnv.ts is now ~420 lines and does five unrelated jobs: silences console output, registers seven custom matchers via expect.extend, adds a ZodError equality tester, augments the Vitest Assertion and AsymmetricMatchersContaining interfaces, and sets Lambda environment variables. #5693 added toReceiveCommandWith to it and #5655 had to touch the augmentation again for Vitest 5.
This is a proposal to move the matchers into their own modules under packages/testing/src/matchers/ and leave setupEnv.ts as a thin setup file.
Why is this needed?
- Each matcher's implementation and its type declaration sit ~250 lines apart in the same file, so adding or changing one means editing two disjoint spots and keeping them in sync by hand.
- The file is the shared
setupFiles entry for every package's vitest.config.ts and for tsconfig.test.json, so unrelated churn (env vars vs. matcher logic vs. typings) all shows up as diffs to one hot file.
- The logger, metrics and AWS SDK matcher families have nothing in common beyond living in the same
expect.extend call.
Which area does this relate to?
Tests
Solution
- Create
packages/testing/src/matchers/ with one module per matcher family, e.g. awsSdk.ts (toReceiveCommandWith), logger.ts (toHaveLogged, toHaveLoggedNth), metrics.ts (toHaveEmittedEMFWith, toHaveEmittedNthEMFWith, toHaveEmittedMetricWith, toHaveEmittedNthMetricWith).
- Each module exports the matcher implementations and the interface describing their assertion signatures side by side, so implementation and typing live together.
- An
index.ts in that folder merges the families into a single object and holds the one declare module 'vitest' block that extends Assertion<R, T> and AsymmetricMatchersContaining.
setupEnv.ts keeps its current path (so no vitest.config.ts or tsconfig.test.json changes) and shrinks to: console spies, expect.extend(matchers), the ZodError tester, and env vars.
- No behaviour change. The existing
toReceiveCommandWith unit and type tests must keep passing, and the full pre-push suite must stay at 100% coverage.
Why a matchers/ folder rather than a setup/ folder: this mirrors how matcher libraries such as @testing-library/jest-dom and jest-extended are laid out, with one module per matcher family and a thin entry file that only calls expect.extend. It also matches how this package already groups code by concern (resources/, lmi/, e2e/), and the matchers already have their own unit and type tests, so they are a module in their own right rather than setup glue.
Acknowledgment
Future readers
Please react with 👍 and your use case to help us understand customer demand.
Summary
packages/testing/src/setupEnv.tsis now ~420 lines and does five unrelated jobs: silences console output, registers seven custom matchers viaexpect.extend, adds a ZodError equality tester, augments the VitestAssertionandAsymmetricMatchersContaininginterfaces, and sets Lambda environment variables. #5693 addedtoReceiveCommandWithto it and #5655 had to touch the augmentation again for Vitest 5.This is a proposal to move the matchers into their own modules under
packages/testing/src/matchers/and leavesetupEnv.tsas a thin setup file.Why is this needed?
setupFilesentry for every package'svitest.config.tsand fortsconfig.test.json, so unrelated churn (env vars vs. matcher logic vs. typings) all shows up as diffs to one hot file.expect.extendcall.Which area does this relate to?
Tests
Solution
packages/testing/src/matchers/with one module per matcher family, e.g.awsSdk.ts(toReceiveCommandWith),logger.ts(toHaveLogged,toHaveLoggedNth),metrics.ts(toHaveEmittedEMFWith,toHaveEmittedNthEMFWith,toHaveEmittedMetricWith,toHaveEmittedNthMetricWith).index.tsin that folder merges the families into a single object and holds the onedeclare module 'vitest'block that extendsAssertion<R, T>andAsymmetricMatchersContaining.setupEnv.tskeeps its current path (so novitest.config.tsortsconfig.test.jsonchanges) and shrinks to: console spies,expect.extend(matchers), the ZodError tester, and env vars.toReceiveCommandWithunit and type tests must keep passing, and the full pre-push suite must stay at 100% coverage.Why a
matchers/folder rather than asetup/folder: this mirrors how matcher libraries such as@testing-library/jest-domandjest-extendedare laid out, with one module per matcher family and a thin entry file that only callsexpect.extend. It also matches how this package already groups code by concern (resources/,lmi/,e2e/), and the matchers already have their own unit and type tests, so they are a module in their own right rather than setup glue.Acknowledgment
Future readers
Please react with 👍 and your use case to help us understand customer demand.