herr 0.7.3
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 +4 -0
- data/.rspec +1 -0
- data/.travis.yml +15 -0
- data/.yardopts +2 -0
- data/CONTRIBUTING.md +26 -0
- data/Gemfile +10 -0
- data/LICENSE +7 -0
- data/README.md +990 -0
- data/Rakefile +11 -0
- data/UPGRADE.md +81 -0
- data/gemfiles/Gemfile.activemodel-3.2.x +7 -0
- data/gemfiles/Gemfile.activemodel-4.0 +7 -0
- data/gemfiles/Gemfile.activemodel-4.1 +7 -0
- data/gemfiles/Gemfile.activemodel-4.2 +7 -0
- data/her.gemspec +30 -0
- data/lib/her.rb +16 -0
- data/lib/her/api.rb +115 -0
- data/lib/her/collection.rb +12 -0
- data/lib/her/errors.rb +27 -0
- data/lib/her/middleware.rb +10 -0
- data/lib/her/middleware/accept_json.rb +17 -0
- data/lib/her/middleware/first_level_parse_json.rb +36 -0
- data/lib/her/middleware/parse_json.rb +21 -0
- data/lib/her/middleware/second_level_parse_json.rb +36 -0
- data/lib/her/model.rb +72 -0
- data/lib/her/model/associations.rb +141 -0
- data/lib/her/model/associations/association.rb +103 -0
- data/lib/her/model/associations/association_proxy.rb +46 -0
- data/lib/her/model/associations/belongs_to_association.rb +96 -0
- data/lib/her/model/associations/has_many_association.rb +100 -0
- data/lib/her/model/associations/has_one_association.rb +79 -0
- data/lib/her/model/attributes.rb +266 -0
- data/lib/her/model/base.rb +33 -0
- data/lib/her/model/deprecated_methods.rb +61 -0
- data/lib/her/model/http.rb +114 -0
- data/lib/her/model/introspection.rb +65 -0
- data/lib/her/model/nested_attributes.rb +45 -0
- data/lib/her/model/orm.rb +205 -0
- data/lib/her/model/parse.rb +227 -0
- data/lib/her/model/paths.rb +121 -0
- data/lib/her/model/relation.rb +164 -0
- data/lib/her/version.rb +3 -0
- data/spec/api_spec.rb +131 -0
- data/spec/collection_spec.rb +26 -0
- data/spec/middleware/accept_json_spec.rb +10 -0
- data/spec/middleware/first_level_parse_json_spec.rb +62 -0
- data/spec/middleware/second_level_parse_json_spec.rb +35 -0
- data/spec/model/associations_spec.rb +416 -0
- data/spec/model/attributes_spec.rb +268 -0
- data/spec/model/callbacks_spec.rb +145 -0
- data/spec/model/dirty_spec.rb +86 -0
- data/spec/model/http_spec.rb +194 -0
- data/spec/model/introspection_spec.rb +76 -0
- data/spec/model/nested_attributes_spec.rb +134 -0
- data/spec/model/orm_spec.rb +479 -0
- data/spec/model/parse_spec.rb +373 -0
- data/spec/model/paths_spec.rb +341 -0
- data/spec/model/relation_spec.rb +226 -0
- data/spec/model/validations_spec.rb +42 -0
- data/spec/model_spec.rb +31 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/extensions/array.rb +5 -0
- data/spec/support/extensions/hash.rb +5 -0
- data/spec/support/macros/her_macros.rb +17 -0
- data/spec/support/macros/model_macros.rb +29 -0
- data/spec/support/macros/request_macros.rb +27 -0
- metadata +280 -0
@@ -0,0 +1,268 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.join(File.dirname(__FILE__), "../spec_helper.rb")
|
3
|
+
|
4
|
+
describe Her::Model::Attributes do
|
5
|
+
context "mapping data to Ruby objects" do
|
6
|
+
before { spawn_model "Foo::User" }
|
7
|
+
|
8
|
+
it "handles new resource" do
|
9
|
+
@new_user = Foo::User.new(:fullname => "Tobias Fünke")
|
10
|
+
@new_user.new?.should be_truthy
|
11
|
+
@new_user.fullname.should == "Tobias Fünke"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "accepts new resource with strings as hash keys" do
|
15
|
+
@new_user = Foo::User.new('fullname' => "Tobias Fünke")
|
16
|
+
@new_user.fullname.should == "Tobias Fünke"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "handles method missing for getter" do
|
20
|
+
@new_user = Foo::User.new(:fullname => 'Mayonegg')
|
21
|
+
expect { @new_user.unknown_method_for_a_user }.to raise_error(NoMethodError)
|
22
|
+
expect { @new_user.fullname }.not_to raise_error()
|
23
|
+
end
|
24
|
+
|
25
|
+
it "handles method missing for setter" do
|
26
|
+
@new_user = Foo::User.new
|
27
|
+
expect { @new_user.fullname = "Tobias Fünke" }.not_to raise_error()
|
28
|
+
end
|
29
|
+
|
30
|
+
it "handles method missing for query" do
|
31
|
+
@new_user = Foo::User.new
|
32
|
+
expect { @new_user.fullname? }.not_to raise_error()
|
33
|
+
end
|
34
|
+
|
35
|
+
it "handles respond_to for getter" do
|
36
|
+
@new_user = Foo::User.new(:fullname => 'Mayonegg')
|
37
|
+
@new_user.should_not respond_to(:unknown_method_for_a_user)
|
38
|
+
@new_user.should respond_to(:fullname)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "handles respond_to for setter" do
|
42
|
+
@new_user = Foo::User.new
|
43
|
+
@new_user.should respond_to(:fullname=)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "handles respond_to for query" do
|
47
|
+
@new_user = Foo::User.new
|
48
|
+
@new_user.should respond_to(:fullname?)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "handles has_attribute? for getter" do
|
52
|
+
@new_user = Foo::User.new(:fullname => 'Mayonegg')
|
53
|
+
@new_user.should_not have_attribute(:unknown_method_for_a_user)
|
54
|
+
@new_user.should have_attribute(:fullname)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "handles get_attribute for getter" do
|
58
|
+
@new_user = Foo::User.new(:fullname => 'Mayonegg')
|
59
|
+
@new_user.get_attribute(:unknown_method_for_a_user).should be_nil
|
60
|
+
@new_user.get_attribute(:fullname).should == 'Mayonegg'
|
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
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
context "assigning new resource data" do
|
72
|
+
before do
|
73
|
+
spawn_model "Foo::User"
|
74
|
+
@user = Foo::User.new(:active => false)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "handles data update through #assign_attributes" do
|
78
|
+
@user.assign_attributes :active => true
|
79
|
+
@user.should be_active
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "checking resource equality" do
|
84
|
+
before do
|
85
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
86
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
87
|
+
builder.use Faraday::Request::UrlEncoded
|
88
|
+
builder.adapter :test do |stub|
|
89
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke" }.to_json] }
|
90
|
+
stub.get("/users/2") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke" }.to_json] }
|
91
|
+
stub.get("/admins/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke" }.to_json] }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
spawn_model "Foo::User"
|
96
|
+
spawn_model "Foo::Admin"
|
97
|
+
end
|
98
|
+
|
99
|
+
let(:user) { Foo::User.find(1) }
|
100
|
+
|
101
|
+
it "returns true for the exact same object" do
|
102
|
+
user.should == user
|
103
|
+
end
|
104
|
+
|
105
|
+
it "returns true for the same resource via find" do
|
106
|
+
user.should == Foo::User.find(1)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "returns true for the same class with identical data" do
|
110
|
+
user.should == Foo::User.new(:id => 1, :fullname => "Lindsay Fünke")
|
111
|
+
end
|
112
|
+
|
113
|
+
it "returns true for a different resource with the same data" do
|
114
|
+
user.should == Foo::Admin.find(1)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns false for the same class with different data" do
|
118
|
+
user.should_not == Foo::User.new(:id => 2, :fullname => "Tobias Fünke")
|
119
|
+
end
|
120
|
+
|
121
|
+
it "returns false for a non-resource with the same data" do
|
122
|
+
fake_user = double(:data => { :id => 1, :fullname => "Lindsay Fünke" })
|
123
|
+
user.should_not == fake_user
|
124
|
+
end
|
125
|
+
|
126
|
+
it "delegates eql? to ==" do
|
127
|
+
other = Object.new
|
128
|
+
user.should_receive(:==).with(other).and_return(true)
|
129
|
+
user.eql?(other).should be_truthy
|
130
|
+
end
|
131
|
+
|
132
|
+
it "treats equal resources as equal for Array#uniq" do
|
133
|
+
user2 = Foo::User.find(1)
|
134
|
+
[user, user2].uniq.should == [user]
|
135
|
+
end
|
136
|
+
|
137
|
+
it "treats equal resources as equal for hash keys" do
|
138
|
+
Foo::User.find(1)
|
139
|
+
hash = { user => true }
|
140
|
+
hash[Foo::User.find(1)] = false
|
141
|
+
hash.size.should == 1
|
142
|
+
hash.should == { user => false }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context "handling metadata and errors" do
|
147
|
+
before do
|
148
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
149
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
150
|
+
builder.adapter :test do |stub|
|
151
|
+
stub.post("/users") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke" }.to_json] }
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
spawn_model 'Foo::User' do
|
156
|
+
store_response_errors :errors
|
157
|
+
store_metadata :my_data
|
158
|
+
end
|
159
|
+
|
160
|
+
@user = Foo::User.new(:_errors => ["Foo", "Bar"], :_metadata => { :secret => true })
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should return response_errors stored in the method provided by `store_response_errors`" do
|
164
|
+
@user.errors.should == ["Foo", "Bar"]
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should remove the default method for errors" do
|
168
|
+
expect { @user.response_errors }.to raise_error(NoMethodError)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should return metadata stored in the method provided by `store_metadata`" do
|
172
|
+
@user.my_data.should == { :secret => true }
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should remove the default method for metadata" do
|
176
|
+
expect { @user.metadata }.to raise_error(NoMethodError)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should work with #save" do
|
180
|
+
@user.assign_attributes(:fullname => "Tobias Fünke")
|
181
|
+
@user.save
|
182
|
+
expect { @user.metadata }.to raise_error(NoMethodError)
|
183
|
+
@user.my_data.should be_empty
|
184
|
+
@user.errors.should be_empty
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context "overwriting default attribute methods" do
|
189
|
+
context "for getter method" do
|
190
|
+
before do
|
191
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
192
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
193
|
+
builder.adapter :test do |stub|
|
194
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :document => { :url => "http://example.com" } }.to_json] }
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
spawn_model 'Foo::User' do
|
199
|
+
def document
|
200
|
+
@attributes[:document][:url]
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
it "bypasses Her's method" do
|
206
|
+
@user = Foo::User.find(1)
|
207
|
+
@user.document.should == "http://example.com"
|
208
|
+
|
209
|
+
@user = Foo::User.find(1)
|
210
|
+
@user.document.should == "http://example.com"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context "for setter method" do
|
215
|
+
before do
|
216
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
217
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
218
|
+
builder.adapter :test do |stub|
|
219
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :document => { :url => "http://example.com" } }.to_json] }
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
spawn_model 'Foo::User' do
|
224
|
+
def document=(document)
|
225
|
+
@attributes[:document] = document[:url]
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
it "bypasses Her's method" do
|
231
|
+
@user = Foo::User.find(1)
|
232
|
+
@user.document.should == "http://example.com"
|
233
|
+
|
234
|
+
@user = Foo::User.find(1)
|
235
|
+
@user.document.should == "http://example.com"
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context "for predicate method" do
|
240
|
+
before do
|
241
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
242
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
243
|
+
builder.adapter :test do |stub|
|
244
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke", :document => { :url => nil } }.to_json] }
|
245
|
+
stub.get("/users/2") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :document => { :url => "http://example.com" } }.to_json] }
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
spawn_model 'Foo::User' do
|
250
|
+
def document?
|
251
|
+
document[:url].present?
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
it "byoasses Her's method" do
|
257
|
+
@user = Foo::User.find(1)
|
258
|
+
@user.document?.should be_falsey
|
259
|
+
|
260
|
+
@user = Foo::User.find(1)
|
261
|
+
@user.document?.should be_falsey
|
262
|
+
|
263
|
+
@user = Foo::User.find(2)
|
264
|
+
@user.document?.should be_truthy
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.join(File.dirname(__FILE__), "../spec_helper.rb")
|
3
|
+
|
4
|
+
describe "Her::Model and ActiveModel::Callbacks" do
|
5
|
+
before do
|
6
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
7
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
8
|
+
end
|
9
|
+
|
10
|
+
spawn_model "Foo::User"
|
11
|
+
end
|
12
|
+
|
13
|
+
context :before_save do
|
14
|
+
subject { Foo::User.create(:name => "Tobias Funke") }
|
15
|
+
before do
|
16
|
+
Her::API.default_api.connection.adapter :test do |stub|
|
17
|
+
stub.post("/users") { |env| [200, {}, { :id => 1, :name => env[:body][:name] }.to_json] }
|
18
|
+
stub.put("/users/1") { |env| [200, {}, { :id => 1, :name => env[:body][:name] }.to_json] }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when using a symbol callback" do
|
23
|
+
before do
|
24
|
+
class Foo::User
|
25
|
+
before_save :alter_name
|
26
|
+
def alter_name; self.name.upcase!; end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
its(:name) { should == "TOBIAS FUNKE" }
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when using a block callback" do
|
34
|
+
before do
|
35
|
+
class Foo::User
|
36
|
+
before_save lambda { self.name.upcase! }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
its(:name) { should == "TOBIAS FUNKE" }
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when changing a value of an existing resource in a callback" do
|
44
|
+
before do
|
45
|
+
class Foo::User
|
46
|
+
before_save :alter_name
|
47
|
+
def alter_name
|
48
|
+
self.name = "Lumberjack" if persisted?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should call the server with the canged value" do
|
54
|
+
subject.name.should == "Tobias Funke"
|
55
|
+
subject.save
|
56
|
+
subject.name.should == "Lumberjack"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context :before_create do
|
62
|
+
subject { Foo::User.create(:name => "Tobias Funke") }
|
63
|
+
before do
|
64
|
+
Her::API.default_api.connection.adapter :test do |stub|
|
65
|
+
stub.post("/users") { |env| [200, {}, { :id => 1, :name => env[:body][:name] }.to_json] }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when using a symbol callback" do
|
70
|
+
before do
|
71
|
+
class Foo::User
|
72
|
+
before_create :alter_name
|
73
|
+
def alter_name; self.name.upcase!; end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
its(:name) { should == "TOBIAS FUNKE" }
|
78
|
+
end
|
79
|
+
|
80
|
+
context "when using a block callback" do
|
81
|
+
before do
|
82
|
+
class Foo::User
|
83
|
+
before_create lambda { self.name.upcase! }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
its(:name) { should == "TOBIAS FUNKE" }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context :after_find do
|
92
|
+
subject { Foo::User.find(1) }
|
93
|
+
before do
|
94
|
+
Her::API.default_api.connection.adapter :test do |stub|
|
95
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Funke" }.to_json] }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when using a symbol callback" do
|
100
|
+
before do
|
101
|
+
class Foo::User
|
102
|
+
after_find :alter_name
|
103
|
+
def alter_name; self.name.upcase!; end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
its(:name) { should == "TOBIAS FUNKE" }
|
108
|
+
end
|
109
|
+
|
110
|
+
context "when using a block callback" do
|
111
|
+
before do
|
112
|
+
class Foo::User
|
113
|
+
after_find lambda { self.name.upcase! }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
its(:name) { should == "TOBIAS FUNKE" }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context :after_initialize do
|
122
|
+
subject { Foo::User.new(:name => "Tobias Funke") }
|
123
|
+
|
124
|
+
context "when using a symbol callback" do
|
125
|
+
before do
|
126
|
+
class Foo::User
|
127
|
+
after_initialize :alter_name
|
128
|
+
def alter_name; self.name.upcase!; end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
its(:name) { should == "TOBIAS FUNKE" }
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when using a block callback" do
|
136
|
+
before do
|
137
|
+
class Foo::User
|
138
|
+
after_initialize lambda { self.name.upcase! }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
its(:name) { should == "TOBIAS FUNKE" }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.join(File.dirname(__FILE__), "../spec_helper.rb")
|
3
|
+
|
4
|
+
describe "Her::Model and ActiveModel::Dirty" do
|
5
|
+
context "checking dirty attributes" do
|
6
|
+
before do
|
7
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
8
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
9
|
+
builder.use Faraday::Request::UrlEncoded
|
10
|
+
builder.adapter :test do |stub|
|
11
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke" }.to_json] }
|
12
|
+
stub.get("/users/2") { |env| [200, {}, { :id => 2, :fullname => "Maeby Fünke" }.to_json] }
|
13
|
+
stub.get("/users/3") { |env| [200, {}, { :user_id => 3, :fullname => "Maeby Fünke" }.to_json] }
|
14
|
+
stub.put("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke" }.to_json] }
|
15
|
+
stub.put("/users/2") { |env| [400, {}, { :errors => ["Email cannot be blank"] }.to_json] }
|
16
|
+
stub.post("/users") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke" }.to_json] }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
spawn_model "Foo::User" do
|
21
|
+
attributes :fullname, :email
|
22
|
+
end
|
23
|
+
spawn_model "Dynamic::User" do
|
24
|
+
primary_key :user_id
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "for existing resource" do
|
29
|
+
let(:user) { Foo::User.find(1) }
|
30
|
+
it "has no changes" do
|
31
|
+
user.changes.should be_empty
|
32
|
+
user.should_not be_changed
|
33
|
+
end
|
34
|
+
context "with successful save" do
|
35
|
+
it "tracks dirty attributes" do
|
36
|
+
user.fullname = "Tobias Fünke"
|
37
|
+
user.fullname_changed?.should be_truthy
|
38
|
+
user.email_changed?.should be_falsey
|
39
|
+
user.should be_changed
|
40
|
+
user.save
|
41
|
+
user.should_not be_changed
|
42
|
+
end
|
43
|
+
|
44
|
+
it "tracks previous changes" do
|
45
|
+
user.fullname = "Tobias Fünke"
|
46
|
+
user.save
|
47
|
+
user.previous_changes.should eq({"fullname"=>"Lindsay Fünke"})
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'tracks dirty attribute for mass assign for dynamic created attributes' do
|
51
|
+
user = Dynamic::User.find(3)
|
52
|
+
user.assign_attributes(:fullname => 'New Fullname')
|
53
|
+
user.fullname_changed?.should be_truthy
|
54
|
+
user.should be_changed
|
55
|
+
user.changes.length.should eq(1)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "with erroneous save" do
|
60
|
+
it "tracks dirty attributes" do
|
61
|
+
user = Foo::User.find(2)
|
62
|
+
user.fullname = "Tobias Fünke"
|
63
|
+
user.fullname_changed?.should be_truthy
|
64
|
+
user.email_changed?.should be_falsey
|
65
|
+
user.should be_changed
|
66
|
+
user.save
|
67
|
+
user.should be_changed
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "for new resource" do
|
73
|
+
let(:user) { Foo::User.new(:fullname => "Lindsay Fünke") }
|
74
|
+
it "has changes" do
|
75
|
+
user.should be_changed
|
76
|
+
end
|
77
|
+
it "tracks dirty attributes" do
|
78
|
+
user.fullname = "Tobias Fünke"
|
79
|
+
user.fullname_changed?.should be_truthy
|
80
|
+
user.should be_changed
|
81
|
+
user.save
|
82
|
+
user.should_not be_changed
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|