her 0.6.8 → 0.7
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 +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +3 -3
- data/Gemfile +8 -0
- data/README.md +49 -11
- data/gemfiles/Gemfile.activemodel-3.2.x +2 -0
- data/gemfiles/Gemfile.activemodel-4.0 +2 -0
- data/gemfiles/Gemfile.activemodel-4.1 +7 -0
- data/her.gemspec +5 -4
- data/lib/her/api.rb +8 -2
- data/lib/her/errors.rb +9 -0
- data/lib/her/middleware/parse_json.rb +1 -1
- data/lib/her/model/associations.rb +1 -0
- data/lib/her/model/associations/association.rb +13 -29
- data/lib/her/model/associations/association_proxy.rb +46 -0
- data/lib/her/model/associations/belongs_to_association.rb +4 -2
- data/lib/her/model/associations/has_many_association.rb +2 -1
- data/lib/her/model/associations/has_one_association.rb +2 -1
- data/lib/her/model/attributes.rb +18 -19
- data/lib/her/model/http.rb +5 -1
- data/lib/her/model/orm.rb +12 -1
- data/lib/her/model/parse.rb +27 -26
- data/lib/her/model/paths.rb +1 -1
- data/lib/her/model/relation.rb +2 -0
- data/lib/her/version.rb +1 -1
- data/spec/middleware/first_level_parse_json_spec.rb +5 -0
- data/spec/model/associations_spec.rb +76 -5
- data/spec/model/attributes_spec.rb +15 -9
- data/spec/model/dirty_spec.rb +19 -7
- data/spec/model/http_spec.rb +8 -0
- data/spec/model/introspection_spec.rb +5 -0
- data/spec/model/orm_spec.rb +77 -11
- data/spec/model/parse_spec.rb +30 -1
- data/spec/model/paths_spec.rb +4 -4
- data/spec/model/relation_spec.rb +4 -4
- data/spec/spec_helper.rb +4 -0
- data/spec/support/macros/request_macros.rb +9 -1
- metadata +63 -53
@@ -2,6 +2,7 @@ module Her
|
|
2
2
|
module Model
|
3
3
|
module Associations
|
4
4
|
class HasManyAssociation < Association
|
5
|
+
|
5
6
|
# @private
|
6
7
|
def self.attach(klass, name, opts)
|
7
8
|
opts = {
|
@@ -19,7 +20,7 @@ module Her
|
|
19
20
|
cached_name = :"@_her_association_#{name}"
|
20
21
|
|
21
22
|
cached_data = (instance_variable_defined?(cached_name) && instance_variable_get(cached_name))
|
22
|
-
cached_data || instance_variable_set(cached_name, Her::Model::Associations::HasManyAssociation.
|
23
|
+
cached_data || instance_variable_set(cached_name, Her::Model::Associations::HasManyAssociation.proxy(self, #{opts.inspect}))
|
23
24
|
end
|
24
25
|
RUBY
|
25
26
|
end
|
@@ -2,6 +2,7 @@ module Her
|
|
2
2
|
module Model
|
3
3
|
module Associations
|
4
4
|
class HasOneAssociation < Association
|
5
|
+
|
5
6
|
# @private
|
6
7
|
def self.attach(klass, name, opts)
|
7
8
|
opts = {
|
@@ -18,7 +19,7 @@ module Her
|
|
18
19
|
cached_name = :"@_her_association_#{name}"
|
19
20
|
|
20
21
|
cached_data = (instance_variable_defined?(cached_name) && instance_variable_get(cached_name))
|
21
|
-
cached_data || instance_variable_set(cached_name, Her::Model::Associations::HasOneAssociation.
|
22
|
+
cached_data || instance_variable_set(cached_name, Her::Model::Associations::HasOneAssociation.proxy(self, #{opts.inspect}))
|
22
23
|
end
|
23
24
|
RUBY
|
24
25
|
end
|
data/lib/her/model/attributes.rb
CHANGED
@@ -33,8 +33,12 @@ module Her
|
|
33
33
|
# @private
|
34
34
|
def self.initialize_collection(klass, parsed_data={})
|
35
35
|
collection_data = klass.extract_array(parsed_data).map do |item_data|
|
36
|
-
|
37
|
-
|
36
|
+
if item_data.kind_of?(klass)
|
37
|
+
resource = item_data
|
38
|
+
else
|
39
|
+
resource = klass.new(klass.parse(item_data))
|
40
|
+
resource.run_callbacks :find
|
41
|
+
end
|
38
42
|
resource
|
39
43
|
end
|
40
44
|
Her::Collection.new(collection_data, parsed_data[:metadata], parsed_data[:errors])
|
@@ -77,14 +81,9 @@ module Her
|
|
77
81
|
end
|
78
82
|
end
|
79
83
|
|
80
|
-
# @private
|
81
|
-
def respond_to?(method, include_private = false)
|
82
|
-
method.to_s.end_with?('=') || method.to_s.end_with?('?') || @attributes.include?(method) || super
|
83
|
-
end
|
84
|
-
|
85
84
|
# @private
|
86
85
|
def respond_to_missing?(method, include_private = false)
|
87
|
-
method.to_s.end_with?('=') || method.to_s.end_with?('?') || @attributes.include?(method) ||
|
86
|
+
method.to_s.end_with?('=') || method.to_s.end_with?('?') || @attributes.include?(method) || super
|
88
87
|
end
|
89
88
|
|
90
89
|
# Assign new attributes to a resource
|
@@ -168,6 +167,7 @@ module Her
|
|
168
167
|
#
|
169
168
|
# @private
|
170
169
|
def new_from_parsed_data(parsed_data)
|
170
|
+
parsed_data = parsed_data.with_indifferent_access
|
171
171
|
new(parse(parsed_data[:data]).merge :_metadata => parsed_data[:metadata], :_errors => parsed_data[:errors])
|
172
172
|
end
|
173
173
|
|
@@ -185,20 +185,19 @@ module Her
|
|
185
185
|
attributes.each do |attribute|
|
186
186
|
attribute = attribute.to_sym
|
187
187
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
end
|
188
|
+
unless instance_methods.include?(:"#{attribute}=")
|
189
|
+
define_method("#{attribute}=") do |value|
|
190
|
+
@attributes[:"#{attribute}"] = nil unless @attributes.include?(:"#{attribute}")
|
191
|
+
self.send(:"#{attribute}_will_change!") if @attributes[:'#{attribute}'] != value
|
192
|
+
@attributes[:"#{attribute}"] = value
|
194
193
|
end
|
194
|
+
end
|
195
195
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
end
|
196
|
+
unless instance_methods.include?(:"#{attribute}?")
|
197
|
+
define_method("#{attribute}?") do
|
198
|
+
@attributes.include?(:"#{attribute}") && @attributes[:"#{attribute}"].present?
|
200
199
|
end
|
201
|
-
|
200
|
+
end
|
202
201
|
end
|
203
202
|
end
|
204
203
|
|
data/lib/her/model/http.rb
CHANGED
@@ -39,9 +39,13 @@ module Her
|
|
39
39
|
superclass.use_api if superclass.respond_to?(:use_api)
|
40
40
|
end
|
41
41
|
|
42
|
-
|
42
|
+
unless value
|
43
|
+
return (@_her_use_api.respond_to? :call) ? @_her_use_api.call : @_her_use_api
|
44
|
+
end
|
45
|
+
|
43
46
|
@_her_use_api = value
|
44
47
|
end
|
48
|
+
|
45
49
|
alias her_api use_api
|
46
50
|
alias uses_api use_api
|
47
51
|
|
data/lib/her/model/orm.rb
CHANGED
@@ -46,7 +46,10 @@ module Her
|
|
46
46
|
@response_errors = parsed_data[:errors]
|
47
47
|
|
48
48
|
return false if !response.success? || @response_errors.any?
|
49
|
-
|
49
|
+
if self.changed_attributes.present?
|
50
|
+
@previously_changed = self.changed_attributes.clone
|
51
|
+
self.changed_attributes.clear
|
52
|
+
end
|
50
53
|
end
|
51
54
|
end
|
52
55
|
end
|
@@ -54,6 +57,14 @@ module Her
|
|
54
57
|
self
|
55
58
|
end
|
56
59
|
|
60
|
+
# Similar to save(), except that ResourceInvalid is raised if the save fails
|
61
|
+
def save!
|
62
|
+
if !self.save
|
63
|
+
raise Her::Errors::ResourceInvalid, self
|
64
|
+
end
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
57
68
|
# Destroy a resource
|
58
69
|
#
|
59
70
|
# @example
|
data/lib/her/model/parse.rb
CHANGED
@@ -10,7 +10,7 @@ module Her
|
|
10
10
|
# @user.to_params
|
11
11
|
# # => { :id => 1, :name => 'John Smith' }
|
12
12
|
def to_params
|
13
|
-
self.class.to_params(self.attributes)
|
13
|
+
self.class.to_params(self.attributes, self.changes)
|
14
14
|
end
|
15
15
|
|
16
16
|
module ClassMethods
|
@@ -23,8 +23,15 @@ module Her
|
|
23
23
|
end
|
24
24
|
|
25
25
|
# @private
|
26
|
-
def to_params(attributes)
|
27
|
-
|
26
|
+
def to_params(attributes, changes={})
|
27
|
+
filtered_attributes = attributes.dup.symbolize_keys
|
28
|
+
if her_api.options[:send_only_modified_attributes]
|
29
|
+
filtered_attributes = changes.symbolize_keys.keys.inject({}) do |hash, attribute|
|
30
|
+
hash[attribute] = filtered_attributes[attribute]
|
31
|
+
hash
|
32
|
+
end
|
33
|
+
end
|
34
|
+
include_root_in_json? ? { included_root_element => filtered_attributes } : filtered_attributes
|
28
35
|
end
|
29
36
|
|
30
37
|
# Return or change the value of `include_root_in_json`
|
@@ -34,15 +41,13 @@ module Her
|
|
34
41
|
# include Her::Model
|
35
42
|
# include_root_in_json true
|
36
43
|
# end
|
37
|
-
def include_root_in_json(value
|
38
|
-
@_her_include_root_in_json ||= begin
|
39
|
-
superclass.include_root_in_json if superclass.respond_to?(:include_root_in_json)
|
40
|
-
end
|
41
|
-
|
42
|
-
return @_her_include_root_in_json unless value
|
44
|
+
def include_root_in_json(value)
|
43
45
|
@_her_include_root_in_json = value
|
44
46
|
end
|
45
|
-
|
47
|
+
|
48
|
+
def include_root_in_json?
|
49
|
+
@_her_include_root_in_json || (superclass.respond_to?(:include_root_in_json?) && superclass.include_root_in_json?)
|
50
|
+
end
|
46
51
|
|
47
52
|
# Return or change the value of `parse_root_in`
|
48
53
|
#
|
@@ -51,16 +56,14 @@ module Her
|
|
51
56
|
# include Her::Model
|
52
57
|
# parse_root_in_json true
|
53
58
|
# end
|
54
|
-
def parse_root_in_json(value
|
55
|
-
@_her_parse_root_in_json ||= begin
|
56
|
-
superclass.parse_root_in_json if superclass.respond_to?(:parse_root_in_json)
|
57
|
-
end
|
58
|
-
|
59
|
-
return @_her_parse_root_in_json unless value
|
59
|
+
def parse_root_in_json(value, options = {})
|
60
60
|
@_her_parse_root_in_json = value
|
61
61
|
@_her_parse_root_in_json_format = options[:format]
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
|
+
def parse_root_in_json?
|
65
|
+
@_her_parse_root_in_json || (superclass.respond_to?(:parse_root_in_json?) && superclass.parse_root_in_json?)
|
66
|
+
end
|
64
67
|
|
65
68
|
# Return or change the value of `request_new_object_on_build`
|
66
69
|
#
|
@@ -70,14 +73,12 @@ module Her
|
|
70
73
|
# request_new_object_on_build true
|
71
74
|
# end
|
72
75
|
def request_new_object_on_build(value = nil)
|
73
|
-
@_her_request_new_object_on_build ||= begin
|
74
|
-
superclass.request_new_object_on_build if superclass.respond_to?(:request_new_object_on_build)
|
75
|
-
end
|
76
|
-
|
77
|
-
return @_her_request_new_object_on_build unless value
|
78
76
|
@_her_request_new_object_on_build = value
|
79
77
|
end
|
80
|
-
|
78
|
+
|
79
|
+
def request_new_object_on_build?
|
80
|
+
@_her_request_new_object_on_build || (superclass.respond_to?(:request_new_object_on_build?) && superclass.request_new_object_on_build?)
|
81
|
+
end
|
81
82
|
|
82
83
|
# Return or change the value of `root_element`. Always defaults to the base name of the class.
|
83
84
|
#
|
@@ -132,17 +133,17 @@ module Her
|
|
132
133
|
|
133
134
|
# @private
|
134
135
|
def included_root_element
|
135
|
-
include_root_in_json == true ? root_element : include_root_in_json
|
136
|
+
include_root_in_json? == true ? root_element : include_root_in_json?
|
136
137
|
end
|
137
138
|
|
138
139
|
# @private
|
139
140
|
def parsed_root_element
|
140
|
-
parse_root_in_json == true ? root_element : parse_root_in_json
|
141
|
+
parse_root_in_json? == true ? root_element : parse_root_in_json?
|
141
142
|
end
|
142
143
|
|
143
144
|
# @private
|
144
145
|
def active_model_serializers_format?
|
145
|
-
@_her_parse_root_in_json_format == :active_model_serializers
|
146
|
+
@_her_parse_root_in_json_format == :active_model_serializers || (superclass.respond_to?(:active_model_serializers_format?) && superclass.active_model_serializers_format?)
|
146
147
|
end
|
147
148
|
end
|
148
149
|
end
|
data/lib/her/model/paths.rb
CHANGED
@@ -94,7 +94,7 @@ module Her
|
|
94
94
|
unless path.is_a?(String)
|
95
95
|
parameters = path.try(:with_indifferent_access) || parameters
|
96
96
|
path =
|
97
|
-
if parameters.include?(primary_key) && parameters[primary_key]
|
97
|
+
if parameters.include?(primary_key) && parameters[primary_key] && !parameters[primary_key].kind_of?(Array)
|
98
98
|
resource_path.dup
|
99
99
|
else
|
100
100
|
collection_path.dup
|
data/lib/her/model/relation.rb
CHANGED
@@ -84,6 +84,7 @@ module Her
|
|
84
84
|
# # Fetched via GET "/users/1" and GET "/users/2"
|
85
85
|
def find(*ids)
|
86
86
|
params = @params.merge(ids.last.is_a?(Hash) ? ids.pop : {})
|
87
|
+
ids = Array(params[@parent.primary_key]) if params.key?(@parent.primary_key)
|
87
88
|
|
88
89
|
results = ids.flatten.compact.uniq.map do |id|
|
89
90
|
resource = nil
|
@@ -95,6 +96,7 @@ module Her
|
|
95
96
|
@parent.request(request_params) do |parsed_data, response|
|
96
97
|
if response.success?
|
97
98
|
resource = @parent.new_from_parsed_data(parsed_data)
|
99
|
+
resource.instance_variable_set(:@changed_attributes, {})
|
98
100
|
resource.run_callbacks :find
|
99
101
|
else
|
100
102
|
return nil
|
data/lib/her/version.rb
CHANGED
@@ -7,6 +7,7 @@ describe Her::Middleware::FirstLevelParseJSON do
|
|
7
7
|
let(:body_with_errors) { "{\"id\": 1, \"name\": \"Tobias Fünke\", \"errors\": { \"name\": [ \"not_valid\", \"should_be_present\" ] }, \"metadata\": 3}" }
|
8
8
|
let(:body_with_malformed_json) { "wut." }
|
9
9
|
let(:body_with_invalid_json) { "true" }
|
10
|
+
let(:empty_body) { '' }
|
10
11
|
let(:nil_body) { nil }
|
11
12
|
|
12
13
|
it "parses body as json" do
|
@@ -45,6 +46,10 @@ describe Her::Middleware::FirstLevelParseJSON do
|
|
45
46
|
subject.parse(nil_body)[:data].should eq({})
|
46
47
|
end
|
47
48
|
|
49
|
+
it 'ensures that an empty response returns an empty hash' do
|
50
|
+
subject.parse(empty_body)[:data].should eq({})
|
51
|
+
end
|
52
|
+
|
48
53
|
context 'with status code 204' do
|
49
54
|
it 'returns an empty body' do
|
50
55
|
env = { :status => 204 }
|
@@ -59,7 +59,7 @@ describe Her::Model::Associations do
|
|
59
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
|
-
context "
|
62
|
+
context "single has_one association" do
|
63
63
|
before { Foo::User.has_one :category, :class_name => "Topic", :foreign_key => "topic_id", :data_key => :topic, :default => nil }
|
64
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
|
@@ -146,11 +146,11 @@ describe Her::Model::Associations do
|
|
146
146
|
end
|
147
147
|
|
148
148
|
it "does not refetch the parents models data if they have been fetched before" do
|
149
|
-
@user_with_included_data.comments.first.user.
|
149
|
+
@user_with_included_data.comments.first.user.object_id.should == @user_with_included_data.object_id
|
150
150
|
end
|
151
151
|
|
152
152
|
it "uses the given inverse_of key to set the parent model" do
|
153
|
-
@user_with_included_data.posts.first.admin.
|
153
|
+
@user_with_included_data.posts.first.admin.object_id.should == @user_with_included_data.object_id
|
154
154
|
end
|
155
155
|
|
156
156
|
it "fetches data that was not included through has_many" do
|
@@ -198,8 +198,8 @@ describe Her::Model::Associations do
|
|
198
198
|
end
|
199
199
|
|
200
200
|
it "can tell if it has a association" do
|
201
|
-
@user_without_included_data.has_association?(:unknown_association).should
|
202
|
-
@user_without_included_data.has_association?(:organization).should
|
201
|
+
@user_without_included_data.has_association?(:unknown_association).should be false
|
202
|
+
@user_without_included_data.has_association?(:organization).should be true
|
203
203
|
end
|
204
204
|
|
205
205
|
it "fetches the resource corresponding to a named association" do
|
@@ -217,6 +217,11 @@ describe Her::Model::Associations do
|
|
217
217
|
comment.id.should eq(5)
|
218
218
|
end
|
219
219
|
|
220
|
+
it "'s associations responds to #empty?" do
|
221
|
+
@user_without_included_data.organization.respond_to?(:empty?).should be_truthy
|
222
|
+
@user_without_included_data.organization.should_not be_empty
|
223
|
+
end
|
224
|
+
|
220
225
|
[:create, :save_existing, :destroy].each do |type|
|
221
226
|
context "after #{type}" do
|
222
227
|
let(:subject) { self.send("user_with_included_data_after_#{type}")}
|
@@ -244,6 +249,7 @@ describe Her::Model::Associations do
|
|
244
249
|
builder.use Faraday::Request::UrlEncoded
|
245
250
|
builder.adapter :test do |stub|
|
246
251
|
stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke", :organization => { :id => 1, :name => "Bluth Company Inc." }, :organization_id => 1 }.to_json] }
|
252
|
+
stub.get("/users/4") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke", :organization => { :id => 1, :name => "Bluth Company Inc." } }.to_json] }
|
247
253
|
stub.get("/users/2") { |env| [200, {}, { :id => 2, :name => "Lindsay Fünke", :organization_id => 1 }.to_json] }
|
248
254
|
stub.get("/users/3") { |env| [200, {}, { :id => 2, :name => "Lindsay Fünke", :company => nil }.to_json] }
|
249
255
|
stub.get("/companies/1") { |env| [200, {}, { :id => 1, :name => "Bluth Company" }.to_json] }
|
@@ -259,6 +265,7 @@ describe Her::Model::Associations do
|
|
259
265
|
@user_with_included_data = Foo::User.find(1)
|
260
266
|
@user_without_included_data = Foo::User.find(2)
|
261
267
|
@user_with_included_nil_data = Foo::User.find(3)
|
268
|
+
@user_with_included_data_but_no_fk = Foo::User.find(4)
|
262
269
|
end
|
263
270
|
|
264
271
|
it "maps an array of included data through belongs_to" do
|
@@ -276,6 +283,57 @@ describe Her::Model::Associations do
|
|
276
283
|
@user_without_included_data.company.id.should == 1
|
277
284
|
@user_without_included_data.company.name.should == "Bluth Company"
|
278
285
|
end
|
286
|
+
|
287
|
+
it "does not require foreugn key to have nested object" do
|
288
|
+
@user_with_included_data_but_no_fk.company.name.should == "Bluth Company Inc."
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
context "object returned by the association method" do
|
293
|
+
before do
|
294
|
+
spawn_model "Foo::Role" do
|
295
|
+
def present?
|
296
|
+
"of_course"
|
297
|
+
end
|
298
|
+
end
|
299
|
+
spawn_model "Foo::User" do
|
300
|
+
has_one :role
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
let(:associated_value) { Foo::Role.new }
|
305
|
+
let(:user_with_role) do
|
306
|
+
Foo::User.new.tap { |user| user.role = associated_value }
|
307
|
+
end
|
308
|
+
|
309
|
+
subject { user_with_role.role }
|
310
|
+
|
311
|
+
it "doesnt mask the object's basic methods" do
|
312
|
+
subject.class.should == Foo::Role
|
313
|
+
end
|
314
|
+
|
315
|
+
it "doesnt mask core methods like extend" do
|
316
|
+
committer = Module.new
|
317
|
+
subject.extend committer
|
318
|
+
associated_value.should be_kind_of committer
|
319
|
+
end
|
320
|
+
|
321
|
+
it "can return the association object" do
|
322
|
+
subject.association.should be_kind_of Her::Model::Associations::Association
|
323
|
+
end
|
324
|
+
|
325
|
+
it "still can call fetch via the association" do
|
326
|
+
subject.association.fetch.should eq associated_value
|
327
|
+
end
|
328
|
+
|
329
|
+
it "calls missing methods on associated value" do
|
330
|
+
subject.present?.should == "of_course"
|
331
|
+
end
|
332
|
+
|
333
|
+
it "can use association methods like where" do
|
334
|
+
subject.where(role: 'committer').association.
|
335
|
+
params.should include :role
|
336
|
+
end
|
279
337
|
end
|
280
338
|
|
281
339
|
context "building and creating association data" do
|
@@ -318,5 +376,18 @@ describe Her::Model::Associations do
|
|
318
376
|
@user.comments.should == [@comment]
|
319
377
|
end
|
320
378
|
end
|
379
|
+
|
380
|
+
context "with #new" do
|
381
|
+
it "creates nested models from hash attibutes" do
|
382
|
+
user = Foo::User.new(:name => "vic", :comments => [{:text => "hello"}])
|
383
|
+
user.comments.first.text.should == "hello"
|
384
|
+
end
|
385
|
+
|
386
|
+
it "assigns nested models if given as already constructed objects" do
|
387
|
+
bye = Foo::Comment.new(:text => "goodbye")
|
388
|
+
user = Foo::User.new(:name => 'vic', :comments => [bye])
|
389
|
+
user.comments.first.text.should == 'goodbye'
|
390
|
+
end
|
391
|
+
end
|
321
392
|
end
|
322
393
|
end
|
@@ -7,7 +7,7 @@ describe Her::Model::Attributes do
|
|
7
7
|
|
8
8
|
it "handles new resource" do
|
9
9
|
@new_user = Foo::User.new(:fullname => "Tobias Fünke")
|
10
|
-
@new_user.new?.should
|
10
|
+
@new_user.new?.should be_truthy
|
11
11
|
@new_user.fullname.should == "Tobias Fünke"
|
12
12
|
end
|
13
13
|
|
@@ -19,17 +19,17 @@ describe Her::Model::Attributes do
|
|
19
19
|
it "handles method missing for getter" do
|
20
20
|
@new_user = Foo::User.new(:fullname => 'Mayonegg')
|
21
21
|
expect { @new_user.unknown_method_for_a_user }.to raise_error(NoMethodError)
|
22
|
-
expect { @new_user.fullname }.
|
22
|
+
expect { @new_user.fullname }.not_to raise_error()
|
23
23
|
end
|
24
24
|
|
25
25
|
it "handles method missing for setter" do
|
26
26
|
@new_user = Foo::User.new
|
27
|
-
expect { @new_user.fullname = "Tobias Fünke" }.
|
27
|
+
expect { @new_user.fullname = "Tobias Fünke" }.not_to raise_error()
|
28
28
|
end
|
29
29
|
|
30
30
|
it "handles method missing for query" do
|
31
31
|
@new_user = Foo::User.new
|
32
|
-
expect { @new_user.fullname? }.
|
32
|
+
expect { @new_user.fullname? }.not_to raise_error()
|
33
33
|
end
|
34
34
|
|
35
35
|
it "handles respond_to for getter" do
|
@@ -59,6 +59,12 @@ describe Her::Model::Attributes do
|
|
59
59
|
@new_user.get_attribute(:unknown_method_for_a_user).should be_nil
|
60
60
|
@new_user.get_attribute(:fullname).should == 'Mayonegg'
|
61
61
|
end
|
62
|
+
|
63
|
+
it "handles get_attribute for getter with dash" do
|
64
|
+
@new_user = Foo::User.new(:'life-span' => '3 years')
|
65
|
+
@new_user.get_attribute(:unknown_method_for_a_user).should be_nil
|
66
|
+
@new_user.get_attribute(:'life-span').should == '3 years'
|
67
|
+
end
|
62
68
|
end
|
63
69
|
|
64
70
|
|
@@ -113,14 +119,14 @@ describe Her::Model::Attributes do
|
|
113
119
|
end
|
114
120
|
|
115
121
|
it "returns false for a non-resource with the same data" do
|
116
|
-
fake_user =
|
122
|
+
fake_user = double(:data => { :id => 1, :fullname => "Lindsay Fünke" })
|
117
123
|
user.should_not == fake_user
|
118
124
|
end
|
119
125
|
|
120
126
|
it "delegates eql? to ==" do
|
121
127
|
other = Object.new
|
122
128
|
user.should_receive(:==).with(other).and_return(true)
|
123
|
-
user.eql?(other).should
|
129
|
+
user.eql?(other).should be_truthy
|
124
130
|
end
|
125
131
|
|
126
132
|
it "treats equal resources as equal for Array#uniq" do
|
@@ -249,13 +255,13 @@ describe Her::Model::Attributes do
|
|
249
255
|
|
250
256
|
it "byoasses Her's method" do
|
251
257
|
@user = Foo::User.find(1)
|
252
|
-
@user.document?.should
|
258
|
+
@user.document?.should be_falsey
|
253
259
|
|
254
260
|
@user = Foo::User.find(1)
|
255
|
-
@user.document?.should
|
261
|
+
@user.document?.should be_falsey
|
256
262
|
|
257
263
|
@user = Foo::User.find(2)
|
258
|
-
@user.document?.should
|
264
|
+
@user.document?.should be_truthy
|
259
265
|
end
|
260
266
|
end
|
261
267
|
end
|