sensis-formtastic-rails3 1.d4e5326

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.textile +584 -0
  3. data/Rakefile +127 -0
  4. data/generators/form/USAGE +16 -0
  5. data/generators/form/form_generator.rb +120 -0
  6. data/generators/form/templates/view__form.html.erb +5 -0
  7. data/generators/form/templates/view__form.html.haml +4 -0
  8. data/generators/formtastic/formtastic_generator.rb +24 -0
  9. data/generators/formtastic/templates/formtastic.css +131 -0
  10. data/generators/formtastic/templates/formtastic.rb +54 -0
  11. data/generators/formtastic/templates/formtastic_changes.css +14 -0
  12. data/generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb +16 -0
  13. data/init.rb +5 -0
  14. data/lib/formtastic.rb +1870 -0
  15. data/lib/formtastic/i18n.rb +35 -0
  16. data/lib/formtastic/layout_helper.rb +10 -0
  17. data/lib/formtastic/railtie.rb +12 -0
  18. data/lib/formtastic/util.rb +36 -0
  19. data/lib/generators/formtastic/form/form_generator.rb +86 -0
  20. data/lib/generators/formtastic/install/install_generator.rb +24 -0
  21. data/lib/locale/en.yml +8 -0
  22. data/rails/init.rb +2 -0
  23. data/spec/buttons_spec.rb +166 -0
  24. data/spec/commit_button_spec.rb +401 -0
  25. data/spec/custom_builder_spec.rb +98 -0
  26. data/spec/defaults_spec.rb +20 -0
  27. data/spec/error_proc_spec.rb +27 -0
  28. data/spec/errors_spec.rb +105 -0
  29. data/spec/form_helper_spec.rb +142 -0
  30. data/spec/helpers/layout_helper_spec.rb +21 -0
  31. data/spec/i18n_spec.rb +152 -0
  32. data/spec/include_blank_spec.rb +74 -0
  33. data/spec/input_spec.rb +786 -0
  34. data/spec/inputs/boolean_input_spec.rb +104 -0
  35. data/spec/inputs/check_boxes_input_spec.rb +426 -0
  36. data/spec/inputs/country_input_spec.rb +118 -0
  37. data/spec/inputs/date_input_spec.rb +168 -0
  38. data/spec/inputs/datetime_input_spec.rb +310 -0
  39. data/spec/inputs/file_input_spec.rb +34 -0
  40. data/spec/inputs/hidden_input_spec.rb +78 -0
  41. data/spec/inputs/numeric_input_spec.rb +44 -0
  42. data/spec/inputs/password_input_spec.rb +46 -0
  43. data/spec/inputs/radio_input_spec.rb +243 -0
  44. data/spec/inputs/select_input_spec.rb +546 -0
  45. data/spec/inputs/string_input_spec.rb +64 -0
  46. data/spec/inputs/text_input_spec.rb +34 -0
  47. data/spec/inputs/time_input_spec.rb +206 -0
  48. data/spec/inputs/time_zone_input_spec.rb +110 -0
  49. data/spec/inputs_spec.rb +476 -0
  50. data/spec/label_spec.rb +89 -0
  51. data/spec/semantic_errors_spec.rb +98 -0
  52. data/spec/semantic_fields_for_spec.rb +45 -0
  53. data/spec/spec.opts +2 -0
  54. data/spec/spec_helper.rb +289 -0
  55. data/spec/support/custom_macros.rb +494 -0
  56. data/spec/support/output_buffer.rb +4 -0
  57. data/spec/support/test_environment.rb +45 -0
  58. metadata +234 -0
@@ -0,0 +1,64 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'string input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ describe "when object is provided" do
14
+ before do
15
+ @form = semantic_form_for(@new_post) do |builder|
16
+ concat(builder.input(:title, :as => :string))
17
+ end
18
+ end
19
+
20
+ it_should_have_input_wrapper_with_class(:string)
21
+ it_should_have_input_wrapper_with_id("post_title_input")
22
+ it_should_have_label_with_text(/Title/)
23
+ it_should_have_label_for("post_title")
24
+ it_should_have_input_with_id("post_title")
25
+ it_should_have_input_with_type(:text)
26
+ it_should_have_input_with_name("post[title]")
27
+ it_should_have_maxlength_matching_column_limit
28
+ it_should_use_default_text_field_size_for_columns_longer_than_default_text_field_size(:string)
29
+ it_should_use_column_size_for_columns_shorter_than_default_text_field_size(:string)
30
+ it_should_use_default_text_field_size_when_method_has_no_database_column(:string)
31
+ it_should_apply_custom_input_attributes_when_input_html_provided(:string)
32
+ it_should_apply_custom_for_to_label_when_input_html_id_provided(:string)
33
+ it_should_apply_error_logic_for_input_type(:string)
34
+ end
35
+
36
+ describe "when no object is provided" do
37
+ before do
38
+ @form = semantic_form_for(:project, :url => 'http://test.host/') do |builder|
39
+ concat(builder.input(:title, :as => :string))
40
+ end
41
+ end
42
+
43
+ it_should_have_label_with_text(/Title/)
44
+ it_should_have_label_for("project_title")
45
+ it_should_have_input_with_id("project_title")
46
+ it_should_have_input_with_type(:text)
47
+ it_should_have_input_with_name("project[title]")
48
+ end
49
+
50
+ describe "when size is nil" do
51
+ before do
52
+ @form = semantic_form_for(:project, :url => 'http://test.host/') do |builder|
53
+ concat(builder.input(:title, :as => :string, :input_html => {:size => nil}))
54
+ end
55
+ end
56
+
57
+ it "should have no size attribute" do
58
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
59
+ output_buffer.should_not have_tag("input[@size]")
60
+ end
61
+ end
62
+
63
+ end
64
+
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'text input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+
12
+ @form = semantic_form_for(@new_post) do |builder|
13
+ concat(builder.input(:body, :as => :text))
14
+ end
15
+ end
16
+
17
+ it_should_have_input_wrapper_with_class("text")
18
+ it_should_have_input_wrapper_with_id("post_body_input")
19
+ it_should_have_label_with_text(/Body/)
20
+ it_should_have_label_for("post_body")
21
+ it_should_have_textarea_with_id("post_body")
22
+ it_should_have_textarea_with_name("post[body]")
23
+ it_should_apply_error_logic_for_input_type(:numeric)
24
+
25
+ it 'should use input_html to style inputs' do
26
+ form = semantic_form_for(@new_post) do |builder|
27
+ concat(builder.input(:title, :as => :text, :input_html => { :class => 'myclass' }))
28
+ end
29
+ output_buffer.concat(form) if Formtastic::Util.rails3?
30
+ output_buffer.should have_tag("form li textarea.myclass")
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,206 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'time input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ describe "general" do
14
+ before do
15
+ ::I18n.backend.reload!
16
+ output_buffer.replace ''
17
+ end
18
+
19
+ describe "with :ignore_date" do
20
+ before do
21
+ @form = semantic_form_for(@new_post) do |builder|
22
+ concat(builder.input(:publish_at, :as => :time, :ignore_date => true))
23
+ end
24
+ end
25
+
26
+ it 'should not have an input for day, month and year' do
27
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
28
+ output_buffer.should_not have_tag('#post_publish_at_1i')
29
+ output_buffer.should_not have_tag('#post_publish_at_2i')
30
+ output_buffer.should_not have_tag('#post_publish_at_3i')
31
+ end
32
+
33
+ it 'should have an input for hour and minute' do
34
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
35
+ output_buffer.should have_tag('#post_publish_at_4i')
36
+ output_buffer.should have_tag('#post_publish_at_5i')
37
+ end
38
+
39
+ end
40
+
41
+ describe "without seconds" do
42
+ before do
43
+ @form = semantic_form_for(@new_post) do |builder|
44
+ concat(builder.input(:publish_at, :as => :time))
45
+ end
46
+ end
47
+
48
+ it_should_have_input_wrapper_with_class("time")
49
+ it_should_have_input_wrapper_with_id("post_publish_at_input")
50
+ it_should_have_a_nested_fieldset
51
+ it_should_apply_error_logic_for_input_type(:time)
52
+
53
+ it 'should have a legend and label with the label text inside the fieldset' do
54
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
55
+ output_buffer.should have_tag('form li.time fieldset legend.label label', /Publish at/)
56
+ end
57
+
58
+ it 'should associate the legend label with the first select' do
59
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
60
+ output_buffer.should have_tag('form li.time fieldset legend.label label[@for="post_publish_at_1i"]')
61
+ end
62
+
63
+ it 'should have an ordered list of two items inside the fieldset' do
64
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
65
+ output_buffer.should have_tag('form li.time fieldset ol')
66
+ output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
67
+ end
68
+
69
+ it 'should have five labels for hour and minute' do
70
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
71
+ output_buffer.should have_tag('form li.time fieldset ol li label', :count => 2)
72
+ output_buffer.should have_tag('form li.time fieldset ol li label', /hour/i)
73
+ output_buffer.should have_tag('form li.time fieldset ol li label', /minute/i)
74
+ end
75
+
76
+ it 'should have two selects for hour and minute' do
77
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
78
+ output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
79
+ end
80
+ end
81
+
82
+ describe "with seconds" do
83
+ before do
84
+ @form = semantic_form_for(@new_post) do |builder|
85
+ concat(builder.input(:publish_at, :as => :time, :include_seconds => true))
86
+ end
87
+ end
88
+
89
+ it 'should have five labels for hour and minute' do
90
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
91
+ output_buffer.should have_tag('form li.time fieldset ol li label', :count => 3)
92
+ output_buffer.should have_tag('form li.time fieldset ol li label', /hour/i)
93
+ output_buffer.should have_tag('form li.time fieldset ol li label', /minute/i)
94
+ output_buffer.should have_tag('form li.time fieldset ol li label', /second/i)
95
+ end
96
+
97
+ it 'should have three selects for hour, minute and seconds' do
98
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
99
+ output_buffer.should have_tag('form li.time fieldset ol li', :count => 3)
100
+ end
101
+
102
+ it 'should generate a sanitized label and matching ids for attribute' do
103
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
104
+ 4.upto(6) do |i|
105
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_publish_at_#{i}i']")
106
+ output_buffer.should have_tag("form li fieldset ol li #post_publish_at_#{i}i")
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ describe ':selected option' do
113
+
114
+ describe "when the object has a value" do
115
+ it "should select the object value (ignoring :selected)" do
116
+ output_buffer.replace ''
117
+ @new_post.stub!(:created_at => Time.mktime(2012, 11, 30, 21, 45))
118
+ with_deprecation_silenced do
119
+ @form = semantic_form_for(@new_post) do |builder|
120
+ concat(builder.input(:created_at, :as => :time, :selected => Time.mktime(1999, 12, 31, 22, 59)))
121
+ end
122
+ end
123
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
124
+ output_buffer.should have_tag("form li ol li select#post_created_at_4i option[@selected]", :count => 1)
125
+ output_buffer.should have_tag("form li ol li select#post_created_at_4i option[@value='21'][@selected]", :count => 1)
126
+ end
127
+ end
128
+
129
+ describe 'when the object has no value (nil)' do
130
+ it "should select the :selected if provided as a Time" do
131
+ output_buffer.replace ''
132
+ @new_post.stub!(:created_at => nil)
133
+ with_deprecation_silenced do
134
+ @form = semantic_form_for(@new_post) do |builder|
135
+ concat(builder.input(:created_at, :as => :time, :selected => Time.mktime(1999, 12, 31, 22, 59)))
136
+ end
137
+ end
138
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
139
+ output_buffer.should have_tag("form li ol li select#post_created_at_4i option[@selected]", :count => 1)
140
+ output_buffer.should have_tag("form li ol li select#post_created_at_4i option[@value='22'][@selected]", :count => 1)
141
+ end
142
+
143
+ it "should not select an option if the :selected is provided as nil" do
144
+ output_buffer.replace ''
145
+ @new_post.stub!(:created_at => nil)
146
+ with_deprecation_silenced do
147
+ @form = semantic_form_for(@new_post) do |builder|
148
+ concat(builder.input(:created_at, :as => :time, :selected => nil))
149
+ end
150
+ end
151
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
152
+ output_buffer.should_not have_tag("form li ol li select#post_created_at_4i option[@selected]")
153
+ end
154
+
155
+ it "should select nothing if a :selected is not provided" do
156
+ output_buffer.replace ''
157
+ @new_post.stub!(:created_at => nil)
158
+ form = semantic_form_for(@new_post) do |builder|
159
+ concat(builder.input(:created_at, :as => :time))
160
+ end
161
+ output_buffer.concat(form) if Formtastic::Util.rails3?
162
+ output_buffer.should_not have_tag("form li ol li select option[@selected]")
163
+ end
164
+ end
165
+
166
+ end
167
+
168
+ describe ':labels option' do
169
+ fields = [:hour, :minute, :second]
170
+ fields.each do |field|
171
+ it "should replace the #{field} label with the specified text if :labels[:#{field}] is set" do
172
+ output_buffer.replace ''
173
+ form = semantic_form_for(@new_post) do |builder|
174
+ concat(builder.input(:created_at, :as => :time, :include_seconds => true, :labels => { field => "another #{field} label" }))
175
+ end
176
+ output_buffer.concat(form) if Formtastic::Util.rails3?
177
+ output_buffer.should have_tag('form li.time fieldset ol li label', :count => fields.length)
178
+ fields.each do |f|
179
+ output_buffer.should have_tag('form li.time fieldset ol li label', f == field ? /another #{f} label/i : /#{f}/i)
180
+ end
181
+ end
182
+
183
+ it "should not display the label for the #{field} field when :labels[:#{field}] is blank" do
184
+ output_buffer.replace ''
185
+ form = semantic_form_for(@new_post) do |builder|
186
+ concat(builder.input(:created_at, :as => :time, :include_seconds => true, :labels => { field => "" }))
187
+ end
188
+ output_buffer.concat(form) if Formtastic::Util.rails3?
189
+ output_buffer.should have_tag('form li.time fieldset ol li label', :count => fields.length-1)
190
+ fields.each do |f|
191
+ output_buffer.should have_tag('form li.time fieldset ol li label', /#{f}/i) unless field == f
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ it 'should warn about :selected deprecation' do
198
+ with_deprecation_silenced do
199
+ ::ActiveSupport::Deprecation.should_receive(:warn).any_number_of_times
200
+ semantic_form_for(@new_post) do |builder|
201
+ concat(builder.input(:created_at, :as => :time, :selected => Time.mktime(1999)))
202
+ end
203
+ end
204
+ end
205
+
206
+ end
@@ -0,0 +1,110 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'time_zone input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+
12
+ @form = semantic_form_for(@new_post) do |builder|
13
+ concat(builder.input(:time_zone))
14
+ end
15
+ end
16
+
17
+ it_should_have_input_wrapper_with_class("time_zone")
18
+ it_should_have_input_wrapper_with_id("post_time_zone_input")
19
+ it_should_apply_error_logic_for_input_type(:time_zone)
20
+
21
+ it 'should generate a label for the input' do
22
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
23
+ output_buffer.should have_tag('form li label')
24
+ output_buffer.should have_tag('form li label[@for="post_time_zone"]')
25
+ output_buffer.should have_tag('form li label', /Time zone/)
26
+ end
27
+
28
+ it "should generate a select" do
29
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
30
+ output_buffer.should have_tag("form li select")
31
+ output_buffer.should have_tag("form li select#post_time_zone")
32
+ output_buffer.should have_tag("form li select[@name=\"post[time_zone]\"]")
33
+ end
34
+
35
+ it 'should use input_html to style inputs' do
36
+ form = semantic_form_for(@new_post) do |builder|
37
+ concat(builder.input(:time_zone, :input_html => { :class => 'myclass' }))
38
+ end
39
+ output_buffer.concat(form) if Formtastic::Util.rails3?
40
+ output_buffer.should have_tag("form li select.myclass")
41
+ end
42
+
43
+ describe 'when no object is given' do
44
+ before(:each) do
45
+ @form = semantic_form_for(:project, :url => 'http://test.host/') do |builder|
46
+ concat(builder.input(:time_zone, :as => :time_zone))
47
+ end
48
+ end
49
+
50
+ it 'should generate labels' do
51
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
52
+ output_buffer.should have_tag('form li label')
53
+ output_buffer.should have_tag('form li label[@for="project_time_zone"]')
54
+ output_buffer.should have_tag('form li label', /Time zone/)
55
+ end
56
+
57
+ it 'should generate select inputs' do
58
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
59
+ output_buffer.should have_tag("form li select")
60
+ output_buffer.should have_tag("form li select#project_time_zone")
61
+ output_buffer.should have_tag("form li select[@name=\"project[time_zone]\"]")
62
+ end
63
+ end
64
+
65
+ describe 'when :selected is set' do
66
+ before do
67
+ @output_buffer = ''
68
+ end
69
+
70
+ # Note: Not possible to override default selected value for time_zone input
71
+ # without overriding Rails time_zone_select. This Rails helper works "a bit different". =/
72
+ #
73
+ # describe "no selected items" do
74
+ # before do
75
+ # @new_post.stub!(:time_zone).and_return('Stockholm')
76
+ #
77
+ # semantic_form_for(@new_post) do |builder|
78
+ # concat(builder.input(:time_zone, :as => :time_zone, :selected => nil))
79
+ # end
80
+ # end
81
+ #
82
+ # it 'should not have any selected item(s)' do
83
+ # output_buffer.should_not have_tag("form li select option[@selected='selected']")
84
+ # end
85
+ # end
86
+
87
+ describe "single selected item" do
88
+ before do
89
+ # Note: See above...only works for the "attribute is nil" case.
90
+ # @new_post.stub!(:time_zone).and_return('Stockholm')
91
+ @new_post.stub!(:time_zone).and_return(nil)
92
+
93
+ with_deprecation_silenced do
94
+ @form = semantic_form_for(@new_post) do |builder|
95
+ concat(builder.input(:time_zone, :as => :time_zone, :selected => 'Melbourne'))
96
+ end
97
+ end
98
+ end
99
+
100
+ it 'should have a selected item; the specified one' do
101
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
102
+ output_buffer.should have_tag("form li select option[@selected='selected']", :count => 1)
103
+ output_buffer.should have_tag("form li select option[@selected='selected']", /Melbourne/i)
104
+ output_buffer.should have_tag("form li select option[@selected='selected'][@value='Melbourne']")
105
+ end
106
+ end
107
+
108
+ end
109
+
110
+ end
@@ -0,0 +1,476 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'SemanticFormBuilder#inputs' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ describe 'with a block' do
14
+
15
+ describe 'when no options are provided' do
16
+ before do
17
+ output_buffer.replace 'before_builder' # clear the output buffer and sets before_builder
18
+ @form = semantic_form_for(@new_post) do |builder|
19
+ @inputs_output = builder.inputs do
20
+ concat('hello')
21
+ end
22
+ end
23
+ end
24
+
25
+ it 'should output just the content wrapped in inputs, not the whole template' do
26
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
27
+ output_buffer.should =~ /before_builder/
28
+ @inputs_output.should_not =~ /before_builder/
29
+ end
30
+
31
+ it 'should render a fieldset inside the form, with a class of "inputs"' do
32
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
33
+ output_buffer.should have_tag("form fieldset.inputs")
34
+ end
35
+
36
+ it 'should render an ol inside the fieldset' do
37
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
38
+ output_buffer.should have_tag("form fieldset.inputs ol")
39
+ end
40
+
41
+ it 'should render the contents of the block inside the ol' do
42
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
43
+ output_buffer.should have_tag("form fieldset.inputs ol", /hello/)
44
+ end
45
+
46
+ it 'should not render a legend inside the fieldset' do
47
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
48
+ output_buffer.should_not have_tag("form fieldset.inputs legend")
49
+ end
50
+
51
+ it 'should render a fieldset even if no object is given' do
52
+ form = semantic_form_for(:project, :url => 'http://test.host/') do |builder|
53
+ @inputs_output = builder.inputs do
54
+ concat('bye')
55
+ end
56
+ end
57
+
58
+ output_buffer.concat(form) if Formtastic::Util.rails3?
59
+ output_buffer.should have_tag("form fieldset.inputs ol", /bye/)
60
+ end
61
+ end
62
+
63
+ describe 'when a :for option is provided' do
64
+
65
+ before do
66
+ @new_post.stub!(:respond_to?).and_return(true, true)
67
+ @new_post.stub!(:author).and_return(@bob)
68
+ end
69
+
70
+ it 'should render nested inputs' do
71
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
72
+
73
+ form = semantic_form_for(@new_post) do |builder|
74
+ inputs = builder.inputs :for => [:author, @bob] do |bob_builder|
75
+ concat(bob_builder.input(:login))
76
+ end
77
+ concat(inputs)
78
+ end
79
+
80
+ output_buffer.concat(form) if Formtastic::Util.rails3?
81
+ output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
82
+ output_buffer.should_not have_tag("form fieldset.inputs #author_login")
83
+
84
+ end
85
+
86
+ it 'should concat rendered nested inputs to the template under rails3' do
87
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
88
+ ::Formtastic::Util.stub!(:rails3?).and_return(true)
89
+
90
+ form = semantic_form_for(@new_post) do |builder|
91
+ builder.inputs :for => [:author, @bob] do |bob_builder|
92
+ concat(bob_builder.input(:login))
93
+ end
94
+ end
95
+
96
+ output_buffer.concat(form) if Formtastic::Util.rails3?
97
+ output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
98
+ output_buffer.should_not have_tag("form fieldset.inputs #author_login")
99
+
100
+ end
101
+
102
+ describe "as a symbol representing the association name" do
103
+
104
+ it 'should nest the inputs with an _attributes suffix on the association name' do
105
+ form = semantic_form_for(@new_post) do |post|
106
+ inputs = post.inputs :for => :author do |author|
107
+ concat(author.input(:login))
108
+ end
109
+ concat(inputs)
110
+ end
111
+ output_buffer.concat(form) if Formtastic::Util.rails3?
112
+ output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
113
+ end
114
+
115
+ end
116
+
117
+ describe "as a symbol representing a has_many association name" do
118
+ before do
119
+ @new_post.stub!(:authors).and_return([@bob, @fred])
120
+ @new_post.stub!(:authors_attributes=)
121
+ end
122
+
123
+ it 'should nest the inputs with a name input for each item' do
124
+ form = semantic_form_for(@new_post) do |post|
125
+ post.inputs :for => :authors do |author|
126
+ concat(author.input(:login))
127
+ end
128
+ end
129
+
130
+ output_buffer.concat(form) if Formtastic::Util.rails3?
131
+ output_buffer.should have_tag("form input[@name='post[authors_attributes][0][login]']")
132
+ output_buffer.should have_tag("form input[@name='post[authors_attributes][1][login]']")
133
+ end
134
+ end
135
+
136
+ describe 'as an array containing the a symbole for the association name and the associated object' do
137
+
138
+ it 'should nest the inputs with an _attributes suffix on the association name' do
139
+ form = semantic_form_for(@new_post) do |post|
140
+ inputs = post.inputs :for => [:author, @new_post.author] do |author|
141
+ concat(author.input(:login))
142
+ end
143
+ concat(inputs)
144
+ end
145
+ output_buffer.concat(form) if Formtastic::Util.rails3?
146
+ output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
147
+ end
148
+
149
+ end
150
+
151
+ describe 'as an associated object' do
152
+
153
+ it 'should not nest the inputs with an _attributes suffix' do
154
+ form = semantic_form_for(@new_post) do |post|
155
+ inputs = post.inputs :for => @new_post.author do |author|
156
+ concat(author.input(:login))
157
+ end
158
+ concat(inputs)
159
+ end
160
+ output_buffer.concat(form) if Formtastic::Util.rails3?
161
+ output_buffer.should have_tag("form input[@name='post[author][login]']")
162
+ end
163
+
164
+ end
165
+
166
+ it 'should raise an error if :for and block with no argument is given' do
167
+ semantic_form_for(@new_post) do |builder|
168
+ proc {
169
+ builder.inputs(:for => [:author, @bob]) do
170
+ #
171
+ end
172
+ }.should raise_error(ArgumentError, 'You gave :for option with a block to inputs method, ' <<
173
+ 'but the block does not accept any argument.')
174
+ end
175
+ end
176
+
177
+ it 'should pass options down to semantic_fields_for' do
178
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
179
+
180
+ form = semantic_form_for(@new_post) do |builder|
181
+ inputs = builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
182
+ concat(bob_builder.input(:login))
183
+ end
184
+ concat(inputs)
185
+ end
186
+
187
+ output_buffer.concat(form) if Formtastic::Util.rails3?
188
+ output_buffer.should have_tag('form fieldset ol li #post_author_attributes_10_login')
189
+ end
190
+
191
+ it 'should not add builder as a fieldset attribute tag' do
192
+ form = semantic_form_for(@new_post) do |builder|
193
+ inputs = builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
194
+ concat('input')
195
+ end
196
+ concat(inputs)
197
+ end
198
+
199
+ output_buffer.concat(form) if Formtastic::Util.rails3?
200
+ output_buffer.should_not have_tag('fieldset[@builder="Formtastic::SemanticFormHelper"]')
201
+ end
202
+
203
+ it 'should send parent_builder as an option to allow child index interpolation' do
204
+ form = semantic_form_for(@new_post) do |builder|
205
+ builder.instance_variable_set('@nested_child_index', 0)
206
+ inputs = builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
207
+ concat('input')
208
+ end
209
+ concat(inputs)
210
+ end
211
+
212
+ output_buffer.concat(form) if Formtastic::Util.rails3?
213
+ output_buffer.should have_tag('fieldset legend', 'Author #1')
214
+ end
215
+
216
+ it 'should also provide child index interpolation when nested child index is a hash' do
217
+ form = semantic_form_for(@new_post) do |builder|
218
+ builder.instance_variable_set('@nested_child_index', :author => 10)
219
+ inputs = builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
220
+ concat('input')
221
+ end
222
+ concat(inputs)
223
+ end
224
+
225
+ output_buffer.concat(form) if Formtastic::Util.rails3?
226
+ output_buffer.should have_tag('fieldset legend', 'Author #11')
227
+ end
228
+ end
229
+
230
+ describe 'when a :name or :title option is provided' do
231
+ describe 'and is a string' do
232
+ before do
233
+ @legend_text = "Advanced options"
234
+ @legend_text_using_name = "Advanced options 2"
235
+ @legend_text_using_title = "Advanced options 3"
236
+ @nested_forms_legend_text = "This is a nested form title"
237
+ @form = semantic_form_for(@new_post) do |builder|
238
+ inputs = builder.inputs @legend_text do
239
+ end
240
+ concat(inputs)
241
+ inputs = builder.inputs :name => @legend_text_using_name do
242
+ end
243
+ concat(inputs)
244
+ inputs = builder.inputs :title => @legend_text_using_title do
245
+ end
246
+ concat(inputs)
247
+ inputs = builder.inputs @nested_forms_legend_text, :for => :authors do |nf|
248
+ end
249
+ concat(inputs)
250
+ end
251
+ end
252
+
253
+ it 'should render a fieldset with a legend inside the form' do
254
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
255
+ output_buffer.should have_tag("form fieldset legend", /^#{@legend_text}$/)
256
+ output_buffer.should have_tag("form fieldset legend", /^#{@legend_text_using_name}$/)
257
+ output_buffer.should have_tag("form fieldset legend", /^#{@legend_text_using_title}$/)
258
+ output_buffer.should have_tag("form fieldset legend", /^#{@nested_forms_legend_text}$/)
259
+ end
260
+ end
261
+
262
+ describe 'and is a symbol' do
263
+ before do
264
+ @localized_legend_text = "Localized advanced options"
265
+ @localized_legend_text_using_name = "Localized advanced options 2"
266
+ @localized_legend_text_using_title = "Localized advanced options 3"
267
+ @localized_nested_forms_legend_text = "This is a localized nested form title"
268
+ ::I18n.backend.store_translations :en, :formtastic => {
269
+ :titles => {
270
+ :post => {
271
+ :advanced_options => @localized_legend_text,
272
+ :advanced_options_using_name => @localized_legend_text_using_name,
273
+ :advanced_options_using_title => @localized_legend_text_using_title,
274
+ :nested_forms_title => @localized_nested_forms_legend_text
275
+ }
276
+ }
277
+ }
278
+ @form = semantic_form_for(@new_post) do |builder|
279
+ inputs = builder.inputs :advanced_options do
280
+ end
281
+ concat(inputs)
282
+ inputs =builder.inputs :name => :advanced_options_using_name do
283
+ end
284
+ concat(inputs)
285
+ inputs = builder.inputs :title => :advanced_options_using_title do
286
+ end
287
+ concat(inputs)
288
+ inputs = builder.inputs :nested_forms_title, :for => :authors do |nf|
289
+ end
290
+ concat(inputs)
291
+ end
292
+ end
293
+
294
+ it 'should render a fieldset with a localized legend inside the form' do
295
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
296
+ output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text}$/)
297
+ output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text_using_name}$/)
298
+ output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text_using_title}$/)
299
+ output_buffer.should have_tag("form fieldset legend", /^#{@localized_nested_forms_legend_text}$/)
300
+ end
301
+ end
302
+ end
303
+
304
+ describe 'when other options are provided' do
305
+ before do
306
+ @id_option = 'advanced'
307
+ @class_option = 'wide'
308
+
309
+ @form = semantic_form_for(@new_post) do |builder|
310
+ builder.inputs :id => @id_option, :class => @class_option do
311
+ end
312
+ end
313
+ end
314
+
315
+ it 'should pass the options into the fieldset tag as attributes' do
316
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
317
+ output_buffer.should have_tag("form fieldset##{@id_option}")
318
+ output_buffer.should have_tag("form fieldset.#{@class_option}")
319
+ end
320
+ end
321
+
322
+ end
323
+
324
+ describe 'without a block' do
325
+
326
+ before do
327
+ ::Post.stub!(:reflections).and_return({:author => mock('reflection', :options => {}, :macro => :belongs_to),
328
+ :comments => mock('reflection', :options => {}, :macro => :has_many) })
329
+ ::Author.stub!(:find).and_return([@fred, @bob])
330
+
331
+ @new_post.stub!(:title)
332
+ @new_post.stub!(:body)
333
+ @new_post.stub!(:author_id)
334
+
335
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
336
+ @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
337
+ @new_post.stub!(:column_for_attribute).with(:created_at).and_return(mock('column', :type => :datetime))
338
+ @new_post.stub!(:column_for_attribute).with(:author).and_return(nil)
339
+ end
340
+
341
+ describe 'with no args' do
342
+ before do
343
+ @form = semantic_form_for(@new_post) do |builder|
344
+ concat(builder.inputs)
345
+ end
346
+ end
347
+
348
+ it 'should render a form' do
349
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
350
+ output_buffer.should have_tag('form')
351
+ end
352
+
353
+ it 'should render a fieldset inside the form' do
354
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
355
+ output_buffer.should have_tag('form > fieldset.inputs')
356
+ end
357
+
358
+ it 'should not render a legend in the fieldset' do
359
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
360
+ output_buffer.should_not have_tag('form > fieldset.inputs > legend')
361
+ end
362
+
363
+ it 'should render an ol in the fieldset' do
364
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
365
+ output_buffer.should have_tag('form > fieldset.inputs > ol')
366
+ end
367
+
368
+ it 'should render a list item in the ol for each column and reflection' do
369
+ # Remove the :has_many macro and :created_at column
370
+ count = ::Post.content_columns.size + ::Post.reflections.size - 2
371
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
372
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => count)
373
+ end
374
+
375
+ it 'should render a string list item for title' do
376
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
377
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
378
+ end
379
+
380
+ it 'should render a text list item for body' do
381
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
382
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
383
+ end
384
+
385
+ it 'should render a select list item for author_id' do
386
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
387
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.select', :count => 1)
388
+ end
389
+
390
+ it 'should not render timestamps inputs by default' do
391
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
392
+ output_buffer.should_not have_tag('form > fieldset.inputs > ol > li.datetime')
393
+ end
394
+ end
395
+
396
+ describe 'with column names as args' do
397
+ describe 'and an object is given' do
398
+ it 'should render a form with a fieldset containing two list items' do
399
+ form = semantic_form_for(@new_post) do |builder|
400
+ concat(builder.inputs(:title, :body))
401
+ end
402
+
403
+ output_buffer.concat(form) if Formtastic::Util.rails3?
404
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
405
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
406
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
407
+ end
408
+ end
409
+
410
+ describe 'and no object is given' do
411
+ it 'should render a form with a fieldset containing two list items' do
412
+ form = semantic_form_for(:project, :url => 'http://test.host') do |builder|
413
+ concat(builder.inputs(:title, :body))
414
+ end
415
+
416
+ output_buffer.concat(form) if Formtastic::Util.rails3?
417
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.string', :count => 2)
418
+ end
419
+ end
420
+ end
421
+
422
+ describe 'when a :for option is provided' do
423
+ describe 'and an object is given' do
424
+ it 'should render nested inputs' do
425
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
426
+ form = semantic_form_for(@new_post) do |builder|
427
+ concat(builder.inputs(:login, :for => @bob))
428
+ end
429
+
430
+ output_buffer.concat(form) if Formtastic::Util.rails3?
431
+ output_buffer.should have_tag("form fieldset.inputs #post_author_login")
432
+ output_buffer.should_not have_tag("form fieldset.inputs #author_login")
433
+ end
434
+ end
435
+
436
+ describe 'and no object is given' do
437
+ it 'should render nested inputs' do
438
+ form = semantic_form_for(:project, :url => 'http://test.host/') do |builder|
439
+ concat(builder.inputs(:login, :for => @bob))
440
+ end
441
+ output_buffer.concat(form) if Formtastic::Util.rails3?
442
+ output_buffer.should have_tag("form fieldset.inputs #project_author_login")
443
+ output_buffer.should_not have_tag("form fieldset.inputs #project_login")
444
+ end
445
+ end
446
+ end
447
+
448
+ describe 'with column names and an options hash as args' do
449
+ before do
450
+ @form = semantic_form_for(@new_post) do |builder|
451
+ @legend_text_using_option = "Legendary Legend Text"
452
+ @legend_text_using_arg = "Legendary Legend Text 2"
453
+ concat(builder.inputs(:title, :body, :name => @legend_text_using_option, :id => "my-id"))
454
+ concat(builder.inputs(@legend_text_using_arg, :title, :body, :id => "my-id-2"))
455
+ end
456
+ end
457
+
458
+ it 'should render a form with a fieldset containing two list items' do
459
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
460
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 4)
461
+ end
462
+
463
+ it 'should pass the options down to the fieldset' do
464
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
465
+ output_buffer.should have_tag('form > fieldset#my-id.inputs')
466
+ end
467
+
468
+ it 'should use the special :name option as a text for the legend tag' do
469
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
470
+ output_buffer.should have_tag('form > fieldset#my-id.inputs > legend', /^#{@legend_text_using_option}$/)
471
+ output_buffer.should have_tag('form > fieldset#my-id-2.inputs > legend', /^#{@legend_text_using_arg}$/)
472
+ end
473
+ end
474
+
475
+ end
476
+ end