reform 2.3.0.rc1 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +5 -1
  3. data/.travis.yml +7 -11
  4. data/CHANGES.md +43 -3
  5. data/Gemfile +2 -5
  6. data/ISSUE_TEMPLATE.md +1 -1
  7. data/LICENSE.txt +1 -1
  8. data/README.md +7 -9
  9. data/Rakefile +6 -10
  10. data/lib/reform/contract.rb +7 -7
  11. data/lib/reform/contract/custom_error.rb +41 -0
  12. data/lib/reform/contract/validate.rb +10 -6
  13. data/lib/reform/errors.rb +27 -15
  14. data/lib/reform/form.rb +22 -11
  15. data/lib/reform/form/call.rb +1 -1
  16. data/lib/reform/form/composition.rb +2 -2
  17. data/lib/reform/form/dry.rb +22 -60
  18. data/lib/reform/form/dry/input_hash.rb +37 -0
  19. data/lib/reform/form/populator.rb +9 -11
  20. data/lib/reform/form/prepopulate.rb +3 -2
  21. data/lib/reform/form/validate.rb +19 -12
  22. data/lib/reform/result.rb +36 -9
  23. data/lib/reform/validation.rb +10 -8
  24. data/lib/reform/validation/groups.rb +2 -4
  25. data/lib/reform/version.rb +1 -1
  26. data/reform.gemspec +9 -9
  27. data/test/benchmarking.rb +10 -11
  28. data/test/call_test.rb +8 -8
  29. data/test/changed_test.rb +13 -13
  30. data/test/coercion_test.rb +56 -24
  31. data/test/composition_test.rb +49 -51
  32. data/test/contract/custom_error_test.rb +55 -0
  33. data/test/contract_test.rb +18 -18
  34. data/test/default_test.rb +3 -3
  35. data/test/deserialize_test.rb +14 -17
  36. data/test/docs/validation_test.rb +134 -0
  37. data/test/errors_test.rb +131 -86
  38. data/test/feature_test.rb +9 -11
  39. data/test/fixtures/dry_error_messages.yml +65 -52
  40. data/test/form_option_test.rb +3 -3
  41. data/test/form_test.rb +6 -6
  42. data/test/from_test.rb +17 -21
  43. data/test/inherit_test.rb +28 -35
  44. data/test/module_test.rb +23 -28
  45. data/test/parse_option_test.rb +12 -12
  46. data/test/parse_pipeline_test.rb +3 -3
  47. data/test/populate_test.rb +146 -93
  48. data/test/populator_skip_test.rb +3 -4
  49. data/test/prepopulator_test.rb +20 -21
  50. data/test/read_only_test.rb +12 -1
  51. data/test/readable_test.rb +7 -7
  52. data/test/reform_test.rb +38 -42
  53. data/test/save_test.rb +16 -19
  54. data/test/setup_test.rb +15 -15
  55. data/test/skip_if_test.rb +30 -19
  56. data/test/skip_setter_and_getter_test.rb +8 -9
  57. data/test/test_helper.rb +12 -5
  58. data/test/validate_test.rb +160 -140
  59. data/test/validation/dry_validation_test.rb +407 -236
  60. data/test/validation/result_test.rb +29 -31
  61. data/test/validation_library_provided_test.rb +3 -3
  62. data/test/virtual_test.rb +46 -6
  63. data/test/writeable_test.rb +13 -13
  64. metadata +32 -29
  65. data/test/readonly_test.rb +0 -14
@@ -8,72 +8,70 @@ class ErrorsResultTest < Minitest::Spec
8
8
  # TODO: errors(args) not tested.
9
9
 
10
10
  describe "Contract::Result#success?" do
11
- let (:failed) { MyResult.new(false) }
12
- let (:succeeded) { MyResult.new(true) }
11
+ let(:failed) { MyResult.new(false) }
12
+ let(:succeeded) { MyResult.new(true) }
13
13
 
14
- it { Reform::Contract::Result.new([failed, failed]).success?.must_equal false }
15
- it { Reform::Contract::Result.new([succeeded, failed]).success?.must_equal false }
16
- it { Reform::Contract::Result.new([failed, succeeded]).success?.must_equal false }
17
- it { Reform::Contract::Result.new([succeeded, succeeded]).success?.must_equal true }
14
+ it { assert_equal Reform::Contract::Result.new([failed, failed]).success?, false }
15
+ it { assert_equal Reform::Contract::Result.new([succeeded, failed]).success?, false }
16
+ it { assert_equal Reform::Contract::Result.new([failed, succeeded]).success?, false }
17
+ it { assert Reform::Contract::Result.new([succeeded, succeeded]).success? }
18
18
  end
19
19
 
20
20
  describe "Contract::Result#errors" do
21
- let (:results) {
21
+ let(:results) do
22
22
  [
23
- MyResult.new(false, { title: ["must be filled"], nested: { something: [] } }),
24
- MyResult.new(false, { length: ["no Int"] })
23
+ MyResult.new(false, {length: ["no Int"]}),
24
+ MyResult.new(false, {title: ["must be filled"], nested: {something: []}}),
25
+ MyResult.new(false, {title: ["must be filled"], nested: {something: []}}),
26
+ MyResult.new(false, {title: ["something more"], nested: {something: []}})
25
27
  ]
26
- }
28
+ end
27
29
 
28
- it { Reform::Contract::Result.new(results).errors.must_equal({:title=>["must be filled"], :length=>["no Int"]}) }
30
+ it { assert_equal Reform::Contract::Result.new(results).errors, {title: ["must be filled", "something more"], length: ["no Int"]} }
29
31
  end
30
32
 
31
33
  describe "Result::Pointer" do
32
- let (:errors) do # dry result #errors format.
34
+ let(:errors) do # dry result #errors format.
33
35
  {
34
36
  title: ["ignore"],
35
- artist: { age: ["too old"],
37
+ artist: {age: ["too old"],
36
38
  bands: {
37
- 0 => { name: "too new school" },
38
- 1 => { name: "too boring" },
39
+ 0 => {name: "too new school"},
40
+ 1 => {name: "too boring"},
39
41
  }
40
42
  }
41
43
  }
42
44
  end
43
45
 
44
- let (:top) { Reform::Contract::Result::Pointer.new(MyResult.new(false, errors), []) }
45
- it { top.success?.must_equal false }
46
- it { top.errors.must_equal errors }
46
+ let(:top) { Reform::Contract::Result::Pointer.new(MyResult.new(false, errors), []) }
47
+ it { assert_equal top.success?, false }
48
+ it { assert_equal top.errors, errors }
47
49
 
48
- let (:artist) { Reform::Contract::Result::Pointer.new(MyResult.new(false, errors), [:artist]) }
49
- it { artist.success?.must_equal false }
50
- it { artist.errors.must_equal({:age=>["too old"], :bands=>{0=>{:name=>"too new school"}, 1=>{:name=>"too boring"}}}) }
50
+ let(:artist) { Reform::Contract::Result::Pointer.new(MyResult.new(false, errors), [:artist]) }
51
+ it { assert_equal artist.success?, false }
52
+ it { assert_equal artist.errors,({age: ["too old"], bands: {0 => {name: "too new school"}, 1 => {name: "too boring"}}}) }
51
53
 
52
- let (:band) { Reform::Contract::Result::Pointer.new(MyResult.new(false, errors), [:artist, :bands, 1]) }
53
- it { band.success?.must_equal false }
54
- it { band.errors.must_equal({:name=>"too boring"}) }
54
+ let(:band) { Reform::Contract::Result::Pointer.new(MyResult.new(false, errors), [:artist, :bands, 1]) }
55
+ it { assert_equal band.success?, false }
56
+ it { assert_equal band.errors,({name: "too boring"}) }
55
57
 
56
58
  describe "advance" do
57
59
  let(:advanced) { artist.advance(:bands, 1) }
58
60
 
59
- it { advanced.success?.must_equal false }
60
- it { advanced.errors.must_equal({:name=>"too boring"}) }
61
+ it { assert_equal advanced.success?, false }
62
+ it { assert_equal advanced.errors,({name: "too boring"}) }
61
63
 
62
- it { artist.advance([:absolute, :nonsense]).must_equal nil }
64
+ it { assert_nil artist.advance(%i[absolute nonsense]) }
63
65
  end
64
66
  end
65
67
  end
66
68
 
67
-
68
69
  # validation group:
69
70
 
70
71
  # form.errors/messages/hint(*args) ==> {:title: [..]}
71
72
  # @call_result.errors/messages/hint(*args) }
72
73
 
73
-
74
-
75
74
  # # result = Result(original_result => [:band, :label], my_local_result => [] )
76
75
  # # result.messages(locale: :en) merges original_result and my_local_result
77
76
 
78
77
  # form.errors => Result(fetch tree of all nested forms.messages(*args))
79
-
@@ -1,8 +1,8 @@
1
- require 'reform'
2
- require 'minitest/autorun'
1
+ require "reform"
2
+ require "minitest/autorun"
3
3
 
4
4
  class ValidationLibraryProvidedTest < MiniTest::Spec
5
- it 'no validation library loaded' do
5
+ it "no validation library loaded" do
6
6
  assert_raises Reform::Validation::NoValidationLibraryError do
7
7
  class PersonForm < Reform::Form
8
8
  property :name
data/test/virtual_test.rb CHANGED
@@ -1,16 +1,20 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class VirtualTest < MiniTest::Spec
4
4
  class CreditCardForm < TestForm
5
5
  property :credit_card_number, virtual: true # no read, no write, it's virtual.
6
+ collection :transactions, virtual: true, populate_if_empty: OpenStruct do
7
+ property :id
8
+ end
6
9
  end
7
10
 
8
- let (:form) { CreditCardForm.new(Object.new) }
11
+ let(:form) { CreditCardForm.new(Object.new) }
9
12
 
10
13
  it {
11
- form.validate("credit_card_number" => "123")
14
+ form.validate(credit_card_number: "123", transactions: [id: 1])
12
15
 
13
- form.credit_card_number.must_equal "123" # this is still readable in the UI.
16
+ assert_equal form.credit_card_number, "123" # this is still readable in the UI.
17
+ assert_equal form.transactions.first.id, 1 # this is still readable in the UI.
14
18
 
15
19
  form.sync
16
20
 
@@ -19,6 +23,42 @@ class VirtualTest < MiniTest::Spec
19
23
  hash = nested
20
24
  end
21
25
 
22
- hash.must_equal("credit_card_number"=> "123")
26
+ assert_equal hash, "credit_card_number" => "123", "transactions" => ["id" => 1]
27
+ }
28
+ end
29
+
30
+ class VirtualAndDefaultTest < MiniTest::Spec
31
+ class CreditCardForm < TestForm
32
+ property :credit_card_number, virtual: true, default: "123" # no read, no write, it's virtual.
33
+ collection :transactions, virtual: true, populate_if_empty: OpenStruct, default: [OpenStruct.new(id: 2)] do
34
+ property :id
35
+ end
36
+ end
37
+
38
+ def hash(form)
39
+ hash = {}
40
+ form.save do |nested|
41
+ hash = nested
42
+ end
43
+ hash
44
+ end
45
+
46
+ let(:form) { CreditCardForm.new(Object.new) }
47
+
48
+ it {
49
+ form = CreditCardForm.new(Object.new)
50
+ form.validate({})
51
+
52
+ assert_equal hash(form), "credit_card_number" => "123", "transactions" => ["id" => 2]
53
+
54
+ form = CreditCardForm.new(Object.new)
55
+ form.validate(credit_card_number: "123", transactions: [id: 1])
56
+
57
+ assert_equal form.credit_card_number, "123" # this is still readable in the UI.
58
+ assert_equal form.transactions.first.id, 1 # this is still readable in the UI.
59
+
60
+ form.sync
61
+
62
+ assert_equal hash(form), "credit_card_number" => "123", "transactions" => ["id" => 1]
23
63
  }
24
- end
64
+ end
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class WriteableTest < MiniTest::Spec
4
4
  Location = Struct.new(:country)
@@ -7,24 +7,24 @@ class WriteableTest < MiniTest::Spec
7
7
  property :country, writeable: false
8
8
  end
9
9
 
10
- let (:loc) { Location.new("Australia") }
11
- let (:form) { LocationForm.new(loc) }
10
+ let(:loc) { Location.new("Australia") }
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
 
@@ -36,23 +36,23 @@ class WritableTest < MiniTest::Spec
36
36
  property :country, writable: false
37
37
  end
38
38
 
39
- let (:loc) { Location.new("Australia") }
40
- let (:form) { LocationForm.new(loc) }
39
+ let(:loc) { Location.new("Australia") }
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,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reform
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0.rc1
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  - Fran Worley
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-02-26 00:00:00.000000000 Z
12
+ date: 2021-02-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: disposable
@@ -32,39 +32,39 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.5.0
34
34
  - !ruby/object:Gem::Dependency
35
- name: uber
35
+ name: representable
36
36
  requirement: !ruby/object:Gem::Requirement
37
37
  requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.4.0
38
41
  - - "<"
39
42
  - !ruby/object:Gem::Version
40
- version: 0.2.0
43
+ version: 3.1.0
41
44
  type: :runtime
42
45
  prerelease: false
43
46
  version_requirements: !ruby/object:Gem::Requirement
44
47
  requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 2.4.0
45
51
  - - "<"
46
52
  - !ruby/object:Gem::Version
47
- version: 0.2.0
53
+ version: 3.1.0
48
54
  - !ruby/object:Gem::Dependency
49
- name: representable
55
+ name: uber
50
56
  requirement: !ruby/object:Gem::Requirement
51
57
  requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: 2.4.0
55
58
  - - "<"
56
59
  - !ruby/object:Gem::Version
57
- version: 3.1.0
60
+ version: 0.2.0
58
61
  type: :runtime
59
62
  prerelease: false
60
63
  version_requirements: !ruby/object:Gem::Requirement
61
64
  requirements:
62
- - - ">="
63
- - !ruby/object:Gem::Version
64
- version: 2.4.0
65
65
  - - "<"
66
66
  - !ruby/object:Gem::Version
67
- version: 3.1.0
67
+ version: 0.2.0
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: bundler
70
70
  requirement: !ruby/object:Gem::Requirement
@@ -80,7 +80,7 @@ dependencies:
80
80
  - !ruby/object:Gem::Version
81
81
  version: '0'
82
82
  - !ruby/object:Gem::Dependency
83
- name: rake
83
+ name: minitest
84
84
  requirement: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - ">="
@@ -94,7 +94,7 @@ dependencies:
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
96
  - !ruby/object:Gem::Dependency
97
- name: minitest
97
+ name: minitest-line
98
98
  requirement: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - ">="
@@ -108,7 +108,7 @@ dependencies:
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  - !ruby/object:Gem::Dependency
111
- name: dry-types
111
+ name: pry-byebug
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - ">="
@@ -136,19 +136,19 @@ dependencies:
136
136
  - !ruby/object:Gem::Version
137
137
  version: '0'
138
138
  - !ruby/object:Gem::Dependency
139
- name: dry-validation
139
+ name: rake
140
140
  requirement: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - ">="
143
143
  - !ruby/object:Gem::Version
144
- version: 0.10.1
144
+ version: '0'
145
145
  type: :development
146
146
  prerelease: false
147
147
  version_requirements: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - ">="
150
150
  - !ruby/object:Gem::Version
151
- version: 0.10.1
151
+ version: '0'
152
152
  description: Form object decoupled from models.
153
153
  email:
154
154
  - apotonick@gmail.com
@@ -169,6 +169,7 @@ files:
169
169
  - TODO.md
170
170
  - lib/reform.rb
171
171
  - lib/reform/contract.rb
172
+ - lib/reform/contract/custom_error.rb
172
173
  - lib/reform/contract/validate.rb
173
174
  - lib/reform/errors.rb
174
175
  - lib/reform/form.rb
@@ -176,6 +177,7 @@ files:
176
177
  - lib/reform/form/coercion.rb
177
178
  - lib/reform/form/composition.rb
178
179
  - lib/reform/form/dry.rb
180
+ - lib/reform/form/dry/input_hash.rb
179
181
  - lib/reform/form/module.rb
180
182
  - lib/reform/form/populator.rb
181
183
  - lib/reform/form/prepopulate.rb
@@ -190,9 +192,11 @@ files:
190
192
  - test/changed_test.rb
191
193
  - test/coercion_test.rb
192
194
  - test/composition_test.rb
195
+ - test/contract/custom_error_test.rb
193
196
  - test/contract_test.rb
194
197
  - test/default_test.rb
195
198
  - test/deserialize_test.rb
199
+ - test/docs/validation_test.rb
196
200
  - test/errors_test.rb
197
201
  - test/feature_test.rb
198
202
  - test/fixtures/dry_error_messages.yml
@@ -208,7 +212,6 @@ files:
208
212
  - test/prepopulator_test.rb
209
213
  - test/read_only_test.rb
210
214
  - test/readable_test.rb
211
- - test/readonly_test.rb
212
215
  - test/reform_test.rb
213
216
  - test/save_test.rb
214
217
  - test/setup_test.rb
@@ -225,7 +228,7 @@ homepage: https://github.com/trailblazer/reform
225
228
  licenses:
226
229
  - MIT
227
230
  metadata: {}
228
- post_install_message:
231
+ post_install_message:
229
232
  rdoc_options: []
230
233
  require_paths:
231
234
  - lib
@@ -236,13 +239,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
236
239
  version: '0'
237
240
  required_rubygems_version: !ruby/object:Gem::Requirement
238
241
  requirements:
239
- - - ">"
242
+ - - ">="
240
243
  - !ruby/object:Gem::Version
241
- version: 1.3.1
244
+ version: '0'
242
245
  requirements: []
243
- rubyforge_project:
244
- rubygems_version: 2.6.3
245
- signing_key:
246
+ rubygems_version: 3.0.3
247
+ signing_key:
246
248
  specification_version: 4
247
249
  summary: Form object decoupled from models with validation, population and presentation.
248
250
  test_files:
@@ -251,9 +253,11 @@ test_files:
251
253
  - test/changed_test.rb
252
254
  - test/coercion_test.rb
253
255
  - test/composition_test.rb
256
+ - test/contract/custom_error_test.rb
254
257
  - test/contract_test.rb
255
258
  - test/default_test.rb
256
259
  - test/deserialize_test.rb
260
+ - test/docs/validation_test.rb
257
261
  - test/errors_test.rb
258
262
  - test/feature_test.rb
259
263
  - test/fixtures/dry_error_messages.yml
@@ -269,7 +273,6 @@ test_files:
269
273
  - test/prepopulator_test.rb
270
274
  - test/read_only_test.rb
271
275
  - test/readable_test.rb
272
- - test/readonly_test.rb
273
276
  - test/reform_test.rb
274
277
  - test/save_test.rb
275
278
  - test/setup_test.rb