reform 2.1.0 → 2.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +4 -12
  4. data/CHANGES.md +8 -0
  5. data/README.md +36 -743
  6. data/Rakefile +1 -31
  7. data/gemfiles/{Gemfile.rails-3.1 → Gemfile.disposable-0.3} +1 -2
  8. data/lib/reform.rb +0 -9
  9. data/lib/reform/contract.rb +5 -1
  10. data/lib/reform/form.rb +1 -4
  11. data/lib/reform/form/composition.rb +1 -2
  12. data/lib/reform/form/dry.rb +29 -16
  13. data/lib/reform/form/module.rb +15 -3
  14. data/lib/reform/form/validate.rb +1 -1
  15. data/lib/reform/validation.rb +3 -3
  16. data/lib/reform/version.rb +1 -1
  17. data/reform.gemspec +3 -10
  18. data/test/coercion_test.rb +7 -7
  19. data/test/composition_test.rb +5 -1
  20. data/test/contract_test.rb +10 -4
  21. data/test/deserialize_test.rb +3 -3
  22. data/test/errors_test.rb +48 -28
  23. data/test/form_option_test.rb +3 -1
  24. data/test/form_test.rb +19 -14
  25. data/test/module_test.rb +51 -11
  26. data/test/populate_test.rb +21 -7
  27. data/test/reform_test.rb +24 -20
  28. data/test/save_test.rb +10 -4
  29. data/test/skip_if_test.rb +5 -3
  30. data/test/test_helper.rb +3 -43
  31. data/test/validate_test.rb +34 -14
  32. data/test/validation/dry_test.rb +60 -0
  33. data/test/validation/dry_validation_test.rb +65 -43
  34. data/test/validation/errors.yml +4 -0
  35. metadata +16 -192
  36. data/database.sqlite3 +0 -0
  37. data/gemfiles/Gemfile.rails-3.2 +0 -7
  38. data/gemfiles/Gemfile.rails-4.0 +0 -8
  39. data/gemfiles/Gemfile.rails-4.1 +0 -8
  40. data/gemfiles/Gemfile.rails-4.2 +0 -8
  41. data/lib/reform/active_record.rb +0 -4
  42. data/lib/reform/form/active_model.rb +0 -87
  43. data/lib/reform/form/active_model/form_builder_methods.rb +0 -48
  44. data/lib/reform/form/active_model/model_reflections.rb +0 -46
  45. data/lib/reform/form/active_model/model_validations.rb +0 -110
  46. data/lib/reform/form/active_model/validations.rb +0 -107
  47. data/lib/reform/form/active_record.rb +0 -30
  48. data/lib/reform/form/lotus.rb +0 -59
  49. data/lib/reform/form/multi_parameter_attributes.rb +0 -48
  50. data/lib/reform/form/validation/unique_validator.rb +0 -54
  51. data/lib/reform/rails.rb +0 -13
  52. data/test/active_model_custom_validation_translations_test.rb +0 -75
  53. data/test/active_model_test.rb +0 -207
  54. data/test/active_model_validation_for_property_named_format_test.rb +0 -18
  55. data/test/active_record_test.rb +0 -273
  56. data/test/builder_test.rb +0 -32
  57. data/test/custom_validation_test.rb +0 -47
  58. data/test/dummy/Rakefile +0 -7
  59. data/test/dummy/app/controllers/albums_controller.rb +0 -18
  60. data/test/dummy/app/controllers/application_controller.rb +0 -4
  61. data/test/dummy/app/controllers/musician_controller.rb +0 -5
  62. data/test/dummy/app/forms/album_form.rb +0 -18
  63. data/test/dummy/app/helpers/application_helper.rb +0 -2
  64. data/test/dummy/app/models/album.rb +0 -4
  65. data/test/dummy/app/models/song.rb +0 -3
  66. data/test/dummy/app/views/albums/new.html.erb +0 -28
  67. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  68. data/test/dummy/config.ru +0 -4
  69. data/test/dummy/config/application.rb +0 -20
  70. data/test/dummy/config/boot.rb +0 -10
  71. data/test/dummy/config/database.yml +0 -22
  72. data/test/dummy/config/environment.rb +0 -5
  73. data/test/dummy/config/environments/development.rb +0 -16
  74. data/test/dummy/config/environments/production.rb +0 -46
  75. data/test/dummy/config/environments/test.rb +0 -33
  76. data/test/dummy/config/locales/en.yml +0 -14
  77. data/test/dummy/config/routes.rb +0 -4
  78. data/test/dummy/db/test.sqlite3 +0 -0
  79. data/test/form_builder_test.rb +0 -138
  80. data/test/lotus/Gemfile +0 -5
  81. data/test/lotus/lotus_test.rb +0 -31
  82. data/test/lotus_test.rb +0 -150
  83. data/test/model_reflections_test.rb +0 -138
  84. data/test/model_validations_test.rb +0 -82
  85. data/test/mongoid_test.rb +0 -313
  86. data/test/multi_parameter_attributes_test.rb +0 -50
  87. data/test/rails/integration_test.rb +0 -54
  88. data/test/unique_test.rb +0 -135
  89. data/test/validation/activemodel_validation_test.rb +0 -252
@@ -6,7 +6,9 @@ class FormOptionTest < MiniTest::Spec
6
6
 
7
7
  class SongForm < Reform::Form
8
8
  property :title
9
- validates :title, presence: true
9
+ validation do
10
+ key(:title).required
11
+ end
10
12
  end
11
13
 
12
14
  class AlbumForm < Reform::Form
@@ -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
- cloned.validates :title, presence: true
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
- end
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
@@ -8,7 +8,9 @@ class ModuleInclusionTest < MiniTest::Spec
8
8
  property :band do
9
9
  property :title
10
10
 
11
- validates :title, presence: true
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
- validates :band, presence: true
24
+ validation do
25
+ key(:band).required
26
+ end
23
27
 
24
- property :cool, type: Virtus::Attribute::Boolean # test coercion.
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
- validates :station, presence: true
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=>["can't be blank"]})
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
- validates :name, :presence => true
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
- validates :label, :presence => true
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"=>["can't be blank"], :"band.label"=>["can't be blank"], :name=>["can't be blank"]})
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
+
@@ -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
- validates :name, presence: true
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
- validates :title, presence: true
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
- validates :name, presence: true
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
- validates :title, presence: true
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
- validates :name, presence: true
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
- validates :title, presence: true
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
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  # TODO: this test should be removed.
4
- class ReformTest < ReformSpec
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
- validates :name, :presence => true
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
- validates :name, :presence => true
74
- validates :title, :presence => true
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=>["can't be blank"], :title=>["can't be blank"]})
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::Form::ActiveModel::Errors }
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=>["can't be blank"]})
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
- unless (rails4_0? or rails3_2?)
136
- describe "inheritance" do
137
- class HitForm < SongForm
138
- property :position
139
- validates :position, :presence => true
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
- let (:form) { HitForm.new(OpenStruct.new()) }
144
- it do
145
- form.validate({"title" => "The Body"})
146
- form.title.must_equal "The Body"
147
- form.position.must_equal nil
148
- form.errors.messages.must_equal({:name=>["can't be blank"], :position=>["can't be blank"]})
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
@@ -7,15 +7,21 @@ class SaveTest < BaseTest
7
7
 
8
8
  class AlbumForm < Reform::Form
9
9
  property :name
10
- validates :name, presence: true
10
+ validation do
11
+ key(:name).required
12
+ end
11
13
 
12
14
  collection :songs do
13
15
  property :title
14
- validates :title, presence: true
16
+ validation do
17
+ key(:title).required
18
+ end
15
19
 
16
20
  property :composer do
17
21
  property :name
18
- validates :name, presence: true
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
@@ -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"].blank? } do
8
+ property :hit, skip_if: lambda { |options| options[:fragment]["title"]=="" } do
9
9
  property :title
10
- validates :title, presence: true
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
@@ -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/active_model/validations"
42
+ require "reform/form/dry"
80
43
  Reform::Contract.class_eval do
81
- feature Reform::Form::ActiveModel::Validations
44
+ feature Reform::Form::Dry
82
45
  end
83
46
  # FIXME!
84
47
  Reform::Form.class_eval do
85
- feature Reform::Form::ActiveModel::Validations
48
+ feature Reform::Form::Dry
86
49
  end
87
-
88
- I18n.load_path << Dir['test/dummy/config/locales/*.yml']
89
- I18n.backend.load_translations