bgg 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +20 -0
  6. data/Gemfile.lock +54 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.md +73 -0
  9. data/Rakefile +38 -0
  10. data/VERSION +1 -0
  11. data/bgg.gemspec +122 -0
  12. data/lib/bgg.rb +53 -0
  13. data/lib/bgg/collection.rb +58 -0
  14. data/lib/bgg/collection_item.rb +69 -0
  15. data/lib/bgg/game.rb +57 -0
  16. data/lib/bgg/play.rb +64 -0
  17. data/lib/bgg/plays.rb +26 -0
  18. data/lib/bgg/plays_iterator.rb +64 -0
  19. data/lib/bgg/search.rb +34 -0
  20. data/lib/bgg/search_result.rb +18 -0
  21. data/lib/bgg/user.rb +60 -0
  22. data/sample_data/collection?username=texasjdl +5224 -0
  23. data/sample_data/collection?username=texasjdl&own=1&excludesubtype=boardgameexpansion +2606 -0
  24. data/sample_data/collection?username=yyyyyyy +3 -0
  25. data/sample_data/hot?type=boardgame +253 -0
  26. data/sample_data/plays?pages=9999999999999&username=ryanmacg +2 -0
  27. data/sample_data/plays?username=beetss&page=1 +3 -0
  28. data/sample_data/plays?username=ryanmacg +504 -0
  29. data/sample_data/plays?username=texasjdl&id=84876 +192 -0
  30. data/sample_data/plays?username=texasjdl&id=84876&type=thing +199 -0
  31. data/sample_data/plays?username=texasjdl&page=1 +717 -0
  32. data/sample_data/plays?username=texasjdl&page=2 +709 -0
  33. data/sample_data/plays?username=texasjdl&page=3 +707 -0
  34. data/sample_data/plays?username=yyyyyyy&page=1 +667 -0
  35. data/sample_data/search?query=Burgun +47 -0
  36. data/sample_data/search?query=Burgun&exact=1 +3 -0
  37. data/sample_data/search?query=Burgund&type=boardgame +12 -0
  38. data/sample_data/search?query=The+Castles+of+Burgundy&exact=1 +7 -0
  39. data/sample_data/search?query=yyyyyyy +3 -0
  40. data/sample_data/thing?id=10000000&type=boardgame +3 -0
  41. data/sample_data/thing?id=29773&type=boardgame +90 -0
  42. data/sample_data/thing?id=70512&type=boardgame +82 -0
  43. data/sample_data/thing?id=84876&type=boardgame +82 -0
  44. data/sample_data/user?name=texasjdl +17 -0
  45. data/sample_data/user?name=yyyyyyy +17 -0
  46. data/spec/bgg_api_spec.rb +113 -0
  47. data/spec/bgg_collection_item_spec.rb +259 -0
  48. data/spec/bgg_collection_spec.rb +83 -0
  49. data/spec/bgg_game_spec.rb +232 -0
  50. data/spec/bgg_play_spec.rb +166 -0
  51. data/spec/bgg_plays_iterator_spec.rb +156 -0
  52. data/spec/bgg_plays_spec.rb +60 -0
  53. data/spec/bgg_search_result_spec.rb +73 -0
  54. data/spec/bgg_search_spec.rb +84 -0
  55. data/spec/bgg_user_spec.rb +113 -0
  56. data/spec/spec_helper.rb +29 -0
  57. metadata +241 -0
@@ -0,0 +1,166 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe Bgg::Play do
5
+ describe 'instance' do
6
+ let(:item_data) { {'id'=>'7680984',
7
+ 'date'=>'2012-06-23',
8
+ 'quantity'=>'1',
9
+ 'length'=>'0',
10
+ 'incomplete'=>'0',
11
+ 'nowinstats'=>'0',
12
+ 'location'=>'',
13
+ 'item'=>[{'name'=>'Cheeky Monkey', 'objecttype'=>'thing', 'objectid'=>'29773', 'subtypes'=>[{'subtype'=>[{'value'=>'boardgame'}]}]}]} }
14
+
15
+ let(:item) { Bgg::Play.new(item_data) }
16
+
17
+ describe '.id' do
18
+ it 'exists' do
19
+ expect( item ).to respond_to(:id)
20
+ end
21
+
22
+ it 'returns correct value' do
23
+ expect( item.id ).to eq(7680984)
24
+ end
25
+ end
26
+
27
+ describe '.date' do
28
+ it 'exists' do
29
+ expect( item ).to respond_to(:date)
30
+ end
31
+
32
+ # FIXME: should move to an actual date object
33
+ it 'returns the correct value' do
34
+ expect( item.date ).to eq('2012-06-23')
35
+ end
36
+ end
37
+
38
+ describe '.quantity' do
39
+ it 'exists' do
40
+ expect( item ).to respond_to(:quantity)
41
+ end
42
+
43
+ it 'returns the correct value' do
44
+ expect( item.quantity ).to eq(1)
45
+ end
46
+ end
47
+
48
+ describe '.length' do
49
+ it 'exists' do
50
+ expect( item ).to respond_to(:length)
51
+ end
52
+
53
+ it 'returns the correct value' do
54
+ expect( item.length ).to eq(0)
55
+ end
56
+ end
57
+
58
+ describe '.incomplete?' do
59
+ it 'exists' do
60
+ expect( item ).to respond_to(:incomplete?)
61
+ end
62
+
63
+ it 'returns true when incomplete == 0' do
64
+ item_data['incomplete'] = '0'
65
+ expect( item.incomplete? ).to eq(false)
66
+ end
67
+
68
+ it 'returns true when incomplete == 1' do
69
+ item_data['incomplete'] = '1'
70
+ expect( item.incomplete? ).to eq(true)
71
+ end
72
+ end
73
+
74
+ describe '.location' do
75
+ it 'exists' do
76
+ expect( item ).to respond_to(:location)
77
+ end
78
+
79
+ it 'returns empty string when it is empty' do
80
+ expect( item.location ).to eq('')
81
+ end
82
+
83
+ it 'returns a string when it is filled in' do
84
+ item_data['location'] = 'BGGCon!'
85
+ expect( item.location ).to eq('BGGCon!')
86
+ end
87
+ end
88
+
89
+ describe '.nowinstats?' do
90
+ it 'exists' do
91
+ expect( item ).to respond_to(:nowinstats?)
92
+ end
93
+
94
+ it 'returns true when nowinstats == 1' do
95
+ item_data['nowinstats'] = '1'
96
+ expect( item.nowinstats? ).to eq(true)
97
+ end
98
+
99
+ it 'returns false when nowinstats == 0' do
100
+ item_data['nowinstats'] = '0'
101
+ expect( item.nowinstats? ).to eq(false)
102
+ end
103
+ end
104
+
105
+ describe '.players' do
106
+ it 'exists' do
107
+ expect( item ).to respond_to(:players)
108
+ end
109
+
110
+ it 'returns the list of players' do
111
+ expect( item.players ).to match_array([])
112
+ end
113
+ end
114
+
115
+ describe '.game_name' do
116
+ it 'exists' do
117
+ expect( item ).to respond_to(:game_name)
118
+ end
119
+
120
+ it 'returns the correct value' do
121
+ expect( item.game_name ).to eq('Cheeky Monkey')
122
+ end
123
+ end
124
+
125
+ describe '.game_id' do
126
+ it 'exists' do
127
+ expect( item ).to respond_to(:game_id)
128
+ end
129
+
130
+ it 'returns the correct value' do
131
+ expect( item.game_id ).to eq(29773)
132
+ end
133
+ end
134
+
135
+ describe '.game_type' do
136
+ it 'exists' do
137
+ expect( item ).to respond_to(:game_type)
138
+ end
139
+
140
+ it 'returns the correct value' do
141
+ expect( item.game_type ).to eq('boardgame')
142
+ end
143
+ end
144
+
145
+ describe '.game' do
146
+ it 'exists' do
147
+ expect( item ).to respond_to(:game)
148
+ end
149
+
150
+ it 'returns a Bgg::Game object corresponding to the entry' do
151
+ response_file = 'sample_data/thing?id=29773&type=boardgame'
152
+ request_url = 'http://www.boardgamegeek.com/xmlapi2/thing'
153
+
154
+ stub_request(:any, request_url).
155
+ with(query: {id: 29773, type: 'boardgame'}).
156
+ to_return(body: File.open(response_file), status: 200)
157
+
158
+ game = item.game
159
+
160
+ expect( game ).to be_instance_of(Bgg::Game)
161
+ expect( game.name ).to eq('Cheeky Monkey')
162
+ expect( game.designers ).to eq(['Reiner Knizia'])
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,156 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe Bgg::Plays::Iterator do
5
+ describe 'instance' do
6
+ let(:username) { 'texasjdl' }
7
+ let(:request_url) { 'http://www.boardgamegeek.com/xmlapi2/plays' }
8
+ let(:query) { {username: username, page: 1} }
9
+ let(:response_file) { "sample_data/plays?username=#{username}&page=1" }
10
+ let(:iterator) { Bgg::Plays::Iterator.new(username) }
11
+
12
+ before do
13
+ stub_request(:any, request_url).
14
+ with(query: query).
15
+ to_return(body: File.open(response_file), status: 200)
16
+ end
17
+
18
+ it 'is Enumerable' do
19
+ expect( iterator ).to be_a_kind_of(Enumerable)
20
+ end
21
+
22
+ context 'when the user has no plays' do
23
+ let(:username) { 'beetss' }
24
+ it 'returns an empty iterator' do
25
+ expect( iterator.empty? ).to eq(true)
26
+ end
27
+ end
28
+
29
+ context 'when the user does not exist' do
30
+ let(:username) { 'yyyyyyy' }
31
+ it 'returns an empty iterator' do
32
+ expect{ iterator }.to raise_error(ArgumentError, 'user does not exist')
33
+ end
34
+ end
35
+
36
+ context 'when the user exists and has plays' do
37
+ it 'returns an instance' do
38
+ expect( iterator ).to be_instance_of(Bgg::Plays::Iterator)
39
+ end
40
+ end
41
+
42
+ describe '.each' do
43
+ it 'exists' do
44
+ expect( iterator ).to respond_to(:each)
45
+ end
46
+
47
+ it 'allows stepping through results' do
48
+ iterator.each do |item|
49
+ expect( item ).to be_instance_of(Bgg::Play)
50
+ break if iterator.iteration == 3
51
+ end
52
+ end
53
+
54
+ it 'only allows stepping through the results once' do
55
+ iterator.each { break if iterator.iteration == 2 }
56
+ iterator.each { fail }
57
+ end
58
+
59
+ it 'returns multiple pages of results' do
60
+ [2,3].each do |i|
61
+ stub_request(:any, request_url).
62
+ with(query: {username: username, page: i}).
63
+ to_return(body: File.open("sample_data/plays?username=#{username}&page=#{i}"),
64
+ status: 200)
65
+ end
66
+
67
+ iterator.each { }
68
+ expect( iterator.iteration ).to eq(299)
69
+ end
70
+ end
71
+
72
+ describe '.iteration' do
73
+ it 'exists' do
74
+ expect( iterator ).to respond_to(:iteration)
75
+ end
76
+
77
+ it 'returns the maximum value when the iterator is exhausted' do
78
+ count = 0
79
+ iterator.each do |item|
80
+ count += 1
81
+ expect( iterator.iteration ).to eq(count)
82
+ break if iterator.iteration == 3
83
+ end
84
+ end
85
+
86
+ it 'returns the current iteration through the block' do
87
+ count = 0
88
+ iterator.each do |item|
89
+ count += 1
90
+ expect( iterator.iteration ).to eq(count)
91
+ break if iterator.iteration == 3
92
+ end
93
+ end
94
+
95
+ context 'when the iterator starts empty,' do
96
+ let(:username) { 'beetss' }
97
+ it 'returns 0' do
98
+ expect( iterator.iteration ).to eq(0)
99
+ end
100
+ end
101
+ end
102
+
103
+ describe '.empty?' do
104
+ it 'exists' do
105
+ expect( iterator ).to respond_to(:empty?)
106
+ end
107
+
108
+ context 'when the iterator has no results' do
109
+ let(:username) { 'beetss' }
110
+ it 'returns true' do
111
+ expect( iterator.empty? ).to eq(true)
112
+ end
113
+ end
114
+
115
+ context 'when the iterator has results' do
116
+ it 'returns false' do
117
+ expect( iterator.empty? ).to eq(false)
118
+ end
119
+ end
120
+
121
+ context 'when the iterator has paged through results' do
122
+ it 'returns true if each() has already reached the end' do
123
+ [2,3].each do |i|
124
+ stub_request(:any, request_url).
125
+ with(query: {username: username, page: i}).
126
+ to_return(body: File.open("sample_data/plays?username=#{username}&page=#{i}"),
127
+ status: 200)
128
+ end
129
+
130
+ iterator.each{ }
131
+ expect( iterator.empty? ).to eq(true)
132
+ end
133
+ end
134
+ end
135
+
136
+ describe '.total_count' do
137
+ it 'exists' do
138
+ expect( iterator ).to respond_to(:total_count)
139
+ end
140
+
141
+ context 'when the user has no plays' do
142
+ let(:username) { 'beetss' }
143
+ it 'returns 0' do
144
+ expect( iterator.total_count ).to eq(0)
145
+ end
146
+ end
147
+
148
+ context 'when the user has plays' do
149
+ let(:username) { 'texasjdl' }
150
+ it 'returns the correct count' do
151
+ expect( iterator.total_count ).to eq(299)
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe Bgg::Plays do
5
+ describe 'class method' do
6
+ describe 'find_by_username' do
7
+ it 'throws an ArgumentError when a number is passed in' do
8
+ expect{ Bgg::Collection.find_by_username(38383) }.to raise_error(ArgumentError)
9
+ end
10
+
11
+ it 'throws an ArgumentError when an empty string is passed in' do
12
+ expect{ Bgg::Collection.find_by_username('') }.to raise_error(ArgumentError)
13
+ end
14
+
15
+ it 'throws an ArgumentError when a string of only numbers is passed in' do
16
+ expect{ Bgg::Collection.find_by_username('38383') }.to raise_error(ArgumentError)
17
+ end
18
+
19
+ it 'throws an ArgumentError when a non-existent user is passed in' do
20
+ response_file = 'sample_data/plays?username=yyyyyyy&page=1'
21
+ request_url = 'http://www.boardgamegeek.com/xmlapi2/plays'
22
+
23
+ stub_request(:any, request_url).
24
+ with(query: {username: 'yyyyyyy', page: 1}).
25
+ to_return(body: File.open(response_file), status: 200)
26
+
27
+ expect{ Bgg::Plays.find_by_username('yyyyyyy') }.to raise_error(ArgumentError)
28
+ end
29
+
30
+ it 'returns an empty iterator when a valid user has no plays' do
31
+ response_file = 'sample_data/plays?username=beetss&page=1'
32
+ request_url = 'http://www.boardgamegeek.com/xmlapi2/plays'
33
+
34
+ stub_request(:any, request_url).
35
+ with(query: {username: 'beetss', page: 1}).
36
+ to_return(body: File.open(response_file), status: 200)
37
+
38
+ iterator = Bgg::Plays.find_by_username('beetss')
39
+ expect( iterator ).to be_an_instance_of(Bgg::Plays::Iterator)
40
+ expect( iterator.empty? ).to eq(true)
41
+ end
42
+
43
+ it 'creates a Bgg::Plays::Iterator object for a user who has plays' do
44
+ response_file = 'sample_data/plays?username=texasjdl&page=1'
45
+ request_url = 'http://www.boardgamegeek.com/xmlapi2/plays'
46
+
47
+ stub_request(:any, request_url).
48
+ with(query: {username: 'texasjdl', page: 1}).
49
+ to_return(body: File.open(response_file), status: 200)
50
+
51
+ plays = Bgg::Plays.find_by_username('texasjdl')
52
+ first_play = plays.first
53
+
54
+ expect( plays ).to be_a_kind_of(Bgg::Plays::Iterator)
55
+ expect( first_play ).to be_instance_of(Bgg::Play)
56
+ expect( first_play.players ).to be_instance_of(Array)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe Bgg::Search::Result do
5
+ describe 'instance' do
6
+ let(:item_data) { {'type'=>'boardgame',
7
+ 'id'=>'84876',
8
+ 'name'=>[{'type'=>'primary', 'value'=>'The Castles of Burgundy'}],
9
+ 'yearpublished'=>[{'value'=>'2011'}]} }
10
+ let(:search_result) { Bgg::Search::Result.new(item_data) }
11
+
12
+ describe '.id' do
13
+ it 'exists' do
14
+ expect( search_result ).to respond_to(:id)
15
+ end
16
+
17
+ it 'returns correct value' do
18
+ expect( search_result.id ).to eq(84876)
19
+ end
20
+ end
21
+
22
+ describe '.name' do
23
+ it 'exists' do
24
+ expect( search_result ).to respond_to(:name)
25
+ end
26
+
27
+ it 'returns the correct value' do
28
+ expect( search_result.name ).to eq('The Castles of Burgundy')
29
+ end
30
+ end
31
+
32
+ describe '.type' do
33
+ it 'exists' do
34
+ expect( search_result ).to respond_to(:type)
35
+ end
36
+
37
+ it 'returns boardgame when it is a boardgame' do
38
+ expect( search_result.type ).to eq('boardgame')
39
+ end
40
+ end
41
+
42
+ describe '.year_published' do
43
+ it 'exists' do
44
+ expect( search_result ).to respond_to(:year_published)
45
+ end
46
+
47
+ it 'returns the year it was published' do
48
+ expect( search_result.year_published ).to eq(2011)
49
+ end
50
+ end
51
+
52
+ describe '.game' do
53
+ it 'exists' do
54
+ expect( search_result ).to respond_to(:game)
55
+ end
56
+
57
+ it 'returns a Bgg::Game object corresponding to the entry' do
58
+ response_file = 'sample_data/thing?id=84876&type=boardgame'
59
+ request_url = 'http://www.boardgamegeek.com/xmlapi2/thing'
60
+
61
+ stub_request(:any, request_url).
62
+ with(query: {id: 84876, type: 'boardgame'}).
63
+ to_return(body: File.open(response_file), status: 200)
64
+
65
+ game = search_result.game
66
+
67
+ expect( game ).to be_instance_of(Bgg::Game)
68
+ expect( game.name ).to eq('The Castles of Burgundy')
69
+ expect( game.designers ).to eq(['Stefan Feld'])
70
+ end
71
+ end
72
+ end
73
+ end