her 0.6.3 → 0.6.4

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.
@@ -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: {}