jeckle 0.3.1 → 0.4.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +0 -1
- data/History.markdown +1 -6
- data/README.md +19 -72
- data/examples/dribbble.rb +2 -7
- data/jeckle.gemspec +4 -4
- data/lib/jeckle/http.rb +26 -1
- data/lib/jeckle/resource.rb +0 -2
- data/lib/jeckle/rest_actions.rb +86 -6
- data/lib/jeckle/setup.rb +1 -1
- data/lib/jeckle/version.rb +1 -1
- data/lib/jeckle.rb +1 -1
- data/spec/fixtures/jeckle_config.rb +1 -1
- data/spec/fixtures/resources/comment_legacy.rb +6 -0
- data/spec/fixtures/resources/post.rb +10 -0
- data/spec/fixtures/resources/post_legacy.rb +6 -0
- data/spec/fixtures/resources/shot.rb +5 -0
- data/spec/{lib/jeckle → jeckle}/api_spec.rb +0 -0
- data/spec/{lib/jeckle → jeckle}/http_spec.rb +10 -2
- data/spec/{lib/jeckle → jeckle}/model_spec.rb +0 -0
- data/spec/{lib/jeckle → jeckle}/request_spec.rb +0 -0
- data/spec/{lib/jeckle → jeckle}/resource_spec.rb +0 -0
- data/spec/jeckle/rest_actions_spec.rb +139 -0
- data/spec/{lib/jeckle → jeckle}/setup_spec.rb +0 -0
- metadata +53 -48
- data/lib/jeckle/attribute_aliasing.rb +0 -13
- data/spec/lib/jeckle/attribute_aliasing_spec.rb +0 -19
- data/spec/lib/jeckle/rest_actions_spec.rb +0 -86
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af2832253f3702818065479fe480f305f5bf86ec
|
4
|
+
data.tar.gz: 9cde3a73a47758f448008c652548298fe1953ba3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30866c07299223ec34ad6579951e4d5918839bbf526f895b813a6de285cdbfabb73e4ccd25b561519c6fbb480ced002fa9284ac6f1fd7ccb754d57dd91fea5f4
|
7
|
+
data.tar.gz: 35eafdd5290a5ec2ed8c366c4a18f893be12d33405c72d895f245f76cd1745a3340d4e4b7955a8b986066fc5721cee8545db6b65e169b457bdf719690a341328
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/History.markdown
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
## v.0.3.1
|
2
|
-
|
3
|
-
* Add attribute aliasing
|
4
|
-
* Add possibility to change the resource name when call Resource.search.
|
5
|
-
|
6
1
|
## v.0.3.0
|
7
2
|
|
8
3
|
* Change Jeckle::Resource.default_api to Jeckle::Resource.api
|
@@ -13,4 +8,4 @@
|
|
13
8
|
|
14
9
|
## v.0.2.0
|
15
10
|
|
16
|
-
* Add Jeckle middlewares
|
11
|
+
* Add Jeckle middlewares
|
data/README.md
CHANGED
@@ -20,25 +20,19 @@ Let third party APIs be Heckle for your app's Jeckle.
|
|
20
20
|
|
21
21
|
Add this line to your application's Gemfile:
|
22
22
|
|
23
|
-
|
24
|
-
gem 'jeckle'
|
25
|
-
```
|
23
|
+
gem 'jeckle'
|
26
24
|
|
27
25
|
And then execute:
|
28
26
|
|
29
|
-
|
30
|
-
$ bundle
|
31
|
-
```
|
32
|
-
|
33
|
-
## Usage
|
34
|
-
|
35
|
-
### Configuring an API
|
27
|
+
$ bundle
|
36
28
|
|
37
|
-
|
29
|
+
### For Rails applications
|
38
30
|
|
39
|
-
|
31
|
+
We recommend to create a initializer:
|
40
32
|
|
41
33
|
```ruby
|
34
|
+
# config/initializers/jeckle.rb
|
35
|
+
|
42
36
|
Jeckle.configure do |config|
|
43
37
|
config.register :some_service do |api|
|
44
38
|
api.base_uri = 'http://api.someservice.com'
|
@@ -52,13 +46,17 @@ Jeckle.configure do |config|
|
|
52
46
|
end
|
53
47
|
```
|
54
48
|
|
55
|
-
|
56
|
-
|
57
|
-
Following the previous example, Dribbble.com consists of pieces of web designers work called "Shots". Each shot has the attributes `id`, `name`, `url` and `image_url`. A Jeckle resource representing Dribbble's shots would be something like this:
|
49
|
+
And then put your API stuff scoped inside a `services` folder:
|
58
50
|
|
59
51
|
```ruby
|
60
|
-
|
61
|
-
|
52
|
+
# app/services/some_service/models/my_resource.rb
|
53
|
+
|
54
|
+
module SomeService
|
55
|
+
module Models
|
56
|
+
class MyResource
|
57
|
+
include Jeckle::Resource
|
58
|
+
|
59
|
+
api :some_service
|
62
60
|
|
63
61
|
attribute :id
|
64
62
|
end
|
@@ -66,60 +64,9 @@ class Shot
|
|
66
64
|
end
|
67
65
|
```
|
68
66
|
|
69
|
-
### Fetching data
|
70
|
-
|
71
|
-
The resource class allows us to search shots through HTTP requests to the API, based on the provided information. For example, we can find a specific shot by providing its id to the `find` method:
|
72
|
-
|
73
|
-
```ruby
|
74
|
-
# GET http://api.dribbble.com/shots/1600459
|
75
|
-
shot = Shot.find 1600459
|
76
|
-
```
|
77
|
-
|
78
|
-
That will return a `Shot` instance, containing the shot info:
|
79
|
-
|
80
|
-
```ruby
|
81
|
-
shot.id
|
82
|
-
=> 1600459
|
83
|
-
|
84
|
-
shot.name
|
85
|
-
=> "Daryl Heckle And Jeckle Oates"
|
86
|
-
|
87
|
-
shot.image_url
|
88
|
-
=> "https://d13yacurqjgara.cloudfront.net/users/85699/screenshots/1600459/daryl_heckle_and_jeckle_oates-dribble.jpg"
|
89
|
-
```
|
90
|
-
|
91
|
-
You can also look for many shots matching one or more attributes, by using the `search` method:
|
92
|
-
|
93
|
-
```ruby
|
94
|
-
# GET http://api.dribbble.com/shots?name=avengers
|
95
|
-
shots = Shot.search name: 'avengers'
|
96
|
-
```
|
97
|
-
|
98
|
-
### Attribute Aliasing
|
99
|
-
|
100
|
-
Sometimes you want to call the API's attributes something else, either because their names aren't very concise or because they're out of you app's convention. If that's the case, you can add an `as` option:
|
101
|
-
|
102
|
-
```ruby
|
103
|
-
attribute :thumbnailSize, String, as: :thumbnail_size
|
104
|
-
```
|
105
|
-
|
106
|
-
Both mapping will work:
|
107
|
-
|
108
|
-
```ruby
|
109
|
-
shot.thumbnailSize
|
110
|
-
=> "50x50"
|
111
|
-
|
112
|
-
shot.thumbnail_size
|
113
|
-
=> "50x50"
|
114
|
-
```
|
115
|
-
|
116
|
-
We're all set! Now we can expand the mapping of our API, e.g to add ability to search Dribbble Designer directory by adding Designer class, or we can expand the original mapping of Shot class to include more attributes, such as tags or comments.
|
117
|
-
|
118
|
-
## Examples
|
119
|
-
|
120
|
-
You can see more examples here: [https://github.com/tomas-stefano/jeckle/tree/master/examples](https://github.com/tomas-stefano/jeckle/tree/master/examples)
|
121
|
-
|
122
67
|
## Roadmap
|
123
68
|
|
124
|
-
|
125
|
-
|
69
|
+
- Faraday middleware abstraction
|
70
|
+
- Per action API
|
71
|
+
- Comprehensive restful actions
|
72
|
+
- Testability
|
data/examples/dribbble.rb
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
require 'jeckle'
|
2
2
|
|
3
|
-
# Here is an example using the Dribbble API
|
4
|
-
|
5
3
|
Jeckle.configure do |config|
|
6
4
|
config.register :dribbble do |api|
|
7
5
|
api.base_uri = 'http://api.dribbble.com'
|
8
|
-
api.middlewares do
|
9
|
-
response :json
|
10
|
-
end
|
11
6
|
end
|
12
7
|
end
|
13
8
|
|
@@ -19,7 +14,7 @@ class Shot
|
|
19
14
|
attribute :id, Integer
|
20
15
|
attribute :name, String
|
21
16
|
attribute :url, String
|
22
|
-
attribute :image_url, String
|
17
|
+
attribute :image_url, String
|
23
18
|
end
|
24
19
|
|
25
20
|
shot = Shot.find 1600459
|
@@ -30,5 +25,5 @@ shot.id
|
|
30
25
|
shot.name
|
31
26
|
# => Daryl Heckle And Jeckle Oates
|
32
27
|
|
33
|
-
|
28
|
+
shot.image_url
|
34
29
|
# => https://d13yacurqjgara.cloudfront.net/users/85699/screenshots/1600459/daryl_heckle_and_jeckle_oates-dribble.jpg
|
data/jeckle.gemspec
CHANGED
@@ -21,11 +21,11 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_dependency 'activemodel', '>= 4.0'
|
22
22
|
spec.add_dependency 'faraday', '~> 0.9'
|
23
23
|
spec.add_dependency 'faraday_middleware'
|
24
|
-
spec.add_dependency 'virtus'
|
24
|
+
spec.add_dependency 'virtus', '~> 1.0'
|
25
25
|
|
26
|
-
spec.add_development_dependency 'bundler', '
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
27
27
|
spec.add_development_dependency 'rake'
|
28
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
28
|
+
spec.add_development_dependency 'rspec', '~> 3.1'
|
29
29
|
|
30
30
|
if RUBY_ENGINE == 'rbx'
|
31
31
|
spec.add_development_dependency 'rubinius-compiler'
|
@@ -34,6 +34,6 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_development_dependency 'pry'
|
35
35
|
else
|
36
36
|
spec.add_development_dependency 'pry-nav' if RUBY_VERSION < '2.0.0'
|
37
|
-
spec.add_development_dependency 'pry-byebug'
|
37
|
+
spec.add_development_dependency 'pry-byebug' if RUBY_VERSION >= '2.0.0'
|
38
38
|
end
|
39
39
|
end
|
data/lib/jeckle/http.rb
CHANGED
@@ -11,6 +11,8 @@ module Jeckle
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
# @public
|
15
|
+
#
|
14
16
|
# The name of the resource that Jeckle uses to make the request
|
15
17
|
#
|
16
18
|
# @example
|
@@ -39,6 +41,23 @@ module Jeckle
|
|
39
41
|
@resource_name ||= model_name.element.pluralize
|
40
42
|
end
|
41
43
|
|
44
|
+
# @public
|
45
|
+
#
|
46
|
+
# Overwritten the resource name without write the resource name method.
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
#
|
50
|
+
# module OtherApi
|
51
|
+
# class Project
|
52
|
+
# include Jeckle::Resource
|
53
|
+
# resource 'projects.json'
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
def resource(jeckle_resource_name)
|
58
|
+
@resource_name = jeckle_resource_name
|
59
|
+
end
|
60
|
+
|
42
61
|
# The API name that Jeckle uses to find all the api settings like domain, headers, etc.
|
43
62
|
#
|
44
63
|
# @example
|
@@ -72,7 +91,13 @@ module Jeckle
|
|
72
91
|
end
|
73
92
|
|
74
93
|
def run_request(endpoint, options = {})
|
75
|
-
Jeckle::Request.run api_mapping[:default_api], endpoint, options
|
94
|
+
response = Jeckle::Request.run api_mapping[:default_api], endpoint, options
|
95
|
+
|
96
|
+
if logger = api_mapping[:default_api].logger
|
97
|
+
logger.debug("#{self} Response: #{response}")
|
98
|
+
end
|
99
|
+
|
100
|
+
response
|
76
101
|
end
|
77
102
|
end
|
78
103
|
end
|
data/lib/jeckle/resource.rb
CHANGED
data/lib/jeckle/rest_actions.rb
CHANGED
@@ -5,20 +5,100 @@ module Jeckle
|
|
5
5
|
end
|
6
6
|
|
7
7
|
module Collection
|
8
|
+
# @public
|
9
|
+
#
|
10
|
+
# The root name that Jeckle will parse the <b>response</b>. Default is <b>false</b>.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
#
|
14
|
+
# module Dribble
|
15
|
+
# class Shot
|
16
|
+
# include Jeckle::Resource
|
17
|
+
# root collection: true, member: true
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# Shot.collection_root_name # => Will parse the root node as 'shots'
|
22
|
+
# Shot.member_root_name # => Will parse the root node as 'shot'
|
23
|
+
#
|
24
|
+
# Sometimes that are APIs you need to fetch /projects, BUT the root node is extremely different from the resource name.
|
25
|
+
#
|
26
|
+
# module OtherApi
|
27
|
+
# class Project
|
28
|
+
# include Jeckle::Resource
|
29
|
+
# api :my_api
|
30
|
+
# root collection: 'awesome-projects', member: 'awesome-project'
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
def root(options={})
|
35
|
+
@collection_root_name = find_root_name(options[:collection], :pluralize)
|
36
|
+
@member_root_name = find_root_name(options[:member], :singularize)
|
37
|
+
end
|
38
|
+
|
39
|
+
# @public
|
40
|
+
#
|
41
|
+
# Member action that requests for the resource using the resource name
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
#
|
45
|
+
# Post.find(1) # => posts/1
|
46
|
+
#
|
8
47
|
def find(id)
|
9
48
|
endpoint = "#{resource_name}/#{id}"
|
10
|
-
|
49
|
+
response = run_request(endpoint).response.body
|
50
|
+
attributes = parse_response(response, member_root_name)
|
11
51
|
|
12
|
-
new
|
52
|
+
new(attributes)
|
13
53
|
end
|
14
54
|
|
55
|
+
# @public
|
56
|
+
#
|
57
|
+
# Collection action that requests for the resource using the resource name
|
58
|
+
#
|
59
|
+
# @example
|
60
|
+
#
|
61
|
+
# Post.search({ status: 'published' }) # => posts/?status=published
|
62
|
+
# Post.where({ status: 'published' }) # => posts/?status=published
|
63
|
+
#
|
15
64
|
def search(params = {})
|
16
|
-
|
65
|
+
response = run_request(resource_name, params).response.body || []
|
66
|
+
collection = parse_response(response, collection_root_name)
|
67
|
+
|
68
|
+
Array(collection).map { |attributes| new(attributes) }
|
69
|
+
end
|
70
|
+
alias :where :search
|
71
|
+
|
72
|
+
# @private
|
73
|
+
#
|
74
|
+
def parse_response(response, root_name)
|
75
|
+
if root_name
|
76
|
+
response[root_name]
|
77
|
+
else
|
78
|
+
response
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# @private
|
83
|
+
#
|
84
|
+
def find_root_name(root_name, root_method)
|
85
|
+
return root_name if root_name.is_a?(String)
|
17
86
|
|
18
|
-
|
19
|
-
|
87
|
+
if root_name
|
88
|
+
model_name.element.send(root_method)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# @private
|
93
|
+
#
|
94
|
+
def collection_root_name
|
95
|
+
@collection_root_name
|
96
|
+
end
|
20
97
|
|
21
|
-
|
98
|
+
# @private
|
99
|
+
#
|
100
|
+
def member_root_name
|
101
|
+
@member_root_name
|
22
102
|
end
|
23
103
|
end
|
24
104
|
end
|
data/lib/jeckle/setup.rb
CHANGED
data/lib/jeckle/version.rb
CHANGED
data/lib/jeckle.rb
CHANGED
@@ -5,7 +5,7 @@ require 'virtus'
|
|
5
5
|
|
6
6
|
require 'jeckle/version'
|
7
7
|
|
8
|
-
%w(setup api model request http rest_actions resource errors
|
8
|
+
%w(setup api model request http rest_actions resource errors).each do |file_name|
|
9
9
|
require "jeckle/#{file_name}"
|
10
10
|
end
|
11
11
|
|
@@ -2,7 +2,7 @@ Jeckle.configure do |config|
|
|
2
2
|
config.register :my_super_api do |api|
|
3
3
|
api.base_uri = 'http://my-super-api.com.br'
|
4
4
|
api.headers = { 'Content-Type' => 'application/json' }
|
5
|
-
api.logger = Logger.new(
|
5
|
+
api.logger = Logger.new('spec/requests.log')
|
6
6
|
api.basic_auth = { username: 'steven_seagal', password: 'youAlwaysLose' }
|
7
7
|
api.namespaces = { prefix: 'api', version: 'v1' }
|
8
8
|
api.params = { hello: 'world' }
|
File without changes
|
@@ -2,8 +2,16 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe Jeckle::HTTP do
|
4
4
|
describe '.resource_name' do
|
5
|
-
|
6
|
-
|
5
|
+
context 'when resource is not namespaced' do
|
6
|
+
it 'returns resource name based on class name' do
|
7
|
+
expect(FakeResource.resource_name).to eq 'fake_resources'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'when resource is overwritten by .resource method' do
|
12
|
+
it 'returns resource name passed on the .resource method' do
|
13
|
+
expect(Shot.resource_name).to eq 'shots.json'
|
14
|
+
end
|
7
15
|
end
|
8
16
|
|
9
17
|
context 'when resource class is namespaced' do
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Jeckle::RESTActions do
|
4
|
+
let(:api) { FakeResource.api_mapping[:default_api] }
|
5
|
+
let(:fake_request) { OpenStruct.new response: OpenStruct.new(body: body) }
|
6
|
+
|
7
|
+
describe '.root' do
|
8
|
+
context 'when collection is true' do
|
9
|
+
it 'collection root name should be in plural' do
|
10
|
+
expect(Post.collection_root_name).to eq('posts')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when collection is false' do
|
15
|
+
it 'collection root name should be nil' do
|
16
|
+
expect(FakeResource.collection_root_name).to be nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when member is true' do
|
21
|
+
it 'member root name should be in singular' do
|
22
|
+
expect(Post.member_root_name).to eq('post')
|
23
|
+
expect(CommentLegacy.member_root_name).to eq('comment_legacy')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when member is false' do
|
28
|
+
it 'member root name should be nil' do
|
29
|
+
expect(FakeResource.member_root_name).to be nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when collection is overwritten' do
|
34
|
+
it 'collection root name should use the collection option' do
|
35
|
+
expect(PostLegacy.collection_root_name).to eq('super-posts')
|
36
|
+
expect(CommentLegacy.collection_root_name).to eq('super-comments')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when member is overwritten' do
|
41
|
+
it 'member root name should use the member option' do
|
42
|
+
expect(PostLegacy.member_root_name).to eq('super-post')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.find' do
|
48
|
+
context 'when do not have root node' do
|
49
|
+
let(:body) do
|
50
|
+
{ id: 1001 }
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'calls default API connection with GET' do
|
54
|
+
expect(Jeckle::Request).to receive(:run)
|
55
|
+
.with(api, 'fake_resources/1001', {}).and_return(fake_request)
|
56
|
+
|
57
|
+
FakeResource.find 1001
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'returns an instance of resource' do
|
61
|
+
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
62
|
+
|
63
|
+
expect(FakeResource.find 1001).to be_an_instance_of(FakeResource)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when have root node in response' do
|
68
|
+
let(:body) do
|
69
|
+
{ 'post' => { 'id' => 1001 } }
|
70
|
+
end
|
71
|
+
|
72
|
+
let(:post) { Post.find 1001 }
|
73
|
+
|
74
|
+
it 'calls default API connection with GET' do
|
75
|
+
expect(Jeckle::Request).to receive(:run)
|
76
|
+
.with(api, 'posts/1001', {}).and_return(fake_request)
|
77
|
+
|
78
|
+
Post.find(1001)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'returns an instance of resource' do
|
82
|
+
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
83
|
+
|
84
|
+
expect(post).to be_an_instance_of(Post)
|
85
|
+
expect(post.id).to be(1001)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '.search' do
|
91
|
+
let(:query) { { name: 'cocada' } }
|
92
|
+
|
93
|
+
context 'when there are results WITHOUT root node' do
|
94
|
+
let(:body) { [{ id: 1001 }, { id: 1002 }] }
|
95
|
+
|
96
|
+
it 'calls default API connection with GET and search params' do
|
97
|
+
expect(Jeckle::Request).to receive(:run)
|
98
|
+
.with(api, 'fake_resources', query).and_return(fake_request)
|
99
|
+
|
100
|
+
FakeResource.search query
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'returns an Array of resources' do
|
104
|
+
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
105
|
+
|
106
|
+
expect(FakeResource.search query).to match [
|
107
|
+
an_instance_of(FakeResource),
|
108
|
+
an_instance_of(FakeResource)
|
109
|
+
]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'when there are results WITH collection root node' do
|
114
|
+
let(:body) do
|
115
|
+
{ 'posts' => [{ id: 1001 }, { id: 1002 } ] }
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'returns an Array of resources' do
|
119
|
+
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
120
|
+
results = Post.where(query)
|
121
|
+
|
122
|
+
expect(results).to match [
|
123
|
+
Post.new(id: 1001),
|
124
|
+
Post.new(id: 1002)
|
125
|
+
]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'when there are no results' do
|
130
|
+
let(:body) { nil }
|
131
|
+
|
132
|
+
it 'returns an empty Array' do
|
133
|
+
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
134
|
+
|
135
|
+
expect(FakeResource.search query).to match []
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jeckle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomas D'Stefano
|
@@ -9,120 +9,120 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-10-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - '>='
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '4.0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - '>='
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '4.0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: faraday
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- -
|
32
|
+
- - ~>
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: '0.9'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - ~>
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0.9'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: faraday_middleware
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- -
|
46
|
+
- - '>='
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: '0'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- -
|
53
|
+
- - '>='
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '0'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: virtus
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- -
|
60
|
+
- - ~>
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: '0'
|
62
|
+
version: '1.0'
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: '0'
|
69
|
+
version: '1.0'
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: bundler
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- -
|
74
|
+
- - ~>
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: '1.6'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- -
|
81
|
+
- - ~>
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '1.6'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: rake
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- -
|
88
|
+
- - '>='
|
89
89
|
- !ruby/object:Gem::Version
|
90
90
|
version: '0'
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- -
|
95
|
+
- - '>='
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: rspec
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- -
|
102
|
+
- - ~>
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: '3.
|
104
|
+
version: '3.1'
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- -
|
109
|
+
- - ~>
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: '3.
|
111
|
+
version: '3.1'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: pry-byebug
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- - '
|
116
|
+
- - '>='
|
117
117
|
- !ruby/object:Gem::Version
|
118
|
-
version:
|
118
|
+
version: '0'
|
119
119
|
type: :development
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- - '
|
123
|
+
- - '>='
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version:
|
125
|
+
version: '0'
|
126
126
|
description: Simple module for building client APIs
|
127
127
|
email:
|
128
128
|
- tomas_stefano@successoft.com
|
@@ -131,9 +131,9 @@ executables: []
|
|
131
131
|
extensions: []
|
132
132
|
extra_rdoc_files: []
|
133
133
|
files:
|
134
|
-
-
|
135
|
-
-
|
136
|
-
-
|
134
|
+
- .gitignore
|
135
|
+
- .rspec
|
136
|
+
- .travis.yml
|
137
137
|
- Gemfile
|
138
138
|
- History.markdown
|
139
139
|
- LICENSE.txt
|
@@ -143,7 +143,6 @@ files:
|
|
143
143
|
- jeckle.gemspec
|
144
144
|
- lib/jeckle.rb
|
145
145
|
- lib/jeckle/api.rb
|
146
|
-
- lib/jeckle/attribute_aliasing.rb
|
147
146
|
- lib/jeckle/errors.rb
|
148
147
|
- lib/jeckle/http.rb
|
149
148
|
- lib/jeckle/model.rb
|
@@ -154,15 +153,18 @@ files:
|
|
154
153
|
- lib/jeckle/version.rb
|
155
154
|
- spec/fixtures/jeckle_config.rb
|
156
155
|
- spec/fixtures/models/fake_model.rb
|
156
|
+
- spec/fixtures/resources/comment_legacy.rb
|
157
157
|
- spec/fixtures/resources/fake_resource.rb
|
158
|
-
- spec/
|
159
|
-
- spec/
|
160
|
-
- spec/
|
161
|
-
- spec/
|
162
|
-
- spec/
|
163
|
-
- spec/
|
164
|
-
- spec/
|
165
|
-
- spec/
|
158
|
+
- spec/fixtures/resources/post.rb
|
159
|
+
- spec/fixtures/resources/post_legacy.rb
|
160
|
+
- spec/fixtures/resources/shot.rb
|
161
|
+
- spec/jeckle/api_spec.rb
|
162
|
+
- spec/jeckle/http_spec.rb
|
163
|
+
- spec/jeckle/model_spec.rb
|
164
|
+
- spec/jeckle/request_spec.rb
|
165
|
+
- spec/jeckle/resource_spec.rb
|
166
|
+
- spec/jeckle/rest_actions_spec.rb
|
167
|
+
- spec/jeckle/setup_spec.rb
|
166
168
|
- spec/spec_helper.rb
|
167
169
|
- spec/support/shared_examples.rb
|
168
170
|
homepage: https://github.com/tomas-stefano/jeckle
|
@@ -175,31 +177,34 @@ require_paths:
|
|
175
177
|
- lib
|
176
178
|
required_ruby_version: !ruby/object:Gem::Requirement
|
177
179
|
requirements:
|
178
|
-
- -
|
180
|
+
- - '>='
|
179
181
|
- !ruby/object:Gem::Version
|
180
182
|
version: '0'
|
181
183
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
182
184
|
requirements:
|
183
|
-
- -
|
185
|
+
- - '>'
|
184
186
|
- !ruby/object:Gem::Version
|
185
|
-
version:
|
187
|
+
version: 1.3.1
|
186
188
|
requirements: []
|
187
189
|
rubyforge_project:
|
188
|
-
rubygems_version: 2.
|
190
|
+
rubygems_version: 2.0.5
|
189
191
|
signing_key:
|
190
192
|
specification_version: 4
|
191
193
|
summary: Simple module for building client APIs
|
192
194
|
test_files:
|
193
195
|
- spec/fixtures/jeckle_config.rb
|
194
196
|
- spec/fixtures/models/fake_model.rb
|
197
|
+
- spec/fixtures/resources/comment_legacy.rb
|
195
198
|
- spec/fixtures/resources/fake_resource.rb
|
196
|
-
- spec/
|
197
|
-
- spec/
|
198
|
-
- spec/
|
199
|
-
- spec/
|
200
|
-
- spec/
|
201
|
-
- spec/
|
202
|
-
- spec/
|
203
|
-
- spec/
|
199
|
+
- spec/fixtures/resources/post.rb
|
200
|
+
- spec/fixtures/resources/post_legacy.rb
|
201
|
+
- spec/fixtures/resources/shot.rb
|
202
|
+
- spec/jeckle/api_spec.rb
|
203
|
+
- spec/jeckle/http_spec.rb
|
204
|
+
- spec/jeckle/model_spec.rb
|
205
|
+
- spec/jeckle/request_spec.rb
|
206
|
+
- spec/jeckle/resource_spec.rb
|
207
|
+
- spec/jeckle/rest_actions_spec.rb
|
208
|
+
- spec/jeckle/setup_spec.rb
|
204
209
|
- spec/spec_helper.rb
|
205
210
|
- spec/support/shared_examples.rb
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class AttributeAliasingResource
|
4
|
-
include Jeckle::Resource
|
5
|
-
|
6
|
-
attribute :firstName, String, as: :first_name
|
7
|
-
end
|
8
|
-
|
9
|
-
RSpec.describe Jeckle::AttributeAliasing do
|
10
|
-
let(:first_name) { 'First Name' }
|
11
|
-
let(:resource) { AttributeAliasingResource.new(firstName: first_name) }
|
12
|
-
|
13
|
-
describe '.attribute' do
|
14
|
-
it 'initializes attributes by :as options' do
|
15
|
-
expect(resource.first_name).to eq first_name
|
16
|
-
expect(resource.firstName).to eq first_name
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe Jeckle::RESTActions do
|
4
|
-
let(:api) { FakeResource.api_mapping[:default_api] }
|
5
|
-
|
6
|
-
describe '.find' do
|
7
|
-
let(:fake_request) { OpenStruct.new response: OpenStruct.new(body: { id: 1001 }) }
|
8
|
-
|
9
|
-
it 'calls default API connection with GET' do
|
10
|
-
expect(Jeckle::Request).to receive(:run)
|
11
|
-
.with(api, 'fake_resources/1001', {}).and_return(fake_request)
|
12
|
-
|
13
|
-
FakeResource.find 1001
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'returns an instance of resource' do
|
17
|
-
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
18
|
-
|
19
|
-
expect(FakeResource.find 1001).to be_an_instance_of(FakeResource)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe '.search' do
|
24
|
-
let(:fake_request) { OpenStruct.new response: OpenStruct.new(body: body) }
|
25
|
-
|
26
|
-
let(:query) { { name: 'cocada' } }
|
27
|
-
|
28
|
-
context 'when there are results WITHOUT root node' do
|
29
|
-
let(:body) { [{ id: 1001 }, { id: 1002 }] }
|
30
|
-
|
31
|
-
it 'calls default API connection with GET and search params' do
|
32
|
-
expect(Jeckle::Request).to receive(:run)
|
33
|
-
.with(api, 'fake_resources', { params: query }).and_return(fake_request)
|
34
|
-
|
35
|
-
FakeResource.search query
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'returns an Array of resources' do
|
39
|
-
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
40
|
-
|
41
|
-
expect(FakeResource.search query).to match [
|
42
|
-
an_instance_of(FakeResource),
|
43
|
-
an_instance_of(FakeResource)
|
44
|
-
]
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
context 'when there are results WITH root node' do
|
49
|
-
let(:body) do
|
50
|
-
{ 'fake_resources' => [{ id: 1001 }, { id: 1002 } ] }
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'returns an Array of resources' do
|
54
|
-
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
55
|
-
|
56
|
-
expect(FakeResource.search query).to match [
|
57
|
-
an_instance_of(FakeResource),
|
58
|
-
an_instance_of(FakeResource)
|
59
|
-
]
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
context 'when there are no results' do
|
64
|
-
let(:fake_request) { OpenStruct.new response: OpenStruct.new(body: nil) }
|
65
|
-
|
66
|
-
it 'returns an empty Array' do
|
67
|
-
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
68
|
-
|
69
|
-
expect(FakeResource.search query).to match []
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
context 'when the endpoint is overwritten' do
|
74
|
-
let(:endpoint) { 'custom_endpoint' }
|
75
|
-
let(:query) { { resource_name: endpoint, name: 'cocada' } }
|
76
|
-
let(:body) { [{ id: 1001 }, { id: 1002 }] }
|
77
|
-
|
78
|
-
it 'calls default API connection with GET and search params' do
|
79
|
-
expect(Jeckle::Request).to receive(:run)
|
80
|
-
.with(api, endpoint, params: query).and_return(fake_request)
|
81
|
-
|
82
|
-
FakeResource.search query
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|