Skip to content

Commit af85c29

Browse files
committed
Fix SUB_SPELL_START regexp that was too restrictive
1 parent 3f601f4 commit af85c29

3 files changed

Lines changed: 69 additions & 36 deletions

File tree

hslog/tokens.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
TAG_CHANGE_RE = re.compile(r"TAG_CHANGE Entity=%s tag=(\w+) value=(\w+) ?(%s)?" % (_E, DEF_CHANGE))
3535
META_DATA_RE = re.compile(r"META_DATA - Meta=(\w+) Data=%s InfoCount=(\d+)" % _E)
3636
RESET_GAME_RE = re.compile(r"RESET_GAME$")
37-
SUB_SPELL_START_RE = re.compile(r"SUB_SPELL_START - SpellPrefabGUID=([\w:]+) Source=(\d+) TargetCount=(\d+)$")
37+
SUB_SPELL_START_RE = re.compile(r"SUB_SPELL_START - SpellPrefabGUID=([\w:.]+) Source=(\d+) TargetCount=(\d+)$")
3838
SUB_SPELL_END_RE = re.compile(r"SUB_SPELL_END$")
3939

4040
# Message details

tests/data.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,18 @@
175175
D 23:58:17.9838675 GameState.DebugPrintPower() - SUB_SPELL_END
176176
D 23:58:17.9848671 GameState.DebugPrintPower() - BLOCK_END
177177
""".strip()
178+
179+
180+
BGS_SUB_SPELL_BLOCK = """
181+
D 08:59:23.0098315 GameState.DebugPrintPower() - BLOCK_START BlockType=PLAY Entity=[entityName=Freeze id=2718 zone=PLAY zonePos=0 cardId=TB_BaconShopLockAll_Button player=3] EffectCardId= EffectIndex=0 Target=0 SubOption=-1
182+
D 08:59:23.0098315 GameState.DebugPrintPower() - BLOCK_START BlockType=POWER Entity=[entityName=Freeze id=2718 zone=PLAY zonePos=0 cardId=TB_BaconShopLockAll_Button player=3] EffectCardId= EffectIndex=0 Target=0 SubOption=-1
183+
D 08:59:23.0098315 GameState.DebugPrintPower() - SUB_SPELL_START - SpellPrefabGUID=Bacon_FreezeMinions_AE_Super.prefab:49de73d8b72602f47994a795a78f050d Source=0 TargetCount=0
184+
D 08:59:23.0098315 GameState.DebugPrintPower() - TAG_CHANGE Entity=[entityName=Bolvar, Fireblood id=2871 zone=PLAY zonePos=1 cardId=ICC_858 player=11] tag=FROZEN value=1
185+
D 08:59:23.0098315 GameState.DebugPrintPower() - TAG_CHANGE Entity=[entityName=Cave Hydra id=2872 zone=PLAY zonePos=2 cardId=LOOT_078 player=11] tag=FROZEN value=1
186+
D 08:59:23.0098315 GameState.DebugPrintPower() - TAG_CHANGE Entity=[entityName=Nightmare Amalgam id=2873 zone=PLAY zonePos=3 cardId=GIL_681 player=11] tag=FROZEN value=1
187+
D 08:59:23.0098315 GameState.DebugPrintPower() - TAG_CHANGE Entity=[entityName=Bolvar, Fireblood id=2874 zone=PLAY zonePos=4 cardId=ICC_858 player=11] tag=FROZEN value=1
188+
D 08:59:23.0098315 GameState.DebugPrintPower() - TAG_CHANGE Entity=[entityName=Kindly Grandmother id=2875 zone=PLAY zonePos=5 cardId=KAR_005 player=11] tag=FROZEN value=1
189+
D 08:59:23.0098315 GameState.DebugPrintPower() - SUB_SPELL_END
190+
D 08:59:23.0098315 GameState.DebugPrintPower() - BLOCK_END
191+
D 08:59:23.0098315 GameState.DebugPrintPower() - BLOCK_END
192+
""".strip()

tests/test_main.py

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,12 @@
1313
from hslog.export import FriendlyPlayerExporter
1414
from hslog.parser import parse_initial_tag
1515

16-
from .data import (
17-
CONTROLLER_CHANGE, EMPTY_GAME, FULL_ENTITY, INITIAL_GAME, INVALID_GAME,
18-
OPTIONS_WITH_ERRORS, SUB_SPELL_BLOCK, UNROUNDABLE_TIMESTAMP
19-
)
16+
from . import data
2017

2118

2219
def test_create_empty_game():
2320
parser = LogParser()
24-
parser.read(StringIO(EMPTY_GAME))
21+
parser.read(StringIO(data.EMPTY_GAME))
2522
parser.flush()
2623

2724
# Test resulting game/entities
@@ -95,7 +92,7 @@ def test_tag_value_parsing():
9592

9693
def test_game_initialization():
9794
parser = LogParser()
98-
parser.read(StringIO(INITIAL_GAME))
95+
parser.read(StringIO(data.INITIAL_GAME))
9996
parser.flush()
10097

10198
assert len(parser.games) == 1
@@ -145,23 +142,23 @@ def test_game_initialization():
145142

146143
def test_timestamp_parsing():
147144
parser = LogParser()
148-
parser.read(StringIO(INITIAL_GAME))
145+
parser.read(StringIO(data.INITIAL_GAME))
149146
parser.flush()
150147

151148
assert parser.games[0].packets[0].ts == time(2, 59, 14, 608862)
152149

153150
# Test with an initial datetime
154151
parser2 = LogParser()
155152
parser2._current_date = datetime(2015, 1, 1)
156-
parser2.read(StringIO(INITIAL_GAME))
153+
parser2.read(StringIO(data.INITIAL_GAME))
157154
parser2.flush()
158155

159156
assert parser2.games[0].packets[0].ts == datetime(2015, 1, 1, 2, 59, 14, 608862)
160157

161158
# Same test, with timezone
162159
parser2 = LogParser()
163160
parser2._current_date = parse_datetime("2015-01-01T02:58:00+0200")
164-
parser2.read(StringIO(INITIAL_GAME))
161+
parser2.read(StringIO(data.INITIAL_GAME))
165162
parser2.flush()
166163

167164
ts = parser2.games[0].packets[0].ts
@@ -174,8 +171,8 @@ def test_timestamp_parsing():
174171

175172
def test_unroundable_timestamp():
176173
parser = LogParser()
177-
parser.read(StringIO(INITIAL_GAME))
178-
parser.read(StringIO(UNROUNDABLE_TIMESTAMP))
174+
parser.read(StringIO(data.INITIAL_GAME))
175+
parser.read(StringIO(data.UNROUNDABLE_TIMESTAMP))
179176
parser.flush()
180177

181178
# Timestamp has to be truncated
@@ -184,7 +181,7 @@ def test_unroundable_timestamp():
184181

185182
def test_info_outside_of_metadata():
186183
parser = LogParser()
187-
parser.read(StringIO(INITIAL_GAME))
184+
parser.read(StringIO(data.INITIAL_GAME))
188185
parser.flush()
189186

190187
info = u"D 02:59:14.6500380 GameState.DebugPrintPower() - Info[0] = 99"
@@ -194,18 +191,18 @@ def test_info_outside_of_metadata():
194191

195192
def test_empty_entity_in_options():
196193
parser = LogParser()
197-
parser.read(StringIO(INITIAL_GAME))
194+
parser.read(StringIO(data.INITIAL_GAME))
198195
parser.flush()
199196

200-
data = "target 0 entity="
197+
line = "target 0 entity="
201198
with pytest.raises(ParsingError):
202199
# This can happen, but the game is corrupt
203-
parser.handle_options(None, data)
200+
parser.handle_options(None, line)
204201

205202

206203
def test_warn_level():
207204
parser = LogParser()
208-
parser.read(StringIO(INITIAL_GAME))
205+
parser.read(StringIO(data.INITIAL_GAME))
209206
parser.flush()
210207

211208
line = u"W 09:09:23.1428700 GameState.ReportStuck() - Stuck for 10s 89ms. {...}"
@@ -215,7 +212,7 @@ def test_warn_level():
215212

216213
def test_empty_tasklist():
217214
parser = LogParser()
218-
parser.read(StringIO(INITIAL_GAME))
215+
parser.read(StringIO(data.INITIAL_GAME))
219216
parser.flush()
220217

221218
ts = datetime.now()
@@ -238,7 +235,7 @@ def test_empty_tasklist():
238235
def test_tag_change_unknown_entity_format():
239236
# Format changed in 15590
240237
parser = LogParser()
241-
parser.read(StringIO(INITIAL_GAME))
238+
parser.read(StringIO(data.INITIAL_GAME))
242239
parser.flush()
243240

244241
entity_format = (
@@ -247,8 +244,8 @@ def test_tag_change_unknown_entity_format():
247244
id = parser.parse_entity_id(entity_format)
248245
assert id == 24
249246

250-
data = "TAG_CHANGE Entity=%s tag=ZONE value=HAND" % (entity_format)
251-
packet = parser.handle_power(None, "TAG_CHANGE", data)
247+
line = "TAG_CHANGE Entity=%s tag=ZONE value=HAND" % (entity_format)
248+
packet = parser.handle_power(None, "TAG_CHANGE", line)
252249
assert packet.power_type == PowerType.TAG_CHANGE
253250
assert packet.entity == id
254251
assert packet.tag == GameTag.ZONE
@@ -257,8 +254,8 @@ def test_tag_change_unknown_entity_format():
257254

258255
def test_initial_deck_initial_controller():
259256
parser = LogParser()
260-
parser.read(StringIO(INITIAL_GAME))
261-
parser.read(StringIO(FULL_ENTITY))
257+
parser.read(StringIO(data.INITIAL_GAME))
258+
parser.read(StringIO(data.FULL_ENTITY))
262259
parser.flush()
263260
packet_tree = parser.games[0]
264261
game = packet_tree.export().game
@@ -267,9 +264,9 @@ def test_initial_deck_initial_controller():
267264
assert len(list(game.players[1].initial_deck)) == 0
268265

269266
parser = LogParser()
270-
parser.read(StringIO(INITIAL_GAME))
271-
parser.read(StringIO(FULL_ENTITY))
272-
parser.read(StringIO(CONTROLLER_CHANGE))
267+
parser.read(StringIO(data.INITIAL_GAME))
268+
parser.read(StringIO(data.FULL_ENTITY))
269+
parser.read(StringIO(data.CONTROLLER_CHANGE))
273270
parser.flush()
274271
packet_tree = parser.games[0]
275272
game = packet_tree.export().game
@@ -281,14 +278,14 @@ def test_initial_deck_initial_controller():
281278
def test_invalid_game_one_player():
282279
parser = LogParser()
283280
with pytest.raises(ParsingError):
284-
parser.read(StringIO(INVALID_GAME))
281+
parser.read(StringIO(data.INVALID_GAME))
285282

286283

287284
def test_options_packet_with_errors():
288285
parser = LogParser()
289-
parser.read(StringIO(INITIAL_GAME))
286+
parser.read(StringIO(data.INITIAL_GAME))
290287

291-
parser.read(StringIO(OPTIONS_WITH_ERRORS))
288+
parser.read(StringIO(data.OPTIONS_WITH_ERRORS))
292289
parser.flush()
293290
packet_tree = parser.games[0]
294291

@@ -318,23 +315,23 @@ def test_options_packet_with_errors():
318315

319316
def test_options_no_option_packet():
320317
parser = LogParser()
321-
parser.read(StringIO(INITIAL_GAME))
318+
parser.read(StringIO(data.INITIAL_GAME))
322319

323320
with pytest.raises(ParsingError):
324321
parser.handle_options(None, "option 0 type=END_TURN mainEntity=")
325322

326323

327324
def test_suboptions_no_option_packet():
328325
parser = LogParser()
329-
parser.read(StringIO(INITIAL_GAME))
326+
parser.read(StringIO(data.INITIAL_GAME))
330327

331328
with pytest.raises(ParsingError):
332329
parser.handle_options(None, "subOption 0 entity=1")
333330

334331

335332
def test_error_unhandled_powtype():
336333
parser = LogParser()
337-
parser.read(StringIO(INITIAL_GAME))
334+
parser.read(StringIO(data.INITIAL_GAME))
338335

339336
# This shouldn't raise an exception
340337
parser.read(StringIO(
@@ -346,7 +343,7 @@ def test_error_unhandled_powtype():
346343

347344
def test_target_no_entity():
348345
parser = LogParser()
349-
parser.read(StringIO(INITIAL_GAME))
346+
parser.read(StringIO(data.INITIAL_GAME))
350347

351348
parser.read(StringIO(
352349
"D 01:02:58.3254653 GameState.DebugPrintOptions() - id=2\n" # noqa
@@ -369,7 +366,7 @@ def test_target_no_entity():
369366

370367
def test_reset_game():
371368
parser = LogParser()
372-
parser.read(StringIO(INITIAL_GAME))
369+
parser.read(StringIO(data.INITIAL_GAME))
373370

374371
# This shouldn't raise an exception
375372
parser.read(StringIO(
@@ -381,9 +378,9 @@ def test_reset_game():
381378

382379
def test_sub_spell():
383380
parser = LogParser()
384-
parser.read(StringIO(INITIAL_GAME))
381+
parser.read(StringIO(data.INITIAL_GAME))
385382

386-
parser.read(StringIO(SUB_SPELL_BLOCK))
383+
parser.read(StringIO(data.SUB_SPELL_BLOCK))
387384
parser.flush()
388385

389386
packet_tree = parser.games[0]
@@ -398,3 +395,24 @@ def test_sub_spell():
398395
assert sub_spell_packet.source == 59
399396
assert sub_spell_packet.target_count == 1
400397
assert sub_spell_packet.targets == [41]
398+
399+
400+
def test_sub_spell_battlegrounds():
401+
parser = LogParser()
402+
parser.read(StringIO(data.INITIAL_GAME))
403+
404+
parser.read(StringIO(data.BGS_SUB_SPELL_BLOCK))
405+
parser.flush()
406+
407+
packet_tree = parser.games[0]
408+
play_block = packet_tree.packets[-1]
409+
power_block = play_block.packets[0]
410+
assert len(power_block.packets) == 1
411+
sub_spell_packet = power_block.packets[0]
412+
413+
assert sub_spell_packet.spell_prefab_guid == (
414+
"Bacon_FreezeMinions_AE_Super.prefab:49de73d8b72602f47994a795a78f050d"
415+
)
416+
assert sub_spell_packet.source is None
417+
assert sub_spell_packet.target_count == 0
418+
assert sub_spell_packet.targets == []

0 commit comments

Comments
 (0)