her 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,29 +1,38 @@
1
1
  module Her
2
2
  module Model
3
3
  class Relation
4
- attr_accessor :query_attrs
4
+ # @private
5
+ attr_accessor :params
5
6
 
6
7
  # @private
7
8
  def initialize(parent)
8
9
  @parent = parent
9
- @query_attrs = {}
10
+ @params = {}
10
11
  end
11
12
 
12
13
  # @private
13
14
  def apply_to(attributes)
14
- @query_attrs.merge(attributes)
15
+ @params.merge(attributes)
15
16
  end
16
17
 
17
18
  # Build a new resource
18
- def build(attrs = {})
19
- @parent.new(@query_attrs.merge(attrs))
19
+ def build(attributes = {})
20
+ @parent.new(@params.merge(attributes))
20
21
  end
21
22
 
22
23
  # Add a query string parameter
23
- def where(attrs = {})
24
- return self if attrs.blank?
24
+ #
25
+ # @example
26
+ # @users = User.all
27
+ # # Fetched via GET "/users"
28
+ #
29
+ # @example
30
+ # @users = User.where(:approved => 1).all
31
+ # # Fetched via GET "/users?approved=1"
32
+ def where(params = {})
33
+ return self if params.blank? && @_fetch.blank?
25
34
  self.clone.tap do |r|
26
- r.query_attrs = r.query_attrs.merge(attrs)
35
+ r.params = r.params.merge(params)
27
36
  r.clear_fetch_cache!
28
37
  end
29
38
  end
@@ -53,18 +62,12 @@ module Her
53
62
 
54
63
  # Fetch a collection of resources
55
64
  #
56
- # @example
57
- # @users = User.all
58
- # # Fetched via GET "/users"
59
- #
60
- # @example
61
- # @users = User.where(:approved => 1).all
62
- # # Fetched via GET "/users?approved=1"
65
+ # @private
63
66
  def fetch
64
67
  @_fetch ||= begin
65
- path = @parent.build_request_path(@query_attrs)
68
+ path = @parent.build_request_path(@params)
66
69
  method = @parent.method_for(:find)
67
- @parent.request(@query_attrs.merge(:_method => method, :_path => path)) do |parsed_data, response|
70
+ @parent.request(@params.merge(:_method => method, :_path => path)) do |parsed_data, response|
68
71
  @parent.new_collection(parsed_data)
69
72
  end
70
73
  end
@@ -79,9 +82,9 @@ module Her
79
82
  # @example
80
83
  # @user = User.where(:email => "tobias@bluth.com").create(:fullname => "Tobias Fünke")
81
84
  # # Called via POST "/users/1" with `&email=tobias@bluth.com&fullname=Tobias+Fünke`
82
- def create(attrs = {})
83
- attrs ||= {}
84
- resource = @parent.new(@query_attrs.merge(attrs))
85
+ def create(attributes = {})
86
+ attributes ||= {}
87
+ resource = @parent.new(@params.merge(attributes))
85
88
  resource.save
86
89
 
87
90
  resource
@@ -97,8 +100,8 @@ module Her
97
100
  #
98
101
  # # If collection is empty:
99
102
  # # POST /users with `email=remi@example.com`
100
- def first_or_create(attrs = {})
101
- fetch.first || create(attrs)
103
+ def first_or_create(attributes = {})
104
+ fetch.first || create(attributes)
102
105
  end
103
106
 
104
107
  # Fetch a resource and build it if it's not found
@@ -112,8 +115,8 @@ module Her
112
115
  # # If collection is empty:
113
116
  # @user.email # => "remi@example.com"
114
117
  # @user.new? # => true
115
- def first_or_initialize(attrs = {})
116
- fetch.first || build(attrs)
118
+ def first_or_initialize(attributes = {})
119
+ fetch.first || build(attributes)
117
120
  end
118
121
 
119
122
  # @private
data/lib/her/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Her
2
- VERSION = "0.6.3"
2
+ VERSION = "0.6.4"
3
3
  end
@@ -8,7 +8,7 @@ describe Her::Model::Associations do
8
8
 
9
9
  context "single has_many association" do
10
10
  before { Foo::User.has_many :comments }
11
- its([:has_many]) { should eql [{ :name => :comments, :data_key => :comments, :class_name => "Comment", :path => "/comments", :inverse_of => nil }] }
11
+ its([:has_many]) { should eql [{ :name => :comments, :data_key => :comments, :default => [], :class_name => "Comment", :path => "/comments", :inverse_of => nil }] }
12
12
  end
13
13
 
14
14
  context "multiple has_many associations" do
@@ -17,12 +17,12 @@ describe Her::Model::Associations do
17
17
  Foo::User.has_many :posts
18
18
  end
19
19
 
20
- its([:has_many]) { should eql [{ :name => :comments, :data_key => :comments, :class_name => "Comment", :path => "/comments", :inverse_of => nil }, { :name => :posts, :data_key => :posts, :class_name => "Post", :path => "/posts", :inverse_of => nil }] }
20
+ its([:has_many]) { should eql [{ :name => :comments, :data_key => :comments, :default => [], :class_name => "Comment", :path => "/comments", :inverse_of => nil }, { :name => :posts, :data_key => :posts, :default => [], :class_name => "Post", :path => "/posts", :inverse_of => nil }] }
21
21
  end
22
22
 
23
23
  context "single has_one association" do
24
24
  before { Foo::User.has_one :category }
25
- its([:has_one]) { should eql [{ :name => :category, :data_key => :category, :class_name => "Category", :path => "/category" }] }
25
+ its([:has_one]) { should eql [{ :name => :category, :data_key => :category, :default => nil, :class_name => "Category", :path => "/category" }] }
26
26
  end
27
27
 
28
28
  context "multiple has_one associations" do
@@ -31,12 +31,12 @@ describe Her::Model::Associations do
31
31
  Foo::User.has_one :role
32
32
  end
33
33
 
34
- its([:has_one]) { should eql [{ :name => :category, :data_key => :category, :class_name => "Category", :path => "/category" }, { :name => :role, :data_key => :role, :class_name => "Role", :path => "/role" }] }
34
+ its([:has_one]) { should eql [{ :name => :category, :data_key => :category, :default => nil, :class_name => "Category", :path => "/category" }, { :name => :role, :data_key => :role, :default => nil, :class_name => "Role", :path => "/role" }] }
35
35
  end
36
36
 
37
37
  context "single belongs_to association" do
38
38
  before { Foo::User.belongs_to :organization }
39
- its([:belongs_to]) { should eql [{ :name => :organization, :data_key => :organization, :class_name => "Organization", :foreign_key => "organization_id", :path => "/organizations/:id" }] }
39
+ its([:belongs_to]) { should eql [{ :name => :organization, :data_key => :organization, :default => nil, :class_name => "Organization", :foreign_key => "organization_id", :path => "/organizations/:id" }] }
40
40
  end
41
41
 
42
42
  context "multiple belongs_to association" do
@@ -45,7 +45,7 @@ describe Her::Model::Associations do
45
45
  Foo::User.belongs_to :family
46
46
  end
47
47
 
48
- its([:belongs_to]) { should eql [{ :name => :organization, :data_key => :organization, :class_name => "Organization", :foreign_key => "organization_id", :path => "/organizations/:id" }, { :name => :family, :data_key => :family, :class_name => "Family", :foreign_key => "family_id", :path => "/families/:id" }] }
48
+ its([:belongs_to]) { should eql [{ :name => :organization, :data_key => :organization, :default => nil, :class_name => "Organization", :foreign_key => "organization_id", :path => "/organizations/:id" }, { :name => :family, :data_key => :family, :default => nil, :class_name => "Family", :foreign_key => "family_id", :path => "/families/:id" }] }
49
49
  end
50
50
  end
51
51
 
@@ -55,18 +55,18 @@ describe Her::Model::Associations do
55
55
 
56
56
  context "in base class" do
57
57
  context "single has_many association" do
58
- before { Foo::User.has_many :comments, :class_name => "Post", :inverse_of => :admin, :data_key => :user_comments }
59
- its([:has_many]) { should eql [{ :name => :comments, :data_key => :user_comments, :class_name => "Post", :path => "/comments", :inverse_of => :admin }] }
58
+ before { Foo::User.has_many :comments, :class_name => "Post", :inverse_of => :admin, :data_key => :user_comments, :default => {} }
59
+ its([:has_many]) { should eql [{ :name => :comments, :data_key => :user_comments, :default => {}, :class_name => "Post", :path => "/comments", :inverse_of => :admin }] }
60
60
  end
61
61
 
62
62
  context "signle has_one association" do
63
- before { Foo::User.has_one :category, :class_name => "Topic", :foreign_key => "topic_id", :data_key => :topic }
64
- its([:has_one]) { should eql [{ :name => :category, :data_key => :topic, :class_name => "Topic", :foreign_key => "topic_id", :path => "/category" }] }
63
+ before { Foo::User.has_one :category, :class_name => "Topic", :foreign_key => "topic_id", :data_key => :topic, :default => nil }
64
+ its([:has_one]) { should eql [{ :name => :category, :data_key => :topic, :default => nil, :class_name => "Topic", :foreign_key => "topic_id", :path => "/category" }] }
65
65
  end
66
66
 
67
67
  context "single belongs_to association" do
68
- before { Foo::User.belongs_to :organization, :class_name => "Business", :foreign_key => "org_id", :data_key => :org }
69
- its([:belongs_to]) { should eql [{ :name => :organization, :data_key => :org, :class_name => "Business", :foreign_key => "org_id", :path => "/organizations/:id" }] }
68
+ before { Foo::User.belongs_to :organization, :class_name => "Business", :foreign_key => "org_id", :data_key => :org, :default => true }
69
+ its([:belongs_to]) { should eql [{ :name => :organization, :data_key => :org, :default => true, :class_name => "Business", :foreign_key => "org_id", :path => "/organizations/:id" }] }
70
70
  end
71
71
  end
72
72
 
@@ -76,7 +76,7 @@ describe Her::Model::Associations do
76
76
  describe "associations accessor" do
77
77
  subject { Class.new(Foo::User).associations }
78
78
  its(:object_id) { should_not eql Foo::User.associations.object_id }
79
- its([:has_many]) { should eql [{ :name => :comments, :data_key => :comments, :class_name => "Post", :path => "/comments", :inverse_of => nil }] }
79
+ its([:has_many]) { should eql [{ :name => :comments, :data_key => :comments, :default => [], :class_name => "Post", :path => "/comments", :inverse_of => nil }] }
80
80
  end
81
81
  end
82
82
  end
@@ -145,11 +145,11 @@ describe Her::Model::Associations do
145
145
  end
146
146
 
147
147
  it "does not refetch the parents models data if they have been fetched before" do
148
- @user_with_included_data.comments.first.user.object_id.should == @user_with_included_data.object_id
148
+ @user_with_included_data.comments.first.user.fetch.object_id.should == @user_with_included_data.object_id
149
149
  end
150
150
 
151
151
  it "uses the given inverse_of key to set the parent model" do
152
- @user_with_included_data.posts.first.admin.object_id.should == @user_with_included_data.object_id
152
+ @user_with_included_data.posts.first.admin.fetch.object_id.should == @user_with_included_data.object_id
153
153
  end
154
154
 
155
155
  it "fetches data that was not included through has_many" do
@@ -163,4 +163,85 @@ describe Her::Model::Attributes do
163
163
  expect { @user.metadata }.to raise_error(NoMethodError)
164
164
  end
165
165
  end
166
+
167
+ context "overwriting default attribute methods" do
168
+ context "for getter method" do
169
+ before do
170
+ Her::API.setup :url => "https://api.example.com" do |builder|
171
+ builder.use Her::Middleware::FirstLevelParseJSON
172
+ builder.adapter :test do |stub|
173
+ stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :document => { :url => "http://example.com" } }.to_json] }
174
+ end
175
+ end
176
+
177
+ spawn_model 'Foo::User' do
178
+ def document
179
+ @attributes[:document][:url]
180
+ end
181
+ end
182
+ end
183
+
184
+ it "bypasses Her's method" do
185
+ @user = Foo::User.find(1)
186
+ @user.document.should == "http://example.com"
187
+
188
+ @user = Foo::User.find(1)
189
+ @user.document.should == "http://example.com"
190
+ end
191
+ end
192
+
193
+ context "for setter method" do
194
+ before do
195
+ Her::API.setup :url => "https://api.example.com" do |builder|
196
+ builder.use Her::Middleware::FirstLevelParseJSON
197
+ builder.adapter :test do |stub|
198
+ stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :document => { :url => "http://example.com" } }.to_json] }
199
+ end
200
+ end
201
+
202
+ spawn_model 'Foo::User' do
203
+ def document=(document)
204
+ @attributes[:document] = document[:url]
205
+ end
206
+ end
207
+ end
208
+
209
+ it "bypasses Her's method" do
210
+ @user = Foo::User.find(1)
211
+ @user.document.should == "http://example.com"
212
+
213
+ @user = Foo::User.find(1)
214
+ @user.document.should == "http://example.com"
215
+ end
216
+ end
217
+
218
+ context "for predicate method" do
219
+ before do
220
+ Her::API.setup :url => "https://api.example.com" do |builder|
221
+ builder.use Her::Middleware::FirstLevelParseJSON
222
+ builder.adapter :test do |stub|
223
+ stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke", :document => { :url => nil } }.to_json] }
224
+ stub.get("/users/2") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :document => { :url => "http://example.com" } }.to_json] }
225
+ end
226
+ end
227
+
228
+ spawn_model 'Foo::User' do
229
+ def document?
230
+ document[:url].present?
231
+ end
232
+ end
233
+ end
234
+
235
+ it "byoasses Her's method" do
236
+ @user = Foo::User.find(1)
237
+ @user.document?.should be_false
238
+
239
+ @user = Foo::User.find(1)
240
+ @user.document?.should be_false
241
+
242
+ @user = Foo::User.find(2)
243
+ @user.document?.should be_true
244
+ end
245
+ end
246
+ end
166
247
  end
@@ -10,7 +10,19 @@ describe Her::Model::Relation do
10
10
  builder.adapter :test do |stub|
11
11
  stub.get("/users?foo=1&bar=2") { |env| ok! [{ :id => 2, :fullname => "Tobias Fünke" }] }
12
12
  stub.get("/users?admin=1") { |env| ok! [{ :id => 1, :fullname => "Tobias Fünke" }] }
13
- stub.get("/users") { |env| ok! [{ :id => 1, :fullname => "Tobias Fünke" }, { :id => 2, :fullname => "Lindsay Fünke" }] }
13
+
14
+ stub.get("/users") do |env|
15
+ ok! [
16
+ { :id => 1, :fullname => "Tobias Fünke" },
17
+ { :id => 2, :fullname => "Lindsay Fünke" },
18
+ @created_user,
19
+ ].compact
20
+ end
21
+
22
+ stub.post('/users') do |env|
23
+ @created_user = { :id => 3, :fullname => 'George Michael Bluth' }
24
+ ok! @created_user
25
+ end
14
26
  end
15
27
  end
16
28
 
@@ -33,6 +45,12 @@ describe Her::Model::Relation do
33
45
  @user = Foo::User.where(:foo => 1).where(:bar => 2).first
34
46
  @user.id.should == 2
35
47
  end
48
+
49
+ it "does not reuse relations" do
50
+ Foo::User.all.should have(2).items
51
+ Foo::User.create(:fullname => 'George Michael Bluth').id.should == 3
52
+ Foo::User.all.should have(3).items
53
+ end
36
54
  end
37
55
 
38
56
  context "for parent class" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: her
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rémi Prévost
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-24 00:00:00.000000000 Z
11
+ date: 2013-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -118,6 +118,7 @@ files:
118
118
  - .gitignore
119
119
  - .rspec
120
120
  - .travis.yml
121
+ - .yardopts
121
122
  - CONTRIBUTING.md
122
123
  - Gemfile
123
124
  - LICENSE
@@ -175,7 +176,7 @@ files:
175
176
  - spec/support/macros/her_macros.rb
176
177
  - spec/support/macros/model_macros.rb
177
178
  - spec/support/macros/request_macros.rb
178
- homepage: http://remiprev.github.com/her
179
+ homepage: http://her-rb.org
179
180
  licenses:
180
181
  - MIT
181
182
  metadata: {}