formtastic 2.3.0.rc2 → 2.3.0.rc3
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.
- data/.travis.yml +27 -1
- data/Appraisals +5 -0
- data/CHANGELOG +1 -0
- data/README.textile +19 -26
- data/formtastic.gemspec +4 -3
- data/gemfiles/rails_3.0.gemfile +1 -1
- data/gemfiles/rails_3.1.gemfile +1 -1
- data/gemfiles/rails_3.2.gemfile +1 -1
- data/gemfiles/rails_4.0.4.gemfile +7 -0
- data/gemfiles/rails_4.gemfile +1 -1
- data/lib/formtastic/form_builder.rb +9 -1
- data/lib/formtastic/helpers/form_helper.rb +11 -6
- data/lib/formtastic/helpers/inputs_helper.rb +6 -1
- data/lib/formtastic/inputs/base/collections.rb +1 -1
- data/lib/formtastic/inputs/base/validations.rb +1 -1
- data/lib/formtastic/inputs/boolean_input.rb +4 -14
- data/lib/formtastic/inputs/check_boxes_input.rb +7 -1
- data/lib/formtastic/inputs/radio_input.rb +2 -0
- data/lib/formtastic/util.rb +13 -1
- data/lib/formtastic/version.rb +1 -1
- data/lib/generators/templates/_form.html.slim +2 -2
- data/lib/generators/templates/formtastic.rb +15 -1
- data/spec/actions/generic_action_spec.rb +3 -3
- data/spec/builder/custom_builder_spec.rb +7 -7
- data/spec/builder/semantic_fields_for_spec.rb +8 -8
- data/spec/generators/formtastic/form/form_generator_spec.rb +6 -6
- data/spec/helpers/action_helper_spec.rb +11 -11
- data/spec/helpers/form_helper_spec.rb +22 -11
- data/spec/helpers/input_helper_spec.rb +44 -44
- data/spec/helpers/inputs_helper_spec.rb +64 -31
- data/spec/helpers/semantic_errors_helper_spec.rb +12 -12
- data/spec/i18n_spec.rb +5 -5
- data/spec/inputs/boolean_input_spec.rb +6 -5
- data/spec/inputs/check_boxes_input_spec.rb +27 -9
- data/spec/inputs/country_input_spec.rb +5 -5
- data/spec/inputs/custom_input_spec.rb +1 -1
- data/spec/inputs/date_picker_input_spec.rb +4 -4
- data/spec/inputs/datetime_picker_input_spec.rb +4 -4
- data/spec/inputs/hidden_input_spec.rb +3 -3
- data/spec/inputs/include_blank_spec.rb +2 -2
- data/spec/inputs/number_input_spec.rb +36 -36
- data/spec/inputs/radio_input_spec.rb +23 -5
- data/spec/inputs/range_input_spec.rb +19 -19
- data/spec/inputs/select_input_spec.rb +40 -20
- data/spec/inputs/string_input_spec.rb +2 -2
- data/spec/inputs/time_picker_input_spec.rb +4 -4
- data/spec/localizer_spec.rb +1 -1
- data/spec/spec_helper.rb +203 -188
- data/spec/support/custom_macros.rb +8 -8
- metadata +15 -13
data/lib/formtastic/version.rb
CHANGED
@@ -66,7 +66,21 @@
|
|
66
66
|
# specifying that class here. Defaults to Formtastic::FormBuilder.
|
67
67
|
# Formtastic::Helpers::FormHelper.builder = MyCustomBuilder
|
68
68
|
|
69
|
-
#
|
69
|
+
# All formtastic forms have a class that indicates that they are just that. You
|
70
|
+
# can change it to any class you want.
|
71
|
+
# Formtastic::Helpers::FormHelper.default_form_class = 'formtastic'
|
72
|
+
|
73
|
+
# Formtastic will infer a class name from the model, array, string ot symbol you pass to the
|
74
|
+
# form builder. You can customize the way that class is presented by overriding
|
75
|
+
# this proc.
|
76
|
+
# Formtastic::Helpers::FormHelper.default_form_model_class_proc = proc { |model_class_name| model_class_name }
|
77
|
+
|
78
|
+
# Allows to set a custom field_error_proc wrapper. By default this wrapper
|
79
|
+
# is disabled since `formtastic` already adds an error class to the LI tag
|
80
|
+
# containing the input.
|
81
|
+
# Formtastic::Helpers::FormHelper.formtastic_field_error_proc = proc { |html_tag, instance_tag| html_tag }
|
82
|
+
|
83
|
+
# You can opt-in to Formtastic's use of the HTML5 `required` attribute on `<input>`, `<select>`
|
70
84
|
# and `<textarea>` tags by setting this to true (defaults to false).
|
71
85
|
# Formtastic::FormBuilder.use_required_attribute = false
|
72
86
|
|
@@ -244,7 +244,7 @@ describe 'InputAction::Base' do
|
|
244
244
|
|
245
245
|
describe 'when used on a new record' do
|
246
246
|
before do
|
247
|
-
@new_post.stub
|
247
|
+
@new_post.stub(:new_record?).and_return(true)
|
248
248
|
end
|
249
249
|
|
250
250
|
describe 'when explicit label is provided' do
|
@@ -344,7 +344,7 @@ describe 'InputAction::Base' do
|
|
344
344
|
|
345
345
|
describe 'when used on an existing record' do
|
346
346
|
before do
|
347
|
-
@new_post.stub
|
347
|
+
@new_post.stub(:persisted?).and_return(true)
|
348
348
|
end
|
349
349
|
|
350
350
|
describe 'when explicit label is provided' do
|
@@ -466,7 +466,7 @@ describe 'InputAction::Base' do
|
|
466
466
|
end
|
467
467
|
@new_user_post = ::UserPost.new
|
468
468
|
|
469
|
-
@new_user_post.stub
|
469
|
+
@new_user_post.stub(:new_record?).and_return(true)
|
470
470
|
concat(semantic_form_for(@new_user_post, :url => '') do |builder|
|
471
471
|
concat(builder.action(:submit, :as => :generic))
|
472
472
|
concat(builder.action(:reset, :as => :generic))
|
@@ -47,7 +47,7 @@ describe 'Formtastic::Helpers::FormHelper.builder' do
|
|
47
47
|
describe "when using a custom builder" do
|
48
48
|
|
49
49
|
before do
|
50
|
-
@new_post.stub
|
50
|
+
@new_post.stub(:title)
|
51
51
|
Formtastic::Helpers::FormHelper.builder = MyCustomFormBuilder
|
52
52
|
end
|
53
53
|
|
@@ -72,9 +72,9 @@ describe 'Formtastic::Helpers::FormHelper.builder' do
|
|
72
72
|
|
73
73
|
# See: https://github.com/justinfrench/formtastic/issues/657
|
74
74
|
it "should not conflict with navigasmic" do
|
75
|
-
stub
|
76
|
-
|
77
|
-
lambda { semantic_form_for(@new_post) }.should_not raise_error
|
75
|
+
self.class.any_instance.stub(:builder).and_return('navigasmic')
|
76
|
+
|
77
|
+
lambda { semantic_form_for(@new_post) { |f| } }.should_not raise_error
|
78
78
|
end
|
79
79
|
|
80
80
|
end
|
@@ -82,8 +82,8 @@ describe 'Formtastic::Helpers::FormHelper.builder' do
|
|
82
82
|
describe "fields_for" do
|
83
83
|
|
84
84
|
it "should yield an instance of the parent form builder" do
|
85
|
-
@new_post.stub
|
86
|
-
@new_post.stub
|
85
|
+
@new_post.stub(:comment).and_return([@fred])
|
86
|
+
@new_post.stub(:comment_attributes=)
|
87
87
|
semantic_form_for(@new_post, :builder => MyCustomFormBuilder) do |builder|
|
88
88
|
builder.class.should.kind_of?(MyCustomFormBuilder)
|
89
89
|
|
@@ -102,7 +102,7 @@ describe 'Formtastic::Helpers::FormHelper.builder' do
|
|
102
102
|
describe "fields_for" do
|
103
103
|
|
104
104
|
it "should yield an instance of the parent form builder" do
|
105
|
-
@new_post.stub
|
105
|
+
@new_post.stub(:author_attributes=)
|
106
106
|
semantic_form_for(@new_post, :builder => MyCustomFormBuilder) do |builder|
|
107
107
|
builder.fields_for(:author) do |nested_builder|
|
108
108
|
nested_builder.class.should.kind_of?(MyCustomFormBuilder)
|
@@ -8,7 +8,7 @@ describe 'Formtastic::FormBuilder#fields_for' do
|
|
8
8
|
before do
|
9
9
|
@output_buffer = ''
|
10
10
|
mock_everything
|
11
|
-
@new_post.stub
|
11
|
+
@new_post.stub(:author).and_return(::Author.new)
|
12
12
|
end
|
13
13
|
|
14
14
|
context 'outside a form_for block' do
|
@@ -77,7 +77,7 @@ describe 'Formtastic::FormBuilder#fields_for' do
|
|
77
77
|
end
|
78
78
|
|
79
79
|
it 'should sanitize html id for li tag' do
|
80
|
-
@bob.stub
|
80
|
+
@bob.stub(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
|
81
81
|
concat(semantic_form_for(@new_post) do |builder|
|
82
82
|
concat(builder.semantic_fields_for(@bob, :index => 1) do |nested_builder|
|
83
83
|
concat(nested_builder.inputs(:login))
|
@@ -90,7 +90,7 @@ describe 'Formtastic::FormBuilder#fields_for' do
|
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'should use namespace provided in nested fields' do
|
93
|
-
@bob.stub
|
93
|
+
@bob.stub(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
|
94
94
|
concat(semantic_form_for(@new_post, :namespace => 'context2') do |builder|
|
95
95
|
concat(builder.semantic_fields_for(@bob, :index => 1) do |nested_builder|
|
96
96
|
concat(nested_builder.inputs(:login))
|
@@ -100,9 +100,9 @@ describe 'Formtastic::FormBuilder#fields_for' do
|
|
100
100
|
end
|
101
101
|
|
102
102
|
it 'should render errors on the nested inputs' do
|
103
|
-
@errors =
|
104
|
-
@errors.stub
|
105
|
-
@bob.stub
|
103
|
+
@errors = double('errors')
|
104
|
+
@errors.stub(:[]).with(errors_matcher(:login)).and_return(['oh noes'])
|
105
|
+
@bob.stub(:errors).and_return(@errors)
|
106
106
|
|
107
107
|
concat(semantic_form_for(@new_post, :namespace => 'context2') do |builder|
|
108
108
|
concat(builder.semantic_fields_for(@bob) do |nested_builder|
|
@@ -120,8 +120,8 @@ describe 'Formtastic::FormBuilder#fields_for' do
|
|
120
120
|
output_buffer.replace ''
|
121
121
|
|
122
122
|
@fred.posts.size.should == 1
|
123
|
-
@fred.posts.first.stub
|
124
|
-
@fred.stub
|
123
|
+
@fred.posts.first.stub(:persisted?).and_return(true)
|
124
|
+
@fred.stub(:posts_attributes=)
|
125
125
|
concat(semantic_form_for(@fred) do |builder|
|
126
126
|
concat(builder.semantic_fields_for(:posts) do |nested_builder|
|
127
127
|
concat(nested_builder.input(:id, :as => :hidden))
|
@@ -14,11 +14,11 @@ describe Formtastic::FormGenerator do
|
|
14
14
|
@output_buffer = ''
|
15
15
|
prepare_destination
|
16
16
|
mock_everything
|
17
|
-
::Post.stub
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
::Post.stub(:reflect_on_all_associations).with(:belongs_to).and_return([
|
18
|
+
double('reflection', :name => :author, :options => {}, :klass => ::Author, :macro => :belongs_to),
|
19
|
+
double('reflection', :name => :reviewer, :options => {:class_name => 'Author'}, :klass => ::Author, :macro => :belongs_to),
|
20
|
+
double('reflection', :name => :main_post, :options => {}, :klass => ::Post, :macro => :belongs_to),
|
21
|
+
double('reflection', :name => :attachment, :options => {:polymorphic => true}, :macro => :belongs_to),
|
22
22
|
])
|
23
23
|
end
|
24
24
|
|
@@ -34,7 +34,7 @@ describe Formtastic::FormGenerator do
|
|
34
34
|
|
35
35
|
describe 'with existing model' do
|
36
36
|
it 'should not raise an exception' do
|
37
|
-
lambda { run_generator %w(Post) }.should_not raise_error
|
37
|
+
lambda { run_generator %w(Post) }.should_not raise_error
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -53,7 +53,7 @@ describe 'Formtastic::FormBuilder#action' do
|
|
53
53
|
it 'should call the corresponding action class with .to_html' do
|
54
54
|
[:input, :button, :link].each do |action_style|
|
55
55
|
semantic_form_for(:project, :url => "http://test.host") do |builder|
|
56
|
-
action_instance =
|
56
|
+
action_instance = double('Action instance')
|
57
57
|
action_class = "#{action_style.to_s}_action".classify
|
58
58
|
action_constant = "Formtastic::Actions::#{action_class}".constantize
|
59
59
|
|
@@ -99,7 +99,7 @@ describe 'Formtastic::FormBuilder#action' do
|
|
99
99
|
# it 'should render a label with localized text and not apply the label_str_method' do
|
100
100
|
# with_config :label_str_method, :reverse do
|
101
101
|
# @localized_label_text = 'Localized title'
|
102
|
-
# @new_post.stub
|
102
|
+
# @new_post.stub(:meta_description)
|
103
103
|
# ::I18n.backend.store_translations :en,
|
104
104
|
# :formtastic => {
|
105
105
|
# :labels => {
|
@@ -132,7 +132,7 @@ describe 'Formtastic::FormBuilder#action' do
|
|
132
132
|
#
|
133
133
|
# describe 'and object is given' do
|
134
134
|
# it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
|
135
|
-
# @new_post.stub
|
135
|
+
# @new_post.stub(:meta_description) # a two word method name
|
136
136
|
# @new_post.class.should_receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
|
137
137
|
#
|
138
138
|
# concat(semantic_form_for(@new_post) do |builder|
|
@@ -145,7 +145,7 @@ describe 'Formtastic::FormBuilder#action' do
|
|
145
145
|
# describe 'and object is given with label_str_method set to :capitalize' do
|
146
146
|
# it 'should capitalize method name, passing it down to the label tag' do
|
147
147
|
# with_config :label_str_method, :capitalize do
|
148
|
-
# @new_post.stub
|
148
|
+
# @new_post.stub(:meta_description)
|
149
149
|
#
|
150
150
|
# concat(semantic_form_for(@new_post) do |builder|
|
151
151
|
# concat(builder.input(:meta_description))
|
@@ -266,7 +266,7 @@ describe 'Formtastic::FormBuilder#action' do
|
|
266
266
|
context 'when a customized top-level class does not exist' do
|
267
267
|
|
268
268
|
it 'should instantiate the Formtastic action' do
|
269
|
-
action =
|
269
|
+
action = double('action', :to_html => 'some HTML')
|
270
270
|
Formtastic::Actions::ButtonAction.should_receive(:new).and_return(action)
|
271
271
|
concat(semantic_form_for(@new_post) do |builder|
|
272
272
|
builder.action(:commit, :as => :button)
|
@@ -280,7 +280,7 @@ describe 'Formtastic::FormBuilder#action' do
|
|
280
280
|
class ::ButtonAction < Formtastic::Actions::ButtonAction
|
281
281
|
end
|
282
282
|
|
283
|
-
action =
|
283
|
+
action = double('action', :to_html => 'some HTML')
|
284
284
|
Formtastic::Actions::ButtonAction.should_not_receive(:new)
|
285
285
|
::ButtonAction.should_receive(:new).and_return(action)
|
286
286
|
|
@@ -330,31 +330,31 @@ describe 'Formtastic::FormBuilder#action' do
|
|
330
330
|
concat(semantic_form_for(@new_post) do |builder|
|
331
331
|
concat(builder.action(:cancel, :as => :link))
|
332
332
|
end)
|
333
|
-
}.should_not raise_error
|
333
|
+
}.should_not raise_error
|
334
334
|
|
335
335
|
lambda {
|
336
336
|
concat(semantic_form_for(@new_post) do |builder|
|
337
337
|
concat(builder.action(:submit, :as => :input))
|
338
338
|
end)
|
339
|
-
}.should_not raise_error
|
339
|
+
}.should_not raise_error
|
340
340
|
|
341
341
|
lambda {
|
342
342
|
concat(semantic_form_for(@new_post) do |builder|
|
343
343
|
concat(builder.action(:submit, :as => :button))
|
344
344
|
end)
|
345
|
-
}.should_not raise_error
|
345
|
+
}.should_not raise_error
|
346
346
|
|
347
347
|
lambda {
|
348
348
|
concat(semantic_form_for(@new_post) do |builder|
|
349
349
|
concat(builder.action(:reset, :as => :input))
|
350
350
|
end)
|
351
|
-
}.should_not raise_error
|
351
|
+
}.should_not raise_error
|
352
352
|
|
353
353
|
lambda {
|
354
354
|
concat(semantic_form_for(@new_post) do |builder|
|
355
355
|
concat(builder.action(:reset, :as => :button))
|
356
356
|
end)
|
357
|
-
}.should_not raise_error
|
357
|
+
}.should_not raise_error
|
358
358
|
end
|
359
359
|
|
360
360
|
end
|
@@ -23,7 +23,7 @@ describe 'FormHelper' do
|
|
23
23
|
end)
|
24
24
|
output_buffer.should have_tag("form.formtastic")
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
it 'adds a "novalidate" attribute to the generated form when configured to do so' do
|
28
28
|
with_config :perform_browser_validations, true do
|
29
29
|
concat(semantic_form_for(@new_post, :url => '/hello') do |builder|
|
@@ -31,7 +31,7 @@ describe 'FormHelper' do
|
|
31
31
|
output_buffer.should_not have_tag("form[@novalidate]")
|
32
32
|
end
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
it 'omits a "novalidate" attribute to the generated form when configured to do so' do
|
36
36
|
with_config :perform_browser_validations, false do
|
37
37
|
concat(semantic_form_for(@new_post, :url => '/hello') do |builder|
|
@@ -62,7 +62,7 @@ describe 'FormHelper' do
|
|
62
62
|
end)
|
63
63
|
output_buffer.should have_tag("form.xyz")
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
it 'omits the leading spaces from the classes in the generated form when the default class is nil' do
|
67
67
|
Formtastic::Helpers::FormHelper.default_form_class = nil
|
68
68
|
concat(semantic_form_for(::Post.new, :as => :post, :url => '/hello') do |builder|
|
@@ -102,6 +102,17 @@ describe 'FormHelper' do
|
|
102
102
|
output_buffer.should have_tag("form.namespaced_post")
|
103
103
|
end
|
104
104
|
|
105
|
+
it 'adds a customized class to the generated form' do
|
106
|
+
Formtastic::Helpers::FormHelper.default_form_model_class_proc = lambda { |model_class_name| "#{model_class_name}_form" }
|
107
|
+
concat(semantic_form_for(@new_post, :url => '/hello') do |builder|
|
108
|
+
end)
|
109
|
+
output_buffer.should have_tag("form.post_form")
|
110
|
+
|
111
|
+
concat(semantic_form_for(:project, :url => '/hello') do |builder|
|
112
|
+
end)
|
113
|
+
output_buffer.should have_tag("form.project_form")
|
114
|
+
end
|
115
|
+
|
105
116
|
describe 'allows :html options' do
|
106
117
|
before(:each) do
|
107
118
|
concat(semantic_form_for(@new_post, :url => '/hello', :html => { :id => "something-special", :class => "something-extra", :multipart => true }) do |builder|
|
@@ -142,7 +153,7 @@ describe 'FormHelper' do
|
|
142
153
|
end
|
143
154
|
end
|
144
155
|
|
145
|
-
describe ActionView::Base.field_error_proc do
|
156
|
+
describe 'ActionView::Base.field_error_proc' do
|
146
157
|
it 'is set to no-op wrapper by default' do
|
147
158
|
semantic_form_for(@new_post, :url => '/hello') do |builder|
|
148
159
|
::ActionView::Base.field_error_proc.call("html", nil).should == "html"
|
@@ -150,21 +161,21 @@ describe 'FormHelper' do
|
|
150
161
|
end
|
151
162
|
|
152
163
|
it 'is set to the configured custom field_error_proc' do
|
153
|
-
field_error_proc =
|
154
|
-
Formtastic::Helpers::FormHelper.
|
164
|
+
field_error_proc = double()
|
165
|
+
Formtastic::Helpers::FormHelper.formtastic_field_error_proc = field_error_proc
|
155
166
|
semantic_form_for(@new_post, :url => '/hello') do |builder|
|
156
167
|
::ActionView::Base.field_error_proc.should == field_error_proc
|
157
168
|
end
|
158
169
|
end
|
159
|
-
|
170
|
+
|
160
171
|
it 'is restored to its original value after the form is rendered' do
|
161
|
-
lambda do
|
162
|
-
Formtastic::Helpers::FormHelper.
|
172
|
+
lambda do
|
173
|
+
Formtastic::Helpers::FormHelper.formtastic_field_error_proc = proc {""}
|
163
174
|
semantic_form_for(@new_post, :url => '/hello') { |builder| }
|
164
175
|
end.should_not change(::ActionView::Base, :field_error_proc)
|
165
176
|
end
|
166
|
-
end
|
167
|
-
|
177
|
+
end
|
178
|
+
|
168
179
|
describe "with :builder option" do
|
169
180
|
it "yields an instance of the given builder" do
|
170
181
|
class MyAwesomeCustomBuilder < Formtastic::FormBuilder
|
@@ -9,9 +9,9 @@ describe 'Formtastic::FormBuilder#input' do
|
|
9
9
|
@output_buffer = ''
|
10
10
|
mock_everything
|
11
11
|
|
12
|
-
@errors =
|
13
|
-
@errors.stub
|
14
|
-
@new_post.stub
|
12
|
+
@errors = double('errors')
|
13
|
+
@errors.stub(:[]).and_return([])
|
14
|
+
@new_post.stub(:errors).and_return(@errors)
|
15
15
|
end
|
16
16
|
|
17
17
|
after do
|
@@ -72,7 +72,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'should set and "optional" class also when there is presence validator' do
|
75
|
-
@new_post.class.should_receive(:validators_on).with(:title).
|
75
|
+
@new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
|
76
76
|
active_model_presence_validator([:title])
|
77
77
|
])
|
78
78
|
concat(semantic_form_for(@new_post) do |builder|
|
@@ -112,20 +112,20 @@ describe 'Formtastic::FormBuilder#input' do
|
|
112
112
|
|
113
113
|
describe 'and an object with :validators_on was given (ActiveModel, Active Resource)' do
|
114
114
|
before do
|
115
|
-
@new_post.stub
|
115
|
+
@new_post.stub(:class).and_return(::PostModel)
|
116
116
|
end
|
117
117
|
|
118
118
|
after do
|
119
|
-
@new_post.stub
|
119
|
+
@new_post.stub(:class).and_return(::Post)
|
120
120
|
end
|
121
121
|
describe 'and validates_presence_of was called for the method' do
|
122
122
|
it 'should be required' do
|
123
123
|
|
124
|
-
@new_post.class.should_receive(:validators_on).with(:title).
|
124
|
+
@new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
|
125
125
|
active_model_presence_validator([:title])
|
126
126
|
])
|
127
127
|
|
128
|
-
@new_post.class.should_receive(:validators_on).with(:body).
|
128
|
+
@new_post.class.should_receive(:validators_on).with(:body).at_least(:once).and_return([
|
129
129
|
active_model_presence_validator([:body], {:if => true})
|
130
130
|
])
|
131
131
|
|
@@ -139,7 +139,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
139
139
|
|
140
140
|
it 'should be required when there is :on => :create option on create' do
|
141
141
|
with_config :required_string, " required yo!" do
|
142
|
-
@new_post.class.should_receive(:validators_on).with(:title).
|
142
|
+
@new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
|
143
143
|
active_model_presence_validator([:title], {:on => :create})
|
144
144
|
])
|
145
145
|
concat(semantic_form_for(@new_post) do |builder|
|
@@ -152,7 +152,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
152
152
|
|
153
153
|
it 'should be required when there is :on => :save option on create' do
|
154
154
|
with_config :required_string, " required yo!" do
|
155
|
-
@new_post.class.should_receive(:validators_on).with(:title).
|
155
|
+
@new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
|
156
156
|
active_model_presence_validator([:title], {:on => :save})
|
157
157
|
])
|
158
158
|
concat(semantic_form_for(@new_post) do |builder|
|
@@ -165,7 +165,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
165
165
|
|
166
166
|
it 'should be required when there is :on => :save option on update' do
|
167
167
|
with_config :required_string, " required yo!" do
|
168
|
-
@fred.class.should_receive(:validators_on).with(:login).
|
168
|
+
@fred.class.should_receive(:validators_on).with(:login).at_least(:once).and_return([
|
169
169
|
active_model_presence_validator([:login], {:on => :save})
|
170
170
|
])
|
171
171
|
concat(semantic_form_for(@fred) do |builder|
|
@@ -177,7 +177,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
177
177
|
end
|
178
178
|
|
179
179
|
it 'should not be required when there is :on => :create option on update' do
|
180
|
-
@fred.class.should_receive(:validators_on).with(:login).
|
180
|
+
@fred.class.should_receive(:validators_on).with(:login).at_least(:once).and_return([
|
181
181
|
active_model_presence_validator([:login], {:on => :create})
|
182
182
|
])
|
183
183
|
concat(semantic_form_for(@fred) do |builder|
|
@@ -188,7 +188,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
188
188
|
end
|
189
189
|
|
190
190
|
it 'should not be required when there is :on => :update option on create' do
|
191
|
-
@new_post.class.should_receive(:validators_on).with(:title).
|
191
|
+
@new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
|
192
192
|
active_model_presence_validator([:title], {:on => :update})
|
193
193
|
])
|
194
194
|
concat(semantic_form_for(@new_post) do |builder|
|
@@ -241,14 +241,14 @@ describe 'Formtastic::FormBuilder#input' do
|
|
241
241
|
|
242
242
|
describe 'and validates_inclusion_of was called for the method' do
|
243
243
|
it 'should be required' do
|
244
|
-
@new_post.class.should_receive(:validators_on).with(:published).
|
244
|
+
@new_post.class.should_receive(:validators_on).with(:published).at_least(:once).and_return([
|
245
245
|
active_model_inclusion_validator([:published], {:in => [false, true]})
|
246
246
|
])
|
247
247
|
should_be_required(:tag => :published, :required => true)
|
248
248
|
end
|
249
249
|
|
250
250
|
it 'should not be required if allow_blank is true' do
|
251
|
-
@new_post.class.should_receive(:validators_on).with(:published).
|
251
|
+
@new_post.class.should_receive(:validators_on).with(:published).at_least(:once).and_return([
|
252
252
|
active_model_inclusion_validator([:published], {:in => [false, true], :allow_blank => true})
|
253
253
|
])
|
254
254
|
should_be_required(:tag => :published, :required => false)
|
@@ -282,13 +282,13 @@ describe 'Formtastic::FormBuilder#input' do
|
|
282
282
|
end
|
283
283
|
|
284
284
|
def add_presence_validator(options)
|
285
|
-
@new_post.class.stub
|
285
|
+
@new_post.class.stub(:validators_on).with(options[:tag]).and_return([
|
286
286
|
active_model_presence_validator([options[:tag]], options[:options])
|
287
287
|
])
|
288
288
|
end
|
289
289
|
|
290
290
|
def add_length_validator(options)
|
291
|
-
@new_post.class.should_receive(:validators_on).with(options[:tag]).
|
291
|
+
@new_post.class.should_receive(:validators_on).with(options[:tag]).at_least(:once) {[
|
292
292
|
active_model_length_validator([options[:tag]], options[:options])
|
293
293
|
]}
|
294
294
|
end
|
@@ -377,32 +377,32 @@ describe 'Formtastic::FormBuilder#input' do
|
|
377
377
|
end
|
378
378
|
|
379
379
|
it 'should default to a string for methods on objects that don\'t respond to "column_for_attribute"' do
|
380
|
-
@new_post.stub
|
381
|
-
@new_post.stub
|
380
|
+
@new_post.stub(:method_without_a_database_column)
|
381
|
+
@new_post.stub(:column_for_attribute).and_return(nil)
|
382
382
|
default_input_type(nil, :method_without_a_database_column).should == :string
|
383
383
|
end
|
384
384
|
|
385
385
|
it 'should default to :password for methods that don\'t have a column in the database but "password" is in the method name' do
|
386
|
-
@new_post.stub
|
387
|
-
@new_post.stub
|
386
|
+
@new_post.stub(:password_method_without_a_database_column)
|
387
|
+
@new_post.stub(:column_for_attribute).and_return(nil)
|
388
388
|
default_input_type(nil, :password_method_without_a_database_column).should == :password
|
389
389
|
end
|
390
390
|
|
391
391
|
it 'should default to :password for methods on objects that don\'t respond to "column_for_attribute" but "password" is in the method name' do
|
392
|
-
@new_post.stub
|
393
|
-
@new_post.stub
|
392
|
+
@new_post.stub(:password_method_without_a_database_column)
|
393
|
+
@new_post.stub(:column_for_attribute).and_return(nil)
|
394
394
|
default_input_type(nil, :password_method_without_a_database_column).should == :password
|
395
395
|
end
|
396
396
|
|
397
397
|
it 'should default to :number for "integer" column with name ending in "_id"' do
|
398
|
-
@new_post.stub
|
399
|
-
@new_post.stub
|
398
|
+
@new_post.stub(:aws_instance_id)
|
399
|
+
@new_post.stub(:column_for_attribute).with(:aws_instance_id).and_return(double('column', :type => :integer))
|
400
400
|
default_input_type(:integer, :aws_instance_id).should == :number
|
401
401
|
end
|
402
402
|
|
403
403
|
it 'should default to :select for associations' do
|
404
|
-
@new_post.class.stub
|
405
|
-
@new_post.class.stub
|
404
|
+
@new_post.class.stub(:reflect_on_association).with(:user_id).and_return(double('ActiveRecord::Reflection::AssociationReflection'))
|
405
|
+
@new_post.class.stub(:reflect_on_association).with(:section_id).and_return(double('ActiveRecord::Reflection::AssociationReflection'))
|
406
406
|
default_input_type(:integer, :user_id).should == :select
|
407
407
|
default_input_type(:integer, :section_id).should == :select
|
408
408
|
end
|
@@ -473,11 +473,11 @@ describe 'Formtastic::FormBuilder#input' do
|
|
473
473
|
describe 'defaulting to file column' do
|
474
474
|
Formtastic::FormBuilder.file_methods.each do |method|
|
475
475
|
it "should default to :file for attributes that respond to ##{method}" do
|
476
|
-
column =
|
476
|
+
column = double('column')
|
477
477
|
|
478
478
|
Formtastic::FormBuilder.file_methods.each do |test|
|
479
479
|
### TODO: Check if this is ok
|
480
|
-
column.stub
|
480
|
+
column.stub(method).with(test).and_return(method == test)
|
481
481
|
end
|
482
482
|
|
483
483
|
@new_post.should_receive(method).and_return(column)
|
@@ -493,10 +493,10 @@ describe 'Formtastic::FormBuilder#input' do
|
|
493
493
|
|
494
494
|
it 'should call the corresponding input class with .to_html' do
|
495
495
|
[:select, :time_zone, :radio, :date_select, :datetime_select, :time_select, :boolean, :check_boxes, :hidden, :string, :password, :number, :text, :file].each do |input_style|
|
496
|
-
@new_post.stub
|
497
|
-
@new_post.stub
|
496
|
+
@new_post.stub(:generic_column_name)
|
497
|
+
@new_post.stub(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
|
498
498
|
semantic_form_for(@new_post) do |builder|
|
499
|
-
input_instance =
|
499
|
+
input_instance = double('Input instance')
|
500
500
|
input_class = "#{input_style.to_s}_input".classify
|
501
501
|
input_constant = "Formtastic::Inputs::#{input_class}".constantize
|
502
502
|
|
@@ -542,7 +542,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
542
542
|
it 'should render a label with localized text and not apply the label_str_method' do
|
543
543
|
with_config :label_str_method, :reverse do
|
544
544
|
@localized_label_text = 'Localized title'
|
545
|
-
@new_post.stub
|
545
|
+
@new_post.stub(:meta_description)
|
546
546
|
::I18n.backend.store_translations :en,
|
547
547
|
:formtastic => {
|
548
548
|
:labels => {
|
@@ -575,7 +575,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
575
575
|
|
576
576
|
describe 'and object is given' do
|
577
577
|
it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
|
578
|
-
@new_post.stub
|
578
|
+
@new_post.stub(:meta_description) # a two word method name
|
579
579
|
@new_post.class.should_receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
|
580
580
|
|
581
581
|
concat(semantic_form_for(@new_post) do |builder|
|
@@ -588,7 +588,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
588
588
|
describe 'and object is given with label_str_method set to :capitalize' do
|
589
589
|
it 'should capitalize method name, passing it down to the label tag' do
|
590
590
|
with_config :label_str_method, :capitalize do
|
591
|
-
@new_post.stub
|
591
|
+
@new_post.stub(:meta_description)
|
592
592
|
|
593
593
|
concat(semantic_form_for(@new_post) do |builder|
|
594
594
|
concat(builder.input(:meta_description))
|
@@ -838,15 +838,15 @@ describe 'Formtastic::FormBuilder#input' do
|
|
838
838
|
describe ':collection option' do
|
839
839
|
|
840
840
|
it "should be required on polymorphic associations" do
|
841
|
-
@new_post.stub
|
842
|
-
@new_post.class.stub
|
843
|
-
:commentable =>
|
841
|
+
@new_post.stub(:commentable)
|
842
|
+
@new_post.class.stub(:reflections).and_return({
|
843
|
+
:commentable => double('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
|
844
844
|
})
|
845
|
-
@new_post.stub
|
846
|
-
|
845
|
+
@new_post.stub(:column_for_attribute).with(:commentable).and_return(
|
846
|
+
double('column', :type => :integer)
|
847
847
|
)
|
848
|
-
@new_post.class.stub
|
849
|
-
|
848
|
+
@new_post.class.stub(:reflect_on_association).with(:commentable).and_return(
|
849
|
+
double('reflection', :macro => :belongs_to, :options => { :polymorphic => true })
|
850
850
|
)
|
851
851
|
expect {
|
852
852
|
concat(semantic_form_for(@new_post) do |builder|
|
@@ -892,7 +892,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
892
892
|
context 'when a customized top-level class does not exist' do
|
893
893
|
|
894
894
|
it 'should instantiate the Formtastic input' do
|
895
|
-
input =
|
895
|
+
input = double('input', :to_html => 'some HTML')
|
896
896
|
Formtastic::Inputs::StringInput.should_receive(:new).and_return(input)
|
897
897
|
concat(semantic_form_for(@new_post) do |builder|
|
898
898
|
builder.input(:title, :as => :string)
|
@@ -906,7 +906,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
906
906
|
class ::StringInput < Formtastic::Inputs::StringInput
|
907
907
|
end
|
908
908
|
|
909
|
-
input =
|
909
|
+
input = double('input', :to_html => 'some HTML')
|
910
910
|
Formtastic::Inputs::StringInput.should_not_receive(:new)
|
911
911
|
::StringInput.should_receive(:new).and_return(input)
|
912
912
|
|