pokerstats 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +18 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/bin/checkps +190 -0
- data/generators/pokerstats/USAGE +1 -0
- data/generators/pokerstats/pokerstats_generator.rb +7 -0
- data/generators/pokerstats/templates/create_pokerstats.rhtml +28 -0
- data/lib/pokerstats.rb +2 -0
- data/lib/pokerstats/.gitignore +0 -0
- data/lib/pokerstats/hand_constants.rb +27 -0
- data/lib/pokerstats/hand_history.rb +38 -0
- data/lib/pokerstats/hand_statistics.rb +225 -0
- data/lib/pokerstats/hand_statistics_api.rb +64 -0
- data/lib/pokerstats/player_statistics.rb +58 -0
- data/lib/pokerstats/plugins/aggression_statistics.rb +57 -0
- data/lib/pokerstats/plugins/blind_attack_statistics.rb +78 -0
- data/lib/pokerstats/plugins/cash_statistics.rb +95 -0
- data/lib/pokerstats/plugins/continuation_bet_statistics.rb +68 -0
- data/lib/pokerstats/plugins/preflop_raise_statistics.rb +50 -0
- data/lib/pokerstats/poker-edge.rb +57 -0
- data/lib/pokerstats/pokerstars_file.rb +100 -0
- data/lib/pokerstats/pokerstars_hand_history_parser.rb +141 -0
- data/pokerstats.gemspec +91 -0
- data/spec/file_empty.txt +0 -0
- data/spec/file_many_hands.txt +564 -0
- data/spec/file_one_hand.txt +52 -0
- data/spec/hand_statistics_spec.rb +846 -0
- data/spec/hand_statistics_spec_helper.rb +89 -0
- data/spec/player_statistics_spec.rb +230 -0
- data/spec/pokerstars_file_spec.rb +160 -0
- data/spec/pokerstars_hand_history_parser_spec.rb +197 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/zpokerstars_hand_history_parser_integration.rb.txt +67 -0
- metadata +125 -0
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
require 'bigdecimal/util'
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/pokerstats/hand_constants')
|
4
|
+
include HandConstants
|
5
|
+
|
6
|
+
module HandStatisticsFactories
|
7
|
+
def sample_hand
|
8
|
+
@@sample_hand_result ||= {
|
9
|
+
:session_filename => "a/b/c",
|
10
|
+
:starting_at => Time.now,
|
11
|
+
:name => "PS0001",
|
12
|
+
:description => "This is a description",
|
13
|
+
:sb => "1.00".to_d,
|
14
|
+
:bb => "2.00".to_d,
|
15
|
+
:board => "AS KS QS JS TS",
|
16
|
+
:total_pot => "100.00".to_d,
|
17
|
+
:rake => "4.00".to_d,
|
18
|
+
:played_at => Time.now,
|
19
|
+
:tournament => "T123"
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def sample_player
|
24
|
+
@@sample_player_result ||= {
|
25
|
+
:screen_name => 'sample_player_screen_name',
|
26
|
+
:seat => 1
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def next_sample_player hash={}
|
31
|
+
@@sample_player_count ||= 0
|
32
|
+
player = sample_player.clone
|
33
|
+
player[:screen_name] = player[:screen_name] + "_" + @@sample_player_count.to_s
|
34
|
+
@@sample_player_count += 1
|
35
|
+
player.merge(hash)
|
36
|
+
end
|
37
|
+
|
38
|
+
def sample_action
|
39
|
+
@@sample_action_result ||= {
|
40
|
+
:state => :prelude,
|
41
|
+
:screen_name => sample_player[:screen_name],
|
42
|
+
:action => :pay,
|
43
|
+
:result => :pay,
|
44
|
+
:amount => 10,
|
45
|
+
:other_thing => :baz
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def register_street(street, hash={})
|
50
|
+
@stats.update_hand(hash.merge(:street => street))
|
51
|
+
end
|
52
|
+
|
53
|
+
def register_bet(player, amount, hash={})
|
54
|
+
@stats.register_action player[:screen_name], 'bets', hash.merge(:result => :pay, :amount => amount)
|
55
|
+
end
|
56
|
+
|
57
|
+
def register_post(player, amount, hash={})
|
58
|
+
@stats.register_action player[:screen_name], 'posts', hash.merge(:result => :post, :amount => amount)
|
59
|
+
end
|
60
|
+
|
61
|
+
def register_ante(player, amount, hash={})
|
62
|
+
@stats.register_action player[:screen_name], 'antes', hash.merge(:result => :post, :amount => amount)
|
63
|
+
end
|
64
|
+
|
65
|
+
def register_raise_to(player, amount, hash={})
|
66
|
+
@stats.register_action player[:screen_name], 'raises', hash.merge(:result => :pay_to, :amount => amount)
|
67
|
+
end
|
68
|
+
|
69
|
+
def register_call(player, amount, hash={})
|
70
|
+
@stats.register_action player[:screen_name], 'calls', hash.merge(:result => :pay, :amount => amount)
|
71
|
+
end
|
72
|
+
|
73
|
+
def register_check(player, hash={})
|
74
|
+
@stats.register_action player[:screen_name], 'checks', hash.merge(:result => :neutral)
|
75
|
+
end
|
76
|
+
|
77
|
+
def register_fold(player, hash={})
|
78
|
+
@stats.register_action player[:screen_name], 'folds', hash.merge(:result => :neutral)
|
79
|
+
end
|
80
|
+
|
81
|
+
def register_win(player, amount, hash={})
|
82
|
+
@stats.register_action player[:screen_name], 'wins', hash.merge(:result => :win, :amount => amount)
|
83
|
+
end
|
84
|
+
|
85
|
+
def register_cards(player, data, hash={})
|
86
|
+
@stats.register_action player[:screen_name], 'shows', hash.merge(:result => :cards, :data => data)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
include HandStatisticsFactories
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'activesupport'
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/pokerstats/hand_statistics')
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/pokerstats/player_statistics')
|
6
|
+
include Pokerstats
|
7
|
+
|
8
|
+
TEST = [
|
9
|
+
{"andy" => {
|
10
|
+
:is_blind_attack_opportunity => false,
|
11
|
+
:is_blind_attack_opportunity_taken => nil,
|
12
|
+
:is_blind_defense_opportunity => false,
|
13
|
+
:is_blind_defense_opportunity_taken => nil,
|
14
|
+
:is_cbet_opportunity => true,
|
15
|
+
:is_cbet_opportunity_taken => true,
|
16
|
+
:posted => 1,
|
17
|
+
:paid => 2,
|
18
|
+
:won => 3,
|
19
|
+
:cards => nil,
|
20
|
+
:preflop_passive => 1,
|
21
|
+
:preflop_aggressive => 2,
|
22
|
+
:postflop_passive => 3,
|
23
|
+
:postflop_aggressive => 4,
|
24
|
+
:is_pfr_opportunity => true,
|
25
|
+
:is_pfr_opportunity_taken => true
|
26
|
+
},
|
27
|
+
"judi" => {
|
28
|
+
:is_blind_attack_opportunity => true,
|
29
|
+
:is_blind_attack_opportunity_taken => false,
|
30
|
+
:is_blind_defense_opportunity => true,
|
31
|
+
:is_blind_defense_opportunity_taken => true,
|
32
|
+
:is_cbet_opportunity => true,
|
33
|
+
:is_cbet_opportunity_taken => false,
|
34
|
+
:posted => 10,
|
35
|
+
:paid => 20,
|
36
|
+
:won => 30,
|
37
|
+
:cards => nil,
|
38
|
+
:preflop_passive => 10,
|
39
|
+
:preflop_aggressive => 20,
|
40
|
+
:postflop_passive => 30,
|
41
|
+
:postflop_aggressive => 40,
|
42
|
+
:is_pfr_opportunity => true,
|
43
|
+
:is_pfr_opportunity_taken => false
|
44
|
+
}
|
45
|
+
},
|
46
|
+
{"andy" => {
|
47
|
+
:is_blind_attack_opportunity => false,
|
48
|
+
:is_blind_attack_opportunity_taken => nil,
|
49
|
+
:is_blind_defense_opportunity => false,
|
50
|
+
:is_blind_defense_opportunity_taken => nil,
|
51
|
+
:is_cbet_opportunity => true,
|
52
|
+
:is_cbet_opportunity_taken => false,
|
53
|
+
:posted => 2,
|
54
|
+
:paid => 4,
|
55
|
+
:won => 6,
|
56
|
+
:cards => nil,
|
57
|
+
:preflop_passive => 2,
|
58
|
+
:preflop_aggressive => 4,
|
59
|
+
:postflop_passive => 6,
|
60
|
+
:postflop_aggressive => 8,
|
61
|
+
:is_pfr_opportunity => true,
|
62
|
+
:is_pfr_opportunity_taken => true
|
63
|
+
},
|
64
|
+
"judi" => {
|
65
|
+
:is_blind_attack_opportunity => true,
|
66
|
+
:is_blind_attack_opportunity_taken => false,
|
67
|
+
:is_blind_defense_opportunity => true,
|
68
|
+
:is_blind_defense_opportunity_taken => true,
|
69
|
+
:is_cbet_opportunity => false,
|
70
|
+
:is_cbet_opportunity_taken => nil,
|
71
|
+
:posted => 20,
|
72
|
+
:paid => 30,
|
73
|
+
:won => 40,
|
74
|
+
:cards => nil,
|
75
|
+
:preflop_passive => 20,
|
76
|
+
:preflop_aggressive => 40,
|
77
|
+
:postflop_passive => 60,
|
78
|
+
:postflop_aggressive => 80,
|
79
|
+
:is_pfr_opportunity => true,
|
80
|
+
:is_pfr_opportunity_taken => false
|
81
|
+
}
|
82
|
+
},
|
83
|
+
{"andy" => {
|
84
|
+
:is_blind_attack_opportunity => false,
|
85
|
+
:is_blind_attack_opportunity_taken => nil,
|
86
|
+
:is_blind_defense_opportunity => true,
|
87
|
+
:is_blind_defense_opportunity_taken => false,
|
88
|
+
:is_cbet_opportunity => false,
|
89
|
+
:is_cbet_opportunity_taken => nil,
|
90
|
+
:posted => 3,
|
91
|
+
:paid => 6,
|
92
|
+
:won => 9,
|
93
|
+
:cards => nil,
|
94
|
+
:preflop_passive => 3,
|
95
|
+
:preflop_aggressive => 6,
|
96
|
+
:postflop_passive => 9,
|
97
|
+
:postflop_aggressive => 12,
|
98
|
+
:is_pfr_opportunity => true,
|
99
|
+
:is_pfr_opportunity_taken => true
|
100
|
+
},
|
101
|
+
"judi" => {
|
102
|
+
:is_blind_attack_opportunity => true,
|
103
|
+
:is_blind_attack_opportunity_taken => true,
|
104
|
+
:is_blind_defense_opportunity => true,
|
105
|
+
:is_blind_defense_opportunity_taken => true,
|
106
|
+
:is_cbet_opportunity => false,
|
107
|
+
:is_cbet_opportunity_taken => nil,
|
108
|
+
:posted => 30,
|
109
|
+
:paid => 0,
|
110
|
+
:won => 0,
|
111
|
+
:cards => nil,
|
112
|
+
:preflop_passive => 30,
|
113
|
+
:preflop_aggressive => 60,
|
114
|
+
:postflop_passive => 90,
|
115
|
+
:postflop_aggressive => 120,
|
116
|
+
:is_pfr_opportunity => true,
|
117
|
+
:is_pfr_opportunity_taken => false
|
118
|
+
}
|
119
|
+
}
|
120
|
+
]
|
121
|
+
|
122
|
+
PS_RESULT = {
|
123
|
+
"andy" => {
|
124
|
+
:t_hands => 3,
|
125
|
+
:t_vpip => 3,
|
126
|
+
:t_posted => 6,
|
127
|
+
:t_paid => 12,
|
128
|
+
:t_won => 18,
|
129
|
+
:t_blind_attack_opportunity => 0,
|
130
|
+
:t_blind_attack_opportunity_taken => 0,
|
131
|
+
:t_blind_defense_opportunity => 1,
|
132
|
+
:t_blind_defense_opportunity_taken => 0,
|
133
|
+
:t_cbet_opportunity => 2,
|
134
|
+
:t_cbet_opportunity_taken => 1,
|
135
|
+
:t_preflop_passive => 6,
|
136
|
+
:t_preflop_aggressive => 12,
|
137
|
+
:t_postflop_passive => 18,
|
138
|
+
:t_postflop_aggressive => 24,
|
139
|
+
:t_pfr_opportunity => 3,
|
140
|
+
:t_pfr_opportunity_taken => 3
|
141
|
+
},
|
142
|
+
"judi" => {
|
143
|
+
:t_hands => 3,
|
144
|
+
:t_vpip => 2,
|
145
|
+
:t_posted => 60,
|
146
|
+
:t_paid => 50,
|
147
|
+
:t_won => 70,
|
148
|
+
:t_blind_attack_opportunity => 3,
|
149
|
+
:t_blind_attack_opportunity_taken => 1,
|
150
|
+
:t_blind_defense_opportunity => 3,
|
151
|
+
:t_blind_defense_opportunity_taken => 3,
|
152
|
+
:t_cbet_opportunity => 1,
|
153
|
+
:t_cbet_opportunity_taken => 0,
|
154
|
+
:t_preflop_passive => 60,
|
155
|
+
:t_preflop_aggressive => 120,
|
156
|
+
:t_postflop_passive => 180,
|
157
|
+
:t_postflop_aggressive => 240,
|
158
|
+
:t_pfr_opportunity => 3,
|
159
|
+
:t_pfr_opportunity_taken => 0
|
160
|
+
}
|
161
|
+
}
|
162
|
+
|
163
|
+
class AggregateTo
|
164
|
+
def initialize(player, stat, expected)
|
165
|
+
@player = player
|
166
|
+
@stat = stat
|
167
|
+
@expected = expected
|
168
|
+
end
|
169
|
+
|
170
|
+
def matches?(hash)
|
171
|
+
@actual = hash[@player][@stat]
|
172
|
+
# Satisfy expectation here. Return false or raise an error if it's not met.
|
173
|
+
return @actual == @expected
|
174
|
+
end
|
175
|
+
|
176
|
+
def failure_message
|
177
|
+
"expected report[#{@player.inspect}][#{@stat.inspect}] to aggregate to #{@expected.inspect}, got #{@actual.inspect}"
|
178
|
+
end
|
179
|
+
|
180
|
+
def negative_failure_message
|
181
|
+
"expected report[#{@player.inspect}][#{@stat.inspect}] not to aggregate to #{@expected.inspect}, but it did"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def should_correctly_aggregate(reports, stats = [])
|
186
|
+
reports.keys.each do |each_player|
|
187
|
+
stats.each do |each_stat|
|
188
|
+
reports.should AggregateTo.new(each_player, each_stat, PS_RESULT[each_player][each_stat])
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe PlayerStatistics, "when aggregating statistics" do
|
194
|
+
before do
|
195
|
+
@player_statistics = PlayerStatistics.new
|
196
|
+
for each_test in TEST
|
197
|
+
@hand_statistics = HandStatistics.new
|
198
|
+
@hand_statistics.should_receive(:reports).and_return(each_test)
|
199
|
+
@player_statistics.record(@hand_statistics)
|
200
|
+
end
|
201
|
+
@reports = @player_statistics.reports
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should produce a report with data for each player in the reports" do
|
205
|
+
players = {}
|
206
|
+
for each_hand in TEST
|
207
|
+
for each_player in each_hand.keys
|
208
|
+
players[each_player] = true
|
209
|
+
end
|
210
|
+
end
|
211
|
+
@reports.should have(players.size).keys
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should correctly aggregate aggression for each player" do
|
215
|
+
should_correctly_aggregate @reports, [:t_preflop_passive, :t_preflop_aggressive, :t_postflop_passive, :t_postflop_aggressive]
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should correctly aggregate blind attack statistics' do
|
219
|
+
should_correctly_aggregate @reports, [:t_blind_attack_opportunity, :t_blind_attack_opportunity_taken, :t_blind_defense_opportunity, :t_blind_defense_opportunity_taken]
|
220
|
+
end
|
221
|
+
it 'should correctly aggregate cash statistics' do
|
222
|
+
should_correctly_aggregate @reports, [:t_hands, :t_vpip, :t_posted, :t_paid, :t_won]
|
223
|
+
end
|
224
|
+
it 'should correctly aggregate continuation bet statistics' do
|
225
|
+
should_correctly_aggregate @reports, [:t_cbet_opportunity, :t_cbet_opportunity_taken]
|
226
|
+
end
|
227
|
+
it 'should correctly aggregate preflop raise statistics' do
|
228
|
+
should_correctly_aggregate @reports, [:t_pfr_opportunity, :t_pfr_opportunity_taken]
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'activesupport'
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/pokerstats/hand_history')
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/pokerstats/pokerstars_file')
|
6
|
+
include Pokerstats
|
7
|
+
|
8
|
+
describe PokerstarsFile, "when opened on an empty file" do
|
9
|
+
it "should complain" do
|
10
|
+
lambda{@psfile = PokerstarsFile.open(File.dirname(__FILE__) + '/file_empty.txt')}.should raise_error
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe PokerstarsFile, "when opened on a single-hand file" do
|
15
|
+
ONE_HAND_NUMBER_OF_ENTRIES = 1
|
16
|
+
|
17
|
+
ONE_HAND_ENTRY_NUMBER_OF_LINES = 50
|
18
|
+
ONE_HAND_ENTRY_FIRST_LINE = "PokerStars Game #24759011305: Tournament #139359808, $10+$1 Hold'em No Limit - Level I (10/20) - 2009/02/09 14:02:39 ET"
|
19
|
+
ONE_HAND_ENTRY_LAST_LINE = "Seat 9: MartinBOF84 folded before Flop (didn't bet)"
|
20
|
+
|
21
|
+
before do
|
22
|
+
@psfile = PokerstarsFile.open(File.dirname(__FILE__) + '/file_one_hand.txt')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be open" do
|
26
|
+
@psfile.should_not be_closed
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not be eof" do
|
30
|
+
@psfile.should_not be_eof
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should be at position zero" do
|
34
|
+
@psfile.pos.should be_zero
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should read all the hands in the test file" do
|
38
|
+
@psfile.should have(ONE_HAND_NUMBER_OF_ENTRIES).entries
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have an entry, answering to first, having the correct lines" do
|
42
|
+
@entry = @psfile.first
|
43
|
+
@entry.should have(ONE_HAND_ENTRY_NUMBER_OF_LINES).lines
|
44
|
+
@entry.lines[0].should == ONE_HAND_ENTRY_FIRST_LINE
|
45
|
+
@entry.lines[ONE_HAND_ENTRY_NUMBER_OF_LINES-1].should == ONE_HAND_ENTRY_LAST_LINE
|
46
|
+
@psfile.should be_closed
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should have an entry, answering to entries, having the correct lines" do
|
50
|
+
@entry = @psfile.entries.first
|
51
|
+
@entry.should have(ONE_HAND_ENTRY_NUMBER_OF_LINES).lines
|
52
|
+
@entry.lines.first.should == ONE_HAND_ENTRY_FIRST_LINE
|
53
|
+
@entry.lines.last.should == ONE_HAND_ENTRY_LAST_LINE
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should be at the end of file after reading the entry" do
|
57
|
+
@psfile.first
|
58
|
+
@psfile.should be_eof
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe PokerstarsFile, "when opened on a file encoded in Latin-1, should transliterate properly to ASCII" do
|
63
|
+
LATIN1_LINE_INDEX = 8
|
64
|
+
LATIN1_LINE_TRANSLITERATED = "Seat 8: Gw\"unni (3000 in chips) "
|
65
|
+
|
66
|
+
before do
|
67
|
+
@psfile = PokerstarsFile.open(File.dirname(__FILE__) + '/file_one_hand.txt')
|
68
|
+
@entry = @psfile.entries.first
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should properly transliterate the selected line" do
|
72
|
+
@entry.lines[LATIN1_LINE_INDEX].should == LATIN1_LINE_TRANSLITERATED
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe PokerstarsFile, "when opened on a multi-hand file" do
|
77
|
+
NUMBER_OF_ENTRIES = 12
|
78
|
+
|
79
|
+
FIRST_ENTRY_NUMBER_OF_LINES = 47
|
80
|
+
FIRST_ENTRY_FIRST_LINE = "PokerStars Game #21650146783: Hold'em No Limit ($0.25/$0.50) - 2008/10/31 17:14:44 ET"
|
81
|
+
FIRST_ENTRY_LAST_LINE = "Seat 9: ATTACCA folded before Flop (didn't bet)"
|
82
|
+
|
83
|
+
LAST_ENTRY_NUMBER_OF_LINES = 48
|
84
|
+
LAST_ENTRY_FIRST_LINE = "PokerStars Game #21650401569: Hold'em No Limit ($0.25/$0.50) - 2008/10/31 17:24:58 ET"
|
85
|
+
LAST_ENTRY_LAST_LINE = "Seat 9: ATTACCA folded before Flop (didn't bet)"
|
86
|
+
|
87
|
+
TABLE_OF_STARTING_INDICES = [0, 1526, 2997, 4594, 5939, 7650, 9174, 10740, 12137, 13446, 14589, 15823]
|
88
|
+
|
89
|
+
before do
|
90
|
+
@psfile = PokerstarsFile.open(File.dirname(__FILE__) + '/file_many_hands.txt')
|
91
|
+
@expanded_path = File.expand_path(File.dirname(__FILE__) + '/file_many_hands.txt')
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should be open" do
|
95
|
+
@psfile.should_not be_closed
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should not be eof" do
|
99
|
+
@psfile.should_not be_eof
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should read all the hands in the test file" do
|
103
|
+
@psfile.should have(NUMBER_OF_ENTRIES).entries
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should collect entries with all the proper information" do
|
107
|
+
list = TABLE_OF_STARTING_INDICES.clone
|
108
|
+
@psfile.entries.each do |handrecord|
|
109
|
+
handrecord.source.should == @expanded_path
|
110
|
+
handrecord.position.should == list.shift
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should be able to access records through valid positions" do
|
115
|
+
TABLE_OF_STARTING_INDICES.each do |index|
|
116
|
+
@entry = @psfile.first(index)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should complain when attempting to reach records through invalid positions" do
|
121
|
+
TABLE_OF_STARTING_INDICES.each do |index|
|
122
|
+
lambda {@psfile.pos=each+1}.should raise_error
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should have a first entry having the correct lines, addressable through #first" do
|
127
|
+
@psfile.entries #run through the file to see if it resets properly
|
128
|
+
@entry = @psfile.first(TABLE_OF_STARTING_INDICES.first)
|
129
|
+
@entry.should have(FIRST_ENTRY_NUMBER_OF_LINES).lines
|
130
|
+
@entry.lines.first.should == FIRST_ENTRY_FIRST_LINE
|
131
|
+
@entry.lines.last.should == FIRST_ENTRY_LAST_LINE
|
132
|
+
@psfile.should be_closed
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should have a first entry having the correct lines, addresable through #entries" do
|
136
|
+
@entries = @psfile.entries.first
|
137
|
+
@entries.should have(FIRST_ENTRY_NUMBER_OF_LINES).lines
|
138
|
+
@entries.lines.first.should == FIRST_ENTRY_FIRST_LINE
|
139
|
+
@entries.lines.last.should == FIRST_ENTRY_LAST_LINE
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should have a last entry having the correct lines, addressable through #first" do
|
143
|
+
@entry = @psfile.first(TABLE_OF_STARTING_INDICES.last)
|
144
|
+
@entry.should have(LAST_ENTRY_NUMBER_OF_LINES).lines
|
145
|
+
@entry.lines.first.should == LAST_ENTRY_FIRST_LINE
|
146
|
+
@entry.lines.last.should == LAST_ENTRY_LAST_LINE
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should have a last entry having the correct lines, addressable through #entries" do
|
150
|
+
@entries = @psfile.entries.last
|
151
|
+
@entries.should have(LAST_ENTRY_NUMBER_OF_LINES).lines
|
152
|
+
@entries.lines.first.should == LAST_ENTRY_FIRST_LINE
|
153
|
+
@entries.lines.last.should == LAST_ENTRY_LAST_LINE
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should be at the end of file after reading all the entries" do
|
157
|
+
@psfile.entries
|
158
|
+
@psfile.should be_eof
|
159
|
+
end
|
160
|
+
end
|