granite-form 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +26 -48
- data/.rubocop_todo.yml +304 -27
- data/CHANGELOG.md +7 -2
- data/granite-form.gemspec +2 -1
- data/lib/granite/form/active_record/associations.rb +4 -3
- data/lib/granite/form/config.rb +1 -1
- data/lib/granite/form/errors.rb +34 -32
- data/lib/granite/form/extensions.rb +2 -1
- data/lib/granite/form/model/associations/base.rb +6 -2
- data/lib/granite/form/model/associations/collection/embedded.rb +1 -1
- data/lib/granite/form/model/associations/collection/proxy.rb +3 -3
- data/lib/granite/form/model/associations/embeds_any.rb +1 -1
- data/lib/granite/form/model/associations/embeds_many.rb +15 -11
- data/lib/granite/form/model/associations/embeds_one.rb +9 -8
- data/lib/granite/form/model/associations/nested_attributes.rb +60 -32
- data/lib/granite/form/model/associations/persistence_adapters/active_record/referenced_proxy.rb +2 -1
- data/lib/granite/form/model/associations/persistence_adapters/active_record.rb +7 -6
- data/lib/granite/form/model/associations/persistence_adapters/base.rb +8 -4
- data/lib/granite/form/model/associations/references_any.rb +1 -1
- data/lib/granite/form/model/associations/references_many.rb +3 -2
- data/lib/granite/form/model/associations/references_one.rb +1 -1
- data/lib/granite/form/model/associations/reflections/base.rb +3 -2
- data/lib/granite/form/model/associations/reflections/embeds_any.rb +4 -4
- data/lib/granite/form/model/associations/reflections/embeds_many.rb +4 -1
- data/lib/granite/form/model/associations/reflections/embeds_one.rb +4 -1
- data/lib/granite/form/model/associations/reflections/references_any.rb +6 -6
- data/lib/granite/form/model/associations/reflections/references_many.rb +1 -1
- data/lib/granite/form/model/associations/reflections/references_one.rb +1 -1
- data/lib/granite/form/model/associations/validations.rb +6 -6
- data/lib/granite/form/model/associations.rb +6 -4
- data/lib/granite/form/model/attributes/attribute.rb +1 -0
- data/lib/granite/form/model/attributes/base.rb +9 -7
- data/lib/granite/form/model/attributes/reference_one.rb +1 -1
- data/lib/granite/form/model/attributes/reflections/base/build_type_definition.rb +2 -1
- data/lib/granite/form/model/attributes/reflections/represents/build_type_definition.rb +2 -2
- data/lib/granite/form/model/attributes/represents.rb +1 -1
- data/lib/granite/form/model/attributes.rb +21 -13
- data/lib/granite/form/model/conventions.rb +1 -1
- data/lib/granite/form/model/persistence.rb +1 -1
- data/lib/granite/form/model/primary.rb +1 -1
- data/lib/granite/form/model/representation.rb +4 -4
- data/lib/granite/form/model/scopes.rb +5 -5
- data/lib/granite/form/model/validations.rb +4 -3
- data/lib/granite/form/types/active_support/time_zone.rb +1 -1
- data/lib/granite/form/types/array.rb +1 -1
- data/lib/granite/form/types/big_decimal.rb +1 -1
- data/lib/granite/form/types/boolean.rb +1 -1
- data/lib/granite/form/types/date.rb +1 -1
- data/lib/granite/form/types/date_time.rb +1 -1
- data/lib/granite/form/types/dictionary.rb +1 -1
- data/lib/granite/form/types/float.rb +1 -1
- data/lib/granite/form/types/has_subtype.rb +1 -0
- data/lib/granite/form/types/hash_with_action_controller_parameters.rb +2 -2
- data/lib/granite/form/types/integer.rb +1 -1
- data/lib/granite/form/types/object.rb +2 -1
- data/lib/granite/form/types/string.rb +1 -1
- data/lib/granite/form/types/time.rb +1 -1
- data/lib/granite/form/types/uuid.rb +1 -1
- data/lib/granite/form/util.rb +1 -1
- data/lib/granite/form/version.rb +1 -1
- data/spec/granite/form/active_record/associations_spec.rb +35 -13
- data/spec/granite/form/config_spec.rb +8 -4
- data/spec/granite/form/model/associations/embeds_many_spec.rb +99 -51
- data/spec/granite/form/model/associations/embeds_one_spec.rb +48 -25
- data/spec/granite/form/model/associations/persistence_adapters/active_record_spec.rb +12 -7
- data/spec/granite/form/model/associations/references_many_spec.rb +51 -10
- data/spec/granite/form/model/associations/references_one_spec.rb +17 -6
- data/spec/granite/form/model/associations/reflections/embeds_many_spec.rb +51 -16
- data/spec/granite/form/model/associations/reflections/embeds_one_spec.rb +19 -9
- data/spec/granite/form/model/associations/reflections/references_many_spec.rb +67 -15
- data/spec/granite/form/model/associations/reflections/references_one_spec.rb +34 -11
- data/spec/granite/form/model/associations/validations_spec.rb +16 -5
- data/spec/granite/form/model/associations_spec.rb +28 -9
- data/spec/granite/form/model/attributes/attribute_spec.rb +33 -11
- data/spec/granite/form/model/attributes/base_spec.rb +9 -3
- data/spec/granite/form/model/attributes/reflections/attribute_spec.rb +1 -0
- data/spec/granite/form/model/attributes/reflections/base_spec.rb +1 -0
- data/spec/granite/form/model/attributes/reflections/represents/build_type_definition_spec.rb +3 -1
- data/spec/granite/form/model/attributes/reflections/represents_spec.rb +2 -2
- data/spec/granite/form/model/attributes/represents_spec.rb +2 -2
- data/spec/granite/form/model/attributes_spec.rb +76 -36
- data/spec/granite/form/model/dirty_spec.rb +3 -0
- data/spec/granite/form/model/persistence_spec.rb +15 -5
- data/spec/granite/form/model/primary_spec.rb +17 -2
- data/spec/granite/form/model/representation_spec.rb +13 -3
- data/spec/granite/form/model/scopes_spec.rb +8 -3
- data/spec/granite/form/model/validations/associated_spec.rb +20 -6
- data/spec/granite/form/model/validations/nested_spec.rb +30 -14
- data/spec/granite/form/model/validations_spec.rb +1 -1
- data/spec/granite/form/model_spec.rb +1 -0
- data/spec/granite/form/types/collection_spec.rb +2 -1
- data/spec/granite/form/types/date_spec.rb +1 -1
- data/spec/granite/form/types/date_time_spec.rb +0 -2
- data/spec/granite/form/types/dictionary_spec.rb +1 -0
- data/spec/granite/form/types/has_subtype_spec.rb +6 -1
- data/spec/granite/form/types/hash_with_action_controller_parameters_spec.rb +1 -1
- data/spec/granite/form/types/object_spec.rb +2 -0
- data/spec/granite/form/types/time_spec.rb +0 -2
- data/spec/granite/form/util_spec.rb +6 -3
- data/spec/support/active_record.rb +13 -0
- data/spec/support/shared/nested_attribute_examples.rb +110 -54
- metadata +23 -9
@@ -38,6 +38,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
38
38
|
expect { book.creators << author }
|
39
39
|
.to change { book.creators }.from([]).to([author])
|
40
40
|
end
|
41
|
+
|
41
42
|
specify do
|
42
43
|
expect { book.creators << author }
|
43
44
|
.to change { book.creator_ids }.from([]).to([author.id])
|
@@ -59,6 +60,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
59
60
|
expect { book.author_names = [author.name] }
|
60
61
|
.to change { book.authors }.from([]).to([author])
|
61
62
|
end
|
63
|
+
|
62
64
|
specify do
|
63
65
|
expect { book.authors = [author] }
|
64
66
|
.to change { book.author_names }.from([]).to([author.name])
|
@@ -79,6 +81,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
79
81
|
expect { book.identify = [author.id] }
|
80
82
|
.to change { book.authors }.from([]).to([author])
|
81
83
|
end
|
84
|
+
|
82
85
|
specify do
|
83
86
|
expect { book.authors = [author] }
|
84
87
|
.to change { book.identify }.from([]).to([author.id])
|
@@ -86,7 +89,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
86
89
|
end
|
87
90
|
|
88
91
|
describe ':default' do
|
89
|
-
shared_examples_for
|
92
|
+
shared_examples_for 'persisted default' do |default|
|
90
93
|
before do
|
91
94
|
stub_model(:book) do
|
92
95
|
include Granite::Form::Model::Associations
|
@@ -119,10 +122,10 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
119
122
|
specify { expect { book.owner_ids = '' }.to change { book.owners }.from([author]).to([]) }
|
120
123
|
end
|
121
124
|
|
122
|
-
it_behaves_like
|
123
|
-
it_behaves_like
|
125
|
+
it_behaves_like 'persisted default', -> { authors.map(&:id) }
|
126
|
+
it_behaves_like 'persisted default', -> { authors }
|
124
127
|
|
125
|
-
shared_examples_for
|
128
|
+
shared_examples_for 'new record default' do |default|
|
126
129
|
before do
|
127
130
|
stub_model(:book) do
|
128
131
|
include Granite::Form::Model::Associations
|
@@ -139,7 +142,14 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
139
142
|
specify { expect { book.owners = [other] }.to change { book.owner_ids }.from([nil]).to([other.id]) }
|
140
143
|
specify { expect { book.owners = [other] }.to change { book.owners }.from([an_instance_of(Author)]).to([other]) }
|
141
144
|
specify { expect { book.owner_ids = [other.id] }.to change { book.owner_ids }.from([nil]).to([other.id]) }
|
142
|
-
|
145
|
+
|
146
|
+
specify do
|
147
|
+
expect { book.owner_ids = [other.id] }
|
148
|
+
.to change { book.owners }
|
149
|
+
.from([an_instance_of(Author)])
|
150
|
+
.to([other])
|
151
|
+
end
|
152
|
+
|
143
153
|
specify { expect { book.owners = [] }.to change { book.owner_ids }.from([nil]).to([]) }
|
144
154
|
specify { expect { book.owners = [] }.to change { book.owners }.from([an_instance_of(Author)]).to([]) }
|
145
155
|
specify { expect { book.owner_ids = [] }.not_to change { book.owner_ids }.from([nil]) }
|
@@ -154,12 +164,14 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
154
164
|
specify { expect { book.owner_ids = '' }.to change { book.owners }.from([an_instance_of(Author)]).to([]) }
|
155
165
|
end
|
156
166
|
|
157
|
-
it_behaves_like
|
158
|
-
it_behaves_like
|
167
|
+
it_behaves_like 'new record default', name: 'Author'
|
168
|
+
it_behaves_like 'new record default', -> { Author.new(name: 'Author') }
|
159
169
|
end
|
160
170
|
|
161
171
|
describe 'Book.inspect' do
|
162
|
-
specify
|
172
|
+
specify do
|
173
|
+
expect(Book.inspect).to eq('Book(authors: ReferencesMany(Author), title: String, author_ids: (reference))')
|
174
|
+
end
|
163
175
|
end
|
164
176
|
|
165
177
|
describe '#scope' do
|
@@ -179,6 +191,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
179
191
|
expect { book.authors = [author1, author2] }
|
180
192
|
.to change { book.authors }.from([]).to([author1, author2])
|
181
193
|
end
|
194
|
+
|
182
195
|
specify do
|
183
196
|
expect { book.authors = [author1, author2] }
|
184
197
|
.to change { book.author_ids }.from([]).to([author1.id, author2.id])
|
@@ -188,6 +201,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
188
201
|
expect { book.author_ids = [author1.id, author2.id] }
|
189
202
|
.to change { book.authors }.from([]).to([author2])
|
190
203
|
end
|
204
|
+
|
191
205
|
specify do
|
192
206
|
expect { book.author_ids = [author1.id, author2.id] }
|
193
207
|
.to change { book.author_ids }.from([]).to([author2.id])
|
@@ -197,6 +211,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
197
211
|
expect { book.authors = [author1, author2] }
|
198
212
|
.to change { book.authors.reload }.from([]).to([author2])
|
199
213
|
end
|
214
|
+
|
200
215
|
specify do
|
201
216
|
expect { book.authors = [author1, author2] }
|
202
217
|
.to change {
|
@@ -228,14 +243,17 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
228
243
|
|
229
244
|
describe '#reload' do
|
230
245
|
before { book.authors << author.tap { |a| a.name = 'Don Juan' } }
|
246
|
+
|
231
247
|
it { expect { book.authors.reload }.to change { book.authors.map(&:name) }.from(['Don Juan']).to(['Rick']) }
|
232
248
|
end
|
233
249
|
|
234
250
|
describe '#concat' do
|
235
251
|
it { expect { book.authors.concat author }.to change { book.authors }.from([]).to([author]) }
|
236
252
|
it { expect { book.authors << author << other }.to change { book.authors }.from([]).to([author, other]) }
|
253
|
+
|
237
254
|
context 'no duplication' do
|
238
255
|
before { book.authors << author }
|
256
|
+
|
239
257
|
it { expect { book.authors.concat author }.not_to change { book.authors }.from([author]) }
|
240
258
|
end
|
241
259
|
end
|
@@ -249,8 +267,20 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
249
267
|
|
250
268
|
describe '#author_ids' do
|
251
269
|
it { expect(book_with_author.author_ids).to eq([author.id]) }
|
252
|
-
|
253
|
-
|
270
|
+
|
271
|
+
xit do
|
272
|
+
expect { book_with_author.author_ids << other.id }
|
273
|
+
.to change { book_with_author.authors }
|
274
|
+
.from([author])
|
275
|
+
.to([author, other])
|
276
|
+
end
|
277
|
+
|
278
|
+
it {
|
279
|
+
expect { book_with_author.author_ids = [other.id] }
|
280
|
+
.to change { book_with_author.authors }
|
281
|
+
.from([author])
|
282
|
+
.to([other])
|
283
|
+
}
|
254
284
|
end
|
255
285
|
|
256
286
|
describe '#authors=' do
|
@@ -259,6 +289,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
259
289
|
|
260
290
|
context do
|
261
291
|
before { book.authors = [other] }
|
292
|
+
|
262
293
|
specify { expect { book.authors = [author] }.to change { book.authors }.from([other]).to([author]) }
|
263
294
|
specify { expect { book.authors = [author] }.to change { book.author_ids }.from([other.id]).to([author.id]) }
|
264
295
|
specify { expect { book.authors = [] }.to change { book.authors }.from([other]).to([]) }
|
@@ -267,16 +298,19 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
267
298
|
|
268
299
|
context 'model not persisted' do
|
269
300
|
let(:author) { Author.new }
|
301
|
+
|
270
302
|
specify { expect { book.authors = [author, other] }.to change { book.authors }.from([]).to([author, other]) }
|
271
303
|
specify { expect { book.authors = [author, other] }.to change { book.author_ids }.from([]).to([nil, other.id]) }
|
272
304
|
|
273
305
|
context do
|
274
306
|
before { book.authors = [author, other] }
|
307
|
+
|
275
308
|
specify do
|
276
309
|
expect { author.save! }.to change { book.author_ids }.from([nil, other.id])
|
277
|
-
|
310
|
+
.to(match([be_a(Integer), other.id]))
|
278
311
|
end
|
279
|
-
|
312
|
+
|
313
|
+
specify { expect { author.save! }.not_to(change { book.authors }) }
|
280
314
|
end
|
281
315
|
end
|
282
316
|
end
|
@@ -289,12 +323,30 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
289
323
|
specify { expect { book.author_ids = [author.id.next.to_s] }.not_to change { book.author_ids }.from([]) }
|
290
324
|
specify { expect { book.author_ids = [author.id.next.to_s] }.not_to change { book.authors }.from([]) }
|
291
325
|
|
292
|
-
specify
|
293
|
-
|
326
|
+
specify do
|
327
|
+
expect { book.author_ids = [author.id.next.to_s, author.id] }
|
328
|
+
.to change { book.author_ids }
|
329
|
+
.from([])
|
330
|
+
.to([author.id])
|
331
|
+
end
|
332
|
+
|
333
|
+
specify do
|
334
|
+
expect { book.author_ids = [author.id.next.to_s, author.id] }
|
335
|
+
.to change { book.authors }
|
336
|
+
.from([])
|
337
|
+
.to([author])
|
338
|
+
end
|
294
339
|
|
295
340
|
context do
|
296
341
|
before { book.authors = [other] }
|
297
|
-
|
342
|
+
|
343
|
+
specify do
|
344
|
+
expect { book.author_ids = [author.id] }
|
345
|
+
.to change { book.author_ids }
|
346
|
+
.from([other.id])
|
347
|
+
.to([author.id])
|
348
|
+
end
|
349
|
+
|
298
350
|
specify { expect { book.author_ids = [author.id] }.to change { book.authors }.from([other]).to([author]) }
|
299
351
|
specify { expect { book.author_ids = [] }.to change { book.author_ids }.from([other.id]).to([]) }
|
300
352
|
specify { expect { book.author_ids = [] }.to change { book.authors }.from([other]).to([]) }
|
@@ -14,6 +14,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
14
14
|
references_one :author
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
17
18
|
let(:book) { Book.new }
|
18
19
|
|
19
20
|
specify { expect(book.author).to be_nil }
|
@@ -27,12 +28,14 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
27
28
|
references_one :creator, class_name: 'Author'
|
28
29
|
end
|
29
30
|
end
|
31
|
+
|
30
32
|
let(:author) { Author.create!(name: 'Rick') }
|
31
33
|
|
32
34
|
specify do
|
33
35
|
expect { book.creator = author }
|
34
36
|
.to change { book.creator }.from(nil).to(author)
|
35
37
|
end
|
38
|
+
|
36
39
|
specify do
|
37
40
|
expect { book.creator = author }
|
38
41
|
.to change { book.creator_id }.from(nil).to(author.id)
|
@@ -54,6 +57,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
54
57
|
expect { book.author_name = author.name }
|
55
58
|
.to change { book.author }.from(nil).to(author)
|
56
59
|
end
|
60
|
+
|
57
61
|
specify do
|
58
62
|
expect { book.author = author }
|
59
63
|
.to change { book.author_name }.from(nil).to(author.name)
|
@@ -74,6 +78,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
74
78
|
expect { book.identify = author.id }
|
75
79
|
.to change { book.author }.from(nil).to(author)
|
76
80
|
end
|
81
|
+
|
77
82
|
specify do
|
78
83
|
expect { book.author = author }
|
79
84
|
.to change { book.identify }.from(nil).to(author.id)
|
@@ -81,7 +86,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
81
86
|
end
|
82
87
|
|
83
88
|
describe ':default' do
|
84
|
-
shared_examples_for
|
89
|
+
shared_examples_for 'persisted default' do |default|
|
85
90
|
before do
|
86
91
|
stub_model(:book) do
|
87
92
|
include Granite::Form::Model::Associations
|
@@ -108,10 +113,10 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
108
113
|
specify { expect { book.owner_id = '' }.to change { book.owner }.from(author).to(nil) }
|
109
114
|
end
|
110
115
|
|
111
|
-
it_behaves_like
|
112
|
-
it_behaves_like
|
116
|
+
it_behaves_like 'persisted default', -> { author.id }
|
117
|
+
it_behaves_like 'persisted default', -> { author }
|
113
118
|
|
114
|
-
shared_examples_for
|
119
|
+
shared_examples_for 'new record default' do |default|
|
115
120
|
before do
|
116
121
|
stub_model(:book) do
|
117
122
|
include Granite::Form::Model::Associations
|
@@ -137,8 +142,8 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
137
142
|
specify { expect { book.owner_id = '' }.to change { book.owner }.from(instance_of(Author)).to(nil) }
|
138
143
|
end
|
139
144
|
|
140
|
-
it_behaves_like
|
141
|
-
it_behaves_like
|
145
|
+
it_behaves_like 'new record default', name: 'Author'
|
146
|
+
it_behaves_like 'new record default', -> { Author.new(name: 'Author') }
|
142
147
|
end
|
143
148
|
|
144
149
|
describe 'Book.inspect' do
|
@@ -160,8 +165,9 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
160
165
|
|
161
166
|
specify do
|
162
167
|
expect { book.author_id = author1.id }
|
163
|
-
.not_to
|
168
|
+
.not_to(change { book.author })
|
164
169
|
end
|
170
|
+
|
165
171
|
specify do
|
166
172
|
expect { book.author_id = author2.id }
|
167
173
|
.to change { book.author }.from(nil).to(author2)
|
@@ -171,6 +177,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
171
177
|
expect { book.author = author1 }
|
172
178
|
.to change { book.author_id }.from(nil).to(author1.id)
|
173
179
|
end
|
180
|
+
|
174
181
|
specify do
|
175
182
|
expect { book.author = author2 }
|
176
183
|
.to change { book.author_id }.from(nil).to(author2.id)
|
@@ -183,6 +190,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
183
190
|
book.author_id
|
184
191
|
}.from(nil).to(author1.id)
|
185
192
|
end
|
193
|
+
|
186
194
|
specify do
|
187
195
|
expect { book.author = author2 }
|
188
196
|
.to change {
|
@@ -193,11 +201,12 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
193
201
|
|
194
202
|
specify do
|
195
203
|
expect { book.author = author1 }
|
196
|
-
.not_to
|
204
|
+
.not_to(change do
|
197
205
|
book.association(:author).reload
|
198
206
|
book.author
|
199
|
-
|
207
|
+
end)
|
200
208
|
end
|
209
|
+
|
201
210
|
specify do
|
202
211
|
expect { book.author = author2 }
|
203
212
|
.to change {
|
@@ -220,12 +229,15 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
220
229
|
|
221
230
|
describe '#author=' do
|
222
231
|
let(:author) { Author.create! name: 'Author' }
|
232
|
+
|
223
233
|
specify { expect { book.author = author }.to change { book.author }.from(nil).to(author) }
|
224
234
|
specify { expect { book.author = 'string' }.to raise_error Granite::Form::AssociationTypeMismatch }
|
225
235
|
|
226
236
|
context do
|
227
237
|
let(:other) { Author.create! name: 'Other' }
|
238
|
+
|
228
239
|
before { book.author = other }
|
240
|
+
|
229
241
|
specify { expect { book.author = author }.to change { book.author }.from(other).to(author) }
|
230
242
|
specify { expect { book.author = author }.to change { book.author_id }.from(other.id).to(author.id) }
|
231
243
|
specify { expect { book.author = nil }.to change { book.author }.from(other).to(nil) }
|
@@ -234,29 +246,40 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
234
246
|
|
235
247
|
context 'model not persisted' do
|
236
248
|
let(:author) { Author.new }
|
249
|
+
|
237
250
|
specify { expect { book.author = author }.to change { book.author }.from(nil).to(author) }
|
238
251
|
specify { expect { book.author = author }.not_to change { book.author_id }.from(nil) }
|
239
252
|
|
240
253
|
context do
|
241
254
|
before { book.author = author }
|
255
|
+
|
242
256
|
specify { expect { author.save! }.to change { book.author_id }.from(nil).to(be_a(Integer)) }
|
243
|
-
specify { expect { author.save! }.not_to
|
257
|
+
specify { expect { author.save! }.not_to(change { book.author }) }
|
244
258
|
end
|
245
259
|
end
|
246
260
|
end
|
247
261
|
|
248
262
|
describe '#author_id=' do
|
249
263
|
let(:author) { Author.create!(name: 'Author') }
|
264
|
+
|
250
265
|
specify { expect { book.author_id = author.id }.to change { book.author_id }.from(nil).to(author.id) }
|
251
266
|
specify { expect { book.author_id = author.id }.to change { book.author }.from(nil).to(author) }
|
252
267
|
specify { expect { book.author_id = author }.to change { book.author }.from(nil).to(author) }
|
253
268
|
|
254
|
-
specify
|
269
|
+
specify do
|
270
|
+
expect { book.author_id = author.id.next.to_s }
|
271
|
+
.to change { book.author_id }
|
272
|
+
.from(nil)
|
273
|
+
.to(author.id.next)
|
274
|
+
end
|
275
|
+
|
255
276
|
specify { expect { book.author_id = author.id.next.to_s }.not_to change { book.author }.from(nil) }
|
256
277
|
|
257
278
|
context do
|
258
279
|
let(:other) { Author.create!(name: 'Other') }
|
280
|
+
|
259
281
|
before { book.author = other }
|
282
|
+
|
260
283
|
specify { expect { book.author_id = author.id }.to change { book.author_id }.from(other.id).to(author.id) }
|
261
284
|
specify { expect { book.author_id = author.id }.to change { book.author }.from(other).to(author) }
|
262
285
|
specify { expect { book.author_id = nil }.to change { book.author_id }.from(other.id).to(nil) }
|
@@ -38,16 +38,18 @@ describe Granite::Form::Model::Associations::Validations do
|
|
38
38
|
let(:project) { Project.new title: 'Project' }
|
39
39
|
let(:projects) { [project] }
|
40
40
|
let(:user) { User.new(login: 'Login', profile: profile, projects: projects) }
|
41
|
-
let(:author_attributes) { {name: 'Author'} }
|
41
|
+
let(:author_attributes) { { name: 'Author' } }
|
42
|
+
|
42
43
|
before { project.build_author(author_attributes) }
|
43
44
|
|
44
45
|
specify { expect(user.validate).to eq(true) }
|
45
|
-
specify { expect { user.validate }.not_to
|
46
|
+
specify { expect { user.validate }.not_to(change { user.errors.messages }) }
|
46
47
|
|
47
48
|
context do
|
48
49
|
let(:author_attributes) { {} }
|
49
50
|
|
50
51
|
specify { expect(user.validate).to eq(false) }
|
52
|
+
|
51
53
|
specify do
|
52
54
|
expect { user.validate }.to change { user.errors.messages }
|
53
55
|
.to('projects.0.author.name': ["can't be blank"])
|
@@ -58,13 +60,14 @@ describe Granite::Form::Model::Associations::Validations do
|
|
58
60
|
let(:profile) { Profile.new }
|
59
61
|
|
60
62
|
specify { expect(user.validate).to eq(true) }
|
61
|
-
specify { expect { user.validate }.not_to
|
63
|
+
specify { expect { user.validate }.not_to(change { user.errors.messages }) }
|
62
64
|
end
|
63
65
|
|
64
66
|
context do
|
65
67
|
let(:projects) { [project, Project.new] }
|
66
68
|
|
67
69
|
specify { expect(user.validate).to eq(false) }
|
70
|
+
|
68
71
|
specify do
|
69
72
|
expect { user.validate }.to change { user.errors.messages }
|
70
73
|
.to('projects.1.title': ["can't be blank"])
|
@@ -77,7 +80,8 @@ describe Granite::Form::Model::Associations::Validations do
|
|
77
80
|
let(:project) { Project.new title: 'Project' }
|
78
81
|
let(:projects) { [project] }
|
79
82
|
let(:user) { User.new(login: 'Login', profile: profile, projects: projects) }
|
80
|
-
let(:author_attributes) { {name: 'Author'} }
|
83
|
+
let(:author_attributes) { { name: 'Author' } }
|
84
|
+
|
81
85
|
before { project.build_author(author_attributes) }
|
82
86
|
|
83
87
|
specify { expect(user.validate_ancestry).to eq(true) }
|
@@ -85,14 +89,16 @@ describe Granite::Form::Model::Associations::Validations do
|
|
85
89
|
specify { expect { user.validate_ancestry! }.not_to raise_error }
|
86
90
|
specify { expect(user.valid_ancestry?).to eq(true) }
|
87
91
|
specify { expect(user.invalid_ancestry?).to eq(false) }
|
88
|
-
specify { expect { user.validate_ancestry }.not_to
|
92
|
+
specify { expect { user.validate_ancestry }.not_to(change { user.errors.messages }) }
|
89
93
|
|
90
94
|
context do
|
91
95
|
let(:author_attributes) { {} }
|
96
|
+
|
92
97
|
specify { expect(user.validate_ancestry).to eq(false) }
|
93
98
|
specify { expect { user.validate_ancestry! }.to raise_error Granite::Form::ValidationError }
|
94
99
|
specify { expect(user.valid_ancestry?).to eq(false) }
|
95
100
|
specify { expect(user.invalid_ancestry?).to eq(true) }
|
101
|
+
|
96
102
|
specify do
|
97
103
|
expect { user.validate_ancestry }.to change { user.errors.messages }
|
98
104
|
.to('projects.0.author.name': ["can't be blank"])
|
@@ -101,10 +107,12 @@ describe Granite::Form::Model::Associations::Validations do
|
|
101
107
|
|
102
108
|
context do
|
103
109
|
let(:profile) { Profile.new }
|
110
|
+
|
104
111
|
specify { expect(user.validate_ancestry).to eq(false) }
|
105
112
|
specify { expect { user.validate_ancestry! }.to raise_error Granite::Form::ValidationError }
|
106
113
|
specify { expect(user.valid_ancestry?).to eq(false) }
|
107
114
|
specify { expect(user.invalid_ancestry?).to eq(true) }
|
115
|
+
|
108
116
|
specify do
|
109
117
|
expect { user.validate_ancestry }.to change { user.errors.messages }
|
110
118
|
.to('profile.first_name': ["can't be blank"])
|
@@ -113,10 +121,12 @@ describe Granite::Form::Model::Associations::Validations do
|
|
113
121
|
|
114
122
|
context do
|
115
123
|
let(:projects) { [project, Project.new] }
|
124
|
+
|
116
125
|
specify { expect(user.validate_ancestry).to eq(false) }
|
117
126
|
specify { expect { user.validate_ancestry! }.to raise_error Granite::Form::ValidationError }
|
118
127
|
specify { expect(user.valid_ancestry?).to eq(false) }
|
119
128
|
specify { expect(user.invalid_ancestry?).to eq(true) }
|
129
|
+
|
120
130
|
specify do
|
121
131
|
expect { user.validate_ancestry }.to change { user.errors.messages }
|
122
132
|
.to('projects.1.title': ["can't be blank"])
|
@@ -124,6 +134,7 @@ describe Granite::Form::Model::Associations::Validations do
|
|
124
134
|
|
125
135
|
context do
|
126
136
|
before { user.update(login: '') }
|
137
|
+
|
127
138
|
specify do
|
128
139
|
expect { user.validate_ancestry }.to change { user.errors.messages }
|
129
140
|
.to('projects.1.title': ["can't be blank"], login: ["can't be blank"])
|
@@ -34,9 +34,18 @@ describe Granite::Form::Model::Associations do
|
|
34
34
|
|
35
35
|
describe '#reflect_on_association' do
|
36
36
|
specify { expect(Nobody.reflect_on_association(:blabla)).to be_nil }
|
37
|
-
|
37
|
+
|
38
|
+
specify do
|
39
|
+
expect(Admin.reflect_on_association('projects'))
|
40
|
+
.to be_a Granite::Form::Model::Associations::Reflections::EmbedsMany
|
41
|
+
end
|
42
|
+
|
38
43
|
specify { expect(Admin.reflect_on_association('own_projects').name).to eq(:admin_projects) }
|
39
|
-
|
44
|
+
|
45
|
+
specify do
|
46
|
+
expect(Manager.reflect_on_association(:managed_project))
|
47
|
+
.to be_a Granite::Form::Model::Associations::Reflections::EmbedsOne
|
48
|
+
end
|
40
49
|
end
|
41
50
|
end
|
42
51
|
|
@@ -47,7 +56,8 @@ describe Granite::Form::Model::Associations do
|
|
47
56
|
include Granite::Form::Model::Associations
|
48
57
|
|
49
58
|
embeds_one :author, class_name: 'Borogoves'
|
50
|
-
end.reflect_on_association(:author).data_source
|
59
|
+
end.reflect_on_association(:author).data_source
|
60
|
+
end.to raise_error NameError
|
51
61
|
end
|
52
62
|
|
53
63
|
specify do
|
@@ -58,7 +68,8 @@ describe Granite::Form::Model::Associations do
|
|
58
68
|
embeds_many :projects, class_name: 'Borogoves' do
|
59
69
|
attribute :title
|
60
70
|
end
|
61
|
-
end.reflect_on_association(:projects).data_source
|
71
|
+
end.reflect_on_association(:projects).data_source
|
72
|
+
end.to raise_error NameError
|
62
73
|
end
|
63
74
|
end
|
64
75
|
|
@@ -108,7 +119,9 @@ describe Granite::Form::Model::Associations do
|
|
108
119
|
specify { expect(user.profile).to be_nil }
|
109
120
|
|
110
121
|
describe '.inspect' do
|
111
|
-
specify
|
122
|
+
specify do
|
123
|
+
expect(User.inspect).to eq('User(profile: EmbedsOne(Profile), projects: EmbedsMany(Project), login: Object)')
|
124
|
+
end
|
112
125
|
end
|
113
126
|
|
114
127
|
describe '.association_names' do
|
@@ -118,9 +131,10 @@ describe Granite::Form::Model::Associations do
|
|
118
131
|
describe '#inspect' do
|
119
132
|
let(:profile) { Profile.new first_name: 'Name' }
|
120
133
|
let(:project) { Project.new title: 'Project' }
|
134
|
+
|
121
135
|
specify do
|
122
136
|
expect(User.new(login: 'Login', profile: profile, projects: [project]).inspect)
|
123
|
-
.to eq('#<User profile: #<EmbedsOne #<Profile first_name: "Name", last_name: nil>>, projects: #<EmbedsMany [#<Project author: #<EmbedsOne nil>, title: "P...]>, login: "Login">')
|
137
|
+
.to eq('#<User profile: #<EmbedsOne #<Profile first_name: "Name", last_name: nil>>, projects: #<EmbedsMany [#<Project author: #<EmbedsOne nil>, title: "P...]>, login: "Login">') # rubocop:disable Layout/LineLength
|
124
138
|
end
|
125
139
|
end
|
126
140
|
|
@@ -137,7 +151,8 @@ describe Granite::Form::Model::Associations do
|
|
137
151
|
specify { expect(User.new(projects: [project])).not_to eql(User.new) }
|
138
152
|
|
139
153
|
context do
|
140
|
-
before { User.
|
154
|
+
before { User.include Granite::Form::Model::Primary }
|
155
|
+
|
141
156
|
let(:user) { User.new(projects: [project]) }
|
142
157
|
|
143
158
|
specify { expect(user).to eq(user.clone.tap { |b| b.projects(author: project) }) }
|
@@ -161,13 +176,17 @@ describe Granite::Form::Model::Associations do
|
|
161
176
|
end
|
162
177
|
|
163
178
|
describe '#instantiate' do
|
164
|
-
before
|
179
|
+
before do
|
180
|
+
User.include Granite::Form::Model::Persistence
|
181
|
+
project.build_author(name: 'Author')
|
182
|
+
end
|
183
|
+
|
165
184
|
let(:profile) { Profile.new first_name: 'Name' }
|
166
185
|
let(:project) { Project.new title: 'Project' }
|
167
186
|
let(:user) { User.new(profile: profile, projects: [project]) }
|
168
|
-
before { project.build_author(name: 'Author') }
|
169
187
|
|
170
188
|
specify { expect(User.instantiate(JSON.parse(user.to_json))).to eq(user) }
|
189
|
+
|
171
190
|
specify do
|
172
191
|
expect(User.instantiate(JSON.parse(user.to_json))
|
173
192
|
.tap { |u| u.projects.first.author.name = 'Other' }).not_to eq(user)
|
@@ -5,12 +5,16 @@ describe Granite::Form::Model::Attributes::Attribute do
|
|
5
5
|
|
6
6
|
def attribute(*args)
|
7
7
|
options = args.extract_options!
|
8
|
-
Dummy.add_attribute(Granite::Form::Model::Attributes::Reflections::Attribute, :field,
|
8
|
+
Dummy.add_attribute(Granite::Form::Model::Attributes::Reflections::Attribute, :field,
|
9
|
+
{ type: Object }.merge(options))
|
9
10
|
Dummy.new.attribute(:field)
|
10
11
|
end
|
11
12
|
|
12
13
|
describe '#read' do
|
13
|
-
let(:field)
|
14
|
+
let(:field) do
|
15
|
+
normalizer = ->(v) { v ? v.strip : v }
|
16
|
+
attribute(type: String, normalizer: normalizer, default: :world, enum: %w[hello 42 world])
|
17
|
+
end
|
14
18
|
|
15
19
|
specify { expect(field.tap { |r| r.write(nil) }.read).to eq('world') }
|
16
20
|
specify { expect(field.tap { |r| r.write(:world) }.read).to eq('world') }
|
@@ -36,7 +40,11 @@ describe Granite::Form::Model::Attributes::Attribute do
|
|
36
40
|
specify { expect(field.tap { |r| r.write('') }.read_before_type_cast).to eq('') }
|
37
41
|
|
38
42
|
context ':readonly' do
|
39
|
-
specify
|
43
|
+
specify do
|
44
|
+
attr = attribute(readonly: true, default: :world)
|
45
|
+
attr.write('string')
|
46
|
+
expect(attr.read_before_type_cast).to eq(:world)
|
47
|
+
end
|
40
48
|
end
|
41
49
|
end
|
42
50
|
|
@@ -58,11 +66,22 @@ describe Granite::Form::Model::Attributes::Attribute do
|
|
58
66
|
describe '#normalize' do
|
59
67
|
specify { expect(attribute.normalize(' hello ')).to eq(' hello ') }
|
60
68
|
specify { expect(attribute(normalizer: ->(v) { v.strip }).normalize(' hello ')).to eq('hello') }
|
61
|
-
|
62
|
-
specify
|
69
|
+
|
70
|
+
specify do
|
71
|
+
normalizers = [->(v) { v.strip }, ->(v) { v.first(4) }]
|
72
|
+
attr = attribute(normalizer: normalizers)
|
73
|
+
expect(attr.normalize(' hello ')).to eq('hell')
|
74
|
+
end
|
75
|
+
|
76
|
+
specify do
|
77
|
+
normalizers = [->(v) { v.first(4) }, ->(v) { v.strip }]
|
78
|
+
attr = attribute(normalizer: normalizers)
|
79
|
+
expect(attr.normalize(' hello ')).to eq('hel')
|
80
|
+
end
|
63
81
|
|
64
82
|
context do
|
65
83
|
before { allow_any_instance_of(Dummy).to receive_messages(value: 'value') }
|
84
|
+
|
66
85
|
let(:other) { 'other' }
|
67
86
|
|
68
87
|
specify { expect(attribute(normalizer: ->(_v) { value }).normalize(' hello ')).to eq('value') }
|
@@ -89,12 +108,14 @@ describe Granite::Form::Model::Attributes::Attribute do
|
|
89
108
|
specify { expect(attribute(normalizer: :strip).normalize(' hello ')).to eq('hello') }
|
90
109
|
specify { expect(attribute(normalizer: %i[strip trim]).normalize(' hello ')).to eq('he') }
|
91
110
|
specify { expect(attribute(normalizer: %i[trim strip]).normalize(' hello ')).to eq('h') }
|
92
|
-
specify { expect(attribute(normalizer: [:strip, {trim: {length: 4}}]).normalize(' hello ')).to eq('hell') }
|
93
|
-
specify { expect(attribute(normalizer: {strip: {}, trim: {length: 4}}).normalize(' hello ')).to eq('hell') }
|
111
|
+
specify { expect(attribute(normalizer: [:strip, { trim: { length: 4 } }]).normalize(' hello ')).to eq('hell') }
|
112
|
+
specify { expect(attribute(normalizer: { strip: {}, trim: { length: 4 } }).normalize(' hello ')).to eq('hell') }
|
113
|
+
|
94
114
|
specify do
|
95
|
-
expect(attribute(normalizer: [:strip, {trim: {length: 4}}, ->(v) { v.last(2) }])
|
115
|
+
expect(attribute(normalizer: [:strip, { trim: { length: 4 } }, ->(v) { v.last(2) }])
|
96
116
|
.normalize(' hello ')).to eq('ll')
|
97
117
|
end
|
118
|
+
|
98
119
|
specify { expect(attribute(normalizer: :reset).normalize('')).to eq(nil) }
|
99
120
|
specify { expect(attribute(normalizer: %i[strip reset]).normalize(' ')).to eq(nil) }
|
100
121
|
specify { expect(attribute(normalizer: :reset, default: '!!!').normalize(nil)).to eq('!!!') }
|
@@ -103,10 +124,11 @@ describe Granite::Form::Model::Attributes::Attribute do
|
|
103
124
|
context do
|
104
125
|
let(:length) { 3 }
|
105
126
|
|
106
|
-
specify { expect(attribute(normalizer: [:strip, {trim: {length: 4}}]).normalize(' hello ')).to eq('hel') }
|
107
|
-
specify { expect(attribute(normalizer: {strip: {}, trim: {length: 4}}).normalize(' hello ')).to eq('hel') }
|
127
|
+
specify { expect(attribute(normalizer: [:strip, { trim: { length: 4 } }]).normalize(' hello ')).to eq('hel') }
|
128
|
+
specify { expect(attribute(normalizer: { strip: {}, trim: { length: 4 } }).normalize(' hello ')).to eq('hel') }
|
129
|
+
|
108
130
|
specify do
|
109
|
-
expect(attribute(normalizer: [:strip, {trim: {length: 4}}, ->(v) { v.last(2) }])
|
131
|
+
expect(attribute(normalizer: [:strip, { trim: { length: 4 } }, ->(v) { v.last(2) }])
|
110
132
|
.normalize(' hello ')).to eq('el')
|
111
133
|
end
|
112
134
|
end
|