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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +17 -0
  3. data/.gitignore +1 -1
  4. data/CHANGES.md +23 -0
  5. data/Gemfile +1 -1
  6. data/LICENSE.txt +1 -1
  7. data/README.md +5 -5
  8. data/Rakefile +1 -12
  9. data/lib/reform/contract/validate.rb +1 -1
  10. data/lib/reform/form/dry.rb +47 -9
  11. data/lib/reform/form/populator.rb +13 -3
  12. data/lib/reform/form/prepopulate.rb +1 -1
  13. data/lib/reform/form/validate.rb +3 -3
  14. data/lib/reform/validation/groups.rb +0 -1
  15. data/lib/reform/version.rb +1 -1
  16. data/reform.gemspec +2 -2
  17. data/test/call_test.rb +23 -0
  18. data/test/changed_test.rb +6 -6
  19. data/test/coercion_test.rb +17 -17
  20. data/test/{composition_new_api.rb → composition_test.rb} +27 -28
  21. data/test/{contract_new_api.rb → contract_test.rb} +8 -8
  22. data/test/default_test.rb +2 -2
  23. data/test/deserialize_test.rb +8 -8
  24. data/test/docs/validation_test.rb +134 -0
  25. data/test/{errors_new_api.rb → errors_test.rb} +41 -41
  26. data/test/feature_test.rb +2 -2
  27. data/test/fixtures/dry_error_messages.yml +64 -54
  28. data/test/{form_option_new_api.rb → form_option_test.rb} +1 -1
  29. data/test/{form_new_api.rb → form_test.rb} +3 -3
  30. data/test/from_test.rb +10 -10
  31. data/test/{inherit_new_api.rb → inherit_test.rb} +17 -17
  32. data/test/{module_new_api.rb → module_test.rb} +10 -10
  33. data/test/parse_option_test.rb +7 -7
  34. data/test/parse_pipeline_test.rb +1 -1
  35. data/test/{populate_new_api.rb → populate_test.rb} +136 -53
  36. data/test/populator_skip_test.rb +2 -2
  37. data/test/prepopulator_test.rb +16 -16
  38. data/test/read_only_test.rb +2 -2
  39. data/test/readable_test.rb +3 -3
  40. data/test/{reform_new_api.rb → reform_test.rb} +19 -19
  41. data/test/{save_new_api.rb → save_test.rb} +4 -4
  42. data/test/setup_test.rb +9 -9
  43. data/test/{skip_if_new_api.rb → skip_if_test.rb} +12 -12
  44. data/test/skip_setter_and_getter_test.rb +6 -6
  45. data/test/test_helper.rb +5 -6
  46. data/test/{validate_new_api.rb → validate_test.rb} +65 -78
  47. data/test/validation/{dry_validation_new_api.rb → dry_validation_test.rb} +128 -128
  48. data/test/validation/result_test.rb +14 -14
  49. data/test/virtual_test.rb +7 -7
  50. data/test/writeable_test.rb +8 -8
  51. metadata +42 -75
  52. data/.travis.yml +0 -16
  53. data/Appraisals +0 -8
  54. data/gemfiles/0.13.0.gemfile +0 -8
  55. data/gemfiles/1.5.0.gemfile +0 -9
  56. data/lib/reform/form/dry/new_api.rb +0 -47
  57. data/lib/reform/form/dry/old_api.rb +0 -61
  58. data/test/call_new_api.rb +0 -23
  59. data/test/call_old_api.rb +0 -23
  60. data/test/composition_old_api.rb +0 -184
  61. data/test/contract_old_api.rb +0 -77
  62. data/test/errors_old_api.rb +0 -230
  63. data/test/fixtures/dry_new_api_error_messages.yml +0 -104
  64. data/test/form_old_api.rb +0 -57
  65. data/test/form_option_old_api.rb +0 -24
  66. data/test/inherit_old_api.rb +0 -105
  67. data/test/module_old_api.rb +0 -146
  68. data/test/populate_old_api.rb +0 -304
  69. data/test/reform_old_api.rb +0 -202
  70. data/test/save_old_api.rb +0 -101
  71. data/test/skip_if_old_api.rb +0 -92
  72. data/test/validate_old_api.rb +0 -410
  73. data/test/validation/dry_validation_old_api.rb +0 -772
@@ -11,20 +11,20 @@ class WriteableTest < MiniTest::Spec
11
11
  let(:form) { LocationForm.new(loc) }
12
12
 
13
13
  it do
14
- form.country.must_equal "Australia"
14
+ assert_equal form.country, "Australia"
15
15
 
16
16
  form.validate("country" => "Germany") # this usually won't change when submitting.
17
- form.country.must_equal "Germany"
17
+ assert_equal form.country, "Germany"
18
18
 
19
19
  form.sync
20
- loc.country.must_equal "Australia" # the writer wasn't called.
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.must_equal("country" => "Germany")
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.must_equal "Australia"
43
+ assert_equal form.country, "Australia"
44
44
 
45
45
  form.validate("country" => "Germany") # this usually won't change when submitting.
46
- form.country.must_equal "Germany"
46
+ assert_equal form.country, "Germany"
47
47
 
48
48
  form.sync
49
- loc.country.must_equal "Australia" # the writer wasn't called.
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.must_equal("country" => "Germany")
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.3.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: 2020-07-07 00:00:00.000000000 Z
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.4.2
20
+ version: 0.5.0
21
21
  - - "<"
22
22
  - !ruby/object:Gem::Version
23
- version: 0.5.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.4.2
30
+ version: 0.5.0
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.5.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: 2.4.0
40
+ version: 3.1.1
41
41
  - - "<"
42
42
  - !ruby/object:Gem::Version
43
- version: 3.1.0
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: 2.4.0
50
+ version: 3.1.1
51
51
  - - "<"
52
52
  - !ruby/object:Gem::Version
53
- version: 3.1.0
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/call_new_api.rb
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/composition_new_api.rb
201
- - test/composition_old_api.rb
194
+ - test/composition_test.rb
202
195
  - test/contract/custom_error_test.rb
203
- - test/contract_new_api.rb
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/errors_new_api.rb
208
- - test/errors_old_api.rb
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/fixtures/dry_new_api_error_messages.yml
212
- - test/form_new_api.rb
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/inherit_new_api.rb
218
- - test/inherit_old_api.rb
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/populate_new_api.rb
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/reform_new_api.rb
230
- - test/reform_old_api.rb
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/skip_if_new_api.rb
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/validate_new_api.rb
239
- - test/validate_old_api.rb
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.0.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/call_new_api.rb
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/composition_new_api.rb
276
- - test/composition_old_api.rb
255
+ - test/composition_test.rb
277
256
  - test/contract/custom_error_test.rb
278
- - test/contract_new_api.rb
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/errors_new_api.rb
283
- - test/errors_old_api.rb
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/fixtures/dry_new_api_error_messages.yml
287
- - test/form_new_api.rb
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/inherit_new_api.rb
293
- - test/inherit_old_api.rb
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/populate_new_api.rb
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/reform_new_api.rb
305
- - test/reform_old_api.rb
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/skip_if_new_api.rb
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/validate_new_api.rb
314
- - test/validate_old_api.rb
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
@@ -1,8 +0,0 @@
1
- appraise "1.5.0" do
2
- gem 'dry-monads', "1.3.5"
3
- gem 'dry-validation', '~> 1.5.0'
4
- end
5
-
6
- appraise "0.13.0" do
7
- gem 'dry-validation', '~> 0.13.0'
8
- end
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal", "~> 2.2"
6
- gem "dry-validation", "~> 0.13.0"
7
-
8
- gemspec path: "../"
@@ -1,9 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal", "~> 2.2"
6
- gem "dry-monads", "1.3.5"
7
- gem "dry-validation", "~> 1.5.0"
8
-
9
- gemspec path: "../"
@@ -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
@@ -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