hearthstone 0.2.0
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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +43 -0
- data/Rakefile +2 -0
- data/bin/hearthstone-recorder +7 -0
- data/hearthstone.gemspec +28 -0
- data/lib/hearthstone.rb +7 -0
- data/lib/hearthstone/commands/recorder_command.rb +86 -0
- data/lib/hearthstone/log.rb +7 -0
- data/lib/hearthstone/log/configurator.rb +41 -0
- data/lib/hearthstone/log/data.rb +1 -0
- data/lib/hearthstone/log/data/game.rb +74 -0
- data/lib/hearthstone/log/data/game_player.rb +25 -0
- data/lib/hearthstone/log/data/game_turn.rb +32 -0
- data/lib/hearthstone/log/game_logger.rb +128 -0
- data/lib/hearthstone/log/parser.rb +276 -0
- data/lib/hearthstone/models.rb +3 -0
- data/lib/hearthstone/models/AllSetsAllLanguages.json +1 -0
- data/lib/hearthstone/models/card.rb +20 -0
- data/lib/hearthstone/models/card_store.rb +50 -0
- data/lib/hearthstone/models/entity.rb +67 -0
- data/lib/hearthstone/models/game.rb +151 -0
- data/lib/hearthstone/models/game_loader.rb +52 -0
- data/lib/hearthstone/models/player.rb +37 -0
- data/lib/hearthstone/version.rb +3 -0
- data/spec/fixtures/completed.config +8 -0
- data/spec/fixtures/empty_config.config +0 -0
- data/spec/fixtures/game1.json +2433 -0
- data/spec/fixtures/gamelog1.json +1585 -0
- data/spec/fixtures/gamelog1.log +25508 -0
- data/spec/fixtures/gamelog2.log +85357 -0
- data/spec/hearthstone/log/configurator_spec.rb +61 -0
- data/spec/hearthstone/log/game_logger_spec.rb +57 -0
- data/spec/hearthstone/log/parser_spec.rb +185 -0
- data/spec/hearthstone/models/card_store_spec.rb +16 -0
- data/spec/hearthstone/models/game_loader_spec.rb +153 -0
- data/spec/hearthstone/models/game_spec.rb +157 -0
- metadata +179 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative "../../../lib/hearthstone"
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
describe Hearthstone::Log::Configurator do
|
5
|
+
context "#needs_config?" do
|
6
|
+
it "should needs config for nonexisted config file" do
|
7
|
+
filename = File.join(File.dirname(__FILE__), "../../fixtures/not_found")
|
8
|
+
subject = Hearthstone::Log::Configurator.new(filename)
|
9
|
+
expect(subject.needs_config?).to eq(true)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should needs config for incompleted config file" do
|
13
|
+
filename = File.join(File.dirname(__FILE__), "../../fixtures/empty_config.config")
|
14
|
+
subject = Hearthstone::Log::Configurator.new(filename)
|
15
|
+
expect(subject.needs_config?).to eq(true)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should not need config for completed config file" do
|
19
|
+
filename = File.join(File.dirname(__FILE__), "../../fixtures/completed.config")
|
20
|
+
subject = Hearthstone::Log::Configurator.new(filename)
|
21
|
+
expect(subject.needs_config?).to eq(false)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "#configure" do
|
26
|
+
before(:each) do
|
27
|
+
@file = Tempfile.new("configurator")
|
28
|
+
end
|
29
|
+
|
30
|
+
after(:each) do
|
31
|
+
@file.close
|
32
|
+
end
|
33
|
+
|
34
|
+
it "write configuration file" do
|
35
|
+
subject = Hearthstone::Log::Configurator.new(@file.path)
|
36
|
+
subject.configure
|
37
|
+
|
38
|
+
data = @file.read
|
39
|
+
expect(data).to match(/\[Zone\]/)
|
40
|
+
expect(data).to match(/\[Power\]/)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "append configuration file" do
|
44
|
+
File.open(@file.path, 'w') do |f|
|
45
|
+
config = """[Hello]
|
46
|
+
foo=bar
|
47
|
+
"""
|
48
|
+
f.write(config)
|
49
|
+
end
|
50
|
+
|
51
|
+
subject = Hearthstone::Log::Configurator.new(@file.path)
|
52
|
+
subject.configure
|
53
|
+
|
54
|
+
data = @file.read
|
55
|
+
expect(data).to match(/\[Zone\]/)
|
56
|
+
expect(data).to match(/\[Power\]/)
|
57
|
+
expect(data).to match(/\[Hello\]/)
|
58
|
+
expect(data).to match(/foo=bar/)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require_relative "../../../lib/hearthstone"
|
2
|
+
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
describe Hearthstone::Log::GameLogger do
|
6
|
+
let(:delegate) { double(:delegate) }
|
7
|
+
let(:subject) { Hearthstone::Log::GameLogger.new(delegate) }
|
8
|
+
|
9
|
+
context "#log_file" do
|
10
|
+
it "parse basic game info" do
|
11
|
+
filename = File.join(File.dirname(__FILE__), "../../fixtures/gamelog1.log")
|
12
|
+
File.open(filename) do |file|
|
13
|
+
expect(delegate).to receive(:on_game_over) do |game|
|
14
|
+
expect(game.players.count).to eq(2)
|
15
|
+
|
16
|
+
zardeine = game.players[0]
|
17
|
+
expect(zardeine).to_not be_nil
|
18
|
+
expect(zardeine.first_player).to eq(false)
|
19
|
+
|
20
|
+
siuying = game.players[1]
|
21
|
+
expect(siuying).to_not be_nil
|
22
|
+
expect(siuying.first_player).to eq(true)
|
23
|
+
|
24
|
+
expect(game.mode).to eq(:ranked)
|
25
|
+
expect(game.completed?).to eq(true)
|
26
|
+
expect(game.turns.count).to eq(12)
|
27
|
+
expect(game.turns.first.number).to eq(0)
|
28
|
+
expect(game.turns.last.number).to eq(11)
|
29
|
+
end
|
30
|
+
|
31
|
+
log = file.read
|
32
|
+
subject.log_file(log)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "parse log file #2" do
|
37
|
+
filename = File.join(File.dirname(__FILE__), "../../fixtures/gamelog2.log")
|
38
|
+
File.open(filename) do |file|
|
39
|
+
games = []
|
40
|
+
expect(delegate).to receive(:on_game_over).twice do |game|
|
41
|
+
games << game
|
42
|
+
end
|
43
|
+
|
44
|
+
log = file.read
|
45
|
+
subject.log_file(log)
|
46
|
+
|
47
|
+
game = games.last
|
48
|
+
expect(game.mode).to eq(:ranked)
|
49
|
+
expect(game.players.count).to eq(2)
|
50
|
+
expect(game.completed?).to eq(true)
|
51
|
+
expect(game.turns.count).to eq(25)
|
52
|
+
expect(game.turns.first.number).to eq(0)
|
53
|
+
expect(game.turns.last.number).to eq(24)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require_relative "../../../lib/hearthstone"
|
2
|
+
|
3
|
+
describe Hearthstone::Log::Parser, "#parse_line" do
|
4
|
+
let (:parser) { Hearthstone::Log::Parser.new }
|
5
|
+
it "returns startup on app start" do
|
6
|
+
result = parser.parse_line("Initialize engine version: 4.5.5p3 (b8dc95101aa8)")
|
7
|
+
expect(result).to eq([:startup])
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns choice" do
|
11
|
+
result = parser.parse_line("[Power] GameState.SendChoices() - id=3 ChoiceType=GENERAL")
|
12
|
+
expect(result).to eq([:choice_type, "GENERAL"])
|
13
|
+
|
14
|
+
result = parser.parse_line("[Power] GameState.SendChoices() - m_chosenEntities[0]=[name=Feign Death id=38 zone=HAND zonePos=3 cardId=GVG_026 player=2]")
|
15
|
+
expect(result).to eq([:choose, id: 38, card_id: 'GVG_026', player_id: 2])
|
16
|
+
|
17
|
+
result = parser.parse_line("[Power] GameState.SendChoices() - m_chosenEntities[0]=[name=Undertaker id=8 zone=SETASIDE zonePos=0 cardId=FP1_028 player=1]")
|
18
|
+
expect(result).to eq([:choose, id: 8, card_id: 'FP1_028', player_id: 1])
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns spectator mode" do
|
22
|
+
result = parser.parse_line("[Power] Begin Spectating")
|
23
|
+
expect(result).to eq([:begin_spectator_mode])
|
24
|
+
|
25
|
+
result = parser.parse_line("[Power] End Spectator Mode")
|
26
|
+
expect(result).to eq([:end_spectator_mode])
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns arena and ranked mode" do
|
30
|
+
result = parser.parse_line("[LoadingScreen] LoadingScreen.OnSceneLoaded() - prevMode=HUB currMode=DRAFT")
|
31
|
+
expect(result).to eq([:mode, :arena])
|
32
|
+
|
33
|
+
result = parser.parse_line("[LoadingScreen] LoadingScreen.OnSceneLoaded() - prevMode=GAMEPLAY currMode=TOURNAMENT")
|
34
|
+
expect(result).to eq([:mode, :ranked])
|
35
|
+
|
36
|
+
result = parser.parse_line("[LoadingScreen] LoadingScreen.OnSceneLoaded() - prevMode=HUB currMode=ADVENTURE")
|
37
|
+
expect(result).to eq([:mode, :solo])
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns action start" do
|
41
|
+
result = parser.parse_line("[Power] GameState.DebugPrintPower() - ACTION_START Entity=[name=Undertaker id=59 zone=PLAY zonePos=1 cardId=FP1_028 player=2] SubType=ATTACK Index=-1 Target=[name=Rexxar id=4 zone=PLAY zonePos=0 cardId=HERO_05 player=1]")
|
42
|
+
expect(result).to eq([:action_start, {:subtype=>"ATTACK", :from=>{:id=>59, :card_id=>"FP1_028", :player_id=>2}, :to=>{:id=>4, :card_id=>"HERO_05", :player_id=>1}}])
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns player state change" do
|
46
|
+
result = parser.parse_line("[Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=siuying tag=PLAYER_ID value=2")
|
47
|
+
expect(result).to eq([:player_id, name: "siuying", player_id: 2])
|
48
|
+
|
49
|
+
result = parser.parse_line("[Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=begize tag=FIRST_PLAYER value=1")
|
50
|
+
expect(result).to eq([:first_player, name: "begize"])
|
51
|
+
|
52
|
+
result = parser.parse_line("[Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=begize tag=PLAYSTATE value=WON")
|
53
|
+
expect(result).to eq([:game_over, name: "begize", state: "WON"])
|
54
|
+
|
55
|
+
result = parser.parse_line("[Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=siuying tag=TURN_START value=1418309639")
|
56
|
+
expect(result).to eq([:turn_start, name: "siuying", timestamp: 1418309639])
|
57
|
+
|
58
|
+
result = parser.parse_line("[Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=GameEntity tag=TURN value=3")
|
59
|
+
expect(result).to eq([:turn, 3])
|
60
|
+
|
61
|
+
result = parser.parse_line("[Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=GameEntity tag=TURN_START value=1418310864")
|
62
|
+
expect(result).to eq([:game_start])
|
63
|
+
end
|
64
|
+
|
65
|
+
it "returns entity state change" do
|
66
|
+
result = parser.parse_line("[Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=[name=Silver Hand Recruit id=71 zone=PLAY zonePos=1 cardId=CS2_101t player=1] tag=DAMAGE value=2
|
67
|
+
")
|
68
|
+
expect(result).to eq([:damaged, id: 71, card_id: "CS2_101t", player_id: 1, amount: 2])
|
69
|
+
|
70
|
+
result = parser.parse_line("[Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=[name=Uther Lightbringer id=4 zone=PLAY zonePos=0 cardId=HERO_04 player=1] tag=ATTACKING value=1")
|
71
|
+
expect(result).to eq([:attack, id: 4, card_id: "HERO_04", player_id: 1])
|
72
|
+
|
73
|
+
result = parser.parse_line("[Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=[name=Rexxar id=36 zone=PLAY zonePos=0 cardId=HERO_05 player=2] tag=DEFENDING value=1")
|
74
|
+
expect(result).to eq([:attacked, id: 36, card_id: "HERO_05", player_id: 2])
|
75
|
+
|
76
|
+
result = parser.parse_line("[Power] GameState.DebugPrintPower() - TAG_CHANGE Entity=[name=Fireblast id=37 zone=PLAY zonePos=0 cardId=CS2_034 player=2] tag=CARD_TARGET value=9")
|
77
|
+
expect(result).to eq([:card_target, id: 37, card_id: 'CS2_034', player_id: 2, target: 9])
|
78
|
+
end
|
79
|
+
|
80
|
+
context "returns process change" do
|
81
|
+
it "handles hands" do
|
82
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=47 local=False [name=Reversing Switch id=72 zone=HAND zonePos=7 cardId=PART_006 player=1] zone from -> FRIENDLY HAND"
|
83
|
+
result = parser.parse_line(line)
|
84
|
+
expect(result).to eq([:card_received, player_id: 1, id: 72, card_id: "PART_006"])
|
85
|
+
|
86
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=1 local=False [id=22 cardId= type=INVALID zone=HAND zonePos=4 player=1] zone from -> OPPOSING HAND"
|
87
|
+
result = parser.parse_line(line)
|
88
|
+
expect(result).to eq([:card_received, player_id: 1, id: 22, card_id: ""])
|
89
|
+
|
90
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=16 local=False [id=57 cardId= type=INVALID zone=HAND zonePos=0 player=2] zone from OPPOSING DECK -> OPPOSING HAND"
|
91
|
+
result = parser.parse_line(line)
|
92
|
+
expect(result).to eq([:card_drawn, player_id: 2, id: 57, card_id: ""])
|
93
|
+
|
94
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=27 local=False [name=Boulderfist Ogre id=10 zone=HAND zonePos=0 cardId=CS2_200 player=1] zone from FRIENDLY DECK -> FRIENDLY HAND"
|
95
|
+
result = parser.parse_line(line)
|
96
|
+
expect(result).to eq([:card_drawn, player_id: 1, id: 10, card_id: 'CS2_200'])
|
97
|
+
|
98
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=20 local=False [name=Leper Gnome id=26 zone=HAND zonePos=2 cardId=EX1_029 player=1] zone from OPPOSING PLAY -> OPPOSING HAND"
|
99
|
+
result = parser.parse_line(line)
|
100
|
+
expect(result).to eq([:card_returned, player_id: 1, id: 26, card_id: 'EX1_029'])
|
101
|
+
|
102
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=45 local=False [name=Harvest Golem id=10 zone=HAND zonePos=1 cardId=EX1_556 player=1] zone from FRIENDLY PLAY -> FRIENDLY HAND"
|
103
|
+
result = parser.parse_line(line)
|
104
|
+
expect(result).to eq([:card_returned, player_id: 1, id: 10, card_id: 'EX1_556'])
|
105
|
+
end
|
106
|
+
|
107
|
+
it "handles play" do
|
108
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=1 local=True [name=Loot Hoarder id=57 zone=HAND zonePos=2 cardId=EX1_096 player=2] zone from FRIENDLY HAND -> FRIENDLY PLAY"
|
109
|
+
result = parser.parse_line(line)
|
110
|
+
expect(result).to eq([:card_played, player_id: 2, id: 57, card_id: 'EX1_096'])
|
111
|
+
|
112
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=8 local=False [name=Pint-Sized Summoner id=34 zone=PLAY zonePos=1 cardId=EX1_076 player=1] zone from OPPOSING HAND -> OPPOSING PLAY"
|
113
|
+
result = parser.parse_line(line)
|
114
|
+
expect(result).to eq([:card_played, player_id: 1, id: 34, card_id: 'EX1_076'])
|
115
|
+
|
116
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=84 local=False [name=Ashbringer id=84 zone=PLAY zonePos=0 cardId=EX1_383t player=1] zone from -> OPPOSING PLAY (Weapon)"
|
117
|
+
result = parser.parse_line(line)
|
118
|
+
expect(result).to eq([:card_put_in_play, player_id: 1, id: 84, card_id: 'EX1_383t'])
|
119
|
+
|
120
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=1 local=False [name=Jaina Proudmoore id=4 zone=PLAY zonePos=0 cardId=HERO_08 player=1] zone from -> FRIENDLY PLAY (Hero)"
|
121
|
+
result = parser.parse_line(line)
|
122
|
+
expect(result).to eq([:set_hero, player_id: 1, id: 4, card_id: 'HERO_08'])
|
123
|
+
|
124
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=1 local=False [name=Gul'dan id=36 zone=PLAY zonePos=0 cardId=HERO_07 player=2] zone from -> OPPOSING PLAY (Hero)"
|
125
|
+
result = parser.parse_line(line)
|
126
|
+
expect(result).to eq([:set_hero, player_id: 2, id: 36, card_id: 'HERO_07'])
|
127
|
+
|
128
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=1 local=False [name=Steady Shot id=5 zone=PLAY zonePos=0 cardId=DS1h_292 player=1] zone from -> FRIENDLY PLAY (Hero Power)"
|
129
|
+
result = parser.parse_line(line)
|
130
|
+
expect(result).to eq([:set_hero_power, player_id: 1, id: 5, card_id: 'DS1h_292'])
|
131
|
+
|
132
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=1 local=False [name=Steady Shot id=37 zone=PLAY zonePos=0 cardId=DS1h_292 player=2] zone from -> OPPOSING PLAY (Hero Power)"
|
133
|
+
result = parser.parse_line(line)
|
134
|
+
expect(result).to eq([:set_hero_power, player_id: 2, id: 37, card_id: 'DS1h_292'])
|
135
|
+
end
|
136
|
+
|
137
|
+
it "handles deck" do
|
138
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=2 local=False [name=Sludge Belcher id=46 zone=DECK zonePos=3 cardId=FP1_012 player=2] zone from FRIENDLY HAND -> FRIENDLY DECK"
|
139
|
+
result = parser.parse_line(line)
|
140
|
+
expect(result).to eq([:card_reshuffled, player_id: 2, id: 46, card_id: "FP1_012"])
|
141
|
+
|
142
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=3 local=False [id=69 cardId= type=INVALID zone=DECK zonePos=2 player=2] zone from OPPOSING HAND -> OPPOSING DECK"
|
143
|
+
result = parser.parse_line(line)
|
144
|
+
expect(result).to eq([:card_reshuffled, player_id: 2, id: 69, card_id: ""])
|
145
|
+
|
146
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=1 local=False [id=38 cardId= type=INVALID zone=DECK zonePos=0 player=2] zone from -> FRIENDLY DECK"
|
147
|
+
result = parser.parse_line(line)
|
148
|
+
expect(result).to eq([:card_added_to_deck, player_id: 2, id: 38, card_id: ""])
|
149
|
+
|
150
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=1 local=False [id=6 cardId= type=INVALID zone=DECK zonePos=0 player=1] zone from -> OPPOSING DECK"
|
151
|
+
result = parser.parse_line(line)
|
152
|
+
expect(result).to eq([:card_added_to_deck, player_id: 1, id: 6, card_id: ""])
|
153
|
+
end
|
154
|
+
|
155
|
+
it "handles graveyard" do
|
156
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=21 local=False [name=Webspinner id=65 zone=GRAVEYARD zonePos=2 cardId=FP1_011 player=2] zone from FRIENDLY PLAY -> FRIENDLY GRAVEYARD"
|
157
|
+
result = parser.parse_line(line)
|
158
|
+
expect(result).to eq([:card_destroyed, player_id: 2, id: 65, card_id: "FP1_011"])
|
159
|
+
|
160
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=42 local=False [name=Animal Companion id=50 zone=GRAVEYARD zonePos=0 cardId=NEW1_031 player=2] zone from -> OPPOSING GRAVEYARD"
|
161
|
+
result = parser.parse_line(line)
|
162
|
+
expect(result).to eq([:card_discarded, player_id: 2, id: 50, card_id: "NEW1_031"])
|
163
|
+
|
164
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=86 local=False [name=Uther Lightbringer id=4 zone=GRAVEYARD zonePos=0 cardId=HERO_04 player=1] zone from OPPOSING PLAY (Hero) -> OPPOSING GRAVEYARD"
|
165
|
+
result = parser.parse_line(line)
|
166
|
+
expect(result).to eq([:hero_destroyed, player_id: 1, id: 4, card_id: "HERO_04"])
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
it "handles secrets" do
|
171
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=80 local=False [id=30 cardId= type=INVALID zone=SECRET zonePos=0 player=1] zone from OPPOSING DECK -> OPPOSING SECRET"
|
172
|
+
result = parser.parse_line(line)
|
173
|
+
expect(result).to eq([:card_put_in_play, player_id: 1, id: 30, card_id: ''])
|
174
|
+
|
175
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=29 local=False [name=Explosive Trap id=43 zone=SECRET zonePos=0 cardId=EX1_610 player=2] zone from FRIENDLY DECK -> FRIENDLY SECRET"
|
176
|
+
result = parser.parse_line(line)
|
177
|
+
expect(result).to eq([:card_put_in_play, player_id: 2, id: 43, card_id: 'EX1_610'])
|
178
|
+
|
179
|
+
line = "[Zone] ZoneChangeList.ProcessChanges() - id=45 local=False [name=Freezing Trap id=66 zone=SETASIDE zonePos=0 cardId=EX1_611 player=2] zone from FRIENDLY DECK -> "
|
180
|
+
result = parser.parse_line(line)
|
181
|
+
expect(result).to eq([:card_setaside, player_id: 2, id: 66, card_id: 'EX1_611'])
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative "../../../lib/hearthstone/models"
|
2
|
+
|
3
|
+
|
4
|
+
describe Hearthstone::Models::CardStore do
|
5
|
+
let(:store) { Hearthstone::Models::CardStore.new }
|
6
|
+
|
7
|
+
context "#card_with_id" do
|
8
|
+
it "returns the card with specific id" do
|
9
|
+
jenkins = store.card_with_id("EX1_116")
|
10
|
+
expect(jenkins.name).to eq("Leeroy Jenkins")
|
11
|
+
|
12
|
+
jenkins2 = store.card_with_id("EX1_116")
|
13
|
+
expect(jenkins2).to eq(jenkins)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require_relative "../../../lib/hearthstone/models"
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
describe Hearthstone::Models::GameLoader do
|
5
|
+
before(:all) {
|
6
|
+
filename = File.join(File.dirname(__FILE__), "../../fixtures/game1.json")
|
7
|
+
@data = JSON.parse(open(filename).read, symbolize_names: true)
|
8
|
+
}
|
9
|
+
|
10
|
+
context "#load_players" do
|
11
|
+
it "should load players" do
|
12
|
+
loader = Hearthstone::Models::GameLoader.new(@data)
|
13
|
+
loader.load_players
|
14
|
+
|
15
|
+
game = loader.game
|
16
|
+
expect(game.players.count).to eq(2)
|
17
|
+
|
18
|
+
first = game.players.first
|
19
|
+
expect(first.name).to eq("ALzard")
|
20
|
+
expect(first.hero.name).to eq("Thrall")
|
21
|
+
|
22
|
+
last = game.players.last
|
23
|
+
expect(last.name).to eq("siuying")
|
24
|
+
expect(last.hero.name).to eq("Rexxar")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "Load Games" do
|
29
|
+
before(:each) do
|
30
|
+
@loader = Hearthstone::Models::GameLoader.new(@data)
|
31
|
+
@loader.load_players
|
32
|
+
@game = @loader.game
|
33
|
+
end
|
34
|
+
|
35
|
+
context "#load_event" do
|
36
|
+
it "should load open card event" do
|
37
|
+
@loader.load_event(:open_card, id: 5, card_id: "CS2_101")
|
38
|
+
|
39
|
+
entity = @game.entity_with_id(5)
|
40
|
+
expect(entity.card.id).to eq("CS2_101")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should load card received event" do
|
44
|
+
@loader.load_event(:card_received, player_id: 2, id: 7, card_id: "CS2_101")
|
45
|
+
|
46
|
+
entity = @game.entity_with_id(7)
|
47
|
+
expect(entity.card.id).to eq("CS2_101")
|
48
|
+
|
49
|
+
player = @game.player_with_id(2)
|
50
|
+
expect(player.hand).to include(entity)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should load card reveal event" do
|
54
|
+
@loader.load_event(:open_card, id: 7, card_id: "")
|
55
|
+
@loader.load_event(:card_revealed, id: 7, card_id: "CS2_101")
|
56
|
+
|
57
|
+
entity = @game.entity_with_id(7)
|
58
|
+
expect(entity.card.id).to eq("CS2_101")
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should load card_added_to_deck event" do
|
62
|
+
@loader.load_event(:card_added_to_deck, player_id: 2, id: 7, card_id: "")
|
63
|
+
|
64
|
+
entity = @game.entity_with_id(7)
|
65
|
+
expect(entity.card).to be_nil
|
66
|
+
|
67
|
+
player = @game.player_with_id(2)
|
68
|
+
expect(player.deck).to include(entity)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should handle card_drawn event" do
|
72
|
+
@loader.load_event(:card_drawn, player_id: 2, id: 7, card_id: "CS2_101")
|
73
|
+
|
74
|
+
entity = @game.entity_with_id(7)
|
75
|
+
player = @game.player_with_id(2)
|
76
|
+
expect(player.hand).to include(entity)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should handle card_destroyed event" do
|
80
|
+
@loader.load_event(:card_destroyed, player_id: 1, id: 26)
|
81
|
+
|
82
|
+
entity = @game.entity_with_id(26)
|
83
|
+
player = @game.player_with_id(1)
|
84
|
+
expect(player.graveyard).to include(entity)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should handle card_put_in_play event" do
|
88
|
+
@loader.load_event(:card_put_in_play, player_id: 2, id: 7, card_id: "CS2_101")
|
89
|
+
|
90
|
+
entity = @game.entity_with_id(7)
|
91
|
+
player = @game.player_with_id(2)
|
92
|
+
expect(player.play).to include(entity)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should handle damaged event" do
|
96
|
+
@loader.load_event(:damaged, id: 7, amount: 2)
|
97
|
+
|
98
|
+
entity = @game.entity_with_id(7)
|
99
|
+
expect(entity.damaged).to eq(2)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should handle attached event" do
|
103
|
+
@loader.load_event(:open_card, id: 7, card_id: "")
|
104
|
+
@loader.load_event(:open_card, id: 26, card_id: "")
|
105
|
+
@loader.load_event(:attached, id: 26, target: 7)
|
106
|
+
|
107
|
+
entity = @game.entity_with_id(7)
|
108
|
+
attachment = @game.entity_with_id(26)
|
109
|
+
expect(entity.attachments).to include(attachment)
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "#load_turns" do
|
116
|
+
before(:each) do
|
117
|
+
filename = File.join(File.dirname(__FILE__), "../../fixtures/gamelog1.json")
|
118
|
+
@data = JSON.parse(open(filename).read, symbolize_names: true)
|
119
|
+
@loader = Hearthstone::Models::GameLoader.new(@data)
|
120
|
+
@loader.load_players
|
121
|
+
@game = @loader.game
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should load a game" do
|
125
|
+
@data[:turns].each do |turn|
|
126
|
+
@loader.load_turn(number: turn[:number], events: turn[:events])
|
127
|
+
|
128
|
+
@game.players.each do |player|
|
129
|
+
# deck cards always unknown
|
130
|
+
player.deck.each do |entity|
|
131
|
+
expect(entity.card).to be_nil
|
132
|
+
end
|
133
|
+
|
134
|
+
# graveyard cards always known
|
135
|
+
player.graveyard.each do |entity|
|
136
|
+
expect(entity.card).to_not be_nil
|
137
|
+
end
|
138
|
+
|
139
|
+
# hands cards only known for current player
|
140
|
+
player.hand.each do |entity|
|
141
|
+
if player.name == "siuying"
|
142
|
+
expect(entity.card).to_not be_nil
|
143
|
+
else
|
144
|
+
expect(entity.card).to be_nil
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|