reform 2.0.4 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 565c9da5e49ef68eac9707011e9574284cac113c
4
- data.tar.gz: 5feef4e923913adb8099b6e307aa38b0adff6dbf
3
+ metadata.gz: a7b6c745acf6fc96e9d5c0291d4fa64df5be3c92
4
+ data.tar.gz: 0304e04e195f525af7aed8081c87a328885c2581
5
5
  SHA512:
6
- metadata.gz: c1e962dda69e280292e94394aea4876e3ec2714cf1dc07de305a0c316248ecc065ab23785014838780258c6ac0b91d68d99c5c985494d601ac157636067e97e4
7
- data.tar.gz: dbc31dd351bb1ac8cf223e513676d061ed85237a5eecba759319d753a482e5a20246a3859d6e23b8a6ede2893628587c833c8c1b70242fa2dc2a22e3c78252c9
6
+ metadata.gz: 1070cf32ba255c0b08d5b0dc7bc3a666cd1a515fe627e77af2168519908fe9a0680b132cdc2e77e512cd346c1b458051bc5c1e055db31bcc101ac718dfca8bf4
7
+ data.tar.gz: 42777ea0870fa57d5eb6c87df3cda716bd6eff0f0c479e50610df969845b089c6dcaa366ab1e14c66484c1980fbf621dd045463cc2ae357d5e8fbbcc3f13fdf8
data/CHANGES.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 2.0.5
2
+
3
+ * `ActiveModel::Validator` now delegates all methods properly to the form. It used to crashed with properties called `format` or other private `Object` methods.
4
+ * Simpleform will now properly display fields as required, or not (by introducion `ModelReflections::validators_on`).
5
+ * The `:default` option is not copied into the deserializer anymore from the schema. This requires disposable 0.1.11.
6
+
1
7
  ## 2.0.4
2
8
 
3
9
  * `#sync` and `#save` with block now provide `HashWithIndifferentAccess` in Rails.
data/Gemfile CHANGED
@@ -4,5 +4,4 @@ gemspec
4
4
 
5
5
  #gem 'representable', path: "../representable"
6
6
  # gem "disposable", path: "../disposable"
7
- # gem "disposable", github: "apotonick/disposable"o
8
- # gem "uber", path: "../uber"
7
+ # gem "disposable", github: "apotonick/disposable"
data/database.sqlite3 CHANGED
Binary file
@@ -16,6 +16,11 @@ class Reform::Form < Reform::Contract
16
16
  def reflect_on_association(*args)
17
17
  model_name.to_s.constantize.reflect_on_association(*args)
18
18
  end
19
+
20
+ # this is needed in simpleform to infer required fields.
21
+ def validators_on(*args)
22
+ validator.validators_on(*args)
23
+ end
19
24
  end
20
25
 
21
26
  # Delegate column for attribute to the model to support simple_form's
@@ -5,19 +5,13 @@ require "uber/delegates"
5
5
  module Reform::Form::ActiveModel
6
6
  # AM::Validations for your form.
7
7
  #
8
- # Note: The preferred way for validations should be Lotus::Validations, as ActiveModel::Validation's
9
- # implementation is old, very complex given that it needs to do a simple thing, is using
10
- # globals like @errors, and relies and more than 100 methods to be mixed into your form.
11
- #
12
- # Implements ::validates and friends, and #valid?.
13
- #
8
+ # Provides ::validates, ::validate, #validate, and #valid?.
14
9
  module Validations
15
10
  def self.included(includer)
16
11
  includer.instance_eval do
17
12
  include Reform::Form::ActiveModel
18
- extend Uber::InheritableAttr
19
13
  inheritable_attr :validator
20
- self.validator = Class.new(Validator)
14
+ self.validator = Class.new(Validator) # the actual validations happen in this instance.
21
15
 
22
16
  class << self
23
17
  extend Uber::Delegates
@@ -40,9 +34,10 @@ module Reform::Form::ActiveModel
40
34
  end
41
35
 
42
36
 
43
- # Validators is the validatable object. On the class level, we define validations,
37
+ # Validator is the validatable object. On the class level, we define validations,
44
38
  # on instance, it exposes #valid?.
45
- class Validator
39
+ require "delegate"
40
+ class Validator < SimpleDelegator
46
41
  # current i18n scope: :activemodel.
47
42
  include ActiveModel::Validations
48
43
 
@@ -61,12 +56,12 @@ module Reform::Form::ActiveModel
61
56
  end
62
57
 
63
58
  def initialize(form, name)
64
- @form = form
59
+ super(form)
65
60
  self.class.model_name = name # one of the many reasons why i will drop support for AM::V in 2.1.
66
61
  end
67
62
 
68
- def method_missing(method_name, *args, &block)
69
- @form.send(method_name, *args, &block)
63
+ def method_missing(m, *args, &block)
64
+ __getobj__.send(m, *args, &block) # send all methods to the form, even privates.
70
65
  end
71
66
  end
72
67
 
@@ -81,7 +76,6 @@ module Reform::Form::ActiveModel
81
76
  validator = self.class.validator.new(self, model_name)
82
77
  validator.valid? # run the Validations object's validator with the form as context. this won't pollute anything in the form.
83
78
 
84
-
85
79
  #errors.merge!(validator.errors, "")
86
80
  validator.errors.each do |name, error| # TODO: handle with proper merge, or something. validator.errors is ALWAYS AM::Errors.
87
81
  errors.add(name, error)
@@ -24,12 +24,17 @@ module Reform::Form::MultiParameterAttributes
24
24
 
25
25
  private
26
26
  def params_to_date(year, month, day, hour, minute)
27
- return nil if [year, month, day].any?(&:blank?)
27
+ date_fields = [year, month, day].map!(&:to_i)
28
+ time_fields = [hour, minute].map!(&:to_i)
29
+
30
+ if date_fields.any?(&:zero?) || !Date.valid_date?(*date_fields)
31
+ return nil
32
+ end
28
33
 
29
34
  if hour.blank? && minute.blank?
30
- Date.new(year.to_i, month.to_i, day.to_i) # TODO: test fails.
35
+ Date.new(*date_fields)
31
36
  else
32
- args = [year, month, day, hour, minute].map(&:to_i)
37
+ args = date_fields + time_fields
33
38
  Time.zone ? Time.zone.local(*args) :
34
39
  Time.new(*args)
35
40
  end
@@ -1,3 +1,3 @@
1
1
  module Reform
2
- VERSION = "2.0.4"
2
+ VERSION = "2.0.5"
3
3
  end
@@ -0,0 +1,18 @@
1
+ require "test_helper"
2
+
3
+ class AMValidationWithFormatTest < MiniTest::Spec
4
+ class SongForm < Reform::Form
5
+ property :format
6
+ validates :format, presence: true
7
+ end
8
+
9
+ class Song
10
+ def format
11
+ 1
12
+ end
13
+ end
14
+
15
+ it do
16
+ SongForm.new(Song.new).validate({}).must_equal true
17
+ end
18
+ end
data/test/form_test.rb CHANGED
@@ -25,7 +25,7 @@ class FormTest < MiniTest::Spec
25
25
  property :title, validates: {presence: true}
26
26
  properties :genre, :band, validates: {presence: true}
27
27
  end
28
- it "xxx" do
28
+ it do
29
29
  form = SongForm.new(OpenStruct.new)
30
30
  form.validate({})
31
31
  form.errors.to_s.must_equal "{:title=>[\"can't be blank\"], :genre=>[\"can't be blank\"], :band=>[\"can't be blank\"]}"
@@ -131,4 +131,8 @@ class ModelReflectionTest < MiniTest::Spec
131
131
  form.defined_enums.must_include Artist
132
132
  end
133
133
  end
134
+
135
+ describe "::validators_on" do
136
+ it { assert SongWithArtistForm.validators_on }
137
+ end
134
138
  end
data/test/mongoid_test.rb CHANGED
@@ -1,313 +1,313 @@
1
- # require 'test_helper'
2
- # def mongoid_present?
3
- # require 'mongoid'
4
- # Mongoid.configure do |config|
5
- # config.connect_to("reform-mongoid-test")
6
- # end
7
- # true
8
- # rescue
9
- # false
10
- # end
11
-
12
- # if mongoid_present?
13
- # require 'reform/mongoid'
14
-
15
- # class Disc
16
- # include Mongoid::Document
17
- # field :title, type: String
18
- # has_many :tunes
19
- # has_and_belongs_to_many :musicians
20
- # end
21
-
22
- # class Musician
23
- # include Mongoid::Document
24
- # field :name, type: String
25
- # end
26
-
27
- # class Tune
28
- # include Mongoid::Document
29
- # include Mongoid::Timestamps
30
- # field :title, type: String
31
- # belongs_to :disc
32
- # belongs_to :musician
33
- # end
34
-
35
- # class MongoidTest < MiniTest::Spec
36
- # class TuneForm < Reform::Form
37
- # include Reform::Form::Mongoid
38
- # model :tune
39
-
40
- # property :title
41
- # property :created_at
42
-
43
- # validates_uniqueness_of :title, scope: [:disc_id, :musician_id]
44
- # validates :created_at, :presence => true # have another property to test if we mix up.
45
-
46
- # property :musician do
47
- # property :name
48
- # validates_uniqueness_of :name # this currently also tests if Form::AR is included as a feature.
49
- # end
50
- # end
51
-
52
- # let(:disc) { Disc.create(:title => "Damnation") }
53
- # let(:musician) { Musician.create(:name => "Opeth") }
54
- # let(:form) { TuneForm.new(Tune.new(:musician => Musician.new)) }
55
-
56
- # it { form.class.i18n_scope.must_equal :mongoid }
57
-
58
- # it "allows accessing the database" do
59
- # end
60
-
61
- # # uniqueness
62
- # it "has no errors on title when title is unique for the same musician and disc" do
63
- # form.validate("title" => "The Gargoyle", "musician_id" => musician.id, "disc" => disc.id, "created_at" => "November 6, 1966")
64
- # assert_empty form.errors[:title]
65
- # end
66
-
67
- # it "has errors on title when title is taken for the same musician and disc" do
68
- # skip "replace ActiveModel::Validations with our own, working and reusable gem."
69
- # Tune.create(title: "Windowpane", musician_id: musician.id, disc_id: disc.id)
70
- # form.validate("title" => "Windowpane", "musician_id" => musician.id, "disc" => disc)
71
- # refute_empty form.errors[:title]
72
- # end
73
-
74
- # # nested object taken.
75
- # it "is valid when musician name is unique" do
76
- # form.validate("musician" => {"name" => "Paul Gilbert"}, "title" => "The Gargoyle", "created_at" => "November 6, 1966").must_equal true
77
- # end
78
-
79
- # it "is invalid and shows error when taken" do
80
- # Tune.delete_all
81
- # Musician.create(:name => "Racer X")
82
-
83
- # form.validate("musician" => {"name" => "Racer X"}, "title" => "Ghost Inside My Skin").must_equal false
84
- # form.errors.messages.must_equal({:"musician.name"=>["is already taken"], :created_at => ["can't be blank"]})
85
- # end
86
-
87
- # it "works with Composition" do
88
- # form = Class.new(Reform::Form) do
89
- # include Reform::Form::Mongoid
90
- # include Reform::Form::Composition
91
-
92
- # property :name, :on => :musician
93
- # validates_uniqueness_of :name
94
- # end.new(:musician => Musician.new)
95
-
96
- # Musician.create(:name => "Bad Religion")
97
- # form.validate("name" => "Bad Religion").must_equal false
98
- # end
99
-
100
- # describe "#save" do
101
- # # TODO: test 1-n?
102
- # it "calls model.save" do
103
- # Musician.delete_all
104
- # form.validate("musician" => {"name" => "Bad Religion"}, "title" => "Ghost Inside My Skin")
105
- # form.save
106
- # Musician.where(:name => "Bad Religion").size.must_equal 1
107
- # end
108
-
109
- # it "doesn't call model.save when block is given" do
110
- # Musician.delete_all
111
- # form.validate("name" => "Bad Religion")
112
- # form.save {}
113
- # Musician.where(:name => "Bad Religion").size.must_equal 0
114
- # end
115
- # end
116
- # end
117
-
1
+ require 'test_helper'
2
+ def mongoid_present?
3
+ require 'mongoid'
4
+ Mongoid.configure do |config|
5
+ config.connect_to("reform-mongoid-test")
6
+ end
7
+ true
8
+ rescue
9
+ false
10
+ end
11
+
12
+ if mongoid_present?
13
+ require 'reform/mongoid'
14
+
15
+ class Disc
16
+ include Mongoid::Document
17
+ field :title, type: String
18
+ has_many :tunes
19
+ has_and_belongs_to_many :musicians
20
+ end
21
+
22
+ class Musician
23
+ include Mongoid::Document
24
+ field :name, type: String
25
+ end
26
+
27
+ class Tune
28
+ include Mongoid::Document
29
+ include Mongoid::Timestamps
30
+ field :title, type: String
31
+ belongs_to :disc
32
+ belongs_to :musician
33
+ end
34
+
35
+ class MongoidTest < MiniTest::Spec
36
+ class TuneForm < Reform::Form
37
+ include Reform::Form::Mongoid
38
+ model :tune
39
+
40
+ property :title
41
+ property :created_at
42
+
43
+ validates_uniqueness_of :title, scope: [:disc_id, :musician_id]
44
+ validates :created_at, :presence => true # have another property to test if we mix up.
45
+
46
+ property :musician do
47
+ property :name
48
+ validates_uniqueness_of :name # this currently also tests if Form::AR is included as a feature.
49
+ end
50
+ end
51
+
52
+ let(:disc) { Disc.create(:title => "Damnation") }
53
+ let(:musician) { Musician.create(:name => "Opeth") }
54
+ let(:form) { TuneForm.new(Tune.new(:musician => Musician.new)) }
55
+
56
+ it { form.class.i18n_scope.must_equal :mongoid }
57
+
58
+ it "allows accessing the database" do
59
+ end
60
+
61
+ # uniqueness
62
+ it "has no errors on title when title is unique for the same musician and disc" do
63
+ form.validate("title" => "The Gargoyle", "musician_id" => musician.id, "disc" => disc.id, "created_at" => "November 6, 1966")
64
+ assert_empty form.errors[:title]
65
+ end
66
+
67
+ it "has errors on title when title is taken for the same musician and disc" do
68
+ skip "replace ActiveModel::Validations with our own, working and reusable gem."
69
+ Tune.create(title: "Windowpane", musician_id: musician.id, disc_id: disc.id)
70
+ form.validate("title" => "Windowpane", "musician_id" => musician.id, "disc" => disc)
71
+ refute_empty form.errors[:title]
72
+ end
73
+
74
+ # nested object taken.
75
+ it "is valid when musician name is unique" do
76
+ form.validate("musician" => {"name" => "Paul Gilbert"}, "title" => "The Gargoyle", "created_at" => "November 6, 1966").must_equal true
77
+ end
78
+
79
+ it "is invalid and shows error when taken" do
80
+ Tune.delete_all
81
+ Musician.create(:name => "Racer X")
82
+
83
+ form.validate("musician" => {"name" => "Racer X"}, "title" => "Ghost Inside My Skin").must_equal false
84
+ form.errors.messages.must_equal({:"musician.name"=>["is already taken"], :created_at => ["can't be blank"]})
85
+ end
86
+
87
+ it "works with Composition" do
88
+ form = Class.new(Reform::Form) do
89
+ include Reform::Form::Mongoid
90
+ include Reform::Form::Composition
91
+
92
+ property :name, :on => :musician
93
+ validates_uniqueness_of :name
94
+ end.new(:musician => Musician.new)
95
+
96
+ Musician.create(:name => "Bad Religion")
97
+ form.validate("name" => "Bad Religion").must_equal false
98
+ end
99
+
100
+ describe "#save" do
101
+ # TODO: test 1-n?
102
+ it "calls model.save" do
103
+ Musician.delete_all
104
+ form.validate("musician" => {"name" => "Bad Religion"}, "title" => "Ghost Inside My Skin")
105
+ form.save
106
+ Musician.where(:name => "Bad Religion").size.must_equal 1
107
+ end
108
+
109
+ it "doesn't call model.save when block is given" do
110
+ Musician.delete_all
111
+ form.validate("name" => "Bad Religion")
112
+ form.save {}
113
+ Musician.where(:name => "Bad Religion").size.must_equal 0
114
+ end
115
+ end
116
+ end
117
+
118
118
 
119
- # class PopulateWithActiveRecordTest < MiniTest::Spec
120
- # class DiscForm < Reform::Form
119
+ class PopulateWithActiveRecordTest < MiniTest::Spec
120
+ class DiscForm < Reform::Form
121
121
 
122
- # property :title
122
+ property :title
123
123
 
124
- # collection :tunes, :populate_if_empty => Tune do
125
- # property :title
126
- # end
127
- # end
124
+ collection :tunes, :populate_if_empty => Tune do
125
+ property :title
126
+ end
127
+ end
128
128
 
129
- # let (:disc) { Disc.new(:tunes => []) }
130
- # it do
131
- # form = DiscForm.new(disc)
129
+ let (:disc) { Disc.new(:tunes => []) }
130
+ it do
131
+ form = DiscForm.new(disc)
132
132
 
133
- # form.validate("tunes" => [{"title" => "Straight From The Jacket"}])
133
+ form.validate("tunes" => [{"title" => "Straight From The Jacket"}])
134
134
 
135
- # # form populated.
136
- # form.tunes.size.must_equal 1
137
- # form.tunes[0].model.must_be_kind_of Tune
135
+ # form populated.
136
+ form.tunes.size.must_equal 1
137
+ form.tunes[0].model.must_be_kind_of Tune
138
138
 
139
- # # model NOT populated.
140
- # disc.tunes.must_equal []
139
+ # model NOT populated.
140
+ disc.tunes.must_equal []
141
141
 
142
142
 
143
- # form.sync
143
+ form.sync
144
144
 
145
- # # form populated.
146
- # form.tunes.size.must_equal 1
147
- # form.tunes[0].model.must_be_kind_of Tune
145
+ # form populated.
146
+ form.tunes.size.must_equal 1
147
+ form.tunes[0].model.must_be_kind_of Tune
148
148
 
149
- # # model also populated.
150
- # tune = disc.tunes[0]
151
- # disc.tunes.must_equal [tune]
152
- # tune.title.must_equal "Straight From The Jacket"
149
+ # model also populated.
150
+ tune = disc.tunes[0]
151
+ disc.tunes.must_equal [tune]
152
+ tune.title.must_equal "Straight From The Jacket"
153
153
 
154
154
 
155
- # # if ActiveRecord::VERSION::STRING !~ /^3.0/
156
- # # # saving saves association.
157
- # # form.save
158
- # #
159
- # # disc.reload
160
- # # tune = disc.tunes[0]
161
- # # disc.tunes.must_equal [tune]
162
- # # tune.title.must_equal "Straight From The Jacket"
163
- # # end
164
- # end
155
+ # if ActiveRecord::VERSION::STRING !~ /^3.0/
156
+ # # saving saves association.
157
+ # form.save
158
+ #
159
+ # disc.reload
160
+ # tune = disc.tunes[0]
161
+ # disc.tunes.must_equal [tune]
162
+ # tune.title.must_equal "Straight From The Jacket"
163
+ # end
164
+ end
165
165
 
166
166
 
167
- # describe "modifying 1., adding 2." do
168
- # let (:tune) { Tune.new(:title => "Part 2") }
169
- # let (:disc) { Disc.create.tap { |a| a.tunes << tune } }
167
+ describe "modifying 1., adding 2." do
168
+ let (:tune) { Tune.new(:title => "Part 2") }
169
+ let (:disc) { Disc.create.tap { |a| a.tunes << tune } }
170
170
 
171
- # it do
172
- # form = DiscForm.new(disc)
171
+ it do
172
+ form = DiscForm.new(disc)
173
173
 
174
- # id = disc.tunes[0].id
175
- # disc.tunes[0].persisted?.must_equal true
176
- # assert id.to_s.size > 0
174
+ id = disc.tunes[0].id
175
+ disc.tunes[0].persisted?.must_equal true
176
+ assert id.to_s.size > 0
177
177
 
178
- # form.validate("tunes" => [{"title" => "Part Two"}, {"title" => "Check For A Pulse"}])
178
+ form.validate("tunes" => [{"title" => "Part Two"}, {"title" => "Check For A Pulse"}])
179
179
 
180
- # # form populated.
181
- # form.tunes.size.must_equal 2
182
- # form.tunes[0].model.must_be_kind_of Tune
183
- # form.tunes[1].model.must_be_kind_of Tune
180
+ # form populated.
181
+ form.tunes.size.must_equal 2
182
+ form.tunes[0].model.must_be_kind_of Tune
183
+ form.tunes[1].model.must_be_kind_of Tune
184
184
 
185
- # # model NOT populated.
186
- # disc.tunes.must_equal [tune]
185
+ # model NOT populated.
186
+ disc.tunes.must_equal [tune]
187
187
 
188
188
 
189
- # form.sync
189
+ form.sync
190
190
 
191
- # # form populated.
192
- # form.tunes.size.must_equal 2
191
+ # form populated.
192
+ form.tunes.size.must_equal 2
193
193
 
194
- # # model also populated.
195
- # disc.tunes.size.must_equal 2
194
+ # model also populated.
195
+ disc.tunes.size.must_equal 2
196
196
 
197
- # # corrected title
198
- # disc.tunes[0].title.must_equal "Part Two"
199
- # # ..but same tune.
200
- # disc.tunes[0].id.must_equal id
197
+ # corrected title
198
+ disc.tunes[0].title.must_equal "Part Two"
199
+ # ..but same tune.
200
+ disc.tunes[0].id.must_equal id
201
201
 
202
- # # and a new tune.
203
- # disc.tunes[1].title.must_equal "Check For A Pulse"
204
- # disc.tunes[1].persisted?.must_equal true # TODO: with << strategy, this shouldn't be saved.
205
- # end
202
+ # and a new tune.
203
+ disc.tunes[1].title.must_equal "Check For A Pulse"
204
+ disc.tunes[1].persisted?.must_equal true # TODO: with << strategy, this shouldn't be saved.
205
+ end
206
206
 
207
- # describe 'using nested_models_attributes to modify nested collection' do
208
- # class ActiveModelDiscForm < Reform::Form
209
- # include Reform::Form::ActiveModel
210
- # include Reform::Form::ActiveModel::FormBuilderMethods
207
+ describe 'using nested_models_attributes to modify nested collection' do
208
+ class ActiveModelDiscForm < Reform::Form
209
+ include Reform::Form::ActiveModel
210
+ include Reform::Form::ActiveModel::FormBuilderMethods
211
211
 
212
- # property :title
212
+ property :title
213
213
 
214
- # collection :tunes, :populate_if_empty => Tune do
215
- # property :title
216
- # end
217
- # end
214
+ collection :tunes, :populate_if_empty => Tune do
215
+ property :title
216
+ end
217
+ end
218
218
 
219
- # let (:disc) { Disc.create(:title => 'Greatest Hits') }
220
- # let (:form) { ActiveModelDiscForm.new(disc) }
219
+ let (:disc) { Disc.create(:title => 'Greatest Hits') }
220
+ let (:form) { ActiveModelDiscForm.new(disc) }
221
221
 
222
- # it do
223
- # form.validate('tunes_attributes' => {'0' => {'title' => 'Tango'}})
222
+ it do
223
+ form.validate('tunes_attributes' => {'0' => {'title' => 'Tango'}})
224
224
 
225
- # # form populated.
226
- # form.tunes.size.must_equal 1
227
- # form.tunes[0].model.must_be_kind_of Tune
228
- # form.tunes[0].title.must_equal 'Tango'
225
+ # form populated.
226
+ form.tunes.size.must_equal 1
227
+ form.tunes[0].model.must_be_kind_of Tune
228
+ form.tunes[0].title.must_equal 'Tango'
229
229
 
230
- # # model NOT populated.
231
- # disc.tunes.must_equal []
230
+ # model NOT populated.
231
+ disc.tunes.must_equal []
232
232
 
233
- # form.save
233
+ form.save
234
234
 
235
- # # nested model persisted.
236
- # first_tune = disc.tunes[0]
237
- # first_tune.persisted?.must_equal true
238
- # assert first_tune.id.to_s.size > 0
235
+ # nested model persisted.
236
+ first_tune = disc.tunes[0]
237
+ first_tune.persisted?.must_equal true
238
+ assert first_tune.id.to_s.size > 0
239
239
 
240
- # # form populated.
241
- # form.tunes.size.must_equal 1
240
+ # form populated.
241
+ form.tunes.size.must_equal 1
242
242
 
243
- # # model also populated.
244
- # disc.tunes.size.must_equal 1
245
- # disc.tunes[0].title.must_equal 'Tango'
243
+ # model also populated.
244
+ disc.tunes.size.must_equal 1
245
+ disc.tunes[0].title.must_equal 'Tango'
246
246
 
247
- # form = ActiveModelDiscForm.new(disc)
248
- # form.validate('tunes_attributes' => {'0' => {'id' => first_tune.id, 'title' => 'Tango nuevo'}, '1' => {'title' => 'Waltz'}})
247
+ form = ActiveModelDiscForm.new(disc)
248
+ form.validate('tunes_attributes' => {'0' => {'id' => first_tune.id, 'title' => 'Tango nuevo'}, '1' => {'title' => 'Waltz'}})
249
249
 
250
- # # form populated.
251
- # form.tunes.size.must_equal 2
252
- # form.tunes[0].model.must_be_kind_of Tune
253
- # form.tunes[1].model.must_be_kind_of Tune
254
- # form.tunes[0].title.must_equal 'Tango nuevo'
255
- # form.tunes[1].title.must_equal 'Waltz'
250
+ # form populated.
251
+ form.tunes.size.must_equal 2
252
+ form.tunes[0].model.must_be_kind_of Tune
253
+ form.tunes[1].model.must_be_kind_of Tune
254
+ form.tunes[0].title.must_equal 'Tango nuevo'
255
+ form.tunes[1].title.must_equal 'Waltz'
256
256
 
257
- # # model NOT populated.
258
- # disc.tunes.size.must_equal 1
259
- # disc.tunes[0].title.must_equal 'Tango'
257
+ # model NOT populated.
258
+ disc.tunes.size.must_equal 1
259
+ disc.tunes[0].title.must_equal 'Tango'
260
260
 
261
- # form.save
261
+ form.save
262
262
 
263
- # # form populated.
264
- # form.tunes.size.must_equal 2
263
+ # form populated.
264
+ form.tunes.size.must_equal 2
265
265
 
266
- # # model also populated.
267
- # disc.tunes.size.must_equal 2
268
- # disc.tunes[0].id.must_equal first_tune.id
269
- # disc.tunes[0].persisted?.must_equal true
270
- # disc.tunes[1].persisted?.must_equal true
271
- # disc.tunes[0].title.must_equal 'Tango nuevo'
272
- # disc.tunes[1].title.must_equal 'Waltz'
273
- # end
274
- # end
275
- # end
266
+ # model also populated.
267
+ disc.tunes.size.must_equal 2
268
+ disc.tunes[0].id.must_equal first_tune.id
269
+ disc.tunes[0].persisted?.must_equal true
270
+ disc.tunes[1].persisted?.must_equal true
271
+ disc.tunes[0].title.must_equal 'Tango nuevo'
272
+ disc.tunes[1].title.must_equal 'Waltz'
273
+ end
274
+ end
275
+ end
276
276
 
277
- # # it do
278
- # # a=Disc.new
279
- # # a.tunes << Tune.new(title: "Old What's His Name") # Tune does not get persisted.
277
+ # it do
278
+ # a=Disc.new
279
+ # a.tunes << Tune.new(title: "Old What's His Name") # Tune does not get persisted.
280
280
 
281
- # # a.tunes[1] = Tune.new(title: "Permanent Rust")
281
+ # a.tunes[1] = Tune.new(title: "Permanent Rust")
282
282
 
283
- # # puts "@@@"
284
- # # puts a.tunes.inspect
283
+ # puts "@@@"
284
+ # puts a.tunes.inspect
285
285
 
286
- # # puts "---"
287
- # # a.save
288
- # # puts a.tunes.inspect
286
+ # puts "---"
287
+ # a.save
288
+ # puts a.tunes.inspect
289
289
 
290
- # # b = a.tunes.first
290
+ # b = a.tunes.first
291
291
 
292
- # # a.tunes = [Tune.new(title:"Biomag")]
293
- # # puts "\\\\"
294
- # # a.save
295
- # # a.reload
296
- # # puts a.tunes.inspect
297
-
298
- # # b.reload
299
- # # puts "#{b.inspect}, #{b.persisted?}"
292
+ # a.tunes = [Tune.new(title:"Biomag")]
293
+ # puts "\\\\"
294
+ # a.save
295
+ # a.reload
296
+ # puts a.tunes.inspect
297
+
298
+ # b.reload
299
+ # puts "#{b.inspect}, #{b.persisted?}"
300
300
 
301
301
 
302
- # # a.tunes = [a.tunes.first, Tune.new(title: "Count Down")]
303
- # # b = a.tunes.first
304
- # # puts ":::::"
305
- # # a.save
306
- # # a.reload
307
- # # puts a.tunes.inspect
302
+ # a.tunes = [a.tunes.first, Tune.new(title: "Count Down")]
303
+ # b = a.tunes.first
304
+ # puts ":::::"
305
+ # a.save
306
+ # a.reload
307
+ # puts a.tunes.inspect
308
308
 
309
- # # b.reload
310
- # # puts "#{b.inspect}, #{b.persisted?}"
311
- # # end
312
- # end
313
- # end
309
+ # b.reload
310
+ # puts "#{b.inspect}, #{b.persisted?}"
311
+ # end
312
+ end
313
+ end
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+
3
+ class ReformTest < ReformSpec
4
+ describe "Date" do
5
+ Person = Struct.new(:date_of_birth)
6
+ let (:form) { DateOfBirthForm.new(Person.new) }
7
+
8
+ class DateOfBirthForm < Reform::Form
9
+ feature Reform::Form::ActiveModel::FormBuilderMethods
10
+ feature Reform::Form::MultiParameterAttributes
11
+ property :date_of_birth, type: Date, :multi_params => true
12
+ end
13
+
14
+ it "munges multi-param date fields into a valid Date attribute" do
15
+ date_of_birth_params = { "date_of_birth(1i)"=>"1950", "date_of_birth(2i)"=>"1", "date_of_birth(3i)"=>"1" }
16
+ form.validate(date_of_birth_params)
17
+ form.date_of_birth.must_equal Date.civil(1950, 1, 1)
18
+ end
19
+
20
+ it "handles invalid Time input" do
21
+ date_of_birth_params = { "date_of_birth(1i)"=>"1950", "date_of_birth(2i)"=>"99", "date_of_birth(3i)"=>"1" }
22
+ form.validate(date_of_birth_params)
23
+ form.date_of_birth.must_equal nil
24
+ end
25
+ end
26
+
27
+ describe "DateTime" do
28
+ Party = Struct.new(:start_time)
29
+ let (:form) { PartyForm.new(Party.new) }
30
+
31
+ class PartyForm < Reform::Form
32
+ feature Reform::Form::ActiveModel::FormBuilderMethods
33
+ feature Reform::Form::MultiParameterAttributes
34
+ property :start_time, type: DateTime, :multi_params => true
35
+ end
36
+
37
+ it "munges multi-param date and time fields into a valid Time attribute" do
38
+ start_time_params = { "start_time(1i)"=>"2000", "start_time(2i)"=>"1", "start_time(3i)"=>"1", "start_time(4i)"=>"12", "start_time(5i)"=>"00" }
39
+ time_format = "%Y-%m-%d %H:%M"
40
+ form.validate(start_time_params)
41
+ form.start_time.strftime(time_format).must_equal DateTime.strptime("2000-01-01 12:00", time_format)
42
+ end
43
+
44
+ it "handles invalid Time input" do
45
+ start_time_params = { "start_time(1i)"=>"2000", "start_time(2i)"=>"99", "start_time(3i)"=>"1", "start_time(4i)"=>"12", "start_time(5i)"=>"00" }
46
+ form.validate(start_time_params)
47
+ form.start_time.must_equal nil
48
+ end
49
+ end
50
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reform
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-08-27 00:00:00.000000000 Z
12
+ date: 2015-09-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: disposable
@@ -245,6 +245,7 @@ files:
245
245
  - reform.gemspec
246
246
  - test/active_model_custom_validation_translations_test.rb
247
247
  - test/active_model_test.rb
248
+ - test/active_model_validation_for_property_named_format_test.rb
248
249
  - test/active_record_test.rb
249
250
  - test/benchmarking.rb
250
251
  - test/builder_test.rb
@@ -292,6 +293,7 @@ files:
292
293
  - test/model_validations_test.rb
293
294
  - test/module_test.rb
294
295
  - test/mongoid_test.rb
296
+ - test/multi_parameter_attributes_test.rb
295
297
  - test/populate_test.rb
296
298
  - test/prepopulator_test.rb
297
299
  - test/rails/integration_test.rb
@@ -335,6 +337,7 @@ summary: Form object decoupled from models with validation, population and prese
335
337
  test_files:
336
338
  - test/active_model_custom_validation_translations_test.rb
337
339
  - test/active_model_test.rb
340
+ - test/active_model_validation_for_property_named_format_test.rb
338
341
  - test/active_record_test.rb
339
342
  - test/benchmarking.rb
340
343
  - test/builder_test.rb
@@ -382,6 +385,7 @@ test_files:
382
385
  - test/model_validations_test.rb
383
386
  - test/module_test.rb
384
387
  - test/mongoid_test.rb
388
+ - test/multi_parameter_attributes_test.rb
385
389
  - test/populate_test.rb
386
390
  - test/prepopulator_test.rb
387
391
  - test/rails/integration_test.rb