140 lines
8.3 KiB
Markdown
140 lines
8.3 KiB
Markdown
---
|
|
name: bulbapedia-tests
|
|
description: Fetches move/ability descriptions from Bulbapedia and translates them into atomic TUnit tests in the Gen7 test project. Use when asked to write Bulbapedia-based tests for moves or abilities, e.g. "test tackle" or "write tests for all moves starting with a".
|
|
argument-hint: <target, e.g. "tackle" | "ability intimidate" | "all moves starting with a">
|
|
allowed-tools: WebFetch(domain:bulbapedia.bulbagarden.net), Read, Glob, Grep, Write(Plugins/PkmnLib.Plugin.Gen7.Tests/**), Edit(Plugins/PkmnLib.Plugin.Gen7.Tests/**), Bash(dotnet build:*), Bash(dotnet test:*)
|
|
---
|
|
|
|
# Bulbapedia → Gen7 unit tests
|
|
|
|
Generate atomic unit tests for Gen7 move/ability script implementations, using their
|
|
Bulbapedia descriptions as the source of truth for correct behavior.
|
|
|
|
## Hard constraints (tool whitelist)
|
|
|
|
- **Web access**: only `https://bulbapedia.bulbagarden.net/...` via WebFetch. Never fetch any
|
|
other domain.
|
|
- **File modifications**: only inside `Plugins/PkmnLib.Plugin.Gen7.Tests/`. Never modify the
|
|
implementation project (`Plugins/PkmnLib.Plugin.Gen7/`) or anything else — even if you find a
|
|
bug there. Reading any file in the repo is allowed and encouraged.
|
|
- **Shell**: only `dotnet build` and `dotnet test`.
|
|
|
|
## Step 1 — Resolve targets from the argument
|
|
|
|
The argument describes what to test. Interpret it and resolve it to a list of implemented
|
|
script classes:
|
|
|
|
- A single name (`tackle`, `ability intimidate`) → that one script. Default to moves; the words
|
|
"ability"/"abilities" switch to abilities.
|
|
- A pattern (`all moves starting with a`, `abilities containing 'veil'`) → enumerate with Glob
|
|
against the implementation folders:
|
|
- Moves: `Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/*.cs`
|
|
- Abilities: `Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/*.cs`
|
|
- Only test scripts that actually exist in those folders. If a requested target has no
|
|
implementation file, don't invent one — list it as skipped in the final report.
|
|
- Skip base/helper classes (e.g. `BaseChargeMove.cs`) unless explicitly requested; they are
|
|
covered through the concrete moves.
|
|
|
|
For each target, check whether `Plugins/PkmnLib.Plugin.Gen7.Tests/Scripts/{Moves,Abilities}/<ClassName>Tests.cs`
|
|
already exists. If so, extend it with missing behaviors (via Edit) instead of overwriting it,
|
|
and don't duplicate behaviors that already have a test.
|
|
|
|
## Step 2 — Fetch the Bulbapedia description
|
|
|
|
This fetch procedure is verified to work; follow it exactly.
|
|
|
|
**Primary: WebFetch the rendered wiki page.** URL conventions (spaces become underscores,
|
|
each word capitalized as on Bulbapedia; the `(move)` suffix is lowercase, `(Ability)` is
|
|
capitalized):
|
|
|
|
- Moves: `https://bulbapedia.bulbagarden.net/wiki/<Move_Name>_(move)` — e.g. `Tackle_(move)`, `Fury_Cutter_(move)`
|
|
- Abilities: `https://bulbapedia.bulbagarden.net/wiki/<Ability_Name>_(Ability)` — e.g. `Intimidate_(Ability)`
|
|
|
|
Prompt the fetch with: *"Extract the full Effect section verbatim, including all per-generation
|
|
subsections."* The Effect section is structured as a base description plus generation-delta
|
|
subsections, e.g. for Tackle: base text "Tackle inflicts damage and has no secondary effect.",
|
|
then `Generations V and VI`: "power was increased from 35 to 50...", then
|
|
`Generation VII onwards`: "power was decreased from 50 to 40."
|
|
|
|
**Fallback / exact wording: the MediaWiki API, also via WebFetch.** When the summarized page
|
|
extract seems lossy or you need the exact sentence to quote, fetch the raw wikitext (the Effect
|
|
section is normally section index 1):
|
|
|
|
- `https://bulbapedia.bulbagarden.net/w/api.php?action=parse&page=Tackle_(move)&prop=wikitext&format=json§ion=1`
|
|
|
|
**Name resolution**: if unsure of the exact page title, use the API's opensearch:
|
|
|
|
- `https://bulbapedia.bulbagarden.net/w/api.php?action=opensearch&search=Fury_C&limit=5&format=json`
|
|
→ returns matching titles and URLs (e.g. `Fury Cutter (move)`).
|
|
|
|
**Deriving Gen VII behavior**: this codebase implements **Generation VII**. The Effect section
|
|
is written as deltas — start from the base description and apply every subsection whose range
|
|
includes Gen VII (`Generation VII onwards`, `Generations V to VII`, `Generation VI onwards`, ...);
|
|
ignore subsections entirely outside it (`Generation I`, `Generation VIII`, side games like
|
|
Legends: Arceus). Ability pages often use range headers like "Generations V to VII" — take the
|
|
range containing VII. Also note interactions the page calls out (e.g. "does not activate if a
|
|
Pokémon with Damp is on the field") — those are test cases too.
|
|
|
|
## Step 3 — Read the implementation
|
|
|
|
Read the script class under `Plugins/PkmnLib.Plugin.Gen7/Scripts/{Moves,Abilities}/<ClassName>.cs`
|
|
to learn which hooks it overrides (`ChangeBasePower`, `OnIncomingHit`, `OnFaint`, ...) and what
|
|
its public surface looks like. Tests drive those hook methods directly — do not test behavior
|
|
the script class isn't responsible for (type effectiveness, generic damage formula, or static
|
|
data like base power and accuracy; `DataTests/` already covers move/ability data).
|
|
|
|
## Step 4 — Write atomic tests
|
|
|
|
Follow the existing conventions — `Scripts/Moves/DrainTests.cs` and
|
|
`Scripts/Abilities/AftermathTests.cs` are the reference examples (`DrainTests.cs` also shows
|
|
`<see>` usage and a real `[TestFailing]`), `Scripts/Moves/AcrobaticsTests.cs` a minimal one:
|
|
|
|
- File: `Plugins/PkmnLib.Plugin.Gen7.Tests/Scripts/Moves/<ClassName>Tests.cs` or
|
|
`.../Scripts/Abilities/<ClassName>Tests.cs`.
|
|
- Namespace: `PkmnLib.Plugin.Gen7.Tests.Scripts.Moves` / `...Abilities`. `TUnit` and
|
|
`NSubstitute` are global usings; add the `PkmnLib.*` usings the test needs.
|
|
- **One behavior per test** (atomic). Name: `Method_Scenario_ExpectedOutcome`, e.g.
|
|
`ChangeBasePower_UserNotHoldingItem_BasePowerDoubles`.
|
|
- Each test gets an XML doc comment **quoting the Bulbapedia sentence it verifies**:
|
|
`/// Bulbapedia: "When a Pokémon with this Ability faints from damage caused by a move that makes contact, ..."`.
|
|
- In doc comments, refer to other classes and members with `<see>` tags instead of plain text —
|
|
the class-level comment references the script under test
|
|
(`/// Tests for the <see cref="Aftermath"/> ability.`), and test comments reference types or
|
|
members they mention (`/// If the attacker has no <see cref="IPokemon.BattleData"/>, ...`).
|
|
- Arrange/Act/Assert with `Substitute.For<IExecutingMove>()`, `Substitute.For<IPokemon>()`, etc.
|
|
Assertions are TUnit style: `await Assert.That(actual).IsEqualTo(expected)`.
|
|
- Use `[Arguments(...)]` rows for numeric variations (damage fractions, rounding/integer
|
|
division, overflow guards).
|
|
- Cover the negative cases the description implies (non-contact move → no trigger, holding an
|
|
item → no boost, attacker already fainted, null `BattleData`, ...).
|
|
- `LibraryHelpers.LoadLibrary()` is available when a test genuinely needs the full Gen7 library
|
|
(e.g. looking up real move data); prefer pure mocks otherwise.
|
|
|
|
## Step 5 — Build, run, and mark failures
|
|
|
|
1. Build: `dotnet build Plugins/PkmnLib.Plugin.Gen7.Tests`. Compile errors are always
|
|
test-authoring mistakes — fix them; the attribute cannot rescue non-compiling code.
|
|
2. Run the new tests: `dotnet test Plugins/PkmnLib.Plugin.Gen7.Tests` (TUnit runs on
|
|
Microsoft.Testing.Platform; to run a single class, pass
|
|
`-- --treenode-filter '/*/*/<ClassName>Tests/*'`).
|
|
3. For each failing test, decide who is wrong:
|
|
- **The test is wrong** (misread the page, wrong mock setup, asserting behavior of a
|
|
different generation) → fix the test and rerun.
|
|
- **The implementation is wrong** (test correctly encodes Gen VII Bulbapedia behavior but the
|
|
script does something else) → keep the correct assertion and add the marker so it is
|
|
skipped but tracked:
|
|
```csharp
|
|
[Test, TestFailing("Aftermath deals 1/2 max HP instead of 1/4 (Bulbapedia: '¼ of its own maximum HP')")]
|
|
```
|
|
`TestFailingAttribute` lives in `PkmnLib.Plugin.Gen7.Tests` and takes the failure reason as
|
|
its argument — describe concretely what the implementation does wrong.
|
|
- Never make a wrong test pass by asserting the buggy behavior, and never touch the
|
|
implementation to make a test pass.
|
|
4. Rerun until every test either passes or carries `[TestFailing(...)]`.
|
|
|
|
## Step 6 — Report
|
|
|
|
Summarize: tests written per target, tests marked `[TestFailing]` with their reasons (these are
|
|
implementation bugs the user needs to fix), and targets skipped because no Gen7 implementation
|
|
exists.
|