📦 deps(thirdparty): update snapshots

This commit is contained in:
ci[bot]
2026-07-18 00:02:59 +00:00
parent 82f7c6e56a
commit 47ce7f78dc
1446 changed files with 141041 additions and 6442 deletions
@@ -0,0 +1,50 @@
# Test Guard — JavaScript / TypeScript / Jest / Vitest Patterns
Concrete applications of the nine rules for JS/TS projects. Read this when reviewing or writing Jest or Vitest tests.
## Rule 2: Mock boundaries in JS/TS
Justified mock targets:
- Network: prefer `msw` (Mock Service Worker) over `jest.mock`-ing your own fetch wrapper — it mocks at the true boundary
- LLM / third-party SDK clients (`openai`, `@anthropic-ai/sdk`, Stripe, etc.)
- Timers and randomness: `vi.useFakeTimers()` / `jest.useFakeTimers()`, seeded RNG
- Filesystem and process env in Node code
Unjustified mocks:
- `jest.mock('../utils/helpers')` — mocking your own internal module to isolate a "unit" (Rule 2)
- Mocking a class's private method via prototype patching (Rule 1)
- Hand-built object literals pretending to be domain entities when a real constructor or factory exists (Rule 8)
## Rule 3: test.each
```ts
// Violation: three near-identical it() blocks
// Fix:
test.each([
['Hello World', 'hello-world'],
[' padded ', 'padded'],
['Café Menu', 'cafe-menu'],
])('slugify(%s) → %s', (raw, expected) => {
expect(slugify(raw)).toBe(expected);
});
```
## Snapshot discipline
Snapshot tests are implementation tests in disguise unless the snapshot *is* the contract (e.g., a public JSON output, a CLI's help text). Avoid snapshots of:
- Full component trees that change on every styling tweak (Rule 1 — brittle, asserts implementation)
- Large objects nobody reviews — an unread snapshot approves itself (Rule 4)
Prefer targeted assertions: `expect(screen.getByRole('button')).toHaveTextContent('Save')`.
## UI component tests
- Test what the user sees and does (Testing Library queries by role/label), not component internals or state hooks (Rule 1).
- Don't test that React renders, routes resolve, or props propagate — framework guarantees (Rule 7).
## Rule 9: Real persistence
For data-layer logic (Prisma/Drizzle/Knex queries), run against a real test database — `testcontainers`, a Dockerized Postgres, or SQLite where compatible. Mocking the query builder to test the query builder tests nothing.
@@ -0,0 +1,40 @@
# Test Guard — LLM Application Rules
Three additional rules for projects that call LLM APIs, use agent/workflow frameworks (LangGraph, CrewAI, custom state machines), or wire up observability/telemetry (Langfuse, LangSmith, OpenTelemetry). Apply these on top of the nine core rules.
## Rule 10: Prompt tests — test the contract, not the content
Prompt text changes constantly; tests pinned to wording rot within a week. Don't assert specific phrasing.
Do test:
- The prompt template exists and loads without error (smoke test)
- Template variables are substituted correctly — no leftover `{placeholder}` markers
- The prompt contains required structural markers *if the caller parses them* (e.g., a JSON schema block, a delimiter the parser splits on)
## Rule 11: Observability is infrastructure
Don't unit-test telemetry wiring. The violation pattern is asserting a tracing/analytics mock's call arguments:
```python
# Violation — tests wiring, not behavior
mock_tracer.assert_called_once_with(session_id=..., tags=[...])
```
Mocking observability calls to *prevent side effects* during tests is fine and often necessary. Just don't assert on the mock's call args. If telemetry breaks, dashboards show it; a unit test asserting wiring only breaks refactors.
## Rule 12: Agent and flow tests test transitions
For agent frameworks and state machines: test that given a state plus an event, the flow reaches the correct next state with the correct fields set. Mock the LLM calls to return controlled responses.
Test: state in → state out.
Don't test: the exact prompt string passed to the LLM, the number of LLM calls made, or internal retry logic — those are implementation details (Rule 1) that change with every model upgrade.
A useful pattern is a table of transition cases (data-driven, Rule 3): starting state, mocked LLM response, expected resulting state.
## Severity
- **Must fix:** Rule 12 violations that assert prompt strings or call counts — they break on every model/prompt change
- **Should fix:** Rule 10 wording assertions
- **Worth noting:** Rule 11 — flag it, but don't block a small change on it
@@ -0,0 +1,56 @@
# Test Guard — PHP / PHPUnit / Pest Patterns
Concrete applications of the nine rules for PHP projects, including WordPress and WooCommerce. Read this when reviewing or writing PHP tests.
## Rule 2: Mock boundaries in PHP
Justified mock targets:
- HTTP: Guzzle handlers/middleware, `pre_http_request` filter in WordPress
- External SDKs: payment gateways, mail providers, LLM API clients
- Clock: inject a clock (`psr/clock`) instead of calling `time()` directly
- Filesystem on external paths (prefer `vfsStream` or temp dirs over mocking)
Unjustified mocks:
- Mockery/Prophecy doubles for the project's own value objects, DTOs, or entities — construct real instances (Rule 8)
- Mocking internal services just to isolate a class — if wiring is painful, fix the constructor, don't fake the collaborator
- Partial mocks of the class under test — you are no longer testing the class
## Rule 3: Data providers
```php
/**
* @see Rule 3 — variants of one scenario belong in a data provider.
*/
#[DataProvider('provideSlugCases')]
public function test_slugify_normalizes_input( string $raw, string $expected ): void {
$this->assertSame( $expected, slugify( $raw ) );
}
public static function provideSlugCases(): array {
return array(
'lowercases' => array( 'Hello World', 'hello-world' ),
'strips padding' => array( ' padded ', 'padded' ),
'transliterates' => array( 'Café Menu', 'cafe-menu' ),
);
}
```
Pest equivalent: `it('normalizes slug', ...)->with([...])`.
## WordPress-specific boundaries
- **Integration tests** (`WP_UnitTestCase` / `wp-env` / `wp-cli scaffold`): use the real WordPress test framework with factories — `self::factory()->post->create()`, `self::factory()->user->create()`. Don't mock `WP_Post` or `WP_User`; the factories exist precisely so you don't have to (Rule 8).
- **Unit tests without WordPress loaded** (Brain Monkey / WP_Mock): mocking WordPress functions like `get_option()` or `apply_filters()` is a boundary mock and justified. But assert what *your code does* with the values, not that `get_option` was called with specific args (Rule 1).
- Mock outbound HTTP with the `pre_http_request` filter rather than patching `wp_remote_get` internals.
- Don't test that WordPress sanitizes, escapes, or that hooks fire — that's core's guarantee (Rule 7). Test your callback's behavior given an input.
## WooCommerce notes
- Build real `WC_Product` / `WC_Order` objects via `WC_Helper_Product` and `WC_Helper_Order` in integration tests — never `MagicMock`-style doubles of them (Rule 8).
- Cart and checkout logic is stateful: prefer integration tests over heavily mocked unit tests; mocked carts hide hook-ordering bugs.
## Rule 9: Real database
`WP_UnitTestCase` already wraps each test in a transaction against a real schema — use it for query, meta, and persistence logic instead of mocking `$wpdb`. Mocking `$wpdb->prepare` or `$wpdb->get_results` to test a query builder tests nothing.
@@ -0,0 +1,65 @@
# Test Guard — Python / pytest Patterns
Concrete applications of the nine rules for pytest projects. Read this when reviewing or writing Python tests.
## Rule 2: Mock boundaries in Python
Justified mock targets:
- HTTP clients: `httpx`, `requests`, `aiohttp` (or use `respx` / `responses` instead of raw mocks)
- LLM SDK calls: `openai`, `anthropic`, `litellm.completion` and friends
- Database sessions, when the database is not the subject (see Rule 9)
- Filesystem I/O on external paths (`tmp_path` fixture is often better than mocking)
- Clock and randomness: `time.time`, `datetime.now`, `random` (prefer `freezegun` or injected clocks)
Unjustified mocks (common agent-generated violations):
- `MagicMock()` standing in for a Pydantic model or dataclass — construct the real thing
- Mocking internal utility functions to isolate a "unit"
- Mocking `json.loads` / `json.dumps` or other stdlib pure functions
## Rule 3: Parametrize
```python
# Violation: three copy-pasted tests differing by one value
def test_slug_lowercase(): ...
def test_slug_strips_spaces(): ...
def test_slug_handles_unicode(): ...
# Fix
@pytest.mark.parametrize(
("raw", "expected"),
[
("Hello World", "hello-world"),
(" padded ", "padded"),
("Café Menu", "cafe-menu"),
],
)
def test_slugify_normalizes_input(raw, expected):
assert slugify(raw) == expected
```
## Rule 8: Real Pydantic/dataclass instances
```python
# Wrong — hides field typos and validation errors
state = MagicMock()
state.user_id = "123"
state.status = "ACTIVE"
# Right — Pydantic validates the construction itself
state = UserState(user_id="123", status="ACTIVE")
```
If a model needs many fields, add a factory fixture or use `factory_boy` — don't fall back to `MagicMock`.
## Rule 9: Real database via fixtures
Use a fixture that applies real migrations (e.g., a session-scoped test database with `alembic upgrade head`), and function-scoped transactions rolled back per test. `pytest-postgresql`, `testcontainers`, or an SQLite-compatible fallback all work; the point is real schema, not a mocked session, whenever query or persistence logic is the subject.
## pytest-specific smells
- `assert mock.call_count == N` on anything internal — Rule 1 violation
- `@patch` stacks three or more deep — the test is coupled to implementation; restructure
- Asserting log output via `caplog` for messages no caller parses — Rule 4 violation
- Fixtures that build mocks of project classes — Rule 8 violation, make the fixture build real objects