reform 2.1.0 → 2.2.0.rc1
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/.gitignore +0 -1
- data/.travis.yml +4 -12
- data/CHANGES.md +8 -0
- data/README.md +36 -743
- data/Rakefile +1 -31
- data/gemfiles/{Gemfile.rails-3.1 → Gemfile.disposable-0.3} +1 -2
- data/lib/reform.rb +0 -9
- data/lib/reform/contract.rb +5 -1
- data/lib/reform/form.rb +1 -4
- data/lib/reform/form/composition.rb +1 -2
- data/lib/reform/form/dry.rb +29 -16
- data/lib/reform/form/module.rb +15 -3
- data/lib/reform/form/validate.rb +1 -1
- data/lib/reform/validation.rb +3 -3
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +3 -10
- data/test/coercion_test.rb +7 -7
- data/test/composition_test.rb +5 -1
- data/test/contract_test.rb +10 -4
- data/test/deserialize_test.rb +3 -3
- data/test/errors_test.rb +48 -28
- data/test/form_option_test.rb +3 -1
- data/test/form_test.rb +19 -14
- data/test/module_test.rb +51 -11
- data/test/populate_test.rb +21 -7
- data/test/reform_test.rb +24 -20
- data/test/save_test.rb +10 -4
- data/test/skip_if_test.rb +5 -3
- data/test/test_helper.rb +3 -43
- data/test/validate_test.rb +34 -14
- data/test/validation/dry_test.rb +60 -0
- data/test/validation/dry_validation_test.rb +65 -43
- data/test/validation/errors.yml +4 -0
- metadata +16 -192
- data/database.sqlite3 +0 -0
- data/gemfiles/Gemfile.rails-3.2 +0 -7
- data/gemfiles/Gemfile.rails-4.0 +0 -8
- data/gemfiles/Gemfile.rails-4.1 +0 -8
- data/gemfiles/Gemfile.rails-4.2 +0 -8
- data/lib/reform/active_record.rb +0 -4
- data/lib/reform/form/active_model.rb +0 -87
- data/lib/reform/form/active_model/form_builder_methods.rb +0 -48
- data/lib/reform/form/active_model/model_reflections.rb +0 -46
- data/lib/reform/form/active_model/model_validations.rb +0 -110
- data/lib/reform/form/active_model/validations.rb +0 -107
- data/lib/reform/form/active_record.rb +0 -30
- data/lib/reform/form/lotus.rb +0 -59
- data/lib/reform/form/multi_parameter_attributes.rb +0 -48
- data/lib/reform/form/validation/unique_validator.rb +0 -54
- data/lib/reform/rails.rb +0 -13
- data/test/active_model_custom_validation_translations_test.rb +0 -75
- data/test/active_model_test.rb +0 -207
- data/test/active_model_validation_for_property_named_format_test.rb +0 -18
- data/test/active_record_test.rb +0 -273
- data/test/builder_test.rb +0 -32
- data/test/custom_validation_test.rb +0 -47
- data/test/dummy/Rakefile +0 -7
- data/test/dummy/app/controllers/albums_controller.rb +0 -18
- data/test/dummy/app/controllers/application_controller.rb +0 -4
- data/test/dummy/app/controllers/musician_controller.rb +0 -5
- data/test/dummy/app/forms/album_form.rb +0 -18
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/models/album.rb +0 -4
- data/test/dummy/app/models/song.rb +0 -3
- data/test/dummy/app/views/albums/new.html.erb +0 -28
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -20
- data/test/dummy/config/boot.rb +0 -10
- data/test/dummy/config/database.yml +0 -22
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -16
- data/test/dummy/config/environments/production.rb +0 -46
- data/test/dummy/config/environments/test.rb +0 -33
- data/test/dummy/config/locales/en.yml +0 -14
- data/test/dummy/config/routes.rb +0 -4
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/form_builder_test.rb +0 -138
- data/test/lotus/Gemfile +0 -5
- data/test/lotus/lotus_test.rb +0 -31
- data/test/lotus_test.rb +0 -150
- data/test/model_reflections_test.rb +0 -138
- data/test/model_validations_test.rb +0 -82
- data/test/mongoid_test.rb +0 -313
- data/test/multi_parameter_attributes_test.rb +0 -50
- data/test/rails/integration_test.rb +0 -54
- data/test/unique_test.rb +0 -135
- data/test/validation/activemodel_validation_test.rb +0 -252
data/test/form_option_test.rb
CHANGED
data/test/form_test.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class FormTest < MiniTest::Spec
|
4
|
+
Artist = Struct.new(:name)
|
5
|
+
|
4
6
|
class AlbumForm < Reform::Form
|
5
7
|
property :title
|
6
8
|
|
@@ -19,18 +21,6 @@ class FormTest < MiniTest::Spec
|
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
22
|
-
# combined property/validates syntax.
|
23
|
-
class SongForm < Reform::Form
|
24
|
-
property :composer
|
25
|
-
property :title, validates: {presence: true}
|
26
|
-
properties :genre, :band, validates: {presence: true}
|
27
|
-
end
|
28
|
-
it do
|
29
|
-
form = SongForm.new(OpenStruct.new)
|
30
|
-
form.validate({})
|
31
|
-
form.errors.to_s.must_equal "{:title=>[\"can't be blank\"], :genre=>[\"can't be blank\"], :band=>[\"can't be blank\"]}"
|
32
|
-
end
|
33
|
-
|
34
24
|
describe "::dup" do
|
35
25
|
let (:cloned) { AlbumForm.clone }
|
36
26
|
|
@@ -45,8 +35,23 @@ class FormTest < MiniTest::Spec
|
|
45
35
|
"Album"
|
46
36
|
end
|
47
37
|
end
|
48
|
-
|
38
|
+
|
39
|
+
cloned.validation do
|
40
|
+
key(:title).required
|
41
|
+
end
|
42
|
+
|
49
43
|
cloned.new(OpenStruct.new).validate({})
|
50
44
|
end
|
51
45
|
end
|
52
|
-
|
46
|
+
|
47
|
+
describe "#initialize" do
|
48
|
+
class ArtistForm < Reform::Form
|
49
|
+
property :name
|
50
|
+
property :current_user, virtual: true
|
51
|
+
end
|
52
|
+
|
53
|
+
it "allows injecting :virtual options" do
|
54
|
+
ArtistForm.new(Artist.new, current_user: Object).current_user.must_equal Object
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/test/module_test.rb
CHANGED
@@ -8,7 +8,9 @@ class ModuleInclusionTest < MiniTest::Spec
|
|
8
8
|
property :band do
|
9
9
|
property :title
|
10
10
|
|
11
|
-
|
11
|
+
validation do
|
12
|
+
key(:title).required
|
13
|
+
end
|
12
14
|
|
13
15
|
def id # gets mixed into Form, too.
|
14
16
|
2
|
@@ -19,9 +21,12 @@ class ModuleInclusionTest < MiniTest::Spec
|
|
19
21
|
1
|
20
22
|
end
|
21
23
|
|
22
|
-
|
24
|
+
validation do
|
25
|
+
key(:band).required
|
26
|
+
end
|
23
27
|
|
24
|
-
|
28
|
+
include Dry::Types.module # allows using Types::* in module.
|
29
|
+
property :cool, type: Form::Bool # test coercion.
|
25
30
|
end
|
26
31
|
|
27
32
|
# TODO: test if works, move stuff into inherit_schema!
|
@@ -30,9 +35,13 @@ class ModuleInclusionTest < MiniTest::Spec
|
|
30
35
|
|
31
36
|
collection :airplays do
|
32
37
|
property :station
|
33
|
-
|
38
|
+
validation do
|
39
|
+
key(:station).required
|
40
|
+
end
|
41
|
+
end
|
42
|
+
validation do
|
43
|
+
key(:airplays).required
|
34
44
|
end
|
35
|
-
validates :airplays, presence: true
|
36
45
|
end
|
37
46
|
|
38
47
|
|
@@ -63,7 +72,7 @@ class ModuleInclusionTest < MiniTest::Spec
|
|
63
72
|
it do
|
64
73
|
form = SongForm.new(OpenStruct.new)
|
65
74
|
form.validate({})
|
66
|
-
form.errors.messages.must_equal({:band=>["
|
75
|
+
form.errors.messages.must_equal({:band=>["is missing"]})
|
67
76
|
end
|
68
77
|
|
69
78
|
# coercion works
|
@@ -80,8 +89,9 @@ class ModuleInclusionTest < MiniTest::Spec
|
|
80
89
|
include BandPropertyForm
|
81
90
|
|
82
91
|
property :name
|
83
|
-
|
84
|
-
|
92
|
+
validation do
|
93
|
+
key(:name).required
|
94
|
+
end
|
85
95
|
end
|
86
96
|
|
87
97
|
class AlbumForm < Reform::Form
|
@@ -90,13 +100,43 @@ class ModuleInclusionTest < MiniTest::Spec
|
|
90
100
|
# pp heritage
|
91
101
|
property :band, :inherit => true do
|
92
102
|
property :label
|
93
|
-
|
103
|
+
validation do
|
104
|
+
key(:label).required
|
105
|
+
end
|
94
106
|
end
|
95
107
|
end
|
96
108
|
|
97
109
|
it do
|
98
110
|
form = AlbumForm.new(OpenStruct.new(:band => OpenStruct.new))
|
99
111
|
form.validate({"band" => {}})
|
100
|
-
form.errors.messages.must_equal({:"band.title"=>["
|
112
|
+
form.errors.messages.must_equal({:band=>["must be filled"], :"band.title"=>["is missing"], :"band.label"=>["is missing"], :name=>["is missing"]})
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
describe "module with custom accessors" do
|
117
|
+
module SongModule
|
118
|
+
include Reform::Form::Module
|
119
|
+
|
120
|
+
property :id # no custom accessor for id.
|
121
|
+
property :title # has custom accessor.
|
122
|
+
|
123
|
+
module InstanceMethods
|
124
|
+
def title
|
125
|
+
super.upcase
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class IncludingSongForm < Reform::Form
|
131
|
+
include SongModule
|
132
|
+
end
|
133
|
+
|
134
|
+
let (:song) { OpenStruct.new(id: 1, title: "Instant Mash") }
|
135
|
+
|
136
|
+
it do
|
137
|
+
IncludingSongForm.new(song).id.must_equal 1
|
138
|
+
IncludingSongForm.new(song).title.must_equal "INSTANT MASH"
|
139
|
+
end
|
101
140
|
end
|
102
|
-
end
|
141
|
+
end
|
142
|
+
|
data/test/populate_test.rb
CHANGED
@@ -7,7 +7,9 @@ class PopulatorTest < MiniTest::Spec
|
|
7
7
|
|
8
8
|
class AlbumForm < Reform::Form
|
9
9
|
property :name, populator: ->(options) { self.name = options[:fragment].reverse }
|
10
|
-
|
10
|
+
validation do
|
11
|
+
key(:name).required
|
12
|
+
end
|
11
13
|
|
12
14
|
collection :songs,
|
13
15
|
populator: ->(options) {
|
@@ -16,11 +18,15 @@ class PopulatorTest < MiniTest::Spec
|
|
16
18
|
(item = collection[index]) ? item : collection.insert(index, Song.new) } do
|
17
19
|
|
18
20
|
property :title
|
19
|
-
|
21
|
+
validation do
|
22
|
+
key(:title).required
|
23
|
+
end
|
20
24
|
|
21
25
|
property :composer, populator: ->(options) { options[:model] || self.composer= Artist.new } do
|
22
26
|
property :name
|
23
|
-
|
27
|
+
validation do
|
28
|
+
key(:name).required
|
29
|
+
end
|
24
30
|
end
|
25
31
|
end
|
26
32
|
|
@@ -99,6 +105,8 @@ class PopulatorTest < MiniTest::Spec
|
|
99
105
|
end
|
100
106
|
|
101
107
|
class PopulateWithMethodTest < Minitest::Spec
|
108
|
+
Album = Struct.new(:title)
|
109
|
+
|
102
110
|
class AlbumForm < Reform::Form
|
103
111
|
property :title, populator: :title!
|
104
112
|
|
@@ -138,11 +146,15 @@ class PopulateIfEmptyTest < MiniTest::Spec
|
|
138
146
|
populate_if_empty: Song do # class name works.
|
139
147
|
|
140
148
|
property :title
|
141
|
-
|
149
|
+
validation do
|
150
|
+
key(:title).required
|
151
|
+
end
|
142
152
|
|
143
153
|
property :composer, populate_if_empty: :populate_composer! do # lambda works, too. in form context.
|
144
154
|
property :name
|
145
|
-
|
155
|
+
validation do
|
156
|
+
key(:name).required
|
157
|
+
end
|
146
158
|
end
|
147
159
|
|
148
160
|
private
|
@@ -232,7 +244,9 @@ class PopulateIfEmptyWithDeletionTest < MiniTest::Spec
|
|
232
244
|
populate_if_empty: Song, skip_if: :delete_song! do
|
233
245
|
|
234
246
|
property :title
|
235
|
-
|
247
|
+
validation do
|
248
|
+
key(:title).required
|
249
|
+
end
|
236
250
|
end
|
237
251
|
|
238
252
|
def delete_song!(options)
|
@@ -253,4 +267,4 @@ class PopulateIfEmptyWithDeletionTest < MiniTest::Spec
|
|
253
267
|
form.songs.size.must_equal 1
|
254
268
|
form.songs[0].title.must_equal "Roxanne"
|
255
269
|
end
|
256
|
-
end
|
270
|
+
end
|
data/test/reform_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
# TODO: this test should be removed.
|
4
|
-
class ReformTest <
|
4
|
+
class ReformTest < Minitest::Spec
|
5
5
|
let (:comp) { OpenStruct.new(:name => "Duran Duran", :title => "Rio") }
|
6
6
|
|
7
7
|
let (:form) { SongForm.new(comp) }
|
@@ -10,7 +10,9 @@ class ReformTest < ReformSpec
|
|
10
10
|
property :name
|
11
11
|
property :title
|
12
12
|
|
13
|
-
|
13
|
+
validation do
|
14
|
+
key(:name).required
|
15
|
+
end
|
14
16
|
end
|
15
17
|
|
16
18
|
describe "(new) form with empty models" do
|
@@ -70,8 +72,10 @@ class ReformTest < ReformSpec
|
|
70
72
|
property :name
|
71
73
|
property :title
|
72
74
|
|
73
|
-
|
74
|
-
|
75
|
+
validation do
|
76
|
+
key(:name).required
|
77
|
+
key(:title).required
|
78
|
+
end
|
75
79
|
end
|
76
80
|
let (:form) { ValidatingForm.new(comp) }
|
77
81
|
|
@@ -81,21 +85,22 @@ class ReformTest < ReformSpec
|
|
81
85
|
|
82
86
|
it "populates errors" do
|
83
87
|
form.validate({})
|
84
|
-
form.errors.messages.must_equal({:name=>["
|
88
|
+
form.errors.messages.must_equal({:name=>["is missing"], :title=>["is missing"]})
|
85
89
|
end
|
86
90
|
end
|
87
91
|
end
|
88
92
|
|
93
|
+
# FIXME: add this test to reform-rails.
|
89
94
|
describe "#errors" do
|
90
95
|
before { form.validate({})}
|
91
96
|
|
92
|
-
it { form.errors.must_be_kind_of Reform::
|
97
|
+
it { form.errors.must_be_kind_of Reform::Contract::Errors }
|
93
98
|
|
94
99
|
it { form.errors.messages.must_equal({}) }
|
95
100
|
|
96
101
|
it do
|
97
102
|
form.validate({"name"=>""})
|
98
|
-
form.errors.messages.must_equal({:name=>["
|
103
|
+
form.errors.messages.must_equal({:name=>["must be filled"]})
|
99
104
|
end
|
100
105
|
end
|
101
106
|
|
@@ -132,21 +137,20 @@ class ReformTest < ReformSpec
|
|
132
137
|
end
|
133
138
|
|
134
139
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
140
|
+
describe "inheritance" do
|
141
|
+
class HitForm < SongForm
|
142
|
+
property :position
|
143
|
+
validation do
|
144
|
+
key(:position).required
|
141
145
|
end
|
146
|
+
end
|
142
147
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
end
|
148
|
+
let (:form) { HitForm.new(OpenStruct.new()) }
|
149
|
+
it do
|
150
|
+
form.validate({"title" => "The Body"})
|
151
|
+
form.title.must_equal "The Body"
|
152
|
+
form.position.must_equal nil
|
153
|
+
form.errors.messages.must_equal({:name=>["is missing"], :position=>["is missing"]})
|
150
154
|
end
|
151
155
|
end
|
152
156
|
end
|
data/test/save_test.rb
CHANGED
@@ -7,15 +7,21 @@ class SaveTest < BaseTest
|
|
7
7
|
|
8
8
|
class AlbumForm < Reform::Form
|
9
9
|
property :name
|
10
|
-
|
10
|
+
validation do
|
11
|
+
key(:name).required
|
12
|
+
end
|
11
13
|
|
12
14
|
collection :songs do
|
13
15
|
property :title
|
14
|
-
|
16
|
+
validation do
|
17
|
+
key(:title).required
|
18
|
+
end
|
15
19
|
|
16
20
|
property :composer do
|
17
21
|
property :name
|
18
|
-
|
22
|
+
validation do
|
23
|
+
key(:name).required
|
24
|
+
end
|
19
25
|
end
|
20
26
|
end
|
21
27
|
|
@@ -80,4 +86,4 @@ end
|
|
80
86
|
# song.length.must_equal nil
|
81
87
|
# song.id.must_equal "10: 120"
|
82
88
|
# end
|
83
|
-
# end
|
89
|
+
# end
|
data/test/skip_if_test.rb
CHANGED
@@ -5,9 +5,11 @@ class SkipIfTest < BaseTest
|
|
5
5
|
class AlbumForm < Reform::Form
|
6
6
|
property :title
|
7
7
|
|
8
|
-
property :hit, skip_if: lambda { |options| options[:fragment]["title"]
|
8
|
+
property :hit, skip_if: lambda { |options| options[:fragment]["title"]=="" } do
|
9
9
|
property :title
|
10
|
-
|
10
|
+
validation do
|
11
|
+
key(:title).required
|
12
|
+
end
|
11
13
|
end
|
12
14
|
|
13
15
|
collection :songs, skip_if: :skip_song?, populate_if_empty: BaseTest::Song do
|
@@ -69,4 +71,4 @@ class SkipIfAllBlankTest < BaseTest
|
|
69
71
|
form.songs.size.must_equal 1
|
70
72
|
form.songs[0].title.must_equal "Apathy"
|
71
73
|
end
|
72
|
-
end
|
74
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -4,31 +4,6 @@ require "representable/debug"
|
|
4
4
|
require "declarative/testing"
|
5
5
|
require "pp"
|
6
6
|
|
7
|
-
class ReformSpec < MiniTest::Spec
|
8
|
-
let (:duran) { Struct.new(:name).new("Duran Duran") }
|
9
|
-
let (:rio) { Struct.new(:title).new("Rio") }
|
10
|
-
end
|
11
|
-
|
12
|
-
require 'active_record'
|
13
|
-
class Artist < ActiveRecord::Base
|
14
|
-
end
|
15
|
-
|
16
|
-
class Song < ActiveRecord::Base
|
17
|
-
belongs_to :artist
|
18
|
-
end
|
19
|
-
|
20
|
-
class Album < ActiveRecord::Base
|
21
|
-
has_many :songs
|
22
|
-
end
|
23
|
-
|
24
|
-
ActiveRecord::Base.establish_connection(
|
25
|
-
:adapter => "sqlite3",
|
26
|
-
:database => "#{Dir.pwd}/database.sqlite3"
|
27
|
-
)
|
28
|
-
|
29
|
-
|
30
|
-
#Artist.delete_all
|
31
|
-
|
32
7
|
class BaseTest < MiniTest::Spec
|
33
8
|
class AlbumForm < Reform::Form
|
34
9
|
property :title
|
@@ -62,28 +37,13 @@ MiniTest::Spec.class_eval do
|
|
62
37
|
@saved
|
63
38
|
end
|
64
39
|
end
|
65
|
-
|
66
|
-
def self.rails4_2?
|
67
|
-
::ActiveModel::VERSION::MAJOR == 4 and ::ActiveModel::VERSION::MINOR == 2
|
68
|
-
end
|
69
|
-
|
70
|
-
def self.rails4_0?
|
71
|
-
::ActiveModel::VERSION::MAJOR == 4 and ::ActiveModel::VERSION::MINOR == 0
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.rails3_2?
|
75
|
-
::ActiveModel::VERSION::MAJOR == 3 and ::ActiveModel::VERSION::MINOR == 2
|
76
|
-
end
|
77
40
|
end
|
78
41
|
|
79
|
-
require "reform/form/
|
42
|
+
require "reform/form/dry"
|
80
43
|
Reform::Contract.class_eval do
|
81
|
-
feature Reform::Form::
|
44
|
+
feature Reform::Form::Dry
|
82
45
|
end
|
83
46
|
# FIXME!
|
84
47
|
Reform::Form.class_eval do
|
85
|
-
feature Reform::Form::
|
48
|
+
feature Reform::Form::Dry
|
86
49
|
end
|
87
|
-
|
88
|
-
I18n.load_path << Dir['test/dummy/config/locales/*.yml']
|
89
|
-
I18n.backend.load_translations
|