Files
Deukhoofd f9878e76ba
All checks were successful
Build / Build (push) Successful in 1m7s
Adds more tests, fixes
2026-07-04 13:03:54 +02:00

8.3 KiB

name, description, argument-hint, allowed-tools
name description argument-hint allowed-tools
bulbapedia-tests 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". <target, e.g. "tackle" | "ability intimidate" | "all moves starting with a"> 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&section=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:
      [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.