ruby-poker 0.3.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/ruby-poker.gemspec CHANGED
@@ -1,32 +1,30 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "ruby-poker"
3
- s.version = "0.3.1"
4
- s.date = "2009-01-24"
5
- s.rubyforge_project = "rubypoker"
3
+ s.version = "1.0.0"
6
4
  s.platform = Gem::Platform::RUBY
7
- s.summary = "Poker library in Ruby"
5
+ s.summary = "Poker library in Ruby"
8
6
  s.description = "Ruby library for comparing poker hands and determining the winner."
9
- s.author = "Rob Olson"
10
- s.email = "rko618@gmail.com"
11
- s.homepage = "http://github.com/robolson/ruby-poker"
12
- s.has_rdoc = true
7
+ s.author = "Rob Olson"
8
+ s.email = "rob@thinkingdigitally.com"
9
+ s.homepage = "https://github.com/robolson/ruby-poker"
10
+ s.license = 'BSD'
13
11
  s.files = ["CHANGELOG",
14
- "examples/deck.rb",
15
- "examples/quick_example.rb",
16
- "lib/card.rb",
17
- "lib/ruby-poker.rb",
18
- "LICENSE",
19
- "Rakefile",
20
- "README.rdoc",
21
- "ruby-poker.gemspec"]
22
- s.test_files = ["test/test_card.rb",
23
- "test/test_poker_hand.rb"]
12
+ "examples/deck.rb",
13
+ "examples/quick_example.rb",
14
+ "lib/ruby-poker.rb",
15
+ "lib/ruby-poker/card.rb",
16
+ "lib/ruby-poker/poker_hand.rb",
17
+ "LICENSE",
18
+ "Rakefile",
19
+ "README.rdoc",
20
+ "ruby-poker.gemspec"]
21
+ s.test_files = ["test/test_helper.rb", "test/test_card.rb", "test/test_poker_hand.rb"]
24
22
  s.require_paths << 'lib'
25
-
26
- s.extra_rdoc_files = ["README", "CHANGELOG", "LICENSE"]
23
+
24
+ s.extra_rdoc_files = ["README.rdoc", "CHANGELOG", "LICENSE"]
27
25
  s.rdoc_options << '--title' << 'Ruby Poker Documentation' <<
28
26
  '--main' << 'README.rdoc' <<
29
27
  '--inline-source' << '-q'
30
-
31
- # s.add_dependency("thoughtbot-shoulda", ["> 2.0.0"])
28
+
29
+ s.add_development_dependency('shoulda-context', '~> 1.1')
32
30
  end
data/test/test_card.rb CHANGED
@@ -7,29 +7,65 @@ class TestCard < Test::Unit::TestCase
7
7
  @c2 = Card.new("TD")
8
8
  @c3 = Card.new("jh")
9
9
  @c4 = Card.new("qS")
10
+ @c5 = Card.new("AC")
10
11
  end
11
-
12
- def test_build_from_card
13
- assert_equal("9c", Card.new(@c1).to_s)
14
- end
15
-
12
+
16
13
  def test_class_face_value
17
- assert_nil(Card.face_value('L'))
14
+ assert_equal(0, Card.face_value('L'))
18
15
  assert_equal(13, Card.face_value('A'))
19
16
  end
20
17
 
18
+ def test_build_from_card
19
+ assert_equal("9c", Card.new(@c1).to_s)
20
+ end
21
+
21
22
  def test_build_from_value
22
- assert_equal(@c1, Card.new(7))
23
+ assert_equal(@c1, Card.new(8))
23
24
  assert_equal(@c2, Card.new(22))
24
- assert_equal(@c3, Card.new(37))
25
- assert_equal(@c4, Card.new(52))
25
+ assert_equal(@c3, Card.new(36))
26
+ assert_equal(@c4, Card.new(50))
27
+ assert_equal(@c5, Card.new(13))
28
+ end
29
+
30
+ def test_build_from_face_suit
31
+ assert_equal(8, Card.new('9', 'c').value)
32
+ assert_equal(22, Card.new('T', 'd').value)
33
+ assert_equal(36, Card.new('J', 'h').value)
34
+ assert_equal(50, Card.new('Q', 's').value)
35
+ assert_equal(13, Card.new('A', 'c').value)
36
+ end
37
+
38
+ def test_build_from_value_and_from_face_suit_match
39
+ ticker = 0
40
+ Card::SUITS.each_char do |suit|
41
+ "23456789TJQKA".each_char do |face|
42
+ ticker += 1
43
+ from_value = Card.new(ticker)
44
+ from_face_suit = Card.new(face, suit)
45
+ assert_equal(from_face_suit, from_value,
46
+ "Face and suit #{face + suit} did not match card from value #{ticker}")
47
+ end
48
+ end
49
+ end
50
+
51
+ def test_build_from_value_and_from_face_suit_values_match
52
+ ticker = 0
53
+ 0.upto(3) do |suit|
54
+ 1.upto(13) do |face|
55
+ ticker += 1
56
+ from_value = Card.new(ticker)
57
+ from_face_suit_values = Card.new(face, suit)
58
+ assert_equal(from_face_suit_values, from_value,
59
+ "Face=#{face} and suit=#{suit} did not match card from value #{ticker}")
60
+ end
61
+ end
26
62
  end
27
63
 
28
64
  def test_face
29
65
  assert_equal(8, @c1.face)
30
66
  assert_equal(9, @c2.face)
31
67
  assert_equal(10, @c3.face)
32
- assert_equal(11, @c4.face)
68
+ assert_equal(11, @c4.face)
33
69
  end
34
70
 
35
71
  def test_suit
@@ -40,12 +76,13 @@ class TestCard < Test::Unit::TestCase
40
76
  end
41
77
 
42
78
  def test_value
43
- assert_equal(7, @c1.value)
79
+ assert_equal(8, @c1.value)
44
80
  assert_equal(22, @c2.value)
45
- assert_equal(37, @c3.value)
46
- assert_equal(52, @c4.value)
81
+ assert_equal(36, @c3.value)
82
+ assert_equal(50, @c4.value)
83
+ assert_equal(13, @c5.value)
47
84
  end
48
-
85
+
49
86
  def test_natural_value
50
87
  assert_equal(1, Card.new("AC").natural_value)
51
88
  assert_equal(15, Card.new("2D").natural_value)
@@ -56,14 +93,10 @@ class TestCard < Test::Unit::TestCase
56
93
  assert(@c1 < @c2)
57
94
  assert(@c3 > @c2)
58
95
  end
59
-
96
+
60
97
  def test_equals
61
98
  c = Card.new("9h")
62
99
  assert_not_equal(@c1, c)
63
100
  assert_equal(@c1, @c1)
64
101
  end
65
-
66
- def test_hash
67
- assert_equal(15, @c1.hash)
68
- end
69
- end
102
+ end
data/test/test_helper.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require 'rubygems'
2
+ require 'bundler/setup'
2
3
  require 'test/unit'
3
- require 'shoulda'
4
+ require 'shoulda-context'
4
5
 
5
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
- $LOAD_PATH.unshift(File.dirname(__FILE__))
7
- require 'ruby-poker'
6
+ require 'ruby-poker'
@@ -2,22 +2,62 @@ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
2
 
3
3
  class TestPokerHand < Test::Unit::TestCase
4
4
  context "A PokerHand instance" do
5
-
5
+
6
6
  setup do
7
- @trips = PokerHand.new("2D 9C AS AH AC")
7
+ @quads = PokerHand.new('Kc Kh Kd Ks Qs')
8
8
  @full_boat = PokerHand.new(["2H", "2D", "4C", "4D", "4S"])
9
9
  @flush = PokerHand.new("3D 6D 7D TD QD 5H 2S")
10
10
  @straight = PokerHand.new("8H 9D TS JH QC AS")
11
+ @trips = PokerHand.new("2D 9C AS AH AC")
12
+ @two_pair = PokerHand.new("As Ac Kc Kd 2s")
13
+ @pair = PokerHand.new("As Ac Kc Qd 2s")
14
+ @ace_high = PokerHand.new("As Jh 9c 7d 5s")
15
+ end
16
+
17
+ should "handle empty hands" do
18
+ assert_equal(PokerHand.new.rank, "Empty Hand")
19
+ end
20
+
21
+ should "handle single card hands" do
22
+ assert_equal(PokerHand.new('As').rank, @ace_high.rank)
23
+ end
24
+
25
+ should "handle two card hands" do
26
+ assert_equal(PokerHand.new('As Ac').rank, @pair.rank)
27
+ end
28
+
29
+ should "handle three card hands" do
30
+ assert_equal(PokerHand.new('As Ac Ah').rank, @trips.rank)
31
+ end
32
+
33
+ should "handle four card hands" do
34
+ assert_equal(PokerHand.new('As Ac Kd Kh').rank, @two_pair.rank)
35
+ assert_equal(PokerHand.new('As Ac Ad Ah').rank, @quads.rank)
36
+ end
37
+
38
+ should "handle lower case face card names" do
39
+ assert_equal(0, PokerHand.new('kc kd') <=> PokerHand.new('Kc Kd'))
40
+ assert_equal(0, PokerHand.new('kc kd') <=> PokerHand.new('Kc KD'))
41
+ end
42
+
43
+ should "handle hands without space" do
44
+ assert_equal(0, PokerHand.new('KcKd') <=> PokerHand.new('Kc Kd'))
45
+ assert_equal(0, PokerHand.new('KcKd9d') <=> PokerHand.new('Kc Kd 9d'))
46
+ end
47
+
48
+ should "raise a clear error with invalid cards" do
49
+ e = assert_raises(ArgumentError) { PokerHand.new('Fc') }
50
+ assert_match(/"Fc"/, e.message)
51
+ e = assert_raises(ArgumentError) { PokerHand.new('Tp') }
52
+ assert_match(/"Tp"/, e.message)
11
53
  end
12
-
13
- # there are a lot of combinations that should be tested here. I will add more
14
- # troublesome cases as I think of them.
54
+
15
55
  should "sort using rank" do
16
56
  assert_equal("As Ah Ac 9c 2d", @trips.sort_using_rank)
17
57
  assert_equal("4s 4d 4c 2h 2d", @full_boat.sort_using_rank)
18
58
  assert_equal("Qd Td 7d 6d 3d 2s 5h", @flush.sort_using_rank)
19
59
  assert_equal("Qc Jh Ts 9d 8h As", @straight.sort_using_rank)
20
-
60
+
21
61
  assert_equal("As Ah 3d 3c Kd", PokerHand.new("AS AH KD 3D 3C").sort_using_rank)
22
62
  assert_equal("As Ah 3d 3c 2d", PokerHand.new("2D AS AH 3D 3C").sort_using_rank)
23
63
  end
@@ -33,13 +73,13 @@ class TestPokerHand < Test::Unit::TestCase
33
73
  should "return just the face values of the cards" do
34
74
  assert_equal([1, 8, 13, 13, 13], @trips.face_values)
35
75
  end
36
-
76
+
37
77
  should "recognize a straight flush" do
38
78
  assert !@flush.straight_flush?
39
79
  assert !@straight.straight_flush?
40
80
  assert PokerHand.new("8H 9H TH JH QH AS").straight_flush?
41
81
  end
42
-
82
+
43
83
  should "recognize a royal flush" do
44
84
  assert !@flush.royal_flush?
45
85
  assert PokerHand.new("AD KD QD JD TD").royal_flush?
@@ -59,10 +99,13 @@ class TestPokerHand < Test::Unit::TestCase
59
99
  assert !@trips.full_house?
60
100
  assert @full_boat.full_house?
61
101
  end
62
-
102
+
63
103
  should "recognize a straight" do
64
104
  assert @straight.straight?
105
+ # ace low straight
65
106
  assert PokerHand.new("AH 2S 3D 4H 5D").straight?
107
+ # ace high straight
108
+ assert PokerHand.new("AH KS QD JH TD").straight?
66
109
  end
67
110
 
68
111
  should "recognize a three of a kind" do
@@ -73,12 +116,12 @@ class TestPokerHand < Test::Unit::TestCase
73
116
  assert PokerHand.new("2S 2D TH TD 4S").two_pair?
74
117
  assert !PokerHand.new("6D 7C 5D 5H 3S").two_pair?
75
118
  end
76
-
119
+
77
120
  should "recognize a pair" do
78
121
  assert !PokerHand.new("5C JC 2H 7S 3D").pair?
79
122
  assert PokerHand.new("6D 7C 5D 5H 3S").pair?
80
123
  end
81
-
124
+
82
125
  should "recognize a hand with the rank highest_card" do
83
126
  # hard to test, make sure it does not return null
84
127
  assert PokerHand.new("2D 4S 6C 8C TH").highest_card?
@@ -110,42 +153,42 @@ class TestPokerHand < Test::Unit::TestCase
110
153
  assert_match(/9c/, @trips.to_s)
111
154
  assert_no_match(/AD/, @trips.to_s)
112
155
  end
113
-
156
+
114
157
  should "return the correct number of cards in the hand" do
115
158
  assert_equal(0, PokerHand.new.size)
116
159
  assert_equal(1, PokerHand.new("2c").size)
117
160
  assert_equal(2, PokerHand.new("2c 3d").size)
118
161
  end
119
-
162
+
120
163
  should "be comparable to other PokerHands" do
121
164
  hand1 = PokerHand.new("5C JC 2H 5S 3D")
122
165
  hand2 = PokerHand.new("6D 7C 5D 5H 3S")
123
166
  assert_equal(1, hand1 <=> hand2)
124
167
  assert_equal(-1, hand2 <=> hand1)
125
168
  end
126
-
169
+
127
170
  should "be considered equal to other poker hands that contain the same cards" do
128
171
  assert_equal(0, @trips <=> @trips)
129
-
172
+
130
173
  hand1 = PokerHand.new("Ac Qc Ks Kd 9d 3c")
131
174
  hand2 = PokerHand.new("Ah Qs 9h Kh Kc 3s")
132
175
  assert_equal(0, hand1 <=> hand2)
133
176
  end
134
-
135
- should "be able to add a Card to itself" do
177
+
178
+ should "be able to insert new cards into the hand" do
136
179
  ph = PokerHand.new()
137
180
  ph << "Qd"
138
181
  ph << Card.new("2D")
139
182
  ph << ["3d", "4d"]
140
183
  assert_equal("Qd 2d 3d 4d", ph.just_cards)
141
184
  end
142
-
185
+
143
186
  should "be able to delete a card" do
144
187
  ph = PokerHand.new("Ac")
145
188
  ph.delete("Ac")
146
189
  assert_equal(Array.new, ph.hand)
147
190
  end
148
-
191
+
149
192
  should "detect the two highest pairs when there are more than two" do
150
193
  ph = PokerHand.new("7d 7s 4d 4c 2h 2d")
151
194
  assert_equal([3, 6, 3, 1], ph.two_pair?[0])
@@ -155,66 +198,333 @@ class TestPokerHand < Test::Unit::TestCase
155
198
  # 3: second highest pair is two 4's
156
199
  # 1: kicker is a 2
157
200
  end
158
-
201
+
159
202
  context "when duplicates are allowed" do
160
203
  setup do
161
204
  PokerHand.allow_duplicates = true
162
205
  end
163
-
206
+
164
207
  should "create a PokerHand of unique cards" do
165
208
  uniq_ph = PokerHand.new("3s 4s 3s").uniq
166
209
  assert_instance_of(PokerHand, uniq_ph) # want to be sure uniq hands back a PokerHand
167
210
  assert_contains(uniq_ph.hand, Card.new('3s'))
168
211
  assert_contains(uniq_ph.hand, Card.new('4s'))
169
212
  end
170
-
213
+
171
214
  should "allow five of a kind" do
172
215
  # there is no five of a kind. This just tests to make sure
173
216
  # that ruby-poker doesn't crash if given 5 of the same card
174
217
  ph = PokerHand.new("KS KS KS KS KS")
175
218
  assert_equal("Four of a kind", ph.rank)
176
219
  end
177
-
220
+
178
221
  should "allow duplicates on initialize" do
179
222
  assert_nothing_raised RuntimeError do
180
223
  PokerHand.new("3s 3s")
181
224
  end
182
225
  end
183
-
226
+
184
227
  should "allow duplicate card to be added after initialize" do
185
228
  ph = PokerHand.new("2d")
186
229
  ph << "2d"
187
230
  assert_equal("2d 2d", ph.just_cards)
188
231
  end
189
232
  end
190
-
233
+
191
234
  context "when duplicates are not allowed" do
192
235
  setup do
193
236
  PokerHand.allow_duplicates = false
194
237
  end
195
-
238
+
196
239
  should "not allow duplicates on initialize" do
197
240
  PokerHand.allow_duplicates = false
198
-
241
+
199
242
  assert_raise RuntimeError do
200
243
  PokerHand.new("3s 3s")
201
244
  end
202
-
245
+
203
246
  PokerHand.allow_duplicates = true
204
247
  end
205
-
248
+
206
249
  should "not allow duplicates after initialize" do
207
250
  PokerHand.allow_duplicates = false
208
-
209
- ph = PokerHand.new("2d")
251
+
252
+ ph = PokerHand.new("2d")
210
253
  assert_raise RuntimeError do
211
254
  ph << "2d"
212
255
  end
213
-
256
+
214
257
  PokerHand.allow_duplicates = true
215
258
  end
216
259
  end
217
-
260
+
261
+ should "have an each method" do
262
+ cards = []
263
+ @straight.each do |card|
264
+ cards << card
265
+ end
266
+ assert_equal @straight.to_a, cards
267
+ end
268
+
269
+ should "be Enumerable" do
270
+ assert PokerHand.include?(Enumerable)
271
+ end
218
272
  end
219
- end
220
273
 
274
+ context "addition" do
275
+ setup do
276
+ @base = PokerHand.new('Ac Kc')
277
+ end
278
+
279
+ should "work with a string" do
280
+ assert_equal PokerHand.new('Ac Kc Qc'), @base + 'Qc'
281
+ end
282
+
283
+ should "work with a card" do
284
+ assert_equal PokerHand.new('Ac Kc Qc'), @base + Card.new('Qc')
285
+ end
286
+
287
+ should "work with a hand" do
288
+ assert_equal PokerHand.new('Ac Kc Qc'), @base + PokerHand.new('Qc')
289
+ end
290
+
291
+ should "not modify the receiver hand" do
292
+ result = @base + 'Qc'
293
+ assert_not_equal result, @base
294
+ end
295
+
296
+ should "not affect receiver cards" do
297
+ result = @base + 'Qc'
298
+ result.to_a.first.instance_eval { @face = Card.face_value('2') }
299
+ assert_equal PokerHand.new('Ac Kc'), @base
300
+ end
301
+ end
302
+
303
+ context "PokerHand#pair?" do
304
+
305
+ should "return false with one card" do
306
+ assert !PokerHand.new("2h").pair?
307
+ end
308
+
309
+ context "with a pair" do
310
+
311
+ should "return 2, followed by the pair value" do
312
+ assert_equal [2, 5-1], PokerHand.new("5h 5s").pair?[0]
313
+ end
314
+
315
+ context "with a two card hand" do
316
+ setup do
317
+ @ph = PokerHand.new("5h 5s")
318
+ @scoring = @ph.pair?[0]
319
+ end
320
+
321
+ should "return scoring with 2 entries" do
322
+ assert_equal 2, @scoring.size
323
+ end
324
+ end
325
+
326
+ context "with a three card hand" do
327
+ setup do
328
+ @ph = PokerHand.new("5h 5s 8s")
329
+ @scoring = @ph.pair?[0]
330
+ end
331
+
332
+ should "return scoring with 3 entries" do
333
+ assert_equal 3, @scoring.size
334
+ end
335
+
336
+ should "return the value of the kicker" do
337
+ assert_equal 8-1, @scoring[2]
338
+ end
339
+ end
340
+
341
+ context "with a four card hand" do
342
+ setup do
343
+ @ph = PokerHand.new("5h 5s 8s 7s")
344
+ @scoring = @ph.pair?[0]
345
+ end
346
+
347
+ should "return scoring with 4 entries" do
348
+ assert_equal 4, @scoring.size
349
+ end
350
+
351
+ should "return the values of the kickers" do
352
+ assert_equal 8-1, @scoring[2]
353
+ assert_equal 7-1, @scoring[3]
354
+ end
355
+ end
356
+
357
+ context "with a five (or more) card hand" do
358
+ setup do
359
+ @ph = PokerHand.new("5h 5s 8s 7s 6s 2h")
360
+ @scoring = @ph.pair?[0]
361
+ end
362
+
363
+ should "return scoring with 5 entries" do
364
+ assert_equal 5, @scoring.size
365
+ end
366
+
367
+ should "return the values of the kickers" do
368
+ assert_equal 8-1, @scoring[2]
369
+ assert_equal 7-1, @scoring[3]
370
+ assert_equal 6-1, @scoring[4]
371
+ end
372
+ end
373
+ end
374
+
375
+ context "without a pair" do
376
+ should "return false" do
377
+ assert !PokerHand.new("2h 3h").pair?
378
+ end
379
+ end
380
+ end
381
+
382
+
383
+ def assert_hand_match(expression, cards)
384
+ hand = PokerHand.new(cards)
385
+ assert hand.match?(expression), "#{cards} didn't match #{expression}"
386
+ end
387
+
388
+ def assert_hand_not_match(expression, cards)
389
+ hand = PokerHand.new(cards)
390
+ assert !hand.match?(expression), "#{cards} did match #{expression}"
391
+ end
392
+
393
+ context "matching expression" do
394
+ should "match two faces" do
395
+ assert_hand_match 'AA', 'Ah Ad'
396
+ assert_hand_match 'Q8', 'Qc 8d'
397
+ end
398
+
399
+ should "not match two faces" do
400
+ assert_hand_not_match 'T9', 'Tc 8s'
401
+ assert_hand_not_match 'QQ', 'Tc 8s'
402
+ end
403
+
404
+ should "match unordered faces" do
405
+ assert_hand_match 'K7', '7c Ks'
406
+ end
407
+
408
+ should "match suited when suited" do
409
+ assert_hand_match 'Q8s', 'Qc 8c'
410
+ assert_hand_match '56s', '5h 6h'
411
+ end
412
+
413
+ should "not match suited when offsuit" do
414
+ assert_hand_not_match 'Q8s', 'Qc 8d'
415
+ assert_hand_not_match '56s', '5h 6c'
416
+ end
417
+
418
+ should "match offsuit when offsuited" do
419
+ assert_hand_match 'Q8o', 'Qc 8h'
420
+ assert_hand_match '56o', '5h 6s'
421
+ end
422
+
423
+ should "not match offsuit when suited" do
424
+ assert_hand_not_match 'Q8o', 'Qc 8c'
425
+ assert_hand_not_match '56o', '5h 6h'
426
+ end
427
+
428
+ should "match pair min" do
429
+ assert_hand_match 'JJ+', 'Jc Js'
430
+ assert_hand_match '66+', 'Qc Qh'
431
+ assert_hand_match 'JJ+', 'Ad Ac'
432
+ end
433
+
434
+ should "not match pair min" do
435
+ assert_hand_not_match 'JJ+', 'Tc Ts'
436
+ assert_hand_not_match '66+', 'Qc Kh'
437
+ assert_hand_not_match 'AA+', '2d 2c'
438
+ end
439
+
440
+ should "match face min" do
441
+ assert_hand_match 'AJ+', 'Ac Js'
442
+ assert_hand_match 'AQ+', 'Ac Kc'
443
+ assert_hand_match 'AJ+', 'Ac As'
444
+ assert_hand_match 'QT+', 'Qc Ts'
445
+ assert_hand_match 'QT+', 'Qc Qs'
446
+ assert_hand_not_match 'QT+', 'Qc Ks' # sure? should be matched with KQ+?
447
+ assert_hand_not_match 'AJ+', 'Ac Ts'
448
+ assert_hand_not_match 'AJ+', 'Tc Ts'
449
+ end
450
+
451
+ should "match suited face min" do
452
+ assert_hand_match 'AJs+', 'Ac Jc'
453
+ assert_hand_match 'AQs+', 'Ac Kc'
454
+ assert_hand_not_match 'AJs+', 'Ac As'
455
+ assert_hand_match 'QTs+', 'Qc Tc'
456
+ assert_hand_not_match 'QTs+', 'Qc Ts'
457
+ assert_hand_not_match 'AJs+', 'Ac Qs'
458
+ end
459
+
460
+ should "match offsuit face min" do
461
+ assert_hand_match 'AJo+', 'Ac Jd'
462
+ assert_hand_match 'AQo+', 'Ac Kh'
463
+ assert_hand_match 'AJo+', 'Ac As'
464
+ assert_hand_match 'QTo+', 'Qc Td'
465
+ assert_hand_not_match 'QTo+', 'Qc Tc'
466
+ assert_hand_not_match 'AJo+', 'Ac Qc'
467
+ end
468
+
469
+ should "match face with 1 gap" do
470
+ assert_hand_match '89+', '8c 9d'
471
+ assert_hand_match '89+', '9c Td'
472
+ assert_hand_match '89+', 'Tc Jd'
473
+ assert_hand_match '89+', 'Ac Kd'
474
+ assert_hand_not_match '89+', '8c Td'
475
+ assert_hand_not_match '89+', 'Tc Td'
476
+ assert_hand_not_match '89+', '7c 8d'
477
+ end
478
+
479
+ should "match face with 2 gaps" do
480
+ assert_hand_match '8T+', '8c Td'
481
+ assert_hand_match '8T+', 'Tc 8d'
482
+ assert_hand_match '24+', '9c Jd'
483
+ assert_hand_match '79+', 'Ac Qd'
484
+ assert_hand_not_match '8T+', '8c 9d'
485
+ assert_hand_not_match '8T+', 'Tc Td'
486
+ assert_hand_not_match '8T+', 'Jc Ad'
487
+ assert_hand_not_match '8T+', '7c 9d'
488
+ end
489
+
490
+ should "match face with many gaps" do
491
+ assert_hand_match '8J+', '9c Qd'
492
+ assert_hand_match '8Q+', '9c Kd'
493
+ assert_hand_match '8K+', 'Ac 9d'
494
+ assert_hand_not_match '8J+', '7c Td'
495
+ end
496
+
497
+ should "match face gap with suit" do
498
+ assert_hand_match '89s+', '9c Tc'
499
+ assert_hand_not_match '89s+', '9c Td'
500
+ assert_hand_match '89o+', '9c Th'
501
+ assert_hand_not_match '89o+', '9d Td'
502
+ end
503
+
504
+ [
505
+ %w(),
506
+ %w(Ac),
507
+ %w(Ac Kc Qc),
508
+ %w(Ac Kc Qc Jc Tc),
509
+ ].each do |cards|
510
+ should "raise an error if the number of cards is #{cards.size}" do
511
+ hand = PokerHand.new(cards)
512
+ assert_raises RuntimeError do
513
+ hand.match?('AA')
514
+ end
515
+ end
516
+ end
517
+
518
+ should "raise an error with invalid expression" do
519
+ hand = PokerHand.new("Ac Kc")
520
+ assert_raises ArgumentError do
521
+ hand.match? "foo"
522
+ end
523
+
524
+ assert_raises ArgumentError do
525
+ hand.match? ""
526
+ end
527
+ end
528
+ end
529
+
530
+ end