granite-form 0.5.0 → 0.6.1
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 +14 -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 +31 -14
- 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 +97 -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 +19 -6
- data/.github/CODEOWNERS +0 -1
@@ -57,16 +57,19 @@ describe Granite::Form::ActiveRecord::Associations do
|
|
57
57
|
describe '#projects' do
|
58
58
|
specify do
|
59
59
|
expect { user.projects << Project.new }
|
60
|
-
.not_to
|
60
|
+
.not_to(change { user.read_attribute(:projects) })
|
61
61
|
end
|
62
|
+
|
62
63
|
specify do
|
63
64
|
expect { user.projects << Project.new(title: 'First') }
|
64
|
-
.not_to
|
65
|
+
.not_to(change { user.read_attribute(:projects) })
|
65
66
|
end
|
67
|
+
|
66
68
|
specify do
|
67
69
|
expect { user.projects << Project.new(title: 'First') }
|
68
|
-
.not_to
|
70
|
+
.not_to(change { user.projects.reload.count })
|
69
71
|
end
|
72
|
+
|
70
73
|
specify do
|
71
74
|
user.projects << Project.new(title: 'First')
|
72
75
|
user.save
|
@@ -77,12 +80,14 @@ describe Granite::Form::ActiveRecord::Associations do
|
|
77
80
|
describe '#profile' do
|
78
81
|
specify do
|
79
82
|
expect { user.profile = Profile.new(first_name: 'google.com') }
|
80
|
-
.not_to
|
83
|
+
.not_to(change { user.read_attribute(:profile) })
|
81
84
|
end
|
85
|
+
|
82
86
|
specify do
|
83
87
|
expect { user.profile = Profile.new(first_name: 'google.com') }
|
84
88
|
.to change { user.profile }.from(nil).to(an_instance_of(Profile))
|
85
89
|
end
|
90
|
+
|
86
91
|
specify do
|
87
92
|
user.profile = Profile.new(first_name: 'google.com')
|
88
93
|
user.save
|
@@ -110,8 +115,9 @@ describe Granite::Form::ActiveRecord::Associations do
|
|
110
115
|
describe '#projects' do
|
111
116
|
specify do
|
112
117
|
expect { user.projects << Project.new(title: 'First') }
|
113
|
-
.not_to
|
118
|
+
.not_to(change { user.read_attribute(:projects) })
|
114
119
|
end
|
120
|
+
|
115
121
|
specify do
|
116
122
|
user.projects << Project.new(title: 'First')
|
117
123
|
user.save
|
@@ -120,19 +126,21 @@ describe Granite::Form::ActiveRecord::Associations do
|
|
120
126
|
|
121
127
|
context do
|
122
128
|
let(:project) { Project.new(title: 'First') }
|
129
|
+
|
123
130
|
before { project.build_author(name: 'Author') }
|
124
131
|
|
125
132
|
specify do
|
126
133
|
expect { user.projects << project }
|
127
|
-
.not_to
|
134
|
+
.not_to(change { user.read_attribute(:projects) })
|
128
135
|
end
|
136
|
+
|
129
137
|
specify do
|
130
138
|
expect do
|
131
139
|
user.projects << project
|
132
140
|
user.save
|
133
141
|
end
|
134
142
|
.to change { user.reload.read_attribute(:projects) }.from([])
|
135
|
-
.to([{'title' => 'First', 'author' => {'name' => 'Author'}}])
|
143
|
+
.to([{ 'title' => 'First', 'author' => { 'name' => 'Author' } }])
|
136
144
|
end
|
137
145
|
end
|
138
146
|
end
|
@@ -142,22 +150,25 @@ describe Granite::Form::ActiveRecord::Associations do
|
|
142
150
|
expect { user.profile = Profile.new(first_name: 'google.com') }
|
143
151
|
.to change { user.profile }.from(nil).to(an_instance_of(Profile))
|
144
152
|
end
|
153
|
+
|
145
154
|
specify do
|
146
155
|
user.profile = Profile.new(first_name: 'google.com')
|
147
156
|
user.save
|
148
157
|
expect(user.reload.profile.first_name).to eq('google.com')
|
149
158
|
end
|
159
|
+
|
150
160
|
specify do
|
151
161
|
expect { user.profile = Profile.new(first_name: 'google.com') }
|
152
|
-
.not_to
|
162
|
+
.not_to(change { user.read_attribute(:profile) })
|
153
163
|
end
|
164
|
+
|
154
165
|
specify do
|
155
166
|
expect do
|
156
167
|
user.profile = Profile.new(first_name: 'google.com')
|
157
168
|
user.save
|
158
169
|
end
|
159
170
|
.to change { user.reload.read_attribute(:profile) }.from(nil)
|
160
|
-
.to({first_name: 'google.com', last_name: nil, admin: nil}.to_json)
|
171
|
+
.to({ first_name: 'google.com', last_name: nil, admin: nil }.to_json)
|
161
172
|
end
|
162
173
|
end
|
163
174
|
end
|
@@ -167,7 +178,8 @@ describe Granite::Form::ActiveRecord::Associations do
|
|
167
178
|
expect do
|
168
179
|
stub_class(:book, ActiveRecord::Base) do
|
169
180
|
embeds_one :author, class_name: 'Borogoves'
|
170
|
-
end.reflect_on_association(:author).klass
|
181
|
+
end.reflect_on_association(:author).klass
|
182
|
+
end.to raise_error NameError
|
171
183
|
end
|
172
184
|
|
173
185
|
specify do
|
@@ -176,7 +188,8 @@ describe Granite::Form::ActiveRecord::Associations do
|
|
176
188
|
embeds_many :projects, class_name: 'Borogoves' do
|
177
189
|
attribute :title
|
178
190
|
end
|
179
|
-
end.reflect_on_association(:projects).klass
|
191
|
+
end.reflect_on_association(:projects).klass
|
192
|
+
end.to raise_error NameError
|
180
193
|
end
|
181
194
|
end
|
182
195
|
|
@@ -194,13 +207,22 @@ describe Granite::Form::ActiveRecord::Associations do
|
|
194
207
|
|
195
208
|
specify { expect(User.reflect_on_association(:projects).klass).to eq(User::Project) }
|
196
209
|
specify { expect(User.new.projects).to eq([]) }
|
197
|
-
|
198
|
-
specify
|
210
|
+
|
211
|
+
specify do
|
212
|
+
expect(User.new.tap { |u| u.projects.build(title: 'Project') }.projects)
|
213
|
+
.to be_a(Granite::Form::Model::Associations::Collection::Embedded)
|
214
|
+
end
|
215
|
+
|
216
|
+
specify do
|
217
|
+
expect(User.new.tap { |u| u.projects.build(title: 'Project') }.projects)
|
218
|
+
.to match([have_attributes(title: 'Project')])
|
219
|
+
end
|
199
220
|
|
200
221
|
specify { expect(User.reflect_on_association(:profile).klass).to eq(User::Profile) }
|
201
222
|
specify { expect(User.reflect_on_association(:profile).klass).to be < Profile }
|
202
223
|
specify { expect(User.new.profile).to be_nil }
|
203
224
|
specify { expect(User.new.tap { |u| u.build_profile(first_name: 'Profile') }.profile).to be_a(User::Profile) }
|
225
|
+
|
204
226
|
specify do
|
205
227
|
expect(User.new.tap { |u| u.build_profile(first_name: 'Profile') }.profile)
|
206
228
|
.to have_attributes(first_name: 'Profile', last_name: nil, admin: nil, age: nil)
|
@@ -4,7 +4,8 @@ describe Granite::Form::Config do
|
|
4
4
|
subject { Granite::Form::Config.send :new }
|
5
5
|
|
6
6
|
describe '#include_root_in_json' do
|
7
|
-
its(:include_root_in_json) {
|
7
|
+
its(:include_root_in_json) { is_expected.to eq false }
|
8
|
+
|
8
9
|
specify do
|
9
10
|
expect { subject.include_root_in_json = true }
|
10
11
|
.to change { subject.include_root_in_json }.from(false).to(true)
|
@@ -12,7 +13,8 @@ describe Granite::Form::Config do
|
|
12
13
|
end
|
13
14
|
|
14
15
|
describe '#i18n_scope' do
|
15
|
-
its(:i18n_scope) {
|
16
|
+
its(:i18n_scope) { is_expected.to eq :granite }
|
17
|
+
|
16
18
|
specify do
|
17
19
|
expect { subject.i18n_scope = :data_model }
|
18
20
|
.to change { subject.i18n_scope }.from(:granite).to(:data_model)
|
@@ -20,11 +22,12 @@ describe Granite::Form::Config do
|
|
20
22
|
end
|
21
23
|
|
22
24
|
describe '#logger' do
|
23
|
-
its(:logger) {
|
25
|
+
its(:logger) { is_expected.to be_a Logger }
|
24
26
|
end
|
25
27
|
|
26
28
|
describe '#primary_attribute' do
|
27
|
-
its(:primary_attribute) {
|
29
|
+
its(:primary_attribute) { is_expected.to eq :id }
|
30
|
+
|
28
31
|
specify do
|
29
32
|
expect { subject.primary_attribute = :identified }
|
30
33
|
.to change { subject.primary_attribute }.from(:id).to(:identified)
|
@@ -42,6 +45,7 @@ describe Granite::Form::Config do
|
|
42
45
|
end
|
43
46
|
}.from(nil).to(an_instance_of(Proc))
|
44
47
|
end
|
48
|
+
|
45
49
|
specify { expect { subject.normalizer(:wrong) }.to raise_error Granite::Form::NormalizerMissing }
|
46
50
|
end
|
47
51
|
|
@@ -25,19 +25,20 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
25
25
|
let(:user) { User.new(name: 'User') }
|
26
26
|
let(:association) { user.association(:projects) }
|
27
27
|
|
28
|
-
let(:existing_user) { User.instantiate name: 'Rick', projects: [{title: 'Genesis'}] }
|
28
|
+
let(:existing_user) { User.instantiate name: 'Rick', projects: [{ title: 'Genesis' }] }
|
29
29
|
let(:existing_association) { existing_user.association(:projects) }
|
30
30
|
|
31
31
|
context 'callbacks' do
|
32
32
|
before do
|
33
33
|
User.class_eval do
|
34
34
|
embeds_many :projects,
|
35
|
-
|
36
|
-
|
35
|
+
before_add: ->(object) { callbacks.push([:before_add, object]) },
|
36
|
+
after_add: ->(object) { callbacks.push([:after_add, object]) }
|
37
37
|
|
38
38
|
collection :callbacks, Array
|
39
39
|
end
|
40
40
|
end
|
41
|
+
|
41
42
|
let(:project1) { Project.new(title: 'Project1') }
|
42
43
|
let(:project2) { Project.new(title: 'Project2') }
|
43
44
|
|
@@ -54,18 +55,18 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
54
55
|
end
|
55
56
|
.to change { user.callbacks }
|
56
57
|
.to([
|
57
|
-
|
58
|
-
|
59
|
-
|
58
|
+
[:before_add, project1], [:after_add, project1],
|
59
|
+
[:before_add, project2], [:after_add, project2]
|
60
|
+
])
|
60
61
|
end
|
61
62
|
|
62
63
|
specify do
|
63
64
|
expect { association.concat(project1, project2) }
|
64
65
|
.to change { user.callbacks }
|
65
66
|
.to([
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
[:before_add, project1], [:after_add, project1],
|
68
|
+
[:before_add, project2], [:after_add, project2]
|
69
|
+
])
|
69
70
|
end
|
70
71
|
|
71
72
|
specify do
|
@@ -75,18 +76,18 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
75
76
|
end
|
76
77
|
.to change { user.callbacks }
|
77
78
|
.to([
|
78
|
-
|
79
|
-
|
80
|
-
|
79
|
+
[:before_add, project1], [:after_add, project1],
|
80
|
+
[:before_add, project2], [:after_add, project2]
|
81
|
+
])
|
81
82
|
end
|
82
83
|
|
83
84
|
specify do
|
84
85
|
expect { association.writer([project2, project1]) }
|
85
86
|
.to change { user.callbacks }
|
86
87
|
.to([
|
87
|
-
|
88
|
-
|
89
|
-
|
88
|
+
[:before_add, project2], [:after_add, project2],
|
89
|
+
[:before_add, project1], [:after_add, project1]
|
90
|
+
])
|
90
91
|
end
|
91
92
|
|
92
93
|
specify do
|
@@ -97,18 +98,18 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
97
98
|
end
|
98
99
|
.to change { user.callbacks }
|
99
100
|
.to([
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
[:before_add, project1], [:after_add, project1],
|
102
|
+
[:before_add, project2], [:after_add, project2]
|
103
|
+
])
|
103
104
|
end
|
104
105
|
|
105
106
|
context 'default' do
|
106
107
|
before do
|
107
108
|
User.class_eval do
|
108
109
|
embeds_many :projects,
|
109
|
-
|
110
|
-
|
111
|
-
|
110
|
+
before_add: ->(owner, object) { owner.callbacks.push([:before_add, object]) },
|
111
|
+
after_add: ->(owner, object) { owner.callbacks.push([:after_add, object]) },
|
112
|
+
default: -> { { title: 'Project1' } }
|
112
113
|
|
113
114
|
collection :callbacks, Array
|
114
115
|
end
|
@@ -118,9 +119,9 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
118
119
|
expect { association.concat(project2) }
|
119
120
|
.to change { user.callbacks }
|
120
121
|
.to([
|
121
|
-
|
122
|
-
|
123
|
-
|
122
|
+
[:before_add, project2], [:after_add, project2],
|
123
|
+
[:before_add, project1], [:after_add, project1]
|
124
|
+
])
|
124
125
|
end
|
125
126
|
end
|
126
127
|
end
|
@@ -134,14 +135,17 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
134
135
|
let(:project) { Project.new(title: 'Project') }
|
135
136
|
|
136
137
|
specify { expect(association.build.embedder).to eq(user) }
|
138
|
+
|
137
139
|
specify do
|
138
140
|
expect { association.writer([project]) }
|
139
141
|
.to change { project.embedder }.from(nil).to(user)
|
140
142
|
end
|
143
|
+
|
141
144
|
specify do
|
142
145
|
expect { association.concat(project) }
|
143
146
|
.to change { project.embedder }.from(nil).to(user)
|
144
147
|
end
|
148
|
+
|
145
149
|
specify do
|
146
150
|
expect { association.target = [project] }
|
147
151
|
.to change { project.embedder }.from(nil).to(user)
|
@@ -150,7 +154,7 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
150
154
|
context 'default' do
|
151
155
|
before do
|
152
156
|
User.class_eval do
|
153
|
-
embeds_many :projects, default: -> { {title: 'Project1'} }
|
157
|
+
embeds_many :projects, default: -> { { title: 'Project1' } }
|
154
158
|
end
|
155
159
|
end
|
156
160
|
|
@@ -184,22 +188,24 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
184
188
|
|
185
189
|
specify do
|
186
190
|
expect { association.build(title: 'Swordfish') }
|
187
|
-
.not_to
|
191
|
+
.not_to(change { user.read_attribute(:projects) })
|
188
192
|
end
|
193
|
+
|
189
194
|
specify do
|
190
195
|
expect { association.build(title: 'Swordfish') }
|
191
196
|
.to change { association.reader.map(&:attributes) }
|
192
|
-
.from([]).to([{'title' => 'Swordfish'}])
|
197
|
+
.from([]).to([{ 'title' => 'Swordfish' }])
|
193
198
|
end
|
194
199
|
|
195
200
|
specify do
|
196
201
|
expect { existing_association.build(title: 'Swordfish') }
|
197
|
-
.not_to
|
202
|
+
.not_to(change { existing_user.read_attribute(:projects) })
|
198
203
|
end
|
204
|
+
|
199
205
|
specify do
|
200
206
|
expect { existing_association.build(title: 'Swordfish') }
|
201
207
|
.to change { existing_association.reader.map(&:attributes) }
|
202
|
-
.from([{'title' => 'Genesis'}]).to([{'title' => 'Genesis'}, {'title' => 'Swordfish'}])
|
208
|
+
.from([{ 'title' => 'Genesis' }]).to([{ 'title' => 'Genesis' }, { 'title' => 'Swordfish' }])
|
203
209
|
end
|
204
210
|
end
|
205
211
|
|
@@ -210,27 +216,41 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
210
216
|
end
|
211
217
|
|
212
218
|
describe '#default' do
|
213
|
-
before { User.embeds_many :projects, default: -> { {title: 'Default'} } }
|
214
219
|
before do
|
220
|
+
User.embeds_many :projects, default: -> { { title: 'Default' } }
|
215
221
|
Project.class_eval do
|
216
222
|
include Granite::Form::Model::Primary
|
217
223
|
primary :title
|
218
224
|
end
|
219
225
|
end
|
226
|
+
|
220
227
|
let(:new_project) { Project.new.tap { |p| p.title = 'Project' } }
|
221
228
|
let(:existing_user) { User.instantiate name: 'Rick' }
|
222
229
|
|
223
230
|
specify { expect(association.target.map(&:title)).to eq(['Default']) }
|
224
231
|
specify { expect(association.target.map(&:new_record?)).to eq([true]) }
|
225
|
-
|
232
|
+
|
233
|
+
specify do
|
234
|
+
expect { association.replace([new_project]) }
|
235
|
+
.to change { association.target.map(&:title) }
|
236
|
+
.to eq(['Project'])
|
237
|
+
end
|
238
|
+
|
226
239
|
specify { expect { association.replace([]) }.to change { association.target }.to([]) }
|
227
240
|
|
228
241
|
specify { expect(existing_association.target).to eq([]) }
|
229
|
-
|
230
|
-
specify
|
242
|
+
|
243
|
+
specify do
|
244
|
+
expect { existing_association.replace([new_project]) }
|
245
|
+
.to change { existing_association.target.map(&:title) }
|
246
|
+
.to(['Project'])
|
247
|
+
end
|
248
|
+
|
249
|
+
specify { expect { existing_association.replace([]) }.not_to(change { existing_association.target }) }
|
231
250
|
|
232
251
|
context do
|
233
|
-
before { Project.
|
252
|
+
before { Project.include Granite::Form::Model::Dirty }
|
253
|
+
|
234
254
|
specify { expect(association.target.any?(&:changed?)).to eq(false) }
|
235
255
|
end
|
236
256
|
end
|
@@ -250,18 +270,20 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
250
270
|
|
251
271
|
context do
|
252
272
|
before { association.build(title: 'Swordfish') }
|
273
|
+
|
253
274
|
specify do
|
254
275
|
expect { association.reload }
|
255
|
-
.to change { association.reader.map(&:attributes) }.from([{'title' => 'Swordfish'}]).to([])
|
276
|
+
.to change { association.reader.map(&:attributes) }.from([{ 'title' => 'Swordfish' }]).to([])
|
256
277
|
end
|
257
278
|
end
|
258
279
|
|
259
280
|
context do
|
260
281
|
before { existing_association.build(title: 'Swordfish') }
|
282
|
+
|
261
283
|
specify do
|
262
284
|
expect { existing_association.reload }
|
263
285
|
.to change { existing_association.reader.map(&:attributes) }
|
264
|
-
.from([{'title' => 'Genesis'}, {'title' => 'Swordfish'}]).to([{'title' => 'Genesis'}])
|
286
|
+
.from([{ 'title' => 'Genesis' }, { 'title' => 'Swordfish' }]).to([{ 'title' => 'Genesis' }])
|
265
287
|
end
|
266
288
|
end
|
267
289
|
end
|
@@ -270,7 +292,7 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
270
292
|
let!(:project) { association.build(title: 'Genesis') }
|
271
293
|
|
272
294
|
specify do
|
273
|
-
expect { association.sync }.to change { user.read_attribute(:projects) }.from(nil).to([{'title' => 'Genesis'}])
|
295
|
+
expect { association.sync }.to change { user.read_attribute(:projects) }.from(nil).to([{ 'title' => 'Genesis' }])
|
274
296
|
end
|
275
297
|
|
276
298
|
context 'when embedding is nested' do
|
@@ -288,19 +310,20 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
288
310
|
|
289
311
|
specify do
|
290
312
|
expect { association.sync }.to change { user.read_attribute(:projects) }
|
291
|
-
.from(nil).to([{'title' => 'Genesis', 'deadline' => {'enabled' => true}}])
|
313
|
+
.from(nil).to([{ 'title' => 'Genesis', 'deadline' => { 'enabled' => true } }])
|
292
314
|
end
|
293
315
|
end
|
294
316
|
end
|
295
317
|
|
296
318
|
describe '#clear' do
|
297
319
|
specify { expect(association.clear).to eq(true) }
|
298
|
-
specify { expect { association.clear }.not_to
|
320
|
+
specify { expect { association.clear }.not_to(change { association.reader }) }
|
299
321
|
|
300
322
|
specify { expect(existing_association.clear).to eq(true) }
|
323
|
+
|
301
324
|
specify do
|
302
325
|
expect { existing_association.clear }
|
303
|
-
.to change { existing_association.reader.map(&:attributes) }.from([{'title' => 'Genesis'}]).to([])
|
326
|
+
.to change { existing_association.reader.map(&:attributes) }.from([{ 'title' => 'Genesis' }]).to([])
|
304
327
|
end
|
305
328
|
end
|
306
329
|
|
@@ -312,6 +335,7 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
312
335
|
|
313
336
|
context do
|
314
337
|
before { association.build }
|
338
|
+
|
315
339
|
specify { expect(association.reader.last).to be_a Project }
|
316
340
|
specify { expect(association.reader.last).not_to be_persisted }
|
317
341
|
specify { expect(association.reader.size).to eq(1) }
|
@@ -320,6 +344,7 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
320
344
|
|
321
345
|
context do
|
322
346
|
before { existing_association.build(title: 'Swordfish') }
|
347
|
+
|
323
348
|
specify { expect(existing_association.reader.size).to eq(2) }
|
324
349
|
specify { expect(existing_association.reader.last.title).to eq('Swordfish') }
|
325
350
|
specify { expect(existing_association.reader(true).size).to eq(1) }
|
@@ -342,37 +367,45 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
342
367
|
specify { expect(association.writer([])).to eq([]) }
|
343
368
|
|
344
369
|
specify { expect(association.writer([new_project1])).to eq([new_project1]) }
|
370
|
+
|
345
371
|
specify do
|
346
372
|
expect { association.writer([new_project1]) }
|
347
|
-
.to change { association.reader.map(&:attributes) }.from([]).to([{'title' => 'Project 1'}])
|
373
|
+
.to change { association.reader.map(&:attributes) }.from([]).to([{ 'title' => 'Project 1' }])
|
348
374
|
end
|
349
375
|
|
350
376
|
specify do
|
351
377
|
expect { existing_association.writer([new_project1, Dummy.new, new_project2]) }
|
352
378
|
.to raise_error Granite::Form::AssociationTypeMismatch
|
353
379
|
end
|
380
|
+
|
354
381
|
specify do
|
355
|
-
expect
|
356
|
-
|
382
|
+
expect do
|
383
|
+
muffle(Granite::Form::AssociationTypeMismatch) do
|
384
|
+
existing_association.writer([new_project1, Dummy.new, new_project2])
|
385
|
+
end
|
386
|
+
end.not_to(change { existing_association.reader })
|
357
387
|
end
|
358
388
|
|
359
389
|
specify { expect { existing_association.writer(nil) }.to raise_error NoMethodError }
|
390
|
+
|
360
391
|
specify do
|
361
392
|
expect { muffle(NoMethodError) { existing_association.writer(nil) } }
|
362
|
-
.not_to
|
393
|
+
.not_to(change { existing_association.reader })
|
363
394
|
end
|
364
395
|
|
365
396
|
specify { expect(existing_association.writer([])).to eq([]) }
|
397
|
+
|
366
398
|
specify do
|
367
399
|
expect { existing_association.writer([]) }
|
368
400
|
.to change { existing_association.reader }.to([])
|
369
401
|
end
|
370
402
|
|
371
403
|
specify { expect(existing_association.writer([new_project1, new_project2])).to eq([new_project1, new_project2]) }
|
404
|
+
|
372
405
|
specify do
|
373
406
|
expect { existing_association.writer([new_project1, new_project2]) }
|
374
407
|
.to change { existing_association.reader.map(&:attributes) }
|
375
|
-
.from([{'title' => 'Genesis'}]).to([{'title' => 'Project 1'}, {'title' => 'Project 2'}])
|
408
|
+
.from([{ 'title' => 'Genesis' }]).to([{ 'title' => 'Project 1' }, { 'title' => 'Project 2' }])
|
376
409
|
end
|
377
410
|
end
|
378
411
|
|
@@ -392,39 +425,54 @@ describe Granite::Form::Model::Associations::EmbedsMany do
|
|
392
425
|
specify { expect(existing_association.concat).to eq(existing_user.projects) }
|
393
426
|
|
394
427
|
specify { expect(association.concat(new_project1)).to eq([new_project1]) }
|
428
|
+
|
395
429
|
specify do
|
396
430
|
expect { association.concat(new_project1) }
|
397
|
-
.to change { association.reader.map(&:attributes) }.from([]).to([{'title' => 'Project 1'}])
|
431
|
+
.to change { association.reader.map(&:attributes) }.from([]).to([{ 'title' => 'Project 1' }])
|
398
432
|
end
|
433
|
+
|
399
434
|
specify do
|
400
435
|
expect { association.concat(new_project1) }
|
401
|
-
.not_to
|
436
|
+
.not_to(change { user.read_attribute(:projects) })
|
402
437
|
end
|
403
438
|
|
404
439
|
specify do
|
405
440
|
expect { existing_association.concat(new_project1, invalid_project) }
|
406
441
|
.to change { existing_association.reader.map(&:attributes) }
|
407
|
-
.from([{
|
442
|
+
.from([{ 'title' => 'Genesis' }])
|
443
|
+
.to([
|
444
|
+
{ 'title' => 'Genesis' },
|
445
|
+
{ 'title' => 'Project 1' },
|
446
|
+
{ 'title' => nil }
|
447
|
+
])
|
408
448
|
end
|
409
449
|
|
410
450
|
specify do
|
411
451
|
expect { existing_association.concat(new_project1, Dummy.new, new_project2) }
|
412
452
|
.to raise_error Granite::Form::AssociationTypeMismatch
|
413
453
|
end
|
454
|
+
|
414
455
|
specify do
|
415
|
-
expect
|
456
|
+
expect do
|
457
|
+
muffle(Granite::Form::AssociationTypeMismatch) do
|
458
|
+
existing_association.concat(new_project1, Dummy.new, new_project2)
|
459
|
+
end
|
460
|
+
end
|
416
461
|
.to change { existing_association.reader.map(&:attributes) }
|
417
|
-
.from([{'title' => 'Genesis'}]).to([{'title' => 'Genesis'}, {'title' => 'Project 1'}])
|
462
|
+
.from([{ 'title' => 'Genesis' }]).to([{ 'title' => 'Genesis' }, { 'title' => 'Project 1' }])
|
418
463
|
end
|
419
464
|
|
420
465
|
specify do
|
421
466
|
expect(existing_association.concat(new_project1, new_project2))
|
422
467
|
.to eq([existing_user.projects.first, new_project1, new_project2])
|
423
468
|
end
|
469
|
+
|
424
470
|
specify do
|
425
471
|
expect { existing_association.concat([new_project1, new_project2]) }
|
426
472
|
.to change { existing_association.reader.map(&:attributes) }
|
427
|
-
.from([{'title' => 'Genesis'}]).to([{'title' => 'Genesis'
|
473
|
+
.from([{ 'title' => 'Genesis' }]).to([{ 'title' => 'Genesis' },
|
474
|
+
{ 'title' => 'Project 1' },
|
475
|
+
{ 'title' => 'Project 2' }])
|
428
476
|
end
|
429
477
|
end
|
430
478
|
end
|