ardm 0.0.1 → 0.1.0
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 +5 -13
- data/Gemfile +1 -2
- data/LICENSE +2 -2
- data/README.md +72 -16
- data/ardm.gemspec +1 -0
- data/lib/ardm.rb +2 -1
- data/lib/ardm/active_record.rb +8 -1
- data/lib/ardm/active_record/associations.rb +33 -4
- data/lib/ardm/active_record/base.rb +2 -0
- data/lib/ardm/active_record/collection.rb +5 -0
- data/lib/ardm/active_record/data_mapper_constant.rb +1 -0
- data/lib/ardm/active_record/data_mapper_constant_proxy.rb +24 -0
- data/lib/ardm/active_record/finalize.rb +18 -0
- data/lib/ardm/active_record/predicate_builder/array_handler.rb +10 -16
- data/lib/ardm/active_record/predicate_builder/rails3.rb +42 -15
- data/lib/ardm/active_record/predicate_builder/rails4.rb +39 -13
- data/lib/ardm/active_record/property.rb +24 -12
- data/lib/ardm/active_record/query.rb +9 -18
- data/lib/ardm/active_record/record.rb +54 -11
- data/lib/ardm/active_record/relation.rb +36 -6
- data/lib/ardm/active_record/repository.rb +6 -2
- data/lib/ardm/data_mapper.rb +2 -0
- data/lib/ardm/data_mapper/record.rb +3 -9
- data/lib/ardm/version.rb +1 -1
- data/spec/ardm/datamapper_constants_spec.rb +31 -0
- data/spec/fixtures/article.rb +2 -0
- data/spec/integration/api_key_spec.rb +3 -3
- data/spec/integration/bcrypt_hash_spec.rb +7 -7
- data/spec/integration/comma_separated_list_spec.rb +11 -11
- data/spec/integration/dirty_minder_spec.rb +23 -39
- data/spec/integration/enum_spec.rb +11 -11
- data/spec/integration/epoch_time_spec.rb +6 -6
- data/spec/integration/file_path_spec.rb +23 -23
- data/spec/integration/flag_spec.rb +11 -13
- data/spec/integration/ip_address_spec.rb +15 -15
- data/spec/integration/json_spec.rb +7 -7
- data/spec/integration/slug_spec.rb +6 -6
- data/spec/integration/uri_spec.rb +11 -11
- data/spec/integration/uuid_spec.rb +16 -16
- data/spec/integration/yaml_spec.rb +8 -8
- data/spec/public/model_spec.rb +193 -0
- data/spec/public/property/binary_spec.rb +4 -4
- data/spec/public/property/boolean_spec.rb +3 -3
- data/spec/public/property/class_spec.rb +2 -2
- data/spec/public/property/date_spec.rb +2 -2
- data/spec/public/property/date_time_spec.rb +2 -2
- data/spec/public/property/decimal_spec.rb +2 -2
- data/spec/public/property/discriminator_spec.rb +21 -20
- data/spec/public/property/float_spec.rb +2 -2
- data/spec/public/property/integer_spec.rb +2 -2
- data/spec/public/property/object_spec.rb +14 -13
- data/spec/public/property/serial_spec.rb +2 -2
- data/spec/public/property/string_spec.rb +2 -2
- data/spec/public/property/text_spec.rb +2 -2
- data/spec/public/property/time_spec.rb +2 -2
- data/spec/public/property_spec.rb +44 -48
- data/spec/public/resource_spec.rb +278 -0
- data/spec/schema.rb +33 -4
- data/spec/semipublic/property/boolean_spec.rb +5 -5
- data/spec/semipublic/property/class_spec.rb +3 -3
- data/spec/semipublic/property/date_spec.rb +8 -8
- data/spec/semipublic/property/date_time_spec.rb +9 -9
- data/spec/semipublic/property/decimal_spec.rb +16 -16
- data/spec/semipublic/property/float_spec.rb +16 -16
- data/spec/semipublic/property/integer_spec.rb +16 -16
- data/spec/semipublic/property/lookup_spec.rb +4 -4
- data/spec/semipublic/property/text_spec.rb +2 -2
- data/spec/semipublic/property/time_spec.rb +10 -10
- data/spec/semipublic/property_spec.rb +4 -4
- data/spec/shared/finder_shared_spec.rb +1151 -0
- data/spec/shared/flags_shared_spec.rb +6 -6
- data/spec/shared/identity_function_group.rb +1 -1
- data/spec/shared/public_property_spec.rb +26 -25
- data/spec/shared/resource_spec.rb +1218 -0
- data/spec/shared/semipublic_property_spec.rb +23 -22
- data/spec/spec_helper.rb +17 -0
- data/spec/unit/bcrypt_hash_spec.rb +15 -15
- data/spec/unit/csv_spec.rb +11 -11
- data/spec/unit/dirty_minder_spec.rb +3 -5
- data/spec/unit/enum_spec.rb +17 -17
- data/spec/unit/epoch_time_spec.rb +8 -8
- data/spec/unit/file_path_spec.rb +9 -9
- data/spec/unit/flag_spec.rb +9 -9
- data/spec/unit/ip_address_spec.rb +9 -9
- data/spec/unit/json_spec.rb +11 -11
- data/spec/unit/paranoid_boolean_spec.rb +19 -17
- data/spec/unit/paranoid_datetime_spec.rb +21 -19
- data/spec/unit/regexp_spec.rb +4 -4
- data/spec/unit/uri_spec.rb +8 -8
- data/spec/unit/yaml_spec.rb +9 -9
- metadata +35 -27
- data/lib/ardm/active_record/not_found.rb +0 -7
- data/lib/ardm/data_mapper/not_found.rb +0 -5
@@ -15,8 +15,8 @@ describe Ardm::Property::Serial do
|
|
15
15
|
describe '.options' do
|
16
16
|
subject { described_class.options }
|
17
17
|
|
18
|
-
it {
|
18
|
+
it { is_expected.to be_kind_of(Hash) }
|
19
19
|
|
20
|
-
it {
|
20
|
+
it { is_expected.to eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_integer, :min => 1, :serial => true) }
|
21
21
|
end
|
22
22
|
end
|
@@ -15,8 +15,8 @@ describe Ardm::Property::String do
|
|
15
15
|
describe '.options' do
|
16
16
|
subject { described_class.options }
|
17
17
|
|
18
|
-
it {
|
18
|
+
it { is_expected.to be_kind_of(Hash) }
|
19
19
|
|
20
|
-
it {
|
20
|
+
it { is_expected.to eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_string, :length => 50) }
|
21
21
|
end
|
22
22
|
end
|
@@ -15,9 +15,9 @@ describe Ardm::Property::Text do
|
|
15
15
|
describe '.options' do
|
16
16
|
subject { described_class.options }
|
17
17
|
|
18
|
-
it {
|
18
|
+
it { is_expected.to be_kind_of(Hash) }
|
19
19
|
|
20
|
-
it {
|
20
|
+
it { is_expected.to eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_string, :length => 65535, :lazy => true) }
|
21
21
|
end
|
22
22
|
|
23
23
|
end
|
@@ -15,8 +15,8 @@ describe Ardm::Property::Time do
|
|
15
15
|
describe '.options' do
|
16
16
|
subject { described_class.options }
|
17
17
|
|
18
|
-
it {
|
18
|
+
it { is_expected.to be_kind_of(Hash) }
|
19
19
|
|
20
|
-
it {
|
20
|
+
it { is_expected.to eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_time) }
|
21
21
|
end
|
22
22
|
end
|
@@ -30,37 +30,37 @@ describe Ardm::Property do
|
|
30
30
|
|
31
31
|
describe '#field' do
|
32
32
|
it 'returns @field value if it is present' do
|
33
|
-
Track.properties[:title].field.
|
33
|
+
expect(Track.properties[:title].field).to eql('name')
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
describe '#default_for' do
|
38
38
|
it 'returns default value for non-callables' do
|
39
|
-
Image.properties[:format].default_for(Image.new).
|
39
|
+
expect(Image.properties[:format].default_for(Image.new)).to eq('jpeg')
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'returns result of a call for callable values' do
|
43
|
-
Image.properties[:taken_at].default_for(Image.new).year.
|
43
|
+
expect(Image.properties[:taken_at].default_for(Image.new).year).to eq(Time.now.year)
|
44
44
|
end
|
45
45
|
|
46
46
|
it "sets the default when the record is created" do
|
47
47
|
img = Image.create!(title: 'My Picture')
|
48
|
-
img.format.
|
48
|
+
expect(img.format).to eq('jpeg')
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
describe '#eql?' do
|
53
53
|
it 'is true for properties with the same model and name' do
|
54
|
-
Track.properties[:title].
|
54
|
+
expect(Track.properties[:title]).to eql(Track.properties[:title])
|
55
55
|
end
|
56
56
|
|
57
57
|
|
58
58
|
it 'is false for properties of different models' do
|
59
|
-
Track.properties[:title].
|
59
|
+
expect(Track.properties[:title]).not_to eql(Image.properties[:title])
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'is false for properties with different names' do
|
63
|
-
Track.properties[:title].
|
63
|
+
expect(Track.properties[:title]).not_to eql(Track.properties[:id])
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
@@ -72,26 +72,24 @@ describe Ardm::Property do
|
|
72
72
|
@image.instance_variable_set(:@description, 'Is set by magic')
|
73
73
|
end
|
74
74
|
|
75
|
-
it 'gets instance variable value from the resource directly' do
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
Image.properties[:description].get!(@image).should == 'Is set by magic'
|
80
|
-
end
|
75
|
+
it 'gets instance variable value from the resource directly', pending: true do
|
76
|
+
# if you know a better way to test direct instance variable access,
|
77
|
+
# go ahead and make changes to this example
|
78
|
+
expect(Image.properties[:description].get!(@image)).to eq('Is set by magic')
|
81
79
|
end
|
82
80
|
end
|
83
81
|
|
84
82
|
describe '#index' do
|
85
83
|
it 'returns true when property has an index' do
|
86
|
-
Track.properties[:title].index.
|
84
|
+
expect(Track.properties[:title].index).to be(true)
|
87
85
|
end
|
88
86
|
|
89
87
|
it 'returns index name when property has a named index' do
|
90
|
-
Track.properties[:album].index.
|
88
|
+
expect(Track.properties[:album].index).to eql(:artist_album)
|
91
89
|
end
|
92
90
|
|
93
91
|
it 'returns false when property has no index' do
|
94
|
-
Track.properties[:musicbrainz_hash].index.
|
92
|
+
expect(Track.properties[:musicbrainz_hash].index).to be(false)
|
95
93
|
end
|
96
94
|
end
|
97
95
|
|
@@ -107,48 +105,48 @@ describe Ardm::Property do
|
|
107
105
|
end
|
108
106
|
|
109
107
|
it 'features model name' do
|
110
|
-
@str.
|
108
|
+
expect(@str).to match(/@model=Track/)
|
111
109
|
end
|
112
110
|
|
113
111
|
it 'features property name' do
|
114
|
-
@str.
|
112
|
+
expect(@str).to match(/@name=:title/)
|
115
113
|
end
|
116
114
|
end
|
117
115
|
|
118
116
|
describe '#key?' do
|
119
117
|
describe 'returns true when property is a ' do
|
120
118
|
it 'serial key' do
|
121
|
-
Track.properties[:id].key
|
119
|
+
expect(Track.properties[:id].key?).to be(true)
|
122
120
|
end
|
123
121
|
it 'natural key' do
|
124
|
-
Image.properties[:md5hash].key
|
122
|
+
expect(Image.properties[:md5hash].key?).to be(true)
|
125
123
|
end
|
126
124
|
end
|
127
125
|
|
128
126
|
it 'returns true when property is a part of composite key'
|
129
127
|
|
130
128
|
it 'returns false when property does not relate to a key' do
|
131
|
-
Track.properties[:title].key
|
129
|
+
expect(Track.properties[:title].key?).to be(false)
|
132
130
|
end
|
133
131
|
end
|
134
132
|
|
135
133
|
describe '#lazy?' do
|
136
134
|
it 'returns true when property is lazy loaded' do
|
137
|
-
Image.properties[:description].lazy
|
135
|
+
expect(Image.properties[:description].lazy?).to be(true)
|
138
136
|
end
|
139
137
|
|
140
138
|
it 'returns false when property is not lazy loaded' do
|
141
|
-
Track.properties[:artist].lazy
|
139
|
+
expect(Track.properties[:artist].lazy?).to be(false)
|
142
140
|
end
|
143
141
|
end
|
144
142
|
|
145
143
|
describe '#length' do
|
146
144
|
it 'returns upper bound for Range values' do
|
147
|
-
Image.properties[:description].length.
|
145
|
+
expect(Image.properties[:description].length).to eql(1024)
|
148
146
|
end
|
149
147
|
|
150
148
|
it 'returns value as is for integer values' do
|
151
|
-
Image.properties[:md5hash].length.
|
149
|
+
expect(Image.properties[:md5hash].length).to eql(32)
|
152
150
|
end
|
153
151
|
end
|
154
152
|
|
@@ -159,7 +157,7 @@ describe Ardm::Property do
|
|
159
157
|
end
|
160
158
|
|
161
159
|
it 'should be nil' do
|
162
|
-
@property.min.
|
160
|
+
expect(@property.min).to be_nil
|
163
161
|
end
|
164
162
|
end
|
165
163
|
|
@@ -169,7 +167,7 @@ describe Ardm::Property do
|
|
169
167
|
end
|
170
168
|
|
171
169
|
it 'should be the default value' do
|
172
|
-
@property.min.
|
170
|
+
expect(@property.min).to eq(0)
|
173
171
|
end
|
174
172
|
end
|
175
173
|
|
@@ -180,7 +178,7 @@ describe Ardm::Property do
|
|
180
178
|
end
|
181
179
|
|
182
180
|
it 'should be the expected value' do
|
183
|
-
@property.min.
|
181
|
+
expect(@property.min).to eq(@min)
|
184
182
|
end
|
185
183
|
end
|
186
184
|
end
|
@@ -192,7 +190,7 @@ describe Ardm::Property do
|
|
192
190
|
end
|
193
191
|
|
194
192
|
it 'should be nil' do
|
195
|
-
@property.max.
|
193
|
+
expect(@property.max).to be_nil
|
196
194
|
end
|
197
195
|
end
|
198
196
|
|
@@ -202,7 +200,7 @@ describe Ardm::Property do
|
|
202
200
|
end
|
203
201
|
|
204
202
|
it 'should be the default value' do
|
205
|
-
@property.max.
|
203
|
+
expect(@property.max).to eq(2**31-1)
|
206
204
|
end
|
207
205
|
end
|
208
206
|
|
@@ -213,28 +211,28 @@ describe Ardm::Property do
|
|
213
211
|
end
|
214
212
|
|
215
213
|
it 'should be the expected value' do
|
216
|
-
@property.max.
|
214
|
+
expect(@property.max).to eq(@max)
|
217
215
|
end
|
218
216
|
end
|
219
217
|
end
|
220
218
|
|
221
219
|
describe '#allow_nil?' do
|
222
220
|
it 'returns true when property can accept nil as its value' do
|
223
|
-
Track.properties[:artist].allow_nil
|
221
|
+
expect(Track.properties[:artist].allow_nil?).to be(true)
|
224
222
|
end
|
225
223
|
|
226
224
|
it 'returns false when property nil value is prohibited for this property' do
|
227
|
-
Image.properties[:title].allow_nil
|
225
|
+
expect(Image.properties[:title].allow_nil?).to be(false)
|
228
226
|
end
|
229
227
|
end
|
230
228
|
|
231
229
|
describe '#serial?' do
|
232
230
|
it 'returns true when property is serial (auto incrementing)' do
|
233
|
-
Track.properties[:id].serial
|
231
|
+
expect(Track.properties[:id].serial?).to be(true)
|
234
232
|
end
|
235
233
|
|
236
234
|
it 'returns false when property is NOT serial (auto incrementing)' do
|
237
|
-
Image.properties[:md5hash].serial
|
235
|
+
expect(Image.properties[:md5hash].serial?).to be(false)
|
238
236
|
end
|
239
237
|
end
|
240
238
|
|
@@ -256,12 +254,12 @@ describe Ardm::Property do
|
|
256
254
|
it 'type casts given value' do
|
257
255
|
@property.set(@image, Addressable::URI.parse('http://test.example/'))
|
258
256
|
# get a string that has been typecasted using #to_str
|
259
|
-
@image.title.
|
257
|
+
expect(@image.title).to eq('http://test.example/')
|
260
258
|
end
|
261
259
|
|
262
260
|
it 'sets new property value' do
|
263
261
|
@property.set(@image, 'Updated value')
|
264
|
-
@image.title.
|
262
|
+
expect(@image.title).to eq('Updated value')
|
265
263
|
end
|
266
264
|
end
|
267
265
|
|
@@ -276,41 +274,39 @@ describe Ardm::Property do
|
|
276
274
|
|
277
275
|
it 'directly sets instance variable on given resource' do
|
278
276
|
@property.set!(@image, 'Set with dark Ruby magic')
|
279
|
-
@image.title.
|
277
|
+
expect(@image.title).to eq('Set with dark Ruby magic')
|
280
278
|
end
|
281
279
|
end
|
282
280
|
|
283
281
|
describe '#unique?' do
|
284
282
|
it 'is true for fields that explicitly given uniq index' do
|
285
|
-
Track.properties[:musicbrainz_hash].unique
|
283
|
+
expect(Track.properties[:musicbrainz_hash].unique?).to be(true)
|
286
284
|
end
|
287
285
|
|
288
|
-
it 'is true for serial fields' do
|
289
|
-
|
290
|
-
Track.properties[:title].unique?.should be(true)
|
291
|
-
end
|
286
|
+
it 'is true for serial fields', pending: true do
|
287
|
+
expect(Track.properties[:title].unique?).to be(true)
|
292
288
|
end
|
293
289
|
|
294
290
|
it 'is true for keys' do
|
295
|
-
Image.properties[:md5hash].unique
|
291
|
+
expect(Image.properties[:md5hash].unique?).to be(true)
|
296
292
|
end
|
297
293
|
end
|
298
294
|
|
299
295
|
describe '#unique_index' do
|
300
296
|
it 'returns true when property has unique index' do
|
301
|
-
Track.properties[:musicbrainz_hash].unique_index.
|
297
|
+
expect(Track.properties[:musicbrainz_hash].unique_index).to be(true)
|
302
298
|
end
|
303
299
|
|
304
300
|
it 'returns false when property has no unique index' do
|
305
|
-
Track.properties[:title].unique_index.
|
301
|
+
expect(Track.properties[:title].unique_index).to be(false)
|
306
302
|
end
|
307
303
|
|
308
304
|
it 'returns true when property is unique' do
|
309
|
-
Image.properties[:title].unique_index.
|
305
|
+
expect(Image.properties[:title].unique_index).to be(true)
|
310
306
|
end
|
311
307
|
|
312
308
|
it 'returns :key when property is a key' do
|
313
|
-
Track.properties[:id].unique_index.
|
309
|
+
expect(Track.properties[:id].unique_index).to eq(:key)
|
314
310
|
end
|
315
311
|
end
|
316
312
|
end
|
@@ -0,0 +1,278 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ::ResourceBlog
|
4
|
+
class User < Ardm::Record
|
5
|
+
self.table_name = "users"
|
6
|
+
|
7
|
+
property :name, String, :key => true
|
8
|
+
property :age, Integer
|
9
|
+
property :summary, Text
|
10
|
+
property :description, Text
|
11
|
+
property :admin, Boolean, :accessor => :private
|
12
|
+
|
13
|
+
belongs_to :parent, self, :required => false
|
14
|
+
has n, :children, self, :inverse => :parent
|
15
|
+
|
16
|
+
belongs_to :referrer, self, :required => false
|
17
|
+
has n, :comments
|
18
|
+
|
19
|
+
# FIXME: figure out a different approach than stubbing things out
|
20
|
+
def comment=(*)
|
21
|
+
# do nothing with comment
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Author < User; end
|
26
|
+
|
27
|
+
class Comment < Ardm::Record
|
28
|
+
self.table_name = "comments"
|
29
|
+
|
30
|
+
property :id, Serial
|
31
|
+
property :body, Text
|
32
|
+
|
33
|
+
belongs_to :user
|
34
|
+
end
|
35
|
+
|
36
|
+
class Article < Ardm::Record
|
37
|
+
self.table_name = "articles"
|
38
|
+
|
39
|
+
property :id, Serial
|
40
|
+
property :body, Text
|
41
|
+
timestamps :at
|
42
|
+
|
43
|
+
has n, :paragraphs
|
44
|
+
end
|
45
|
+
|
46
|
+
class Paragraph < Ardm::Record
|
47
|
+
self.table_name = "paragraphs"
|
48
|
+
|
49
|
+
property :id, Serial
|
50
|
+
property :text, String
|
51
|
+
|
52
|
+
belongs_to :article
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
Ardm::Record.finalize
|
57
|
+
|
58
|
+
# TODO: unused?
|
59
|
+
#class ::ResourceDefault < Ardm::Record
|
60
|
+
# property :name, String, :key => true, :default => 'a default value'
|
61
|
+
#end
|
62
|
+
|
63
|
+
describe Ardm::Record do
|
64
|
+
before do
|
65
|
+
@user_model = ResourceBlog::User
|
66
|
+
@author_model = ResourceBlog::Author
|
67
|
+
@comment_model = ResourceBlog::Comment
|
68
|
+
@article_model = ResourceBlog::Article
|
69
|
+
@paragraph_model = ResourceBlog::Paragraph
|
70
|
+
|
71
|
+
user = @user_model.create!(:name => 'dbussink', :age => 25, :description => 'Test')
|
72
|
+
|
73
|
+
@user = @user_model.get!(user.key)
|
74
|
+
end
|
75
|
+
|
76
|
+
# FIXME
|
77
|
+
#it_should_behave_like 'A public Resource'
|
78
|
+
#it_should_behave_like 'A Resource supporting Strategic Eager Loading'
|
79
|
+
|
80
|
+
it 'A resource should respond to raise_on_save_failure' do
|
81
|
+
expect(@user).to respond_to(:raise_on_save_failure)
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#raise_on_save_failure' do
|
85
|
+
after do
|
86
|
+
# reset to the default value
|
87
|
+
reset_raise_on_save_failure(@user_model)
|
88
|
+
reset_raise_on_save_failure(@user)
|
89
|
+
end
|
90
|
+
|
91
|
+
subject { @user.raise_on_save_failure }
|
92
|
+
|
93
|
+
describe 'when model.raise_on_save_failure has not been set' do
|
94
|
+
it { is_expected.to be false }
|
95
|
+
end
|
96
|
+
|
97
|
+
describe 'when model.raise_on_save_failure has been set to true' do
|
98
|
+
before do
|
99
|
+
@user_model.raise_on_save_failure = true
|
100
|
+
end
|
101
|
+
|
102
|
+
it { is_expected.to be true }
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'when resource.raise_on_save_failure has been set to true' do
|
106
|
+
before do
|
107
|
+
@user.raise_on_save_failure = true
|
108
|
+
end
|
109
|
+
|
110
|
+
it { is_expected.to be true }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'A model should respond to raise_on_save_failure=' do
|
115
|
+
expect(@user_model).to respond_to(:raise_on_save_failure=)
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#raise_on_save_failure=' do
|
119
|
+
after do
|
120
|
+
# reset to the default value
|
121
|
+
reset_raise_on_save_failure(@user_model)
|
122
|
+
end
|
123
|
+
|
124
|
+
describe 'with a true value' do
|
125
|
+
subject { @user_model.raise_on_save_failure = true }
|
126
|
+
|
127
|
+
it { is_expected.to be true }
|
128
|
+
|
129
|
+
it 'should set raise_on_save_failure' do
|
130
|
+
expect { subject }.to change {
|
131
|
+
@user_model.raise_on_save_failure
|
132
|
+
}.from(false).to(true)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe 'with a false value' do
|
137
|
+
subject { @user_model.raise_on_save_failure = false }
|
138
|
+
|
139
|
+
it { is_expected.to be false }
|
140
|
+
|
141
|
+
it 'should set raise_on_save_failure' do
|
142
|
+
expect { subject }.to_not change {
|
143
|
+
@user_model.raise_on_save_failure
|
144
|
+
}
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
[ :save, :save! ].each do |method|
|
150
|
+
describe "##{method}" do
|
151
|
+
subject { @user.__send__(method) }
|
152
|
+
|
153
|
+
describe 'when raise_on_save_failure is true' do
|
154
|
+
before do
|
155
|
+
@user.raise_on_save_failure = true
|
156
|
+
end
|
157
|
+
|
158
|
+
describe 'and it is a savable resource' do
|
159
|
+
it { is_expected.to be true }
|
160
|
+
end
|
161
|
+
|
162
|
+
# FIXME: We cannot trigger a failing save with invalid properties anymore.
|
163
|
+
# Invalid properties will result in their own exception.
|
164
|
+
# So Im mocking here, but a better approach is needed.
|
165
|
+
|
166
|
+
describe 'and it is an invalid resource', pending: true do
|
167
|
+
before do
|
168
|
+
expect(@user).to receive(:save_self).and_return(false)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should raise an exception' do
|
172
|
+
expect { subject }.to raise_error(Ardm::SaveFailureError, "Blog::User##{method} returned false, Blog::User was not saved")
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
[ :update, :update! ].each do |method|
|
180
|
+
describe 'with attributes where one is a foreign key' do
|
181
|
+
before do
|
182
|
+
@dkubb = @user_model.create(:name => 'dkubb', :age => 33)
|
183
|
+
@user.referrer = @dkubb
|
184
|
+
@user.save
|
185
|
+
@user = @user_model.get(@user.key)
|
186
|
+
expect(@user.referrer).to eq(@dkubb)
|
187
|
+
|
188
|
+
@solnic = @user_model.create(:name => 'solnic', :age => 28)
|
189
|
+
|
190
|
+
@attributes = {}
|
191
|
+
|
192
|
+
relationship = @user_model.relationships[:referrer]
|
193
|
+
|
194
|
+
# Original datamapper implementation:
|
195
|
+
#relationship.child_key.to_a.each_with_index do |k, i|
|
196
|
+
# @attributes[k.name] = relationship.parent_key.to_a[i].get(@solnic)
|
197
|
+
#end
|
198
|
+
|
199
|
+
# #key returns an array even though there's only one value.
|
200
|
+
@attributes[relationship.foreign_key] = @solnic.key.first
|
201
|
+
|
202
|
+
@return = @user.__send__(method, @attributes)
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'should return true' do
|
206
|
+
expect(@return).to be true
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'should update attributes of Resource' do
|
210
|
+
@attributes.each { |key, value| expect(@user.__send__(key)).to eq(value) }
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'should persist the changes' do
|
214
|
+
resource = @user_model.get(@user.key)
|
215
|
+
@attributes.each { |key, value| expect(resource.__send__(key)).to eq(value) }
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should return correct parent' do
|
219
|
+
resource = @user_model.get(@user.key)
|
220
|
+
expect(resource.referrer).to eq(@solnic)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe '#attribute_get' do
|
226
|
+
subject { object.attribute_get(name) }
|
227
|
+
|
228
|
+
let(:object) { @user }
|
229
|
+
|
230
|
+
context 'with a known property' do
|
231
|
+
let(:name) { :name }
|
232
|
+
|
233
|
+
it 'returns the attribute value' do
|
234
|
+
is_expected.to eq('dbussink')
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context 'with an unknown property' do
|
239
|
+
let(:name) { :unknown }
|
240
|
+
|
241
|
+
it 'returns nil' do
|
242
|
+
is_expected.to be_nil
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
describe '#attribute_set' do
|
248
|
+
subject { object.attribute_set(name, value) }
|
249
|
+
|
250
|
+
let(:object) { @user }
|
251
|
+
|
252
|
+
context 'with a known property' do
|
253
|
+
let(:name) { :name }
|
254
|
+
let(:value) { 'dkubb' }
|
255
|
+
|
256
|
+
it 'sets the attribute' do
|
257
|
+
expect { subject }.to change { object.name }.from('dbussink').to('dkubb')
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'makes the object dirty' do
|
261
|
+
expect { subject }.to change { object.dirty? }.from(false).to(true)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
context 'with an unknown property' do
|
266
|
+
let(:name) { :unknown }
|
267
|
+
let(:value) { double('Unknown Value') }
|
268
|
+
|
269
|
+
it 'does not set the attribute' do
|
270
|
+
expect { subject }.to_not change { object.attributes.dup }
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'does not make the object dirty' do
|
274
|
+
expect { subject }.to_not change { object.dirty? }
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|