Fix class name collision in CardBuilder DSL causing flaky specs#513
Conversation
…classes The righteous_valkyrie_spec.rb test was failing when run with the full test suite due to class name collision. Both RighteousValkyrie and RousingRead defined nested classes named `PowerAndToughnessModification` within the CardBuilder DSL block. Since the block is evaluated at the Magic::Cards module level, these classes were overwriting each other, causing the second card loaded to use the conditions from the first card's class. Fixed by renaming: - PowerAndToughnessModification -> RighteousValkyriePowerAndToughnessModification in righteous_valkyrie.rb - PowerAndToughnessModification -> RousingReadPowerAndToughnessModification in rousing_read.rb Co-authored-by: radar <2687+radar@users.noreply.github.com>
|
No, reopen the classes after the DSL part and keep the class names consistent across both. |
radar
left a comment
There was a problem hiding this comment.
No, reopen the classes after the DSL part and keep the class names consistent across both.
Following the pattern used in other cards like CanopyTactician and ElvishArchdruid: - Use CardBuilder DSL for basic card setup - Reopen the class with explicit inheritance (class CardName < BaseClass) - Define nested classes inside the reopened class This ensures nested classes are scoped to Magic::Cards::CardName::PowerAndToughnessModification instead of Magic::Cards::PowerAndToughnessModification, preventing collisions between cards. Co-authored-by: radar <2687+radar@users.noreply.github.com>
... Done in bee757e. Both cards now reopen their classes after the DSL part, following the pattern used in CanopyTactician, ElvishArchdruid, and GloriousAnthem. The nested classes maintain their original names (PowerAndToughnessModification) and are properly scoped to Magic::Cards::CardName::PowerAndToughnessModification.
Done in bee757e. Both cards now reopen their classes after the DSL part, following the pattern used in CanopyTactician, ElvishArchdruid, and GloriousAnthem. The nested classes maintain their original names (PowerAndToughnessModification) and are properly scoped to Magic::Cards::CardName::PowerAndToughnessModification. |
Nested classes defined within
CardBuilderDSL blocks were colliding at theMagic::Cardsmodule level, causing test flakiness where one card's logic would override another's.Root Cause
When using
Creature("Name") do ... end, the block is evaluated viaClass.new(base_class, &block). Ruby constant lookup rules place nested class definitions at the enclosing module level (Magic::Cards) rather than inside the anonymous class:Load order determined which card's class definition "won", causing non-deterministic test failures.
Solution
Following the established pattern from cards like
CanopyTactician,ElvishArchdruid, andGloriousAnthem, the fix separates the CardBuilder DSL from class definitions:class RighteousValkyrie < Creature)This ensures nested classes are properly scoped to
Magic::Cards::RighteousValkyrie::PowerAndToughnessModificationinstead ofMagic::Cards::PowerAndToughnessModification, preventing collisions while maintaining consistent naming conventions across the codebase.Example:
Original prompt
Created from VS Code via the GitHub Pull Request extension.
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.