reform 2.3.2 → 2.6.1
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 +4 -4
- data/.github/workflows/ci.yml +17 -0
- data/.gitignore +1 -1
- data/CHANGES.md +23 -0
- data/Gemfile +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +5 -5
- data/Rakefile +1 -12
- data/lib/reform/contract/validate.rb +1 -1
- data/lib/reform/form/dry.rb +47 -9
- data/lib/reform/form/populator.rb +13 -3
- data/lib/reform/form/prepopulate.rb +1 -1
- data/lib/reform/form/validate.rb +3 -3
- data/lib/reform/validation/groups.rb +0 -1
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +2 -2
- data/test/call_test.rb +23 -0
- data/test/changed_test.rb +6 -6
- data/test/coercion_test.rb +17 -17
- data/test/{composition_new_api.rb → composition_test.rb} +27 -28
- data/test/{contract_new_api.rb → contract_test.rb} +8 -8
- data/test/default_test.rb +2 -2
- data/test/deserialize_test.rb +8 -8
- data/test/docs/validation_test.rb +134 -0
- data/test/{errors_new_api.rb → errors_test.rb} +41 -41
- data/test/feature_test.rb +2 -2
- data/test/fixtures/dry_error_messages.yml +64 -54
- data/test/{form_option_new_api.rb → form_option_test.rb} +1 -1
- data/test/{form_new_api.rb → form_test.rb} +3 -3
- data/test/from_test.rb +10 -10
- data/test/{inherit_new_api.rb → inherit_test.rb} +17 -17
- data/test/{module_new_api.rb → module_test.rb} +10 -10
- data/test/parse_option_test.rb +7 -7
- data/test/parse_pipeline_test.rb +1 -1
- data/test/{populate_new_api.rb → populate_test.rb} +136 -53
- data/test/populator_skip_test.rb +2 -2
- data/test/prepopulator_test.rb +16 -16
- data/test/read_only_test.rb +2 -2
- data/test/readable_test.rb +3 -3
- data/test/{reform_new_api.rb → reform_test.rb} +19 -19
- data/test/{save_new_api.rb → save_test.rb} +4 -4
- data/test/setup_test.rb +9 -9
- data/test/{skip_if_new_api.rb → skip_if_test.rb} +12 -12
- data/test/skip_setter_and_getter_test.rb +6 -6
- data/test/test_helper.rb +5 -6
- data/test/{validate_new_api.rb → validate_test.rb} +65 -78
- data/test/validation/{dry_validation_new_api.rb → dry_validation_test.rb} +128 -128
- data/test/validation/result_test.rb +14 -14
- data/test/virtual_test.rb +7 -7
- data/test/writeable_test.rb +8 -8
- metadata +42 -75
- data/.travis.yml +0 -16
- data/Appraisals +0 -8
- data/gemfiles/0.13.0.gemfile +0 -8
- data/gemfiles/1.5.0.gemfile +0 -9
- data/lib/reform/form/dry/new_api.rb +0 -47
- data/lib/reform/form/dry/old_api.rb +0 -61
- data/test/call_new_api.rb +0 -23
- data/test/call_old_api.rb +0 -23
- data/test/composition_old_api.rb +0 -184
- data/test/contract_old_api.rb +0 -77
- data/test/errors_old_api.rb +0 -230
- data/test/fixtures/dry_new_api_error_messages.yml +0 -104
- data/test/form_old_api.rb +0 -57
- data/test/form_option_old_api.rb +0 -24
- data/test/inherit_old_api.rb +0 -105
- data/test/module_old_api.rb +0 -146
- data/test/populate_old_api.rb +0 -304
- data/test/reform_old_api.rb +0 -202
- data/test/save_old_api.rb +0 -101
- data/test/skip_if_old_api.rb +0 -92
- data/test/validate_old_api.rb +0 -410
- data/test/validation/dry_validation_old_api.rb +0 -772
data/test/writeable_test.rb
CHANGED
@@ -11,20 +11,20 @@ class WriteableTest < MiniTest::Spec
|
|
11
11
|
let(:form) { LocationForm.new(loc) }
|
12
12
|
|
13
13
|
it do
|
14
|
-
form.country
|
14
|
+
assert_equal form.country, "Australia"
|
15
15
|
|
16
16
|
form.validate("country" => "Germany") # this usually won't change when submitting.
|
17
|
-
form.country
|
17
|
+
assert_equal form.country, "Germany"
|
18
18
|
|
19
19
|
form.sync
|
20
|
-
loc.country
|
20
|
+
assert_equal loc.country, "Australia" # the writer wasn't called.
|
21
21
|
|
22
22
|
hash = {}
|
23
23
|
form.save do |nested|
|
24
24
|
hash = nested
|
25
25
|
end
|
26
26
|
|
27
|
-
hash
|
27
|
+
assert_equal hash, "country" => "Germany"
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -40,19 +40,19 @@ class WritableTest < MiniTest::Spec
|
|
40
40
|
let(:form) { LocationForm.new(loc) }
|
41
41
|
|
42
42
|
it do
|
43
|
-
form.country
|
43
|
+
assert_equal form.country, "Australia"
|
44
44
|
|
45
45
|
form.validate("country" => "Germany") # this usually won't change when submitting.
|
46
|
-
form.country
|
46
|
+
assert_equal form.country, "Germany"
|
47
47
|
|
48
48
|
form.sync
|
49
|
-
loc.country
|
49
|
+
assert_equal loc.country, "Australia" # the writer wasn't called.
|
50
50
|
|
51
51
|
hash = {}
|
52
52
|
form.save do |nested|
|
53
53
|
hash = nested
|
54
54
|
end
|
55
55
|
|
56
|
-
hash
|
56
|
+
assert_equal hash, "country" => "Germany"
|
57
57
|
end
|
58
58
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reform
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-11-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: disposable
|
@@ -17,40 +17,40 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 0.
|
20
|
+
version: 0.5.0
|
21
21
|
- - "<"
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.
|
23
|
+
version: 1.0.0
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
28
|
- - ">="
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
version: 0.
|
30
|
+
version: 0.5.0
|
31
31
|
- - "<"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 1.0.0
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: representable
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 3.1.1
|
41
41
|
- - "<"
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 3.
|
43
|
+
version: 3.2.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
46
|
version_requirements: !ruby/object:Gem::Requirement
|
47
47
|
requirements:
|
48
48
|
- - ">="
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version:
|
50
|
+
version: 3.1.1
|
51
51
|
- - "<"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 3.
|
53
|
+
version: 3.2.0
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
55
|
name: uber
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
@@ -157,9 +157,8 @@ executables: []
|
|
157
157
|
extensions: []
|
158
158
|
extra_rdoc_files: []
|
159
159
|
files:
|
160
|
+
- ".github/workflows/ci.yml"
|
160
161
|
- ".gitignore"
|
161
|
-
- ".travis.yml"
|
162
|
-
- Appraisals
|
163
162
|
- CHANGES.md
|
164
163
|
- CONTRIBUTING.md
|
165
164
|
- Gemfile
|
@@ -168,8 +167,6 @@ files:
|
|
168
167
|
- README.md
|
169
168
|
- Rakefile
|
170
169
|
- TODO.md
|
171
|
-
- gemfiles/0.13.0.gemfile
|
172
|
-
- gemfiles/1.5.0.gemfile
|
173
170
|
- lib/reform.rb
|
174
171
|
- lib/reform/contract.rb
|
175
172
|
- lib/reform/contract/custom_error.rb
|
@@ -181,8 +178,6 @@ files:
|
|
181
178
|
- lib/reform/form/composition.rb
|
182
179
|
- lib/reform/form/dry.rb
|
183
180
|
- lib/reform/form/dry/input_hash.rb
|
184
|
-
- lib/reform/form/dry/new_api.rb
|
185
|
-
- lib/reform/form/dry/old_api.rb
|
186
181
|
- lib/reform/form/module.rb
|
187
182
|
- lib/reform/form/populator.rb
|
188
183
|
- lib/reform/form/prepopulate.rb
|
@@ -193,52 +188,38 @@ files:
|
|
193
188
|
- lib/reform/version.rb
|
194
189
|
- reform.gemspec
|
195
190
|
- test/benchmarking.rb
|
196
|
-
- test/
|
197
|
-
- test/call_old_api.rb
|
191
|
+
- test/call_test.rb
|
198
192
|
- test/changed_test.rb
|
199
193
|
- test/coercion_test.rb
|
200
|
-
- test/
|
201
|
-
- test/composition_old_api.rb
|
194
|
+
- test/composition_test.rb
|
202
195
|
- test/contract/custom_error_test.rb
|
203
|
-
- test/
|
204
|
-
- test/contract_old_api.rb
|
196
|
+
- test/contract_test.rb
|
205
197
|
- test/default_test.rb
|
206
198
|
- test/deserialize_test.rb
|
207
|
-
- test/
|
208
|
-
- test/
|
199
|
+
- test/docs/validation_test.rb
|
200
|
+
- test/errors_test.rb
|
209
201
|
- test/feature_test.rb
|
210
202
|
- test/fixtures/dry_error_messages.yml
|
211
|
-
- test/
|
212
|
-
- test/
|
213
|
-
- test/form_old_api.rb
|
214
|
-
- test/form_option_new_api.rb
|
215
|
-
- test/form_option_old_api.rb
|
203
|
+
- test/form_option_test.rb
|
204
|
+
- test/form_test.rb
|
216
205
|
- test/from_test.rb
|
217
|
-
- test/
|
218
|
-
- test/
|
219
|
-
- test/module_new_api.rb
|
220
|
-
- test/module_old_api.rb
|
206
|
+
- test/inherit_test.rb
|
207
|
+
- test/module_test.rb
|
221
208
|
- test/parse_option_test.rb
|
222
209
|
- test/parse_pipeline_test.rb
|
223
|
-
- test/
|
224
|
-
- test/populate_old_api.rb
|
210
|
+
- test/populate_test.rb
|
225
211
|
- test/populator_skip_test.rb
|
226
212
|
- test/prepopulator_test.rb
|
227
213
|
- test/read_only_test.rb
|
228
214
|
- test/readable_test.rb
|
229
|
-
- test/
|
230
|
-
- test/
|
231
|
-
- test/save_new_api.rb
|
232
|
-
- test/save_old_api.rb
|
215
|
+
- test/reform_test.rb
|
216
|
+
- test/save_test.rb
|
233
217
|
- test/setup_test.rb
|
234
|
-
- test/
|
235
|
-
- test/skip_if_old_api.rb
|
218
|
+
- test/skip_if_test.rb
|
236
219
|
- test/skip_setter_and_getter_test.rb
|
237
220
|
- test/test_helper.rb
|
238
|
-
- test/
|
239
|
-
- test/
|
240
|
-
- test/validation/dry_validation_new_api.rb
|
241
|
-
- test/validation/dry_validation_old_api.rb
|
221
|
+
- test/validate_test.rb
|
222
|
+
- test/validation/dry_validation_test.rb
|
242
223
|
- test/validation/result_test.rb
|
243
224
|
- test/validation_library_provided_test.rb
|
244
225
|
- test/virtual_test.rb
|
@@ -262,58 +243,44 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
262
243
|
- !ruby/object:Gem::Version
|
263
244
|
version: '0'
|
264
245
|
requirements: []
|
265
|
-
rubygems_version: 3.
|
246
|
+
rubygems_version: 3.2.3
|
266
247
|
signing_key:
|
267
248
|
specification_version: 4
|
268
249
|
summary: Form object decoupled from models with validation, population and presentation.
|
269
250
|
test_files:
|
270
251
|
- test/benchmarking.rb
|
271
|
-
- test/
|
272
|
-
- test/call_old_api.rb
|
252
|
+
- test/call_test.rb
|
273
253
|
- test/changed_test.rb
|
274
254
|
- test/coercion_test.rb
|
275
|
-
- test/
|
276
|
-
- test/composition_old_api.rb
|
255
|
+
- test/composition_test.rb
|
277
256
|
- test/contract/custom_error_test.rb
|
278
|
-
- test/
|
279
|
-
- test/contract_old_api.rb
|
257
|
+
- test/contract_test.rb
|
280
258
|
- test/default_test.rb
|
281
259
|
- test/deserialize_test.rb
|
282
|
-
- test/
|
283
|
-
- test/
|
260
|
+
- test/docs/validation_test.rb
|
261
|
+
- test/errors_test.rb
|
284
262
|
- test/feature_test.rb
|
285
263
|
- test/fixtures/dry_error_messages.yml
|
286
|
-
- test/
|
287
|
-
- test/
|
288
|
-
- test/form_old_api.rb
|
289
|
-
- test/form_option_new_api.rb
|
290
|
-
- test/form_option_old_api.rb
|
264
|
+
- test/form_option_test.rb
|
265
|
+
- test/form_test.rb
|
291
266
|
- test/from_test.rb
|
292
|
-
- test/
|
293
|
-
- test/
|
294
|
-
- test/module_new_api.rb
|
295
|
-
- test/module_old_api.rb
|
267
|
+
- test/inherit_test.rb
|
268
|
+
- test/module_test.rb
|
296
269
|
- test/parse_option_test.rb
|
297
270
|
- test/parse_pipeline_test.rb
|
298
|
-
- test/
|
299
|
-
- test/populate_old_api.rb
|
271
|
+
- test/populate_test.rb
|
300
272
|
- test/populator_skip_test.rb
|
301
273
|
- test/prepopulator_test.rb
|
302
274
|
- test/read_only_test.rb
|
303
275
|
- test/readable_test.rb
|
304
|
-
- test/
|
305
|
-
- test/
|
306
|
-
- test/save_new_api.rb
|
307
|
-
- test/save_old_api.rb
|
276
|
+
- test/reform_test.rb
|
277
|
+
- test/save_test.rb
|
308
278
|
- test/setup_test.rb
|
309
|
-
- test/
|
310
|
-
- test/skip_if_old_api.rb
|
279
|
+
- test/skip_if_test.rb
|
311
280
|
- test/skip_setter_and_getter_test.rb
|
312
281
|
- test/test_helper.rb
|
313
|
-
- test/
|
314
|
-
- test/
|
315
|
-
- test/validation/dry_validation_new_api.rb
|
316
|
-
- test/validation/dry_validation_old_api.rb
|
282
|
+
- test/validate_test.rb
|
283
|
+
- test/validation/dry_validation_test.rb
|
317
284
|
- test/validation/result_test.rb
|
318
285
|
- test/validation_library_provided_test.rb
|
319
286
|
- test/virtual_test.rb
|
data/.travis.yml
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
cache: bundler
|
3
|
-
bundler_args: --without benchmarks tools
|
4
|
-
rvm:
|
5
|
-
- ruby-head
|
6
|
-
- 2.7
|
7
|
-
- 2.6
|
8
|
-
- 2.5
|
9
|
-
- 2.4
|
10
|
-
gemfile:
|
11
|
-
- gemfiles/1.5.0.gemfile
|
12
|
-
- gemfiles/0.13.0.gemfile
|
13
|
-
matrix:
|
14
|
-
fast_finish: true
|
15
|
-
allow_failures:
|
16
|
-
- rvm: ruby-head
|
data/Appraisals
DELETED
data/gemfiles/0.13.0.gemfile
DELETED
data/gemfiles/1.5.0.gemfile
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
::Dry::Validation.load_extensions(:hints)
|
2
|
-
|
3
|
-
module Reform::Form::Dry
|
4
|
-
module NewApi
|
5
|
-
|
6
|
-
class Contract < ::Dry::Validation::Contract
|
7
|
-
end
|
8
|
-
|
9
|
-
module Validations
|
10
|
-
module ClassMethods
|
11
|
-
def validation_group_class
|
12
|
-
Group
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.included(includer)
|
17
|
-
includer.extend(ClassMethods)
|
18
|
-
end
|
19
|
-
|
20
|
-
class Group
|
21
|
-
include InputHash
|
22
|
-
|
23
|
-
def initialize(options = {})
|
24
|
-
@validator = options.fetch(:schema, Contract)
|
25
|
-
@schema_inject_params = options.fetch(:with, {})
|
26
|
-
end
|
27
|
-
|
28
|
-
attr_reader :validator, :schema_inject_params, :block
|
29
|
-
|
30
|
-
def instance_exec(&block)
|
31
|
-
@block = block
|
32
|
-
end
|
33
|
-
|
34
|
-
def call(form)
|
35
|
-
# when passing options[:schema] the class instance is already created so we just need to call
|
36
|
-
# "call"
|
37
|
-
return validator.call(input_hash(form)) unless validator.is_a?(Class) && @validator <= ::Dry::Validation::Contract
|
38
|
-
|
39
|
-
dynamic_options = { form: form }
|
40
|
-
inject_options = schema_inject_params.merge(dynamic_options)
|
41
|
-
|
42
|
-
validator.build(inject_options, &block).call(input_hash(form))
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
module Reform::Form::Dry
|
2
|
-
module OldApi
|
3
|
-
class Schema < Dry::Validation::Schema
|
4
|
-
end
|
5
|
-
|
6
|
-
module Validations
|
7
|
-
module ClassMethods
|
8
|
-
def validation_group_class
|
9
|
-
Group
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.included(includer)
|
14
|
-
includer.extend(ClassMethods)
|
15
|
-
end
|
16
|
-
|
17
|
-
class Group
|
18
|
-
include InputHash
|
19
|
-
|
20
|
-
def initialize(options = {})
|
21
|
-
options ||= {}
|
22
|
-
schema_class = options[:schema] || Reform::Form::Dry::OldApi::Schema
|
23
|
-
@validator = Dry::Validation.Schema(schema_class, build: false)
|
24
|
-
|
25
|
-
@schema_inject_params = options[:with] || {}
|
26
|
-
end
|
27
|
-
|
28
|
-
def instance_exec(&block)
|
29
|
-
@validator = Dry::Validation.Schema(@validator, build: false, &block)
|
30
|
-
# inject the keys into the configure block automatically
|
31
|
-
keys = @schema_inject_params.keys
|
32
|
-
@validator.class_eval do
|
33
|
-
configure do
|
34
|
-
keys.each { |k| option k }
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def call(form)
|
40
|
-
dynamic_options = {}
|
41
|
-
dynamic_options[:form] = form if @schema_inject_params[:form]
|
42
|
-
inject_options = @schema_inject_params.merge(dynamic_options)
|
43
|
-
|
44
|
-
# TODO: only pass submitted values to Schema#call?
|
45
|
-
dry_result = call_schema(inject_options, input_hash(form))
|
46
|
-
# dry_messages = dry_result.messages
|
47
|
-
|
48
|
-
return dry_result
|
49
|
-
|
50
|
-
_reform_errors = Reform::Contract::Errors.new(dry_result) # TODO: dry should be merged here.
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
def call_schema(inject_options, input)
|
56
|
-
@validator.new(@validator.rules, inject_options).(input)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/test/call_new_api.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class CallTest < Minitest::Spec
|
4
|
-
Song = Struct.new(:title)
|
5
|
-
|
6
|
-
class SongForm < TestForm
|
7
|
-
property :title
|
8
|
-
|
9
|
-
validation do
|
10
|
-
params { required(:title).filled }
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
let(:form) { SongForm.new(Song.new) }
|
15
|
-
|
16
|
-
it { form.(title: "True North").success?.must_equal true }
|
17
|
-
it { form.(title: "True North").failure?.must_equal false }
|
18
|
-
it { form.(title: "").success?.must_equal false }
|
19
|
-
it { form.(title: "").failure?.must_equal true }
|
20
|
-
|
21
|
-
it { form.(title: "True North").errors.messages.must_equal({}) }
|
22
|
-
it { form.(title: "").errors.messages.must_equal(title: ["must be filled"]) }
|
23
|
-
end
|
data/test/call_old_api.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class CallTest < Minitest::Spec
|
4
|
-
Song = Struct.new(:title)
|
5
|
-
|
6
|
-
class SongForm < TestForm
|
7
|
-
property :title
|
8
|
-
|
9
|
-
validation do
|
10
|
-
required(:title).filled
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
let(:form) { SongForm.new(Song.new) }
|
15
|
-
|
16
|
-
it { form.(title: "True North").success?.must_equal true }
|
17
|
-
it { form.(title: "True North").failure?.must_equal false }
|
18
|
-
it { form.(title: "").success?.must_equal false }
|
19
|
-
it { form.(title: "").failure?.must_equal true }
|
20
|
-
|
21
|
-
it { form.(title: "True North").errors.messages.must_equal({}) }
|
22
|
-
it { form.(title: "").errors.messages.must_equal(title: ["must be filled"]) }
|
23
|
-
end
|
data/test/composition_old_api.rb
DELETED
@@ -1,184 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class FormCompositionInheritanceTest < MiniTest::Spec
|
4
|
-
module SizePrice
|
5
|
-
include Reform::Form::Module
|
6
|
-
|
7
|
-
property :price
|
8
|
-
property :size
|
9
|
-
|
10
|
-
module InstanceMethods
|
11
|
-
def price(for_size: size)
|
12
|
-
case for_size.to_sym
|
13
|
-
when :s then super() * 1
|
14
|
-
when :m then super() * 2
|
15
|
-
when :l then super() * 3
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class OutfitForm < TestForm
|
22
|
-
include Reform::Form::Composition
|
23
|
-
include SizePrice
|
24
|
-
|
25
|
-
property :price, inherit: true, on: :tshirt
|
26
|
-
property :size, inherit: true, on: :measurement
|
27
|
-
end
|
28
|
-
|
29
|
-
let(:measurement) { Measurement.new(:l) }
|
30
|
-
let(:tshirt) { Tshirt.new(2, :m) }
|
31
|
-
let(:form) { OutfitForm.new(tshirt: tshirt, measurement: measurement) }
|
32
|
-
|
33
|
-
Tshirt = Struct.new(:price, :size)
|
34
|
-
Measurement = Struct.new(:size)
|
35
|
-
|
36
|
-
it { form.price.must_equal 6 }
|
37
|
-
it { form.price(for_size: :s).must_equal 2 }
|
38
|
-
end
|
39
|
-
|
40
|
-
class FormCompositionTest < MiniTest::Spec
|
41
|
-
Song = Struct.new(:id, :title, :band)
|
42
|
-
Requester = Struct.new(:id, :name, :requester)
|
43
|
-
Band = Struct.new(:title)
|
44
|
-
|
45
|
-
class RequestForm < TestForm
|
46
|
-
include Composition
|
47
|
-
|
48
|
-
property :name, on: :requester
|
49
|
-
property :requester_id, on: :requester, from: :id
|
50
|
-
properties :title, :id, on: :song
|
51
|
-
# property :channel # FIXME: what about the "main model"?
|
52
|
-
property :channel, virtual: true, on: :song
|
53
|
-
property :requester, on: :requester
|
54
|
-
property :captcha, on: :song, virtual: true
|
55
|
-
|
56
|
-
validation do
|
57
|
-
required(:name).filled
|
58
|
-
required(:title).filled
|
59
|
-
end
|
60
|
-
|
61
|
-
property :band, on: :song do
|
62
|
-
property :title
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
let(:form) { RequestForm.new(song: song, requester: requester) }
|
67
|
-
let(:song) { Song.new(1, "Rio", band) }
|
68
|
-
let(:requester) { Requester.new(2, "Duran Duran", "MCP") }
|
69
|
-
let(:band) { Band.new("Duran^2") }
|
70
|
-
|
71
|
-
# delegation form -> composition works
|
72
|
-
it { form.id.must_equal 1 }
|
73
|
-
it { form.title.must_equal "Rio" }
|
74
|
-
it { form.name.must_equal "Duran Duran" }
|
75
|
-
it { form.requester_id.must_equal 2 }
|
76
|
-
it { assert_nil form.channel }
|
77
|
-
it { form.requester.must_equal "MCP" } # same name as composed model.
|
78
|
-
it { assert_nil form.captcha }
|
79
|
-
|
80
|
-
# #model just returns <Composition>.
|
81
|
-
it { form.mapper.must_be_kind_of Disposable::Composition }
|
82
|
-
|
83
|
-
# #model[] -> composed models
|
84
|
-
it { form.model[:requester].must_equal requester }
|
85
|
-
it { form.model[:song].must_equal song }
|
86
|
-
|
87
|
-
it "creates Composition for you" do
|
88
|
-
form.validate("title" => "Greyhound", "name" => "Frenzal Rhomb").must_equal true
|
89
|
-
form.validate("title" => "", "name" => "Frenzal Rhomb").must_equal false
|
90
|
-
end
|
91
|
-
|
92
|
-
describe "#save" do
|
93
|
-
# #save with {}
|
94
|
-
it do
|
95
|
-
hash = {}
|
96
|
-
|
97
|
-
form.save do |map|
|
98
|
-
hash[:name] = form.name
|
99
|
-
hash[:title] = form.title
|
100
|
-
end
|
101
|
-
|
102
|
-
hash.must_equal({name: "Duran Duran", title: "Rio"})
|
103
|
-
end
|
104
|
-
|
105
|
-
it "provides nested symbolized hash as second block argument" do
|
106
|
-
form.validate("title" => "Greyhound", "name" => "Frenzal Rhomb", "channel" => "JJJ", "captcha" => "wonderful")
|
107
|
-
|
108
|
-
hash = nil
|
109
|
-
|
110
|
-
form.save do |map|
|
111
|
-
hash = map
|
112
|
-
end
|
113
|
-
|
114
|
-
hash.must_equal({
|
115
|
-
song: {"title" => "Greyhound", "id" => 1, "channel" => "JJJ", "captcha" => "wonderful", "band" => {"title" => "Duran^2"}},
|
116
|
-
requester: {"name" => "Frenzal Rhomb", "id" => 2, "requester" => "MCP"}
|
117
|
-
}
|
118
|
-
)
|
119
|
-
end
|
120
|
-
|
121
|
-
it "xxx pushes data to models and calls #save when no block passed" do
|
122
|
-
song.extend(Saveable)
|
123
|
-
requester.extend(Saveable)
|
124
|
-
band.extend(Saveable)
|
125
|
-
|
126
|
-
form.validate("title" => "Greyhound", "name" => "Frenzal Rhomb", "captcha" => "1337")
|
127
|
-
form.captcha.must_equal "1337" # TODO: move to separate test.
|
128
|
-
|
129
|
-
form.save
|
130
|
-
|
131
|
-
requester.name.must_equal "Frenzal Rhomb"
|
132
|
-
requester.saved?.must_equal true
|
133
|
-
song.title.must_equal "Greyhound"
|
134
|
-
song.saved?.must_equal true
|
135
|
-
song.band.title.must_equal "Duran^2"
|
136
|
-
song.band.saved?.must_equal true
|
137
|
-
end
|
138
|
-
|
139
|
-
it "returns true when models all save successfully" do
|
140
|
-
song.extend(Saveable)
|
141
|
-
requester.extend(Saveable)
|
142
|
-
band.extend(Saveable)
|
143
|
-
|
144
|
-
form.save.must_equal true
|
145
|
-
end
|
146
|
-
|
147
|
-
it "returns false when one or more models don't save successfully" do
|
148
|
-
module Unsaveable
|
149
|
-
def save
|
150
|
-
false
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
song.extend(Unsaveable)
|
155
|
-
requester.extend(Saveable)
|
156
|
-
band.extend(Saveable)
|
157
|
-
|
158
|
-
form.save.must_equal false
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
class FormCompositionCollectionTest < MiniTest::Spec
|
164
|
-
Book = Struct.new(:id, :name)
|
165
|
-
Library = Struct.new(:id) do
|
166
|
-
def books
|
167
|
-
[Book.new(1, "My book")]
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
class LibraryForm < TestForm
|
172
|
-
include Reform::Form::Composition
|
173
|
-
|
174
|
-
collection :books, on: :library do
|
175
|
-
property :id
|
176
|
-
property :name
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
let(:form) { LibraryForm.new(library: library) }
|
181
|
-
let(:library) { Library.new(2) }
|
182
|
-
|
183
|
-
it { form.save { |hash| hash.must_equal({library: {"books" => [{"id" => 1, "name" => "My book"}]}}) } }
|
184
|
-
end
|