reform 2.2.4 → 2.6.2

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 (76) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +17 -0
  3. data/.gitignore +5 -1
  4. data/CHANGES.md +80 -4
  5. data/CONTRIBUTING.md +31 -0
  6. data/Gemfile +2 -16
  7. data/ISSUE_TEMPLATE.md +25 -0
  8. data/LICENSE.txt +1 -1
  9. data/README.md +10 -12
  10. data/Rakefile +6 -10
  11. data/lib/reform/contract/custom_error.rb +41 -0
  12. data/lib/reform/contract/validate.rb +53 -23
  13. data/lib/reform/contract.rb +7 -17
  14. data/lib/reform/errors.rb +61 -0
  15. data/lib/reform/form/call.rb +1 -1
  16. data/lib/reform/form/composition.rb +2 -2
  17. data/lib/reform/form/dry/input_hash.rb +37 -0
  18. data/lib/reform/form/dry.rb +25 -35
  19. data/lib/reform/form/populator.rb +20 -26
  20. data/lib/reform/form/prepopulate.rb +5 -4
  21. data/lib/reform/form/validate.rb +29 -14
  22. data/lib/reform/form.rb +36 -10
  23. data/lib/reform/result.rb +90 -0
  24. data/lib/reform/validation/groups.rb +12 -28
  25. data/lib/reform/validation.rb +19 -11
  26. data/lib/reform/version.rb +1 -1
  27. data/lib/reform.rb +1 -0
  28. data/reform.gemspec +13 -13
  29. data/test/benchmarking.rb +39 -6
  30. data/test/call_test.rb +9 -9
  31. data/test/changed_test.rb +14 -14
  32. data/test/coercion_test.rb +57 -25
  33. data/test/composition_test.rb +85 -49
  34. data/test/contract/custom_error_test.rb +55 -0
  35. data/test/contract_test.rb +20 -20
  36. data/test/default_test.rb +4 -4
  37. data/test/deserialize_test.rb +17 -20
  38. data/test/docs/validation_test.rb +134 -0
  39. data/test/errors_test.rb +142 -82
  40. data/test/feature_test.rb +10 -12
  41. data/test/fixtures/dry_error_messages.yml +83 -23
  42. data/test/form_option_test.rb +5 -5
  43. data/test/form_test.rb +8 -8
  44. data/test/from_test.rb +18 -22
  45. data/test/inherit_test.rb +54 -68
  46. data/test/module_test.rb +27 -32
  47. data/test/parse_option_test.rb +40 -0
  48. data/test/parse_pipeline_test.rb +4 -4
  49. data/test/populate_test.rb +217 -100
  50. data/test/populator_skip_test.rb +11 -11
  51. data/test/prepopulator_test.rb +24 -25
  52. data/test/read_only_test.rb +12 -1
  53. data/test/readable_test.rb +9 -9
  54. data/test/reform_test.rb +47 -66
  55. data/test/save_test.rb +35 -23
  56. data/test/setup_test.rb +17 -17
  57. data/test/skip_if_test.rb +33 -22
  58. data/test/skip_setter_and_getter_test.rb +9 -10
  59. data/test/test_helper.rb +23 -14
  60. data/test/validate_test.rb +165 -145
  61. data/test/validation/dry_validation_test.rb +630 -146
  62. data/test/validation/result_test.rb +77 -0
  63. data/test/validation_library_provided_test.rb +16 -0
  64. data/test/virtual_test.rb +47 -7
  65. data/test/writeable_test.rb +38 -9
  66. metadata +46 -38
  67. data/.travis.yml +0 -11
  68. data/gemfiles/Gemfile.disposable-0.3 +0 -6
  69. data/lib/reform/contract/errors.rb +0 -43
  70. data/lib/reform/form/mongoid.rb +0 -37
  71. data/lib/reform/form/orm.rb +0 -26
  72. data/lib/reform/mongoid.rb +0 -4
  73. data/test/deprecation_test.rb +0 -27
  74. data/test/readonly_test.rb +0 -14
  75. data/test/validation/dry_test.rb +0 -60
  76. data/test/validation/errors.yml +0 -4
@@ -0,0 +1,77 @@
1
+ require "test_helper"
2
+
3
+ class ErrorsResultTest < Minitest::Spec
4
+ MyResult = Struct.new(:success?, :errors) do
5
+ def failure?; !success? end
6
+ end
7
+
8
+ # TODO: errors(args) not tested.
9
+
10
+ describe "Contract::Result#success?" do
11
+ let(:failed) { MyResult.new(false) }
12
+ let(:succeeded) { MyResult.new(true) }
13
+
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
+ end
19
+
20
+ describe "Contract::Result#errors" do
21
+ let(:results) do
22
+ [
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: []}})
27
+ ]
28
+ end
29
+
30
+ it { assert_equal Reform::Contract::Result.new(results).errors, {title: ["must be filled", "something more"], length: ["no Int"]} }
31
+ end
32
+
33
+ describe "Result::Pointer" do
34
+ let(:errors) do # dry result #errors format.
35
+ {
36
+ title: ["ignore"],
37
+ artist: {age: ["too old"],
38
+ bands: {
39
+ 0 => {name: "too new school"},
40
+ 1 => {name: "too boring"},
41
+ }
42
+ }
43
+ }
44
+ end
45
+
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 }
49
+
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"}}}) }
53
+
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"}) }
57
+
58
+ describe "advance" do
59
+ let(:advanced) { artist.advance(:bands, 1) }
60
+
61
+ it { assert_equal advanced.success?, false }
62
+ it { assert_equal advanced.errors,({name: "too boring"}) }
63
+
64
+ it { assert_nil artist.advance(%i[absolute nonsense]) }
65
+ end
66
+ end
67
+ end
68
+
69
+ # validation group:
70
+
71
+ # form.errors/messages/hint(*args) ==> {:title: [..]}
72
+ # @call_result.errors/messages/hint(*args) }
73
+
74
+ # # result = Result(original_result => [:band, :label], my_local_result => [] )
75
+ # # result.messages(locale: :en) merges original_result and my_local_result
76
+
77
+ # form.errors => Result(fetch tree of all nested forms.messages(*args))
@@ -0,0 +1,16 @@
1
+ require "reform"
2
+ require "minitest/autorun"
3
+
4
+ class ValidationLibraryProvidedTest < MiniTest::Spec
5
+ it "no validation library loaded" do
6
+ assert_raises Reform::Validation::NoValidationLibraryError do
7
+ class PersonForm < Reform::Form
8
+ property :name
9
+
10
+ validation do
11
+ required(:name).maybe(:str?)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
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
- class CreditCardForm < Reform::Form
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,29 +1,58 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class WriteableTest < MiniTest::Spec
4
4
  Location = Struct.new(:country)
5
5
 
6
- class LocationForm < Reform::Form
6
+ class LocationForm < TestForm
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
- end
29
+ end
30
+
31
+ # writable option is alias of writeable option.
32
+ class WritableTest < MiniTest::Spec
33
+ Location = Struct.new(:country)
34
+
35
+ class LocationForm < TestForm
36
+ property :country, writable: false
37
+ end
38
+
39
+ let(:loc) { Location.new("Australia") }
40
+ let(:form) { LocationForm.new(loc) }
41
+
42
+ it do
43
+ assert_equal form.country, "Australia"
44
+
45
+ form.validate("country" => "Germany") # this usually won't change when submitting.
46
+ assert_equal form.country, "Germany"
47
+
48
+ form.sync
49
+ assert_equal loc.country, "Australia" # the writer wasn't called.
50
+
51
+ hash = {}
52
+ form.save do |nested|
53
+ hash = nested
54
+ end
55
+
56
+ assert_equal hash, "country" => "Germany"
57
+ end
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.2.4
4
+ version: 2.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
- - Garrett Heinlen
8
+ - Fran Worley
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-01-31 00:00:00.000000000 Z
12
+ date: 2022-05-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: disposable
@@ -17,50 +17,56 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: 0.4.1
20
+ version: 0.5.0
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: 1.0.0
21
24
  type: :runtime
22
25
  prerelease: false
23
26
  version_requirements: !ruby/object:Gem::Requirement
24
27
  requirements:
25
28
  - - ">="
26
29
  - !ruby/object:Gem::Version
27
- version: 0.4.1
30
+ version: 0.5.0
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
28
34
  - !ruby/object:Gem::Dependency
29
35
  name: representable
30
36
  requirement: !ruby/object:Gem::Requirement
31
37
  requirements:
32
38
  - - ">="
33
39
  - !ruby/object:Gem::Version
34
- version: 2.4.0
40
+ version: 3.1.1
35
41
  - - "<"
36
42
  - !ruby/object:Gem::Version
37
- version: 3.1.0
43
+ version: '4'
38
44
  type: :runtime
39
45
  prerelease: false
40
46
  version_requirements: !ruby/object:Gem::Requirement
41
47
  requirements:
42
48
  - - ">="
43
49
  - !ruby/object:Gem::Version
44
- version: 2.4.0
50
+ version: 3.1.1
45
51
  - - "<"
46
52
  - !ruby/object:Gem::Version
47
- version: 3.1.0
53
+ version: '4'
48
54
  - !ruby/object:Gem::Dependency
49
- name: bundler
55
+ name: uber
50
56
  requirement: !ruby/object:Gem::Requirement
51
57
  requirements:
52
- - - ">="
58
+ - - "<"
53
59
  - !ruby/object:Gem::Version
54
- version: '0'
55
- type: :development
60
+ version: 0.2.0
61
+ type: :runtime
56
62
  prerelease: false
57
63
  version_requirements: !ruby/object:Gem::Requirement
58
64
  requirements:
59
- - - ">="
65
+ - - "<"
60
66
  - !ruby/object:Gem::Version
61
- version: '0'
67
+ version: 0.2.0
62
68
  - !ruby/object:Gem::Dependency
63
- name: rake
69
+ name: bundler
64
70
  requirement: !ruby/object:Gem::Requirement
65
71
  requirements:
66
72
  - - ">="
@@ -88,7 +94,7 @@ dependencies:
88
94
  - !ruby/object:Gem::Version
89
95
  version: '0'
90
96
  - !ruby/object:Gem::Dependency
91
- name: dry-types
97
+ name: minitest-line
92
98
  requirement: !ruby/object:Gem::Requirement
93
99
  requirements:
94
100
  - - ">="
@@ -116,52 +122,53 @@ dependencies:
116
122
  - !ruby/object:Gem::Version
117
123
  version: '0'
118
124
  - !ruby/object:Gem::Dependency
119
- name: dry-validation
125
+ name: rake
120
126
  requirement: !ruby/object:Gem::Requirement
121
127
  requirements:
122
128
  - - ">="
123
129
  - !ruby/object:Gem::Version
124
- version: 0.10.0
130
+ version: '0'
125
131
  type: :development
126
132
  prerelease: false
127
133
  version_requirements: !ruby/object:Gem::Requirement
128
134
  requirements:
129
135
  - - ">="
130
136
  - !ruby/object:Gem::Version
131
- version: 0.10.0
137
+ version: '0'
132
138
  description: Form object decoupled from models.
133
139
  email:
134
140
  - apotonick@gmail.com
135
- - heinleng@gmail.com
141
+ - frances@safetytoolbox.co.uk
136
142
  executables: []
137
143
  extensions: []
138
144
  extra_rdoc_files: []
139
145
  files:
146
+ - ".github/workflows/ci.yml"
140
147
  - ".gitignore"
141
- - ".travis.yml"
142
148
  - CHANGES.md
149
+ - CONTRIBUTING.md
143
150
  - Gemfile
151
+ - ISSUE_TEMPLATE.md
144
152
  - LICENSE.txt
145
153
  - README.md
146
154
  - Rakefile
147
155
  - TODO.md
148
- - gemfiles/Gemfile.disposable-0.3
149
156
  - lib/reform.rb
150
157
  - lib/reform/contract.rb
151
- - lib/reform/contract/errors.rb
158
+ - lib/reform/contract/custom_error.rb
152
159
  - lib/reform/contract/validate.rb
160
+ - lib/reform/errors.rb
153
161
  - lib/reform/form.rb
154
162
  - lib/reform/form/call.rb
155
163
  - lib/reform/form/coercion.rb
156
164
  - lib/reform/form/composition.rb
157
165
  - lib/reform/form/dry.rb
166
+ - lib/reform/form/dry/input_hash.rb
158
167
  - lib/reform/form/module.rb
159
- - lib/reform/form/mongoid.rb
160
- - lib/reform/form/orm.rb
161
168
  - lib/reform/form/populator.rb
162
169
  - lib/reform/form/prepopulate.rb
163
170
  - lib/reform/form/validate.rb
164
- - lib/reform/mongoid.rb
171
+ - lib/reform/result.rb
165
172
  - lib/reform/validation.rb
166
173
  - lib/reform/validation/groups.rb
167
174
  - lib/reform/version.rb
@@ -171,10 +178,11 @@ files:
171
178
  - test/changed_test.rb
172
179
  - test/coercion_test.rb
173
180
  - test/composition_test.rb
181
+ - test/contract/custom_error_test.rb
174
182
  - test/contract_test.rb
175
183
  - test/default_test.rb
176
- - test/deprecation_test.rb
177
184
  - test/deserialize_test.rb
185
+ - test/docs/validation_test.rb
178
186
  - test/errors_test.rb
179
187
  - test/feature_test.rb
180
188
  - test/fixtures/dry_error_messages.yml
@@ -183,13 +191,13 @@ files:
183
191
  - test/from_test.rb
184
192
  - test/inherit_test.rb
185
193
  - test/module_test.rb
194
+ - test/parse_option_test.rb
186
195
  - test/parse_pipeline_test.rb
187
196
  - test/populate_test.rb
188
197
  - test/populator_skip_test.rb
189
198
  - test/prepopulator_test.rb
190
199
  - test/read_only_test.rb
191
200
  - test/readable_test.rb
192
- - test/readonly_test.rb
193
201
  - test/reform_test.rb
194
202
  - test/save_test.rb
195
203
  - test/setup_test.rb
@@ -197,12 +205,12 @@ files:
197
205
  - test/skip_setter_and_getter_test.rb
198
206
  - test/test_helper.rb
199
207
  - test/validate_test.rb
200
- - test/validation/dry_test.rb
201
208
  - test/validation/dry_validation_test.rb
202
- - test/validation/errors.yml
209
+ - test/validation/result_test.rb
210
+ - test/validation_library_provided_test.rb
203
211
  - test/virtual_test.rb
204
212
  - test/writeable_test.rb
205
- homepage: https://github.com/apotonick/reform
213
+ homepage: https://github.com/trailblazer/reform
206
214
  licenses:
207
215
  - MIT
208
216
  metadata: {}
@@ -221,8 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
229
  - !ruby/object:Gem::Version
222
230
  version: '0'
223
231
  requirements: []
224
- rubyforge_project:
225
- rubygems_version: 2.5.1
232
+ rubygems_version: 3.3.7
226
233
  signing_key:
227
234
  specification_version: 4
228
235
  summary: Form object decoupled from models with validation, population and presentation.
@@ -232,10 +239,11 @@ test_files:
232
239
  - test/changed_test.rb
233
240
  - test/coercion_test.rb
234
241
  - test/composition_test.rb
242
+ - test/contract/custom_error_test.rb
235
243
  - test/contract_test.rb
236
244
  - test/default_test.rb
237
- - test/deprecation_test.rb
238
245
  - test/deserialize_test.rb
246
+ - test/docs/validation_test.rb
239
247
  - test/errors_test.rb
240
248
  - test/feature_test.rb
241
249
  - test/fixtures/dry_error_messages.yml
@@ -244,13 +252,13 @@ test_files:
244
252
  - test/from_test.rb
245
253
  - test/inherit_test.rb
246
254
  - test/module_test.rb
255
+ - test/parse_option_test.rb
247
256
  - test/parse_pipeline_test.rb
248
257
  - test/populate_test.rb
249
258
  - test/populator_skip_test.rb
250
259
  - test/prepopulator_test.rb
251
260
  - test/read_only_test.rb
252
261
  - test/readable_test.rb
253
- - test/readonly_test.rb
254
262
  - test/reform_test.rb
255
263
  - test/save_test.rb
256
264
  - test/setup_test.rb
@@ -258,8 +266,8 @@ test_files:
258
266
  - test/skip_setter_and_getter_test.rb
259
267
  - test/test_helper.rb
260
268
  - test/validate_test.rb
261
- - test/validation/dry_test.rb
262
269
  - test/validation/dry_validation_test.rb
263
- - test/validation/errors.yml
270
+ - test/validation/result_test.rb
271
+ - test/validation_library_provided_test.rb
264
272
  - test/virtual_test.rb
265
273
  - test/writeable_test.rb
data/.travis.yml DELETED
@@ -1,11 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.2.3
4
- - 2.0.0
5
- gemfile:
6
- - gemfiles/Gemfile.disposable-0.3
7
-
8
- matrix:
9
- fast_finish: true
10
- before_install:
11
- - gem install bundler
@@ -1,6 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in reform.gemspec
4
- gemspec :path => '../'
5
-
6
- gem 'minitest'
@@ -1,43 +0,0 @@
1
- class Reform::Contract::Errors
2
- def initialize(*)
3
- @errors = {}
4
- end
5
-
6
- module Merge
7
- def merge!(errors, prefix)
8
- errors.messages.each do |field, msgs|
9
- unless field.to_sym == :base
10
- field = (prefix+[field]).join(".").to_sym # TODO: why is that a symbol in Rails?
11
- end
12
-
13
- msgs.each do |msg|
14
- next if messages[field] and messages[field].include?(msg)
15
- add(field, msg)
16
- end # Forms now contains a plain errors hash. the errors for each item are still available in item.errors.
17
- end
18
- end
19
-
20
- def to_s
21
- messages.inspect
22
- end
23
- end
24
- include Merge
25
-
26
- def add(field, message)
27
- @errors[field] ||= []
28
- @errors[field] << message
29
- end
30
-
31
- def messages
32
- @errors
33
- end
34
-
35
- def empty?
36
- @errors.empty?
37
- end
38
-
39
- # needed by Rails form builder.
40
- def [](name)
41
- @errors[name] || []
42
- end
43
- end
@@ -1,37 +0,0 @@
1
- module Reform::Form::Mongoid
2
- def self.included(base)
3
- base.class_eval do
4
- register_feature Reform::Form::Mongoid
5
- include Reform::Form::ActiveModel
6
- include Reform::Form::ORM
7
- extend ClassMethods
8
- end
9
- end
10
-
11
- module ClassMethods
12
- def validates_uniqueness_of(attribute, options={})
13
- options = options.merge(:attributes => [attribute])
14
- validates_with(UniquenessValidator, options)
15
- end
16
- def i18n_scope
17
- :mongoid
18
- end
19
- end
20
-
21
-
22
- def self.mongoid_namespace
23
- if mongoid_is_4_or_more?
24
- 'Validatable'
25
- else
26
- 'Validations'
27
- end
28
- end
29
-
30
- def self.mongoid_is_4_or_more?
31
- Mongoid::VERSION.split('.').first.to_i >= 4
32
- end
33
-
34
- UniquenessValidator = Class.new("::Mongoid::#{mongoid_namespace}::UniquenessValidator".constantize) do
35
- include Reform::Form::ORM::UniquenessValidator
36
- end
37
- end
@@ -1,26 +0,0 @@
1
- module Reform::Form::ORM
2
- def model_for_property(name)
3
- return model unless is_a?(Reform::Form::Composition) # i am too lazy for proper inheritance. there should be a ActiveRecord::Composition that handles this.
4
-
5
- model_name = options_for(name)[:on]
6
- model[model_name]
7
- end
8
-
9
- module UniquenessValidator
10
- # when calling validates it should create the Vali instance already and set @klass there! # TODO: fix this in AM.
11
- def validate(form)
12
- property = attributes.first
13
-
14
- # here is the thing: why does AM::UniquenessValidator require a filled-out record to work properly? also, why do we need to set
15
- # the class? it would be way easier to pass #validate a hash of attributes and get back an errors hash.
16
- # the class for the finder could either be infered from the record or set in the validator instance itself in the call to ::validates.
17
- record = form.model_for_property(property)
18
- record.send("#{property}=", form.send(property))
19
-
20
- @klass = record.class # this is usually done in the super-sucky #setup method.
21
- super(record).tap do |res|
22
- form.errors.add(property, record.errors.first.last) if record.errors.present?
23
- end
24
- end
25
- end
26
- end
@@ -1,4 +0,0 @@
1
- require 'reform/form/active_model'
2
- require 'reform/form/orm'
3
- require 'reform/form/mongoid'
4
- require 'reform/form/active_model/model_reflections' # only load this in AR context as simple_form currently is bound to AR.
@@ -1,27 +0,0 @@
1
- require "test_helper"
2
-
3
-
4
- class DeprecationRemoveMePopulatorTest < MiniTest::Spec
5
- Album = Struct.new(:songs)
6
- Song = Struct.new(:title)
7
-
8
-
9
- class AlbumForm < Reform::Form
10
- collection :songs, populator: ->(fragment, collection, index, *) { return Representable::Pipeline::Stop if fragment[:title]=="Good"
11
- songs[index]
12
- } do
13
- property :title
14
- end
15
- end
16
-
17
- it do
18
- form = AlbumForm.new(Album.new([Song.new, Song.new]))
19
- hash = {songs: [{title: "Good"}, {title: "Bad"}]}
20
-
21
- form.validate(hash)
22
-
23
- form.songs.size.must_equal 2
24
- form.songs[0].title.must_equal nil
25
- form.songs[1].title.must_equal "Bad"
26
- end
27
- end
@@ -1,14 +0,0 @@
1
- require "test_helper"
2
-
3
- class ReadonlyTest < MiniTest::Spec
4
- class SongForm < Reform::Form
5
- property :artist
6
- property :title, writeable: false
7
- # TODO: what to do with virtual values?
8
- end
9
-
10
- let (:form) { SongForm.new(OpenStruct.new) }
11
-
12
- it { form.readonly?(:artist).must_equal false }
13
- it { form.readonly?(:title).must_equal true }
14
- end