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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +17 -0
- data/.gitignore +5 -1
- data/CHANGES.md +80 -4
- data/CONTRIBUTING.md +31 -0
- data/Gemfile +2 -16
- data/ISSUE_TEMPLATE.md +25 -0
- data/LICENSE.txt +1 -1
- data/README.md +10 -12
- data/Rakefile +6 -10
- data/lib/reform/contract/custom_error.rb +41 -0
- data/lib/reform/contract/validate.rb +53 -23
- data/lib/reform/contract.rb +7 -17
- data/lib/reform/errors.rb +61 -0
- data/lib/reform/form/call.rb +1 -1
- data/lib/reform/form/composition.rb +2 -2
- data/lib/reform/form/dry/input_hash.rb +37 -0
- data/lib/reform/form/dry.rb +25 -35
- data/lib/reform/form/populator.rb +20 -26
- data/lib/reform/form/prepopulate.rb +5 -4
- data/lib/reform/form/validate.rb +29 -14
- data/lib/reform/form.rb +36 -10
- data/lib/reform/result.rb +90 -0
- data/lib/reform/validation/groups.rb +12 -28
- data/lib/reform/validation.rb +19 -11
- data/lib/reform/version.rb +1 -1
- data/lib/reform.rb +1 -0
- data/reform.gemspec +13 -13
- data/test/benchmarking.rb +39 -6
- data/test/call_test.rb +9 -9
- data/test/changed_test.rb +14 -14
- data/test/coercion_test.rb +57 -25
- data/test/composition_test.rb +85 -49
- data/test/contract/custom_error_test.rb +55 -0
- data/test/contract_test.rb +20 -20
- data/test/default_test.rb +4 -4
- data/test/deserialize_test.rb +17 -20
- data/test/docs/validation_test.rb +134 -0
- data/test/errors_test.rb +142 -82
- data/test/feature_test.rb +10 -12
- data/test/fixtures/dry_error_messages.yml +83 -23
- data/test/form_option_test.rb +5 -5
- data/test/form_test.rb +8 -8
- data/test/from_test.rb +18 -22
- data/test/inherit_test.rb +54 -68
- data/test/module_test.rb +27 -32
- data/test/parse_option_test.rb +40 -0
- data/test/parse_pipeline_test.rb +4 -4
- data/test/populate_test.rb +217 -100
- data/test/populator_skip_test.rb +11 -11
- data/test/prepopulator_test.rb +24 -25
- data/test/read_only_test.rb +12 -1
- data/test/readable_test.rb +9 -9
- data/test/reform_test.rb +47 -66
- data/test/save_test.rb +35 -23
- data/test/setup_test.rb +17 -17
- data/test/skip_if_test.rb +33 -22
- data/test/skip_setter_and_getter_test.rb +9 -10
- data/test/test_helper.rb +23 -14
- data/test/validate_test.rb +165 -145
- data/test/validation/dry_validation_test.rb +630 -146
- data/test/validation/result_test.rb +77 -0
- data/test/validation_library_provided_test.rb +16 -0
- data/test/virtual_test.rb +47 -7
- data/test/writeable_test.rb +38 -9
- metadata +46 -38
- data/.travis.yml +0 -11
- data/gemfiles/Gemfile.disposable-0.3 +0 -6
- data/lib/reform/contract/errors.rb +0 -43
- data/lib/reform/form/mongoid.rb +0 -37
- data/lib/reform/form/orm.rb +0 -26
- data/lib/reform/mongoid.rb +0 -4
- data/test/deprecation_test.rb +0 -27
- data/test/readonly_test.rb +0 -14
- data/test/validation/dry_test.rb +0 -60
- 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
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
class VirtualTest < MiniTest::Spec
|
|
4
|
-
class CreditCardForm <
|
|
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
|
|
11
|
+
let(:form) { CreditCardForm.new(Object.new) }
|
|
9
12
|
|
|
10
13
|
it {
|
|
11
|
-
form.validate(
|
|
14
|
+
form.validate(credit_card_number: "123", transactions: [id: 1])
|
|
12
15
|
|
|
13
|
-
form.credit_card_number
|
|
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
|
|
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
|
data/test/writeable_test.rb
CHANGED
|
@@ -1,29 +1,58 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
class WriteableTest < MiniTest::Spec
|
|
4
4
|
Location = Struct.new(:country)
|
|
5
5
|
|
|
6
|
-
class LocationForm <
|
|
6
|
+
class LocationForm < TestForm
|
|
7
7
|
property :country, writeable: false
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
let
|
|
11
|
-
let
|
|
10
|
+
let(:loc) { Location.new("Australia") }
|
|
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
|
-
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
|
+
version: 2.6.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nick Sutterer
|
|
8
|
-
-
|
|
8
|
+
- Fran Worley
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
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.
|
|
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.
|
|
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:
|
|
40
|
+
version: 3.1.1
|
|
35
41
|
- - "<"
|
|
36
42
|
- !ruby/object:Gem::Version
|
|
37
|
-
version:
|
|
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:
|
|
50
|
+
version: 3.1.1
|
|
45
51
|
- - "<"
|
|
46
52
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
53
|
+
version: '4'
|
|
48
54
|
- !ruby/object:Gem::Dependency
|
|
49
|
-
name:
|
|
55
|
+
name: uber
|
|
50
56
|
requirement: !ruby/object:Gem::Requirement
|
|
51
57
|
requirements:
|
|
52
|
-
- - "
|
|
58
|
+
- - "<"
|
|
53
59
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
55
|
-
type: :
|
|
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:
|
|
67
|
+
version: 0.2.0
|
|
62
68
|
- !ruby/object:Gem::Dependency
|
|
63
|
-
name:
|
|
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:
|
|
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:
|
|
125
|
+
name: rake
|
|
120
126
|
requirement: !ruby/object:Gem::Requirement
|
|
121
127
|
requirements:
|
|
122
128
|
- - ">="
|
|
123
129
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: 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
|
|
137
|
+
version: '0'
|
|
132
138
|
description: Form object decoupled from models.
|
|
133
139
|
email:
|
|
134
140
|
- apotonick@gmail.com
|
|
135
|
-
-
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
-
|
|
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/
|
|
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,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
|
data/lib/reform/form/mongoid.rb
DELETED
|
@@ -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
|
data/lib/reform/form/orm.rb
DELETED
|
@@ -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
|
data/lib/reform/mongoid.rb
DELETED
data/test/deprecation_test.rb
DELETED
|
@@ -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
|
data/test/readonly_test.rb
DELETED
|
@@ -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
|