@drmxrcy/tcg-lorcana 0.0.0-202602060544
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +160 -0
- package/package.json +45 -0
- package/src/__tests__/integration/move-enumeration.test.ts +256 -0
- package/src/__tests__/rules/section-01-concepts.test.ts +426 -0
- package/src/__tests__/rules/section-03-gameplay.test.ts +298 -0
- package/src/__tests__/rules/section-04-turn-structure.test.ts +708 -0
- package/src/__tests__/rules/section-05-cards.test.ts +158 -0
- package/src/__tests__/rules/section-06-card-types.test.ts +342 -0
- package/src/__tests__/rules/section-07-abilities.test.ts +333 -0
- package/src/__tests__/rules/section-08-zones.test.ts +231 -0
- package/src/__tests__/rules/section-09-damage.test.ts +148 -0
- package/src/__tests__/rules/section-10-keywords.test.ts +469 -0
- package/src/__tests__/spec-01-foundation-types.test.ts +534 -0
- package/src/__tests__/spec-02-zones-card-states.test.ts +295 -0
- package/src/card-utils.ts +302 -0
- package/src/cards/README.md +296 -0
- package/src/cards/abilities/index.ts +175 -0
- package/src/cards/index.ts +10 -0
- package/src/deck-validation.ts +175 -0
- package/src/engine/lorcana-engine.ts +625 -0
- package/src/game-definition/__tests__/core-zone-integration.test.ts +553 -0
- package/src/game-definition/__tests__/zone-operations.test.ts +362 -0
- package/src/game-definition/__tests__/zones.test.ts +176 -0
- package/src/game-definition/definition.ts +45 -0
- package/src/game-definition/flow/turn-flow.ts +216 -0
- package/src/game-definition/index.ts +31 -0
- package/src/game-definition/moves/abilities/activate-ability.ts +51 -0
- package/src/game-definition/moves/core/__tests__/move-parameter-enumeration.test.ts +316 -0
- package/src/game-definition/moves/core/challenge.test.ts +545 -0
- package/src/game-definition/moves/core/challenge.ts +81 -0
- package/src/game-definition/moves/core/play-card.ts +83 -0
- package/src/game-definition/moves/core/quest.test.ts +448 -0
- package/src/game-definition/moves/core/quest.ts +49 -0
- package/src/game-definition/moves/debug/manual-exert.ts +36 -0
- package/src/game-definition/moves/effects/resolve-bag.ts +35 -0
- package/src/game-definition/moves/effects/resolve-effect.ts +34 -0
- package/src/game-definition/moves/index.ts +85 -0
- package/src/game-definition/moves/locations/move-character-to-location.ts +42 -0
- package/src/game-definition/moves/resources/put-card-into-inkwell.test.ts +462 -0
- package/src/game-definition/moves/resources/put-card-into-inkwell.ts +51 -0
- package/src/game-definition/moves/setup/alter-hand.test.ts +395 -0
- package/src/game-definition/moves/setup/alter-hand.ts +210 -0
- package/src/game-definition/moves/setup/choose-first-player.test.ts +450 -0
- package/src/game-definition/moves/setup/choose-first-player.ts +105 -0
- package/src/game-definition/moves/setup/draw-cards.ts +37 -0
- package/src/game-definition/moves/songs/sing-together.ts +47 -0
- package/src/game-definition/moves/songs/sing.ts +56 -0
- package/src/game-definition/moves/standard/concede.test.ts +189 -0
- package/src/game-definition/moves/standard/concede.ts +72 -0
- package/src/game-definition/moves/standard/pass-turn.ts +49 -0
- package/src/game-definition/setup/game-setup.ts +19 -0
- package/src/game-definition/trackers/tracker-config.ts +23 -0
- package/src/game-definition/win-conditions/lore-victory.ts +26 -0
- package/src/game-definition/zone-operations.ts +405 -0
- package/src/game-definition/zones/zone-configs.ts +59 -0
- package/src/game-definition/zones.ts +283 -0
- package/src/index.ts +189 -0
- package/src/operations/index.ts +7 -0
- package/src/operations/lorcana-operations.ts +288 -0
- package/src/queries/README.md +56 -0
- package/src/resolvers/__tests__/condition-resolver.test.ts +301 -0
- package/src/resolvers/condition-registry.ts +70 -0
- package/src/resolvers/condition-resolver.ts +85 -0
- package/src/resolvers/conditions/basic.ts +81 -0
- package/src/resolvers/conditions/card-state.ts +12 -0
- package/src/resolvers/conditions/comparison.ts +102 -0
- package/src/resolvers/conditions/existence.ts +219 -0
- package/src/resolvers/conditions/history.ts +68 -0
- package/src/resolvers/conditions/index.ts +15 -0
- package/src/resolvers/conditions/logical.ts +55 -0
- package/src/resolvers/conditions/resolution.ts +41 -0
- package/src/resolvers/conditions/revealed.ts +42 -0
- package/src/resolvers/conditions/zone.ts +84 -0
- package/src/setup.test.ts +18 -0
- package/src/targeting/__tests__/filter-resolver.test.ts +294 -0
- package/src/targeting/__tests__/real-cards-targeting.test.ts +303 -0
- package/src/targeting/__tests__/targeting-dsl.test.ts +386 -0
- package/src/targeting/enum-expansion.ts +387 -0
- package/src/targeting/filter-registry.ts +322 -0
- package/src/targeting/filter-resolver.ts +145 -0
- package/src/targeting/index.ts +91 -0
- package/src/targeting/lorcana-target-dsl.ts +495 -0
- package/src/targeting/targeting-ui.ts +407 -0
- package/src/testing/index.ts +14 -0
- package/src/testing/lorcana-test-engine.ts +813 -0
- package/src/types/README.md +303 -0
- package/src/types/__tests__/lorcana-state.test.ts +168 -0
- package/src/types/__tests__/move-enumeration.test.ts +179 -0
- package/src/types/branded-types.ts +106 -0
- package/src/types/game-state.ts +184 -0
- package/src/types/index.ts +87 -0
- package/src/types/keywords.ts +187 -0
- package/src/types/lorcana-state.ts +260 -0
- package/src/types/move-enumeration.ts +126 -0
- package/src/types/move-params.ts +216 -0
- package/src/validators/index.ts +7 -0
- package/src/validators/move-validators.ts +374 -0
- package/src/zones/card-state.ts +234 -0
- package/src/zones/index.ts +42 -0
- package/src/zones/zone-config.ts +150 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Section 5: Cards
|
|
3
|
+
*
|
|
4
|
+
* Tests for rules 5.1 from Disney Lorcana Comprehensive Rules (Aug 22, 2025)
|
|
5
|
+
* Covers card conditions: Ready, Exerted, Damaged, Undamaged, Under, On Top, In a Stack.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
9
|
+
import {
|
|
10
|
+
LorcanaTestEngine,
|
|
11
|
+
PLAYER_ONE,
|
|
12
|
+
PLAYER_TWO,
|
|
13
|
+
} from "../../testing/lorcana-test-engine";
|
|
14
|
+
|
|
15
|
+
describe("Section 5: Cards", () => {
|
|
16
|
+
let testEngine: LorcanaTestEngine;
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
testEngine = new LorcanaTestEngine(
|
|
20
|
+
{ hand: 7, deck: 53, inkwell: 3 },
|
|
21
|
+
{ hand: 7, deck: 53, inkwell: 3 },
|
|
22
|
+
{ skipPreGame: true },
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
afterEach(() => {
|
|
27
|
+
testEngine.dispose();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("5.1. Conditions", () => {
|
|
31
|
+
/**
|
|
32
|
+
* Rule 5.1.1: Ready - Cards enter play ready. A player can't use any of an
|
|
33
|
+
* exerted card's abilities that include exert as part of the cost.
|
|
34
|
+
*/
|
|
35
|
+
test.failing("Rule 5.1.1 - Cards enter play ready", () => {
|
|
36
|
+
// Arrange: Create a character
|
|
37
|
+
const character = testEngine.createCharacterInPlay(PLAYER_ONE, {
|
|
38
|
+
strength: 2,
|
|
39
|
+
willpower: 3,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Assert: Should be ready (not exerted)
|
|
43
|
+
const meta = testEngine.getCardMeta(character);
|
|
44
|
+
expect(meta?.state).toBe("ready");
|
|
45
|
+
expect(true).toBe(false); // Will fail until ready state verified
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Rule 5.1.1 (continued): Exerted card's exert abilities cannot be used.
|
|
50
|
+
*/
|
|
51
|
+
test.failing("Rule 5.1.1 - Cannot use exert abilities when exerted", () => {
|
|
52
|
+
// Arrange: Create character with exert ability, then exert it
|
|
53
|
+
const character = testEngine.createCharacterInPlay(PLAYER_ONE, {
|
|
54
|
+
strength: 2,
|
|
55
|
+
willpower: 3,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Exert by questing
|
|
59
|
+
testEngine.quest(character);
|
|
60
|
+
|
|
61
|
+
// Act: Try to use exert ability
|
|
62
|
+
// Assert: Should fail because character is exerted
|
|
63
|
+
expect(true).toBe(false); // Will fail until exert ability check implemented
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Rule 5.1.2: Exerted - When a card is exerted, it's turned sideways.
|
|
68
|
+
* A player can use an exerted card's abilities that don't require exert.
|
|
69
|
+
*/
|
|
70
|
+
test.failing("Rule 5.1.2 - Exerted cards can use non-exert abilities", () => {
|
|
71
|
+
// Arrange: Character with non-exert ability, exert it
|
|
72
|
+
const character = testEngine.createCharacterInPlay(PLAYER_ONE, {
|
|
73
|
+
strength: 2,
|
|
74
|
+
willpower: 3,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
testEngine.quest(character);
|
|
78
|
+
expect(testEngine.getCardMeta(character)?.state).toBe("exerted");
|
|
79
|
+
|
|
80
|
+
// Act: Use non-exert ability
|
|
81
|
+
// Assert: Should succeed despite being exerted
|
|
82
|
+
expect(true).toBe(false); // Will fail until non-exert ability check implemented
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Rule 5.1.3: Damaged - A card that has at least 1 damage is considered damaged.
|
|
87
|
+
*/
|
|
88
|
+
test.failing("Rule 5.1.3 - Card with 1+ damage is damaged", () => {
|
|
89
|
+
// Arrange: Create character and give it damage
|
|
90
|
+
const character = testEngine.createCharacterInPlay(PLAYER_ONE, {
|
|
91
|
+
strength: 2,
|
|
92
|
+
willpower: 5,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Would need a way to deal damage
|
|
96
|
+
// After damage dealt:
|
|
97
|
+
// Assert: Character should be considered "damaged"
|
|
98
|
+
expect(true).toBe(false); // Will fail until damage tracking implemented
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Rule 5.1.4: Undamaged - A card that has no damage is considered undamaged.
|
|
103
|
+
*/
|
|
104
|
+
test.failing("Rule 5.1.4 - Card with 0 damage is undamaged", () => {
|
|
105
|
+
// Arrange: Create fresh character
|
|
106
|
+
const character = testEngine.createCharacterInPlay(PLAYER_ONE, {
|
|
107
|
+
strength: 2,
|
|
108
|
+
willpower: 3,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Assert: Should have 0 damage, be considered "undamaged"
|
|
112
|
+
expect(testEngine.getDamage(character)).toBe(0);
|
|
113
|
+
// Would need isDamaged() helper
|
|
114
|
+
expect(true).toBe(false); // Will fail until undamaged check implemented
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Rule 5.1.5: Under - A card that has one or more cards on top of it is
|
|
119
|
+
* considered to be under the top card in a stack. A player can't choose
|
|
120
|
+
* any card that's under the top card.
|
|
121
|
+
*/
|
|
122
|
+
test.failing("Rule 5.1.5 - Cards under others cannot be chosen", () => {
|
|
123
|
+
// Arrange: Create stack (e.g., Shift onto character)
|
|
124
|
+
// The base character is "under"
|
|
125
|
+
|
|
126
|
+
// Act: Try to target the under card
|
|
127
|
+
|
|
128
|
+
// Assert: Should not be choosable
|
|
129
|
+
expect(true).toBe(false); // Will fail until stack targeting implemented
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Rule 5.1.6: On Top - A card on top of others doesn't gain the text
|
|
134
|
+
* of any card under it. The card on top is called the top card.
|
|
135
|
+
*/
|
|
136
|
+
test.failing("Rule 5.1.6 - Top card doesn't gain text from cards under", () => {
|
|
137
|
+
// Arrange: Create stack via Shift
|
|
138
|
+
// Base card has ability X, top card has ability Y
|
|
139
|
+
|
|
140
|
+
// Assert: Top card should only have ability Y, not X
|
|
141
|
+
expect(true).toBe(false); // Will fail until stack text handling implemented
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Rule 5.1.7: In a Stack - When a card is placed on top of one or more
|
|
146
|
+
* other cards in play, all cards are in a stack. If top card leaves play,
|
|
147
|
+
* all cards in stack move to the same zone.
|
|
148
|
+
*/
|
|
149
|
+
test.failing("Rule 5.1.7 - Stack moves together when top card leaves", () => {
|
|
150
|
+
// Arrange: Create stack (Shift)
|
|
151
|
+
|
|
152
|
+
// Act: Banish the top card
|
|
153
|
+
|
|
154
|
+
// Assert: All cards in stack should go to discard together
|
|
155
|
+
expect(true).toBe(false); // Will fail until stack leaving play implemented
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
});
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Section 6: Card Types
|
|
3
|
+
*
|
|
4
|
+
* Tests for rules 6.1-6.5 from Disney Lorcana Comprehensive Rules (Aug 22, 2025)
|
|
5
|
+
* Covers Characters, Parts of a Card, Actions, Items, and Locations.
|
|
6
|
+
*
|
|
7
|
+
* Note: Some tests in spec-01-foundation-types.test.ts already cover card type guards.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
11
|
+
import {
|
|
12
|
+
LorcanaTestEngine,
|
|
13
|
+
PLAYER_ONE,
|
|
14
|
+
PLAYER_TWO,
|
|
15
|
+
} from "../../testing/lorcana-test-engine";
|
|
16
|
+
|
|
17
|
+
describe("Section 6: Card Types", () => {
|
|
18
|
+
let testEngine: LorcanaTestEngine;
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
testEngine = new LorcanaTestEngine(
|
|
22
|
+
{ hand: 7, deck: 53, inkwell: 3 },
|
|
23
|
+
{ hand: 7, deck: 53, inkwell: 3 },
|
|
24
|
+
{ skipPreGame: true },
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
testEngine.dispose();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe("6.1. Characters", () => {
|
|
33
|
+
/**
|
|
34
|
+
* Rule 6.1.1: Characters are a type of card that can be in play.
|
|
35
|
+
* A character card in the Play zone is a character; in other zones it's a character card.
|
|
36
|
+
*/
|
|
37
|
+
test.failing("Rule 6.1.1 - Character card becomes character when in play", () => {
|
|
38
|
+
// Arrange: Character in hand (card) vs in play (character)
|
|
39
|
+
|
|
40
|
+
// Assert: Terminology distinction should apply
|
|
41
|
+
expect(true).toBe(false); // Will fail until zone-based terminology implemented
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Rule 6.1.2.1: A character has a Strength value and a Willpower value.
|
|
46
|
+
*/
|
|
47
|
+
test.failing("Rule 6.1.2.1 - Characters have Strength and Willpower", () => {
|
|
48
|
+
// Arrange: Create character with stats
|
|
49
|
+
const character = testEngine.createCharacterInPlay(PLAYER_ONE, {
|
|
50
|
+
strength: 3,
|
|
51
|
+
willpower: 4,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Assert: Character should have both values accessible
|
|
55
|
+
// Would need getStrength/getWillpower helpers
|
|
56
|
+
expect(true).toBe(false); // Will fail until stat access implemented
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Rule 6.1.2.2: A character has at least one classification
|
|
61
|
+
* (Storyborn, Dreamborn, Floodborn, Hero, Villain, etc.).
|
|
62
|
+
*/
|
|
63
|
+
test.failing("Rule 6.1.2.2 - Characters have classifications", () => {
|
|
64
|
+
// Assert: Character should have at least one valid classification
|
|
65
|
+
expect(true).toBe(false); // Will fail until classification system implemented
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Rule 6.1.3: Only characters can quest or challenge.
|
|
70
|
+
*/
|
|
71
|
+
test.failing("Rule 6.1.3 - Only characters can quest or challenge", () => {
|
|
72
|
+
// Assert: Items and locations should not be able to quest/challenge
|
|
73
|
+
expect(true).toBe(false); // Will fail until type restrictions enforced
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Rule 6.1.4: A character must have been in play at the beginning of the Set step
|
|
78
|
+
* to quest, challenge, or exert as part of a cost.
|
|
79
|
+
*/
|
|
80
|
+
test.failing("Rule 6.1.4 - Fresh characters cannot quest/challenge (drying)", () => {
|
|
81
|
+
// Arrange: Create fresh character
|
|
82
|
+
const character = testEngine.createCharacterInPlay(PLAYER_ONE, {
|
|
83
|
+
strength: 2,
|
|
84
|
+
willpower: 3,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Act: Try to quest immediately (this test uses a backdoor that skips drying)
|
|
88
|
+
// In real gameplay, fresh characters can't quest
|
|
89
|
+
|
|
90
|
+
// Assert: Should be blocked until dry
|
|
91
|
+
expect(true).toBe(false); // Will fail until drying properly enforced in moves
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe("6.2. Parts of a Card", () => {
|
|
96
|
+
/**
|
|
97
|
+
* Rule 6.2.3: Ink Type - The ink type of the card, identified by ink type symbol.
|
|
98
|
+
*/
|
|
99
|
+
test.failing("Rule 6.2.3 - Cards have ink type", () => {
|
|
100
|
+
// Assert: Card should have identifiable ink type (amber, ruby, etc.)
|
|
101
|
+
expect(true).toBe(false); // Will fail until ink type access implemented
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Rule 6.2.3.1: Some cards have more than one ink type (dual-ink cards).
|
|
106
|
+
*/
|
|
107
|
+
test.failing("Rule 6.2.3.1 - Dual-ink cards have two ink types", () => {
|
|
108
|
+
// Assert: Dual-ink card should report both types
|
|
109
|
+
expect(true).toBe(false); // Will fail until dual-ink implemented
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Rule 6.2.4: Name - An effect looking for a card with specified name looks
|
|
114
|
+
* only at this line and ignores the version. Full name = name + version.
|
|
115
|
+
*/
|
|
116
|
+
test.failing("Rule 6.2.4 - Name matching ignores version", () => {
|
|
117
|
+
// Arrange: Effect that looks for "Elsa" should find both
|
|
118
|
+
// "Elsa - Ice Queen" and "Elsa - Snow Queen"
|
|
119
|
+
|
|
120
|
+
// Assert: Both versions should match
|
|
121
|
+
expect(true).toBe(false); // Will fail until name matching implemented
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Rule 6.2.4.1: Some characters have two names (separated by &).
|
|
126
|
+
* Effect looking for specified name only needs to match one.
|
|
127
|
+
*/
|
|
128
|
+
test.failing("Rule 6.2.4.1 - Dual-name characters match either name", () => {
|
|
129
|
+
// Arrange: "Flotsam & Jetsam" should match both "Flotsam" and "Jetsam"
|
|
130
|
+
|
|
131
|
+
// Assert: Effect targeting "Flotsam" should find this character
|
|
132
|
+
expect(true).toBe(false); // Will fail until dual-name matching implemented
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Rule 6.2.4.2: A character with multiple names is still a single character.
|
|
137
|
+
*/
|
|
138
|
+
test.failing("Rule 6.2.4.2 - Dual-name is one character", () => {
|
|
139
|
+
// Assert: Should count as 1 character, not 2
|
|
140
|
+
expect(true).toBe(false); // Will fail until dual-name counting verified
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Rule 6.2.7: Card Cost - The amount of ink needed to play the card.
|
|
145
|
+
*/
|
|
146
|
+
test.failing("Rule 6.2.7 - Card cost determines ink needed", () => {
|
|
147
|
+
// Assert: Playing card should require exerting ink equal to cost
|
|
148
|
+
expect(true).toBe(false); // Will fail until cost payment verified
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Rule 6.2.8: Inkwell Symbol - If present, card can be put into inkwell.
|
|
153
|
+
*/
|
|
154
|
+
test.failing("Rule 6.2.8 - Inkable cards have inkwell symbol", () => {
|
|
155
|
+
// Assert: Only cards with inkwell symbol can be inked
|
|
156
|
+
expect(true).toBe(false); // Will fail until inkable check implemented
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Rule 6.2.9: Strength - How much damage character deals in challenge.
|
|
161
|
+
* If 0 or less, deals no damage.
|
|
162
|
+
*/
|
|
163
|
+
test.failing("Rule 6.2.9 - Strength determines challenge damage", () => {
|
|
164
|
+
// Arrange: Create characters with different strengths
|
|
165
|
+
|
|
166
|
+
// Act: Challenge
|
|
167
|
+
|
|
168
|
+
// Assert: Damage dealt should equal strength
|
|
169
|
+
expect(true).toBe(false); // Will fail until strength-based damage verified
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Rule 6.2.10: Willpower - If damage >= willpower, character is banished.
|
|
174
|
+
*/
|
|
175
|
+
test.failing("Rule 6.2.10 - Damage >= Willpower banishes", () => {
|
|
176
|
+
// Arrange: Character with willpower 3
|
|
177
|
+
|
|
178
|
+
// Act: Deal 3 damage
|
|
179
|
+
|
|
180
|
+
// Assert: Character should be banished
|
|
181
|
+
expect(true).toBe(false); // Will fail until willpower threshold implemented
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Rule 6.2.11: Lore Value - How much lore gained when character quests.
|
|
186
|
+
*/
|
|
187
|
+
test.failing("Rule 6.2.11 - Lore value determines quest reward", () => {
|
|
188
|
+
// Arrange: Character with lore 2
|
|
189
|
+
const character = testEngine.createCharacterInPlay(PLAYER_ONE, {
|
|
190
|
+
strength: 2,
|
|
191
|
+
willpower: 3,
|
|
192
|
+
lore: 2,
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Act: Quest
|
|
196
|
+
testEngine.quest(character);
|
|
197
|
+
|
|
198
|
+
// Assert: Should gain 2 lore
|
|
199
|
+
expect(testEngine.getLore(PLAYER_ONE)).toBe(2);
|
|
200
|
+
expect(true).toBe(false); // Will fail until lore value properly used
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
describe("6.3. Actions", () => {
|
|
205
|
+
/**
|
|
206
|
+
* Rule 6.3.1: Actions are a type of card that can be played but can't be in play.
|
|
207
|
+
*/
|
|
208
|
+
test.failing("Rule 6.3.1 - Actions are not in play after resolution", () => {
|
|
209
|
+
// Arrange: Play an action card
|
|
210
|
+
|
|
211
|
+
// Assert: Action should not be in play zone after resolving
|
|
212
|
+
expect(true).toBe(false); // Will fail until action zone handling implemented
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Rule 6.3.1.2: Actions are played from hand but not considered in play.
|
|
217
|
+
* Effect from action doesn't enter the bag.
|
|
218
|
+
*/
|
|
219
|
+
test.failing("Rule 6.3.1.2 - Action effects don't use the bag", () => {
|
|
220
|
+
// Arrange: Play action
|
|
221
|
+
|
|
222
|
+
// Assert: Effect should resolve immediately, not via bag
|
|
223
|
+
expect(true).toBe(false); // Will fail until action resolution implemented
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Rule 6.3.2: Actions have effects rather than abilities.
|
|
228
|
+
*/
|
|
229
|
+
test.failing("Rule 6.3.2 - Actions have effects, not abilities", () => {
|
|
230
|
+
// Terminology distinction
|
|
231
|
+
expect(true).toBe(false); // Will fail until effect/ability distinction implemented
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Rule 6.3.3.3: Songs allow exerting a character to pay instead of ink cost.
|
|
236
|
+
* "Singer" keyword specifies minimum cost of character that can sing.
|
|
237
|
+
*/
|
|
238
|
+
test.failing("Rule 6.3.3.3 - Songs can be sung by characters", () => {
|
|
239
|
+
// Arrange: Song with cost 4, character with Singer 4+
|
|
240
|
+
|
|
241
|
+
// Act: Exert character to play song for free
|
|
242
|
+
|
|
243
|
+
// Assert: Song should be played without paying ink
|
|
244
|
+
expect(true).toBe(false); // Will fail until singing implemented
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Rule 6.3.4: Effects triggered by playing action wait until action resolves.
|
|
249
|
+
*/
|
|
250
|
+
test.failing("Rule 6.3.4 - Triggers from action wait for resolution", () => {
|
|
251
|
+
// Arrange: Effect that triggers when action is played
|
|
252
|
+
|
|
253
|
+
// Act: Play action
|
|
254
|
+
|
|
255
|
+
// Assert: Trigger should resolve after action effect
|
|
256
|
+
expect(true).toBe(false); // Will fail until trigger ordering implemented
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
describe("6.4. Items", () => {
|
|
261
|
+
/**
|
|
262
|
+
* Rule 6.4.1: Items are a type of card that can be in play.
|
|
263
|
+
*/
|
|
264
|
+
test.failing("Rule 6.4.1 - Items stay in play", () => {
|
|
265
|
+
// Arrange: Play an item
|
|
266
|
+
|
|
267
|
+
// Assert: Item should be in play zone
|
|
268
|
+
expect(true).toBe(false); // Will fail until item zone handling implemented
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Rule 6.4.3: If an item has an ability, it can be used the turn played.
|
|
273
|
+
*/
|
|
274
|
+
test.failing("Rule 6.4.3 - Item abilities usable same turn", () => {
|
|
275
|
+
// Arrange: Play item with activated ability
|
|
276
|
+
|
|
277
|
+
// Act: Use ability same turn
|
|
278
|
+
|
|
279
|
+
// Assert: Should work (no drying for items)
|
|
280
|
+
expect(true).toBe(false); // Will fail until item ability timing implemented
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
describe("6.5. Locations", () => {
|
|
285
|
+
/**
|
|
286
|
+
* Rule 6.5.1: Locations are a type of card that can be in play.
|
|
287
|
+
*/
|
|
288
|
+
test.failing("Rule 6.5.1 - Locations stay in play", () => {
|
|
289
|
+
// Arrange: Play a location
|
|
290
|
+
|
|
291
|
+
// Assert: Location should be in play zone
|
|
292
|
+
expect(true).toBe(false); // Will fail until location zone handling implemented
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Rule 6.5.4: Move Cost - Amount of ink needed to move a character to location.
|
|
297
|
+
*/
|
|
298
|
+
test.failing("Rule 6.5.4 - Moving to location costs ink", () => {
|
|
299
|
+
// Arrange: Location with move cost 2
|
|
300
|
+
|
|
301
|
+
// Act: Move character to location
|
|
302
|
+
|
|
303
|
+
// Assert: Should spend 2 ink
|
|
304
|
+
expect(true).toBe(false); // Will fail until move cost implemented
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Rule 6.5.5: Locations have Willpower but no Strength.
|
|
309
|
+
* They don't deal damage when challenged.
|
|
310
|
+
*/
|
|
311
|
+
test.failing("Rule 6.5.5 - Locations have willpower, no strength", () => {
|
|
312
|
+
// Arrange: Challenge a location
|
|
313
|
+
|
|
314
|
+
// Assert: Attacker should take no damage from location
|
|
315
|
+
expect(true).toBe(false); // Will fail until location combat implemented
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Rule 6.5.6: Location may have Lore value, gained at Set step.
|
|
320
|
+
*/
|
|
321
|
+
test.failing("Rule 6.5.6 - Location lore gained at Set step", () => {
|
|
322
|
+
// Arrange: Location with lore 1 in play
|
|
323
|
+
|
|
324
|
+
// Act: Start turn (Set step)
|
|
325
|
+
|
|
326
|
+
// Assert: Should gain 1 lore from location
|
|
327
|
+
expect(true).toBe(false); // Will fail until location lore implemented
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Rule 6.5.7: Location abilities can be used the turn played.
|
|
332
|
+
*/
|
|
333
|
+
test.failing("Rule 6.5.7 - Location abilities usable same turn", () => {
|
|
334
|
+
// Arrange: Play location with activated ability
|
|
335
|
+
|
|
336
|
+
// Act: Use ability same turn
|
|
337
|
+
|
|
338
|
+
// Assert: Should work (no drying for locations)
|
|
339
|
+
expect(true).toBe(false); // Will fail until location ability timing implemented
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
});
|