bgg 1.0.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/.document +5 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +54 -0
- data/LICENSE.txt +20 -0
- data/README.md +73 -0
- data/Rakefile +38 -0
- data/VERSION +1 -0
- data/bgg.gemspec +122 -0
- data/lib/bgg.rb +53 -0
- data/lib/bgg/collection.rb +58 -0
- data/lib/bgg/collection_item.rb +69 -0
- data/lib/bgg/game.rb +57 -0
- data/lib/bgg/play.rb +64 -0
- data/lib/bgg/plays.rb +26 -0
- data/lib/bgg/plays_iterator.rb +64 -0
- data/lib/bgg/search.rb +34 -0
- data/lib/bgg/search_result.rb +18 -0
- data/lib/bgg/user.rb +60 -0
- data/sample_data/collection?username=texasjdl +5224 -0
- data/sample_data/collection?username=texasjdl&own=1&excludesubtype=boardgameexpansion +2606 -0
- data/sample_data/collection?username=yyyyyyy +3 -0
- data/sample_data/hot?type=boardgame +253 -0
- data/sample_data/plays?pages=9999999999999&username=ryanmacg +2 -0
- data/sample_data/plays?username=beetss&page=1 +3 -0
- data/sample_data/plays?username=ryanmacg +504 -0
- data/sample_data/plays?username=texasjdl&id=84876 +192 -0
- data/sample_data/plays?username=texasjdl&id=84876&type=thing +199 -0
- data/sample_data/plays?username=texasjdl&page=1 +717 -0
- data/sample_data/plays?username=texasjdl&page=2 +709 -0
- data/sample_data/plays?username=texasjdl&page=3 +707 -0
- data/sample_data/plays?username=yyyyyyy&page=1 +667 -0
- data/sample_data/search?query=Burgun +47 -0
- data/sample_data/search?query=Burgun&exact=1 +3 -0
- data/sample_data/search?query=Burgund&type=boardgame +12 -0
- data/sample_data/search?query=The+Castles+of+Burgundy&exact=1 +7 -0
- data/sample_data/search?query=yyyyyyy +3 -0
- data/sample_data/thing?id=10000000&type=boardgame +3 -0
- data/sample_data/thing?id=29773&type=boardgame +90 -0
- data/sample_data/thing?id=70512&type=boardgame +82 -0
- data/sample_data/thing?id=84876&type=boardgame +82 -0
- data/sample_data/user?name=texasjdl +17 -0
- data/sample_data/user?name=yyyyyyy +17 -0
- data/spec/bgg_api_spec.rb +113 -0
- data/spec/bgg_collection_item_spec.rb +259 -0
- data/spec/bgg_collection_spec.rb +83 -0
- data/spec/bgg_game_spec.rb +232 -0
- data/spec/bgg_play_spec.rb +166 -0
- data/spec/bgg_plays_iterator_spec.rb +156 -0
- data/spec/bgg_plays_spec.rb +60 -0
- data/spec/bgg_search_result_spec.rb +73 -0
- data/spec/bgg_search_spec.rb +84 -0
- data/spec/bgg_user_spec.rb +113 -0
- data/spec/spec_helper.rb +29 -0
- 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
|