luchadeer 0.1.0 → 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 +4 -4
- data/README.md +21 -7
- data/lib/luchadeer/client.rb +1 -4
- data/lib/luchadeer/search.rb +46 -5
- data/lib/luchadeer/version.rb +1 -1
- data/spec/luchadeer/search_spec.rb +147 -12
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfbc3969949f80b2c6fe14722317f9b88cbdb31e
|
4
|
+
data.tar.gz: f1ad8f45243b83a111039bbf6dc5263f6342edb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 769594975368dc99024b093ae1027068e8d659c43833f6d4b8e47b702959e9dcd696bbd6a483251a3b13dae49b7fbf6367f5a1934f4cc50aa145b419ca381b63
|
7
|
+
data.tar.gz: 8124aef0e0a7062d4d5ee373ab196d1a34f64381fb9cf748d228acbd432be0a816802987a08249c14cf7ebc475119131c14f6aea4020ff3ddcf288f84471edbf
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[][coverage]
|
5
5
|
[][grade]
|
6
6
|
|
7
|
-
[build]:
|
7
|
+
[build]: https://travis-ci.org/paulfri/luchadeer
|
8
8
|
[coverage]: https://coveralls.io/r/paulfri/luchadeer?branch=master
|
9
9
|
[grade]: https://codeclimate.com/github/paulfri/luchadeer
|
10
10
|
|
@@ -18,16 +18,13 @@ The bombingest Giant Bomb API client library for Ruby.
|
|
18
18
|
5. Thread-ready (thready?): no global or class state. Use convenience methods to use a default client per-thread, or use an alternate syntax for full control.
|
19
19
|
|
20
20
|
## Configuration
|
21
|
-
Get your API key [here](http://www.giantbomb.com/api).
|
21
|
+
Get your API key [here](http://www.giantbomb.com/api). If you have a premium account, your API key should give you access to subscriber-only video resources, as well as links to HD-quality videos.
|
22
22
|
|
23
23
|
```ruby
|
24
24
|
Luchadeer.configure(api_key: 'my_api_key') # default client for this thread
|
25
25
|
Luchadeer::Client.new(api_key: 'my_api_key')
|
26
|
-
```
|
27
|
-
|
28
|
-
You can also pass a block to either method, and it will yield the client object to configure to your liking.
|
29
26
|
|
30
|
-
|
27
|
+
# You can also pass a block to either method, and it will yield the client object to configure to your liking.
|
31
28
|
Luchadeer.configure do |client|
|
32
29
|
client.api_key = 'my_api_key'
|
33
30
|
end
|
@@ -47,12 +44,29 @@ end
|
|
47
44
|
## Usage
|
48
45
|
|
49
46
|
```ruby
|
47
|
+
# Resources
|
50
48
|
Luchadeer::Game.find(21373) # or...
|
51
49
|
my_client.game(21373) # => #<Luchadeer::Game name="Shin Megami Tensei: Persona 4" ...>
|
50
|
+
|
51
|
+
# Search: mix and match whatever syntax you like
|
52
|
+
Luchadeer::Search.new(page: 1, limit: 50, query: 'valkyria').fetch
|
53
|
+
|
54
|
+
search = Luchadeer::Search.new
|
55
|
+
search.page(1).limit(50).sort('name', :desc)
|
56
|
+
search.resources([Luchadeer::Game, Luchadeer::Character])
|
57
|
+
search.query('valkyria')
|
58
|
+
search.fetch
|
59
|
+
|
60
|
+
Luchadeer::Search.new { |s|
|
61
|
+
s.query = 'valkyria'
|
62
|
+
s.page = 1
|
63
|
+
s.limit = 50
|
64
|
+
}.fetch
|
52
65
|
```
|
53
66
|
|
54
67
|
## TODO
|
55
|
-
1. Add filtering to search.
|
68
|
+
1. Add custom filtering to search (i.e., the 'filter' request parameter).
|
56
69
|
2. Add per-resource searching class methods on each resource object.
|
57
70
|
3. Refactor the test suite with shared example groups.
|
58
71
|
4. Make the caching layer more flexible - more options besides in-memory store. Add a null store, too.
|
72
|
+
5. Add remaining missing resources: accessory, chat, game_rating, genre, platform, promo, rating_board, region, release, review, theme, types, user_review, video_type. None of these show up in search. Refactoring is probably necessary.
|
data/lib/luchadeer/client.rb
CHANGED
data/lib/luchadeer/search.rb
CHANGED
@@ -10,8 +10,6 @@ require 'luchadeer/video'
|
|
10
10
|
|
11
11
|
module Luchadeer
|
12
12
|
class Search
|
13
|
-
attr_accessor :query
|
14
|
-
|
15
13
|
RESOURCE_TYPES = {
|
16
14
|
'character' => Luchadeer::Character,
|
17
15
|
'company' => Luchadeer::Company,
|
@@ -24,8 +22,12 @@ module Luchadeer
|
|
24
22
|
'video' => Luchadeer::Video
|
25
23
|
}
|
26
24
|
|
27
|
-
def initialize(
|
28
|
-
|
25
|
+
def initialize(opts = {})
|
26
|
+
opts.each do |key, value|
|
27
|
+
send(:"#{key}=", value)
|
28
|
+
end
|
29
|
+
|
30
|
+
yield self if block_given?
|
29
31
|
end
|
30
32
|
|
31
33
|
def fetch
|
@@ -35,10 +37,49 @@ module Luchadeer
|
|
35
37
|
end.compact
|
36
38
|
end
|
37
39
|
|
40
|
+
QUERY_PARAMS = [:query, :limit, :page, :fields, :resources, :sort]
|
41
|
+
attr_writer *QUERY_PARAMS
|
42
|
+
|
43
|
+
QUERY_PARAMS.each do |method|
|
44
|
+
define_method("#{method}") do |param = nil|
|
45
|
+
ivar = "@#{method.to_s}"
|
46
|
+
return instance_variable_get(ivar) unless param
|
47
|
+
instance_variable_set(ivar, param)
|
48
|
+
self
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def resources(resources = nil)
|
53
|
+
return @resources unless resources
|
54
|
+
append_resources(resources)
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
def sort(attribute = nil, dir = :asc)
|
59
|
+
return @sort unless attribute
|
60
|
+
@sort = "#{attribute}:#{dir}"
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
38
64
|
private
|
39
65
|
|
40
66
|
def search_params
|
41
|
-
{ query: @query
|
67
|
+
{ query: @query, limit: @limit, resources: @resources, page: @page,
|
68
|
+
sort: @sort }.delete_if { |_, v| v.nil? }
|
69
|
+
end
|
70
|
+
|
71
|
+
def append_resources(resources)
|
72
|
+
@resources ||= ''
|
73
|
+
resources = (RESOURCE_TYPES.invert[resources] || '') if resources.is_a? Class
|
74
|
+
|
75
|
+
rx = resources.is_a?(Array) ? resources : resources.split(',')
|
76
|
+
rx.each do |r|
|
77
|
+
r = (RESOURCE_TYPES.invert[r] || '') if r.is_a? Class
|
78
|
+
RESOURCE_TYPES[r] or raise(ArgumentError, 'Invalid resource type supplied')
|
79
|
+
@resources << ",#{r}"
|
80
|
+
end
|
81
|
+
|
82
|
+
@resources.sub!(/\A,+/, '')
|
42
83
|
end
|
43
84
|
|
44
85
|
end
|
data/lib/luchadeer/version.rb
CHANGED
@@ -2,26 +2,161 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Luchadeer::Search do
|
4
4
|
let(:query) { 'Chie Satonaka' }
|
5
|
+
let(:limit) { 10 }
|
6
|
+
let(:page) { 1 }
|
7
|
+
let(:sort) { 'name' }
|
8
|
+
let(:search) { described_class.new }
|
5
9
|
let(:search_path) { %r(#{Luchadeer::Client::GIANT_BOMB}/search) }
|
10
|
+
let(:empty_body) { { body: '{ "results": [] }' } }
|
6
11
|
|
7
12
|
describe '#initialize' do
|
8
|
-
it 'instantiates with
|
9
|
-
expect(described_class.new
|
13
|
+
it 'instantiates with no arguments' do
|
14
|
+
expect(described_class.new).to be_instance_of described_class
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'instantiates with an options hash' do
|
18
|
+
expect(described_class.new(query: query).query).to eq query
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'yields self if block given' do
|
22
|
+
expect { |b| described_class.new(&b) }.to yield_control
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#query' do
|
27
|
+
it 'sets the query' do
|
28
|
+
expect(search.query(query).query).to eq query
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns the search instance' do
|
32
|
+
expect(search.query(query)).to eq search
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#limit' do
|
37
|
+
it 'sets the limit' do
|
38
|
+
expect(search.limit(limit).limit).to eq limit
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns the search instance' do
|
42
|
+
expect(search.limit(limit)).to eq search
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#page' do
|
47
|
+
it 'sets the page' do
|
48
|
+
expect(search.page(page).page).to eq page
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'returns the search instance' do
|
52
|
+
expect(search.page(page)).to eq search
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#sort' do
|
57
|
+
it 'sets the sort to the given parameter and defaults to ascending' do
|
58
|
+
expect(search.sort(sort).sort).to eq "#{sort}:asc"
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'allows changing the sort direction' do
|
62
|
+
expect(search.sort(sort, :desc).sort).to eq "#{sort}:desc"
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'allows changing the sort with a string' do
|
66
|
+
expect(search.sort(sort, 'desc').sort).to eq "#{sort}:desc"
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns the search instance' do
|
70
|
+
expect(search.sort(sort)).to eq search
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#resources' do
|
75
|
+
context 'when called with a valid string' do
|
76
|
+
it 'sets resources to the given string' do
|
77
|
+
expect(search.resources('person,location').resources).to eq 'person,location'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when called with an invalid string' do
|
82
|
+
it 'raises ArgumentError' do
|
83
|
+
expect { search.resources('naoto,yosuke,kanji').resources }.to raise_error ArgumentError
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when called with class' do
|
88
|
+
it 'maps the class to a string' do
|
89
|
+
expect(search.resources(Luchadeer::Person).resources).to eq 'person'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'when called with array' do
|
94
|
+
context 'of valid' do
|
95
|
+
context 'strings' do
|
96
|
+
it 'sets resources to comma-delimited string of given strings' do
|
97
|
+
expect(search.resources(['person', 'location']).resources).to eq 'person,location'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'classes' do
|
102
|
+
it 'maps the classes to strings' do
|
103
|
+
expect(search.resources([Luchadeer::Person, Luchadeer::Location]).resources).to eq 'person,location'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'of invalid' do
|
109
|
+
context 'strings' do
|
110
|
+
it 'raises ArgumentError' do
|
111
|
+
expect { search.resources ['person', 'naoto'] }.to raise_error ArgumentError
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'classes' do
|
116
|
+
it 'raises ArgumentError' do
|
117
|
+
expect { search.resources [String, BasicObject, Luchadeer::Search] }.to raise_error ArgumentError
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
10
121
|
end
|
11
122
|
end
|
12
123
|
|
13
124
|
describe '#fetch' do
|
125
|
+
let(:search) { described_class.new(query: query).fetch }
|
126
|
+
|
14
127
|
before :each do
|
15
128
|
Luchadeer.client = Luchadeer::Client.new
|
16
129
|
end
|
17
130
|
|
18
131
|
it 'queries the Giant Bomb search API' do
|
19
|
-
stub = stub_request(:get, search_path).to_return(
|
132
|
+
stub = stub_request(:get, search_path).to_return(empty_body)
|
20
133
|
|
21
|
-
|
134
|
+
search
|
22
135
|
expect(stub).to have_been_requested
|
23
136
|
end
|
24
137
|
|
138
|
+
describe 'request parameters' do
|
139
|
+
it 'includes supplied parameters' do
|
140
|
+
params = { query: query, limit: 10, page: 1, resources: 'video', sort: 'name:asc' }
|
141
|
+
|
142
|
+
stub = stub_request(:get, "http://www.giantbomb.com/api/search")
|
143
|
+
.with(query: { api_key: nil, format: 'json' }.merge(params))
|
144
|
+
.to_return(empty_body)
|
145
|
+
|
146
|
+
described_class.new(params).fetch
|
147
|
+
expect(stub).to have_been_requested
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'omits nil parameters' do
|
151
|
+
stub = stub_request(:get, "http://www.giantbomb.com/api/search")
|
152
|
+
.with(query: { api_key: nil, format: 'json', query: query })
|
153
|
+
.to_return(empty_body)
|
154
|
+
|
155
|
+
described_class.new(query: query, limit: nil, page: nil).fetch
|
156
|
+
expect(stub).to have_been_requested
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
25
160
|
describe 'generates the proper class based on the result type' do
|
26
161
|
subject do
|
27
162
|
stub_request(:get, search_path).to_return(body:
|
@@ -36,7 +171,7 @@ describe Luchadeer::Search do
|
|
36
171
|
{"resource_type": "person"},
|
37
172
|
{"resource_type": "video"}
|
38
173
|
] }')
|
39
|
-
|
174
|
+
search
|
40
175
|
end
|
41
176
|
|
42
177
|
its([0]) { should be_instance_of Luchadeer::Character }
|
@@ -50,18 +185,18 @@ describe Luchadeer::Search do
|
|
50
185
|
its([8]) { should be_instance_of Luchadeer::Video }
|
51
186
|
end
|
52
187
|
|
53
|
-
context 'when
|
54
|
-
it '
|
188
|
+
context 'when the resource type isn\'t mapped' do
|
189
|
+
it 'skips modeling the resource' do
|
55
190
|
stub_request(:get, search_path).to_return(body:
|
56
191
|
'{ "results": [{ "resource_type": "banana"}] }')
|
57
|
-
expect(
|
192
|
+
expect(search).to be_empty
|
58
193
|
end
|
59
194
|
end
|
60
195
|
|
61
|
-
context 'when
|
62
|
-
it '
|
63
|
-
stub_request(:get, search_path).to_return(
|
64
|
-
expect(
|
196
|
+
context 'when there are no results' do
|
197
|
+
it 'returns an empty array' do
|
198
|
+
stub_request(:get, search_path).to_return(empty_body)
|
199
|
+
expect(search).to be_empty
|
65
200
|
end
|
66
201
|
end
|
67
202
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: luchadeer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Friedman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -184,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
184
|
version: '0'
|
185
185
|
requirements: []
|
186
186
|
rubyforge_project:
|
187
|
-
rubygems_version: 2.2.
|
187
|
+
rubygems_version: 2.2.0
|
188
188
|
signing_key:
|
189
189
|
specification_version: 4
|
190
190
|
summary: The bombingest Giant Bomb API client library for Ruby.
|