her 0.1.7 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +7 -3
- data/README.md +82 -40
- data/Rakefile +1 -1
- data/her.gemspec +2 -2
- data/lib/her.rb +1 -1
- data/lib/her/api.rb +48 -32
- data/lib/her/middleware/default_parse_json.rb +18 -8
- data/lib/her/model.rb +3 -1
- data/lib/her/model/hooks.rb +52 -12
- data/lib/her/model/http.rb +142 -0
- data/lib/her/model/introspection.rb +32 -0
- data/lib/her/model/orm.rb +46 -20
- data/lib/her/model/relationships.rb +51 -16
- data/lib/her/version.rb +1 -1
- data/spec/api_spec.rb +25 -4
- data/spec/middleware/default_parse_json_spec.rb +24 -0
- data/spec/model/hooks_spec.rb +80 -80
- data/spec/model/http_spec.rb +58 -0
- data/spec/model/introspection_spec.rb +27 -0
- data/spec/model/orm_spec.rb +8 -0
- metadata +15 -10
data/lib/her/version.rb
CHANGED
data/spec/api_spec.rb
CHANGED
@@ -17,7 +17,20 @@ describe Her::API do
|
|
17
17
|
@api.base_uri.should == "https://api.example.com"
|
18
18
|
end # }}}
|
19
19
|
|
20
|
-
it "sets middleware" do # {{{
|
20
|
+
it "sets additional middleware" do # {{{
|
21
|
+
class Foo < Faraday::Response::Middleware; end;
|
22
|
+
class Bar < Faraday::Response::Middleware; end;
|
23
|
+
|
24
|
+
@api = Her::API.new
|
25
|
+
@api.setup :base_uri => "https://api.example.com", :add_middleware => [Foo, Bar]
|
26
|
+
@api.middleware.should == [Foo, Bar, Her::Middleware::DefaultParseJSON, Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]
|
27
|
+
|
28
|
+
@api = Her::API.new
|
29
|
+
@api.setup :base_uri => "https://api.example.com", :add_middleware => Foo
|
30
|
+
@api.middleware.should == [Foo, Her::Middleware::DefaultParseJSON, Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]
|
31
|
+
end # }}}
|
32
|
+
|
33
|
+
it "overrides middleware" do # {{{
|
21
34
|
class Foo < Faraday::Response::Middleware; end;
|
22
35
|
class Bar < Faraday::Response::Middleware; end;
|
23
36
|
|
@@ -25,6 +38,14 @@ describe Her::API do
|
|
25
38
|
@api.setup :base_uri => "https://api.example.com", :middleware => [Foo, Bar]
|
26
39
|
@api.middleware.should == [Foo, Bar]
|
27
40
|
end # }}}
|
41
|
+
|
42
|
+
it "sets a parse middleware" do # {{{
|
43
|
+
class Foo < Faraday::Response::Middleware; end;
|
44
|
+
|
45
|
+
@api = Her::API.new
|
46
|
+
@api.setup :base_uri => "https://api.example.com", :parse_middleware => Foo
|
47
|
+
@api.middleware.should == [Foo, Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]
|
48
|
+
end # }}}
|
28
49
|
end
|
29
50
|
|
30
51
|
describe "#request" do
|
@@ -45,7 +66,7 @@ describe Her::API do
|
|
45
66
|
end # }}}
|
46
67
|
|
47
68
|
it "parses a request with the default parser" do # {{{
|
48
|
-
FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body =>
|
69
|
+
FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => MultiJson.dump(:data => { :id => 1, :name => "George Michael Bluth" }, :errors => ["This is a single error"], :metadata => { :page => 1, :per_page => 10 }))
|
49
70
|
|
50
71
|
@api = Her::API.new
|
51
72
|
@api.setup :base_uri => "https://api.example.com"
|
@@ -57,7 +78,7 @@ describe Her::API do
|
|
57
78
|
end # }}}
|
58
79
|
|
59
80
|
it "parses a request with a custom parser" do # {{{
|
60
|
-
FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body =>
|
81
|
+
FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => MultiJson.dump(:id => 1, :name => "George Michael Bluth"))
|
61
82
|
|
62
83
|
class CustomParser < Faraday::Response::Middleware
|
63
84
|
def on_complete(env)
|
@@ -73,7 +94,7 @@ describe Her::API do
|
|
73
94
|
end
|
74
95
|
|
75
96
|
@api = Her::API.new
|
76
|
-
@api.setup :base_uri => "https://api.example.com", :
|
97
|
+
@api.setup :base_uri => "https://api.example.com", :parse_middleware => CustomParser
|
77
98
|
@api.request(:_method => :get, :_path => "users/1") do |parsed_data|
|
78
99
|
parsed_data[:data].should == { :id => 1, :name => "George Michael Bluth" }
|
79
100
|
parsed_data[:errors].should == []
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Her::Middleware::DefaultParseJSON do
|
4
|
+
subject { described_class.new }
|
5
|
+
let(:body) { "{\"data\": 1, \"errors\": 2, \"metadata\": 3}" }
|
6
|
+
|
7
|
+
it "parses body as json" do
|
8
|
+
subject.parse(body).tap do |json|
|
9
|
+
json[:data].should == 1
|
10
|
+
json[:errors].should == 2
|
11
|
+
json[:metadata].should == 3
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "parses :body key as json in the env hash" do
|
16
|
+
env = { :body => body }
|
17
|
+
subject.on_complete(env)
|
18
|
+
env[:body].tap do |json|
|
19
|
+
json[:data].should == 1
|
20
|
+
json[:errors].should == 2
|
21
|
+
json[:metadata].should == 3
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/spec/model/hooks_spec.rb
CHANGED
@@ -11,103 +11,103 @@ describe Her::Model::Hooks do
|
|
11
11
|
end # }}}
|
12
12
|
|
13
13
|
describe "method hooks" do
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
it "handles “before save” method hooks" do # {{{
|
15
|
+
User.before_save :set_internal_id
|
16
|
+
User.send(:hooks)[:before_save].length.should == 1
|
17
|
+
User.send(:hooks)[:before_save].first.class.should == Symbol
|
18
|
+
end # }}}
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
it "handles “before create” method hooks" do # {{{
|
21
|
+
User.before_create :set_internal_id
|
22
|
+
User.send(:hooks)[:before_create].length.should == 1
|
23
|
+
User.send(:hooks)[:before_create].first.class.should == Symbol
|
24
|
+
end # }}}
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
it "handles “before update” method hooks" do # {{{
|
27
|
+
User.before_update :set_internal_id
|
28
|
+
User.send(:hooks)[:before_update].length.should == 1
|
29
|
+
User.send(:hooks)[:before_update].first.class.should == Symbol
|
30
|
+
end # }}}
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
it "handles “before destroy” method hooks" do # {{{
|
33
|
+
User.before_destroy :set_internal_id
|
34
|
+
User.send(:hooks)[:before_destroy].length.should == 1
|
35
|
+
User.send(:hooks)[:before_destroy].first.class.should == Symbol
|
36
|
+
end # }}}
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
it "handles “after save” method hooks" do # {{{
|
39
|
+
User.after_save :set_internal_id
|
40
|
+
User.send(:hooks)[:after_save].length.should == 1
|
41
|
+
User.send(:hooks)[:after_save].first.class.should == Symbol
|
42
|
+
end # }}}
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
it "handles “after create” method hooks" do # {{{
|
45
|
+
User.after_create :set_internal_id
|
46
|
+
User.send(:hooks)[:after_create].length.should == 1
|
47
|
+
User.send(:hooks)[:after_create].first.class.should == Symbol
|
48
|
+
end # }}}
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
it "handles “after update” method hooks" do # {{{
|
51
|
+
User.after_update :set_internal_id
|
52
|
+
User.send(:hooks)[:after_update].length.should == 1
|
53
|
+
User.send(:hooks)[:after_update].first.class.should == Symbol
|
54
|
+
end # }}}
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
it "handles “after destroy” method hooks" do # {{{
|
57
|
+
User.after_destroy :set_internal_id
|
58
|
+
User.send(:hooks)[:after_destroy].length.should == 1
|
59
|
+
User.send(:hooks)[:after_destroy].first.class.should == Symbol
|
60
|
+
end # }}}
|
61
61
|
end
|
62
62
|
|
63
63
|
describe "block hooks" do
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
it "handles “before save” block hooks" do # {{{
|
65
|
+
User.before_save { |record| record.internal_id = 42 }
|
66
|
+
User.send(:hooks)[:before_save].length.should == 1
|
67
|
+
User.send(:hooks)[:before_save].first.class.should == Proc
|
68
|
+
end # }}}
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
70
|
+
it "handles “before create” block hooks" do # {{{
|
71
|
+
User.before_create { |record| record.internal_id = 42 }
|
72
|
+
User.send(:hooks)[:before_create].length.should == 1
|
73
|
+
User.send(:hooks)[:before_create].first.class.should == Proc
|
74
|
+
end # }}}
|
75
75
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
76
|
+
it "handles “before update” block hooks" do # {{{
|
77
|
+
User.before_update { |record| record.internal_id = 42 }
|
78
|
+
User.send(:hooks)[:before_update].length.should == 1
|
79
|
+
User.send(:hooks)[:before_update].first.class.should == Proc
|
80
|
+
end # }}}
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
82
|
+
it "handles “before destroy” block hooks" do # {{{
|
83
|
+
User.before_destroy { |record| record.internal_id = 42 }
|
84
|
+
User.send(:hooks)[:before_destroy].length.should == 1
|
85
|
+
User.send(:hooks)[:before_destroy].first.class.should == Proc
|
86
|
+
end # }}}
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
88
|
+
it "handles “after save” block hooks" do # {{{
|
89
|
+
User.after_save { |record| record.internal_id = 42 }
|
90
|
+
User.send(:hooks)[:after_save].length.should == 1
|
91
|
+
User.send(:hooks)[:after_save].first.class.should == Proc
|
92
|
+
end # }}}
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
94
|
+
it "handles “after create” block hooks" do # {{{
|
95
|
+
User.after_create { |record| record.internal_id = 42 }
|
96
|
+
User.send(:hooks)[:after_create].length.should == 1
|
97
|
+
User.send(:hooks)[:after_create].first.class.should == Proc
|
98
|
+
end # }}}
|
99
99
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
100
|
+
it "handles “after update” block hooks" do # {{{
|
101
|
+
User.after_update { |record| record.internal_id = 42 }
|
102
|
+
User.send(:hooks)[:after_update].length.should == 1
|
103
|
+
User.send(:hooks)[:after_update].first.class.should == Proc
|
104
|
+
end # }}}
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
106
|
+
it "handles “after destroy” block hooks" do # {{{
|
107
|
+
User.after_destroy { |record| record.internal_id = 42 }
|
108
|
+
User.send(:hooks)[:after_destroy].length.should == 1
|
109
|
+
User.send(:hooks)[:after_destroy].first.class.should == Proc
|
110
|
+
end # }}}
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
data/spec/model/http_spec.rb
CHANGED
@@ -99,6 +99,15 @@ describe Her::Model::HTTP do
|
|
99
99
|
User.uses_api @api
|
100
100
|
end # }}}
|
101
101
|
|
102
|
+
it "handle GET wrapper method" do # {{{
|
103
|
+
@users = User.get(:popular)
|
104
|
+
@users.length.should == 2
|
105
|
+
@users.first.id.should == 1
|
106
|
+
|
107
|
+
@user = User.get(:"1")
|
108
|
+
@user.id.should == 1
|
109
|
+
end # }}}
|
110
|
+
|
102
111
|
it "handle raw GET" do # {{{
|
103
112
|
User.get_raw("/users") do |parsed_data|
|
104
113
|
parsed_data[:data].should == [{ :id => 1 }]
|
@@ -145,5 +154,54 @@ describe Her::Model::HTTP do
|
|
145
154
|
@user = User.get_resource("/users/1")
|
146
155
|
@user.id.should == 1
|
147
156
|
end # }}}
|
157
|
+
|
158
|
+
it "handle GET collection through a symbol" do # {{{
|
159
|
+
@users = User.get_collection(:popular)
|
160
|
+
@users.length.should == 2
|
161
|
+
@users.first.id.should == 1
|
162
|
+
end # }}}
|
163
|
+
|
164
|
+
it "handle GET resource through a symbol" do # {{{
|
165
|
+
@user = User.get_resource(:"1")
|
166
|
+
@user.id.should == 1
|
167
|
+
end # }}}
|
168
|
+
|
169
|
+
it "handle raw GET through a symbol" do # {{{
|
170
|
+
User.get_raw(:popular) do |parsed_data|
|
171
|
+
parsed_data[:data].should == [{ :id => 1 }, { :id => 2 }]
|
172
|
+
end
|
173
|
+
end # }}}
|
174
|
+
end
|
175
|
+
|
176
|
+
context "setting custom requests" do
|
177
|
+
before do # {{{
|
178
|
+
@api = Her::API.new
|
179
|
+
@api.setup :base_uri => "https://api.example.com"
|
180
|
+
FakeWeb.register_uri(:get, "https://api.example.com/users/popular", :body => { :data => [{ :id => 1 }, { :id => 2 }] }.to_json)
|
181
|
+
FakeWeb.register_uri(:post, "https://api.example.com/users/from_default", :body => { :data => { :id => 4 } }.to_json)
|
182
|
+
|
183
|
+
class User
|
184
|
+
include Her::Model
|
185
|
+
end
|
186
|
+
User.custom_get :popular, :foobar
|
187
|
+
User.custom_post :from_default
|
188
|
+
end # }}}
|
189
|
+
|
190
|
+
it "handles custom methods" do # {{{
|
191
|
+
User.respond_to?(:popular).should be_true
|
192
|
+
User.respond_to?(:foobar).should be_true
|
193
|
+
User.respond_to?(:from_default).should be_true
|
194
|
+
end # }}}
|
195
|
+
|
196
|
+
it "handles custom GET requests" do # {{{
|
197
|
+
@users = User.popular
|
198
|
+
@users.length.should == 2
|
199
|
+
@users.first.id.should == 1
|
200
|
+
end # }}}
|
201
|
+
|
202
|
+
it "handles custom POST requests" do # {{{
|
203
|
+
@user = User.from_default(:name => "Tobias Fünke")
|
204
|
+
@user.id.should be_true
|
205
|
+
end # }}}
|
148
206
|
end
|
149
207
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.join(File.dirname(__FILE__), "../spec_helper.rb")
|
3
|
+
|
4
|
+
describe Her::Model::Introspection do
|
5
|
+
context "introspecting a resource" do
|
6
|
+
before do # {{{
|
7
|
+
Her::API.setup :base_uri => "https://api.example.com"
|
8
|
+
FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1, :name => "Tobias Fünke" } }.to_json)
|
9
|
+
Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
|
10
|
+
class User
|
11
|
+
include Her::Model
|
12
|
+
end
|
13
|
+
end # }}}
|
14
|
+
|
15
|
+
describe "#inspect" do
|
16
|
+
it "outputs resource attributs for an existing resource" do # {{{
|
17
|
+
@user = User.find(1)
|
18
|
+
@user.inspect.should == "#<User(users/1) id=1 name=\"Tobias Fünke\">"
|
19
|
+
end # }}}
|
20
|
+
|
21
|
+
it "outputs resource attributs for an not-saved-yet resource" do # {{{
|
22
|
+
@user = User.new(:name => "Tobias Fünke")
|
23
|
+
@user.inspect.should == "#<User(users) name=\"Tobias Fünke\">"
|
24
|
+
end # }}}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/model/orm_spec.rb
CHANGED
@@ -27,6 +27,14 @@ describe Her::Model::ORM do
|
|
27
27
|
@users.length.should == 2
|
28
28
|
@users.first.name.should == "Tobias Fünke"
|
29
29
|
end # }}}
|
30
|
+
|
31
|
+
it "handles new resource" do # {{{
|
32
|
+
@new_user = User.new(:fullname => "Tobias Fünke")
|
33
|
+
@new_user.new?.should be_true
|
34
|
+
|
35
|
+
@existing_user = User.find(1)
|
36
|
+
@existing_user.new?.should be_false
|
37
|
+
end # }}}
|
30
38
|
end
|
31
39
|
|
32
40
|
context "creating resources" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: her
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-24 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -60,21 +60,21 @@ dependencies:
|
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
63
|
+
name: redcarpet
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - '='
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
69
|
+
version: 1.17.2
|
70
70
|
type: :development
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - '='
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
77
|
+
version: 1.17.2
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
79
|
name: mocha
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -140,7 +140,7 @@ dependencies:
|
|
140
140
|
- !ruby/object:Gem::Version
|
141
141
|
version: '0'
|
142
142
|
- !ruby/object:Gem::Dependency
|
143
|
-
name:
|
143
|
+
name: multi_json
|
144
144
|
requirement: !ruby/object:Gem::Requirement
|
145
145
|
none: false
|
146
146
|
requirements:
|
@@ -177,12 +177,15 @@ files:
|
|
177
177
|
- lib/her/model/base.rb
|
178
178
|
- lib/her/model/hooks.rb
|
179
179
|
- lib/her/model/http.rb
|
180
|
+
- lib/her/model/introspection.rb
|
180
181
|
- lib/her/model/orm.rb
|
181
182
|
- lib/her/model/relationships.rb
|
182
183
|
- lib/her/version.rb
|
183
184
|
- spec/api_spec.rb
|
185
|
+
- spec/middleware/default_parse_json_spec.rb
|
184
186
|
- spec/model/hooks_spec.rb
|
185
187
|
- spec/model/http_spec.rb
|
188
|
+
- spec/model/introspection_spec.rb
|
186
189
|
- spec/model/orm_spec.rb
|
187
190
|
- spec/model/relationships_spec.rb
|
188
191
|
- spec/spec_helper.rb
|
@@ -200,7 +203,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
200
203
|
version: '0'
|
201
204
|
segments:
|
202
205
|
- 0
|
203
|
-
hash: -
|
206
|
+
hash: -3580311510675037650
|
204
207
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
208
|
none: false
|
206
209
|
requirements:
|
@@ -209,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
209
212
|
version: '0'
|
210
213
|
segments:
|
211
214
|
- 0
|
212
|
-
hash: -
|
215
|
+
hash: -3580311510675037650
|
213
216
|
requirements: []
|
214
217
|
rubyforge_project:
|
215
218
|
rubygems_version: 1.8.18
|
@@ -219,8 +222,10 @@ summary: A simple Representational State Transfer-based Hypertext Transfer Proto
|
|
219
222
|
Object Relational Mapper. Her?
|
220
223
|
test_files:
|
221
224
|
- spec/api_spec.rb
|
225
|
+
- spec/middleware/default_parse_json_spec.rb
|
222
226
|
- spec/model/hooks_spec.rb
|
223
227
|
- spec/model/http_spec.rb
|
228
|
+
- spec/model/introspection_spec.rb
|
224
229
|
- spec/model/orm_spec.rb
|
225
230
|
- spec/model/relationships_spec.rb
|
226
231
|
- spec/spec_helper.rb
|