formtastic 1.2.4 → 3.1.5

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.
Files changed (189) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +46 -0
  5. data/.yardopts +1 -0
  6. data/Appraisals +43 -0
  7. data/CHANGELOG +54 -0
  8. data/DEPRECATIONS +52 -0
  9. data/Gemfile +3 -0
  10. data/README.md +629 -0
  11. data/RELEASE_PROCESS +6 -0
  12. data/Rakefile +35 -0
  13. data/app/assets/stylesheets/formtastic.css +289 -0
  14. data/app/assets/stylesheets/formtastic_ie6.css +33 -0
  15. data/app/assets/stylesheets/formtastic_ie7.css +23 -0
  16. data/formtastic.gemspec +42 -0
  17. data/gemfiles/rails_3.2.gemfile +9 -0
  18. data/gemfiles/rails_4.0.4.gemfile +8 -0
  19. data/gemfiles/rails_4.1.gemfile +8 -0
  20. data/gemfiles/rails_4.2.gemfile +8 -0
  21. data/gemfiles/rails_4.gemfile +8 -0
  22. data/gemfiles/rails_5.0.gemfile +8 -0
  23. data/gemfiles/rails_edge.gemfile +15 -0
  24. data/lib/formtastic.rb +40 -1945
  25. data/lib/formtastic/action_class_finder.rb +18 -0
  26. data/lib/formtastic/actions.rb +11 -0
  27. data/lib/formtastic/actions/base.rb +156 -0
  28. data/lib/formtastic/actions/button_action.rb +67 -0
  29. data/lib/formtastic/actions/buttonish.rb +17 -0
  30. data/lib/formtastic/actions/input_action.rb +70 -0
  31. data/lib/formtastic/actions/link_action.rb +88 -0
  32. data/lib/formtastic/deprecation.rb +42 -0
  33. data/lib/formtastic/engine.rb +11 -0
  34. data/lib/formtastic/form_builder.rb +124 -0
  35. data/lib/formtastic/helpers.rb +16 -0
  36. data/lib/formtastic/helpers/action_helper.rb +162 -0
  37. data/lib/formtastic/helpers/actions_helper.rb +168 -0
  38. data/lib/formtastic/helpers/enum.rb +13 -0
  39. data/lib/formtastic/helpers/errors_helper.rb +81 -0
  40. data/lib/formtastic/helpers/fieldset_wrapper.rb +80 -0
  41. data/lib/formtastic/helpers/file_column_detection.rb +16 -0
  42. data/lib/formtastic/helpers/form_helper.rb +203 -0
  43. data/lib/formtastic/helpers/input_helper.rb +407 -0
  44. data/lib/formtastic/helpers/inputs_helper.rb +411 -0
  45. data/lib/formtastic/helpers/reflection.rb +37 -0
  46. data/lib/formtastic/html_attributes.rb +32 -0
  47. data/lib/formtastic/i18n.rb +4 -2
  48. data/lib/formtastic/input_class_finder.rb +18 -0
  49. data/lib/formtastic/inputs.rb +39 -0
  50. data/lib/formtastic/inputs/base.rb +76 -0
  51. data/lib/formtastic/inputs/base/associations.rb +31 -0
  52. data/lib/formtastic/inputs/base/choices.rb +108 -0
  53. data/lib/formtastic/inputs/base/collections.rb +159 -0
  54. data/lib/formtastic/inputs/base/database.rb +22 -0
  55. data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
  56. data/lib/formtastic/inputs/base/errors.rb +58 -0
  57. data/lib/formtastic/inputs/base/fileish.rb +23 -0
  58. data/lib/formtastic/inputs/base/hints.rb +31 -0
  59. data/lib/formtastic/inputs/base/html.rb +53 -0
  60. data/lib/formtastic/inputs/base/labelling.rb +52 -0
  61. data/lib/formtastic/inputs/base/naming.rb +42 -0
  62. data/lib/formtastic/inputs/base/numeric.rb +50 -0
  63. data/lib/formtastic/inputs/base/options.rb +17 -0
  64. data/lib/formtastic/inputs/base/placeholder.rb +17 -0
  65. data/lib/formtastic/inputs/base/stringish.rb +38 -0
  66. data/lib/formtastic/inputs/base/timeish.rb +241 -0
  67. data/lib/formtastic/inputs/base/validations.rb +215 -0
  68. data/lib/formtastic/inputs/base/wrapping.rb +50 -0
  69. data/lib/formtastic/inputs/boolean_input.rb +118 -0
  70. data/lib/formtastic/inputs/check_boxes_input.rb +197 -0
  71. data/lib/formtastic/inputs/color_input.rb +42 -0
  72. data/lib/formtastic/inputs/country_input.rb +86 -0
  73. data/lib/formtastic/inputs/datalist_input.rb +41 -0
  74. data/lib/formtastic/inputs/date_picker_input.rb +93 -0
  75. data/lib/formtastic/inputs/date_select_input.rb +34 -0
  76. data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
  77. data/lib/formtastic/inputs/datetime_select_input.rb +12 -0
  78. data/lib/formtastic/inputs/email_input.rb +41 -0
  79. data/lib/formtastic/inputs/file_input.rb +42 -0
  80. data/lib/formtastic/inputs/hidden_input.rb +62 -0
  81. data/lib/formtastic/inputs/number_input.rb +88 -0
  82. data/lib/formtastic/inputs/password_input.rb +41 -0
  83. data/lib/formtastic/inputs/phone_input.rb +42 -0
  84. data/lib/formtastic/inputs/radio_input.rb +163 -0
  85. data/lib/formtastic/inputs/range_input.rb +95 -0
  86. data/lib/formtastic/inputs/search_input.rb +41 -0
  87. data/lib/formtastic/inputs/select_input.rb +235 -0
  88. data/lib/formtastic/inputs/string_input.rb +36 -0
  89. data/lib/formtastic/inputs/text_input.rb +48 -0
  90. data/lib/formtastic/inputs/time_picker_input.rb +99 -0
  91. data/lib/formtastic/inputs/time_select_input.rb +38 -0
  92. data/lib/formtastic/inputs/time_zone_input.rb +58 -0
  93. data/lib/formtastic/inputs/url_input.rb +41 -0
  94. data/lib/formtastic/localized_string.rb +17 -0
  95. data/lib/formtastic/localizer.rb +152 -0
  96. data/lib/formtastic/namespaced_class_finder.rb +99 -0
  97. data/lib/formtastic/util.rb +35 -16
  98. data/lib/formtastic/version.rb +3 -0
  99. data/lib/generators/formtastic/form/form_generator.rb +64 -37
  100. data/lib/generators/formtastic/input/input_generator.rb +46 -0
  101. data/lib/generators/formtastic/install/install_generator.rb +13 -5
  102. data/lib/generators/templates/_form.html.erb +10 -4
  103. data/lib/generators/templates/_form.html.haml +8 -4
  104. data/lib/generators/templates/_form.html.slim +8 -0
  105. data/lib/generators/templates/formtastic.rb +77 -44
  106. data/lib/generators/templates/input.rb +19 -0
  107. data/lib/locale/en.yml +3 -0
  108. data/sample/basic_inputs.html +224 -0
  109. data/sample/config.ru +69 -0
  110. data/sample/index.html +14 -0
  111. data/spec/action_class_finder_spec.rb +12 -0
  112. data/spec/actions/button_action_spec.rb +63 -0
  113. data/spec/actions/generic_action_spec.rb +521 -0
  114. data/spec/actions/input_action_spec.rb +59 -0
  115. data/spec/actions/link_action_spec.rb +92 -0
  116. data/spec/builder/custom_builder_spec.rb +116 -0
  117. data/spec/builder/error_proc_spec.rb +27 -0
  118. data/spec/builder/semantic_fields_for_spec.rb +142 -0
  119. data/spec/fast_spec_helper.rb +12 -0
  120. data/spec/generators/formtastic/form/form_generator_spec.rb +131 -0
  121. data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
  122. data/spec/generators/formtastic/install/install_generator_spec.rb +47 -0
  123. data/spec/helpers/action_helper_spec.rb +19 -0
  124. data/spec/helpers/actions_helper_spec.rb +143 -0
  125. data/spec/helpers/form_helper_spec.rb +218 -0
  126. data/spec/helpers/input_helper_spec.rb +6 -0
  127. data/spec/helpers/inputs_helper_spec.rb +655 -0
  128. data/spec/helpers/namespaced_action_helper_spec.rb +43 -0
  129. data/spec/helpers/namespaced_input_helper_spec.rb +36 -0
  130. data/spec/helpers/reflection_helper_spec.rb +32 -0
  131. data/spec/helpers/semantic_errors_helper_spec.rb +112 -0
  132. data/spec/i18n_spec.rb +210 -0
  133. data/spec/input_class_finder_spec.rb +10 -0
  134. data/spec/inputs/base/collections_spec.rb +76 -0
  135. data/spec/inputs/base/validations_spec.rb +342 -0
  136. data/spec/inputs/boolean_input_spec.rb +254 -0
  137. data/spec/inputs/check_boxes_input_spec.rb +546 -0
  138. data/spec/inputs/color_input_spec.rb +97 -0
  139. data/spec/inputs/country_input_spec.rb +133 -0
  140. data/spec/inputs/custom_input_spec.rb +55 -0
  141. data/spec/inputs/datalist_input_spec.rb +61 -0
  142. data/spec/inputs/date_picker_input_spec.rb +449 -0
  143. data/spec/inputs/date_select_input_spec.rb +235 -0
  144. data/spec/inputs/datetime_picker_input_spec.rb +490 -0
  145. data/spec/inputs/datetime_select_input_spec.rb +193 -0
  146. data/spec/inputs/email_input_spec.rb +85 -0
  147. data/spec/inputs/file_input_spec.rb +89 -0
  148. data/spec/inputs/hidden_input_spec.rb +135 -0
  149. data/spec/inputs/include_blank_spec.rb +78 -0
  150. data/spec/inputs/label_spec.rb +149 -0
  151. data/spec/inputs/number_input_spec.rb +815 -0
  152. data/spec/inputs/password_input_spec.rb +99 -0
  153. data/spec/inputs/phone_input_spec.rb +85 -0
  154. data/spec/inputs/placeholder_spec.rb +71 -0
  155. data/spec/inputs/radio_input_spec.rb +328 -0
  156. data/spec/inputs/range_input_spec.rb +505 -0
  157. data/spec/inputs/readonly_spec.rb +50 -0
  158. data/spec/inputs/search_input_spec.rb +84 -0
  159. data/spec/inputs/select_input_spec.rb +615 -0
  160. data/spec/inputs/string_input_spec.rb +260 -0
  161. data/spec/inputs/text_input_spec.rb +187 -0
  162. data/spec/inputs/time_picker_input_spec.rb +455 -0
  163. data/spec/inputs/time_select_input_spec.rb +248 -0
  164. data/spec/inputs/time_zone_input_spec.rb +143 -0
  165. data/spec/inputs/url_input_spec.rb +85 -0
  166. data/spec/inputs/with_options_spec.rb +43 -0
  167. data/spec/localizer_spec.rb +130 -0
  168. data/spec/namespaced_class_finder_spec.rb +79 -0
  169. data/spec/spec.opts +2 -0
  170. data/spec/spec_helper.rb +525 -0
  171. data/spec/support/custom_macros.rb +564 -0
  172. data/spec/support/deprecation.rb +6 -0
  173. data/spec/support/shared_examples.rb +1313 -0
  174. data/spec/support/specialized_class_finder_shared_example.rb +27 -0
  175. data/spec/support/test_environment.rb +31 -0
  176. data/spec/util_spec.rb +66 -0
  177. metadata +434 -161
  178. data/README.textile +0 -682
  179. data/generators/form/USAGE +0 -16
  180. data/generators/form/form_generator.rb +0 -111
  181. data/generators/formtastic/formtastic_generator.rb +0 -26
  182. data/init.rb +0 -5
  183. data/lib/formtastic/layout_helper.rb +0 -12
  184. data/lib/formtastic/railtie.rb +0 -14
  185. data/lib/generators/templates/formtastic.css +0 -145
  186. data/lib/generators/templates/formtastic_changes.css +0 -14
  187. data/lib/generators/templates/rails2/_form.html.erb +0 -5
  188. data/lib/generators/templates/rails2/_form.html.haml +0 -4
  189. data/rails/init.rb +0 -2
@@ -0,0 +1,235 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'date select input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ describe "general" do
14
+
15
+ before do
16
+ output_buffer.replace ''
17
+ concat(semantic_form_for(@new_post) do |builder|
18
+ concat(builder.input(:publish_at, :as => :date_select, :order => [:year, :month, :day]))
19
+ end)
20
+ end
21
+
22
+ it_should_have_input_wrapper_with_class("date_select")
23
+ it_should_have_input_wrapper_with_class(:input)
24
+ it_should_have_input_wrapper_with_id("post_publish_at_input")
25
+ it_should_have_a_nested_fieldset
26
+ it_should_have_a_nested_fieldset_with_class('fragments')
27
+ it_should_have_a_nested_ordered_list_with_class('fragments-group')
28
+ it_should_apply_error_logic_for_input_type(:date_select)
29
+
30
+ it 'should have a legend and label with the label text inside the fieldset' do
31
+ output_buffer.should have_tag('form li.date_select fieldset legend.label label', /Publish at/)
32
+ end
33
+
34
+ it 'should associate the legend label with the first select' do
35
+ output_buffer.should have_tag('form li.date_select fieldset legend.label')
36
+ output_buffer.should have_tag('form li.date_select fieldset legend.label label')
37
+ output_buffer.should have_tag('form li.date_select fieldset legend.label label[@for]')
38
+ output_buffer.should have_tag('form li.date_select fieldset legend.label label[@for="post_publish_at_1i"]')
39
+ end
40
+
41
+ it 'should have an ordered list of three items inside the fieldset' do
42
+ output_buffer.should have_tag('form li.date_select fieldset ol.fragments-group')
43
+ output_buffer.should have_tag('form li.date_select fieldset ol li.fragment', :count => 3)
44
+ end
45
+
46
+ it 'should have three labels for year, month and day' do
47
+ output_buffer.should have_tag('form li.date_select fieldset ol li label', :count => 3)
48
+ output_buffer.should have_tag('form li.date_select fieldset ol li label', /year/i)
49
+ output_buffer.should have_tag('form li.date_select fieldset ol li label', /month/i)
50
+ output_buffer.should have_tag('form li.date_select fieldset ol li label', /day/i)
51
+ end
52
+
53
+ it 'should have three selects for year, month and day' do
54
+ output_buffer.should have_tag('form li.date_select fieldset ol li select', :count => 3)
55
+ end
56
+ end
57
+
58
+ describe "when namespace is provided" do
59
+
60
+ before do
61
+ output_buffer.replace ''
62
+ concat(semantic_form_for(@new_post, :namespace => "context2") do |builder|
63
+ concat(builder.input(:publish_at, :as => :date_select, :order => [:year, :month, :day]))
64
+ end)
65
+ end
66
+
67
+ it_should_have_input_wrapper_with_id("context2_post_publish_at_input")
68
+ it_should_have_select_with_id("context2_post_publish_at_1i")
69
+ it_should_have_select_with_id("context2_post_publish_at_2i")
70
+ it_should_have_select_with_id("context2_post_publish_at_3i")
71
+
72
+ end
73
+
74
+ describe "when index is provided" do
75
+
76
+ before do
77
+ @output_buffer = ''
78
+ mock_everything
79
+
80
+ concat(semantic_form_for(@new_post) do |builder|
81
+ concat(builder.fields_for(:author, :index => 3) do |author|
82
+ concat(author.input(:created_at, :as => :date_select))
83
+ end)
84
+ end)
85
+ end
86
+
87
+ it 'should index the id of the wrapper' do
88
+ output_buffer.should have_tag("li#post_author_attributes_3_created_at_input")
89
+ end
90
+
91
+ it 'should index the id of the select tag' do
92
+ output_buffer.should have_tag("select#post_author_attributes_3_created_at_1i")
93
+ output_buffer.should have_tag("select#post_author_attributes_3_created_at_2i")
94
+ output_buffer.should have_tag("select#post_author_attributes_3_created_at_3i")
95
+ end
96
+
97
+ it 'should index the name of the select tag' do
98
+ output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(1i)]']")
99
+ output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(2i)]']")
100
+ output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(3i)]']")
101
+ end
102
+
103
+ end
104
+
105
+ describe ':labels option' do
106
+ fields = [:year, :month, :day]
107
+ fields.each do |field|
108
+ it "should replace the #{field} label with the specified text if :labels[:#{field}] is set" do
109
+ output_buffer.replace ''
110
+ concat(semantic_form_for(@new_post) do |builder|
111
+ concat(builder.input(:created_at, :as => :date_select, :labels => { field => "another #{field} label" }))
112
+ end)
113
+ output_buffer.should have_tag('form li.date_select fieldset ol li label', :count => fields.length)
114
+ fields.each do |f|
115
+ output_buffer.should have_tag('form li.date_select fieldset ol li label', f == field ? /another #{f} label/i : /#{f}/i)
116
+ end
117
+ end
118
+
119
+ it "should not display the label for the #{field} field when :labels[:#{field}] is blank" do
120
+ output_buffer.replace ''
121
+ concat(semantic_form_for(@new_post) do |builder|
122
+ concat(builder.input(:created_at, :as => :date_select, :labels => { field => "" }))
123
+ end)
124
+ output_buffer.should have_tag('form li.date_select fieldset ol li label', :count => fields.length-1)
125
+ fields.each do |f|
126
+ output_buffer.should have_tag('form li.date_select fieldset ol li label', /#{f}/i) unless field == f
127
+ end
128
+ end
129
+
130
+ it "should not display the label for the #{field} field when :labels[:#{field}] is false" do
131
+ output_buffer.replace ''
132
+ concat(semantic_form_for(@new_post) do |builder|
133
+ concat(builder.input(:created_at, :as => :date_select, :labels => { field => false }))
134
+ end)
135
+ output_buffer.should have_tag('form li.date_select fieldset ol li label', :count => fields.length-1)
136
+ fields.each do |f|
137
+ output_buffer.should have_tag('form li.date_select fieldset ol li label', /#{f}/i) unless field == f
138
+ end
139
+ end
140
+
141
+ it "should not render unsafe HTML when :labels[:#{field}] is false" do
142
+ output_buffer.replace ''
143
+ concat(semantic_form_for(@new_post) do |builder|
144
+ concat(builder.input(:created_at, :as => :date_select, :include_seconds => true, :labels => { field => false }))
145
+ end)
146
+ output_buffer.should_not include(">")
147
+ end
148
+
149
+ end
150
+
151
+ it "should not display labels for any fields when :labels is falsy" do
152
+ output_buffer.replace ''
153
+ concat(semantic_form_for(@new_post) do |builder|
154
+ concat(builder.input(:created_at, :as => :date_select, :labels => false))
155
+ end)
156
+ output_buffer.should have_tag('form li.date_select fieldset ol li label', :count => 0)
157
+ end
158
+ end
159
+
160
+ describe "when required" do
161
+ it "should add the required attribute to the input's html options" do
162
+ with_config :use_required_attribute, true do
163
+ concat(semantic_form_for(@new_post) do |builder|
164
+ concat(builder.input(:title, :as => :date_select, :required => true))
165
+ end)
166
+ output_buffer.should have_tag("select[@required]", :count => 3)
167
+ end
168
+ end
169
+ end
170
+
171
+ describe "when order does not include day" do
172
+ before do
173
+ output_buffer.replace ''
174
+ concat(semantic_form_for(@new_post) do |builder|
175
+ concat(builder.input(:publish_at, :as => :date_select, :order => [:year, :month]))
176
+ end)
177
+ end
178
+
179
+ it "should include a hidden input for day" do
180
+ output_buffer.should have_tag('input[@type="hidden"][@name="post[publish_at(3i)]"][@value="1"]')
181
+ end
182
+
183
+ it "should not include a select for day" do
184
+ output_buffer.should_not have_tag('select[@name="post[publish_at(3i)]"]')
185
+ end
186
+ end
187
+
188
+ describe "when order does not include month" do
189
+ before do
190
+ output_buffer.replace ''
191
+ concat(semantic_form_for(@new_post) do |builder|
192
+ concat(builder.input(:publish_at, :as => :date_select, :order => [:year, :day]))
193
+ end)
194
+ end
195
+
196
+ it "should include a hidden input for month" do
197
+ output_buffer.should have_tag('input[@type="hidden"][@name="post[publish_at(2i)]"][@value="1"]')
198
+ end
199
+
200
+ it "should not include a select for month" do
201
+ output_buffer.should_not have_tag('select[@name="post[publish_at(2i)]"]')
202
+ end
203
+ end
204
+
205
+ describe "when order does not include year" do
206
+ before do
207
+ output_buffer.replace ''
208
+ concat(semantic_form_for(@new_post) do |builder|
209
+ concat(builder.input(:publish_at, :as => :date_select, :order => [:month, :day]))
210
+ end)
211
+ end
212
+
213
+ it "should include a hidden input for month" do
214
+ output_buffer.should have_tag("input[@type=\"hidden\"][@name=\"post[publish_at(1i)]\"][@value=\"#{Time.now.year}\"]")
215
+ end
216
+
217
+ it "should not include a select for month" do
218
+ output_buffer.should_not have_tag('select[@name="post[publish_at(1i)]"]')
219
+ end
220
+ end
221
+
222
+ describe "when order does not have year first" do
223
+ before do
224
+ output_buffer.replace ''
225
+ concat(semantic_form_for(@new_post) do |builder|
226
+ concat(builder.input(:publish_at, :as => :date_select, :order => [:day, :month, :year]))
227
+ end)
228
+ end
229
+
230
+ it 'should associate the legend label with the new first select' do
231
+ output_buffer.should have_tag('form li.date_select fieldset legend.label label[@for="post_publish_at_3i"]')
232
+ end
233
+ end
234
+
235
+ end
@@ -0,0 +1,490 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'datetime_picker input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ after do
14
+ ::I18n.backend.reload!
15
+ end
16
+
17
+ context "with an object" do
18
+ before do
19
+ concat(semantic_form_for(@new_post) do |builder|
20
+ concat(builder.input(:publish_at, :as => :datetime_picker))
21
+ end)
22
+ end
23
+
24
+ it_should_have_input_wrapper_with_class(:datetime_picker)
25
+ it_should_have_input_wrapper_with_class(:input)
26
+ it_should_have_input_wrapper_with_class(:stringish)
27
+ it_should_have_input_wrapper_with_id("post_publish_at_input")
28
+ it_should_have_label_with_text(/Publish at/)
29
+ it_should_have_label_for("post_publish_at")
30
+ it_should_have_input_with_id("post_publish_at")
31
+ it_should_have_input_with_type("datetime-local")
32
+ it_should_have_input_with_name("post[publish_at]")
33
+ it_should_apply_custom_input_attributes_when_input_html_provided(:datetime_picker)
34
+ it_should_apply_custom_for_to_label_when_input_html_id_provided(:datetime_picker)
35
+ # TODO why does this blow-up it_should_apply_error_logic_for_input_type(:datetime_picker)
36
+
37
+ end
38
+
39
+ describe ":local option for UTC or local time" do
40
+
41
+ it "should default to a datetime-local input (true)" do
42
+ concat(
43
+ semantic_form_for(@new_post) do |f|
44
+ concat(f.input(:publish_at, :as => :datetime_picker))
45
+ end
46
+ )
47
+ output_buffer.should have_tag "input[type='datetime-local']"
48
+ end
49
+
50
+ it "can be set to true for a datetime-local" do
51
+ concat(
52
+ semantic_form_for(@new_post) do |f|
53
+ concat(f.input(:publish_at, :as => :datetime_picker, :local => true))
54
+ end
55
+ )
56
+ output_buffer.should have_tag "input[type='datetime-local']"
57
+ end
58
+
59
+ it "can be set to false for a datetime" do
60
+ concat(
61
+ semantic_form_for(@new_post) do |f|
62
+ concat(f.input(:publish_at, :as => :datetime_picker, :local => false))
63
+ end
64
+ )
65
+ output_buffer.should have_tag "input[type='datetime']"
66
+ end
67
+
68
+ end
69
+
70
+ describe "size attribute" do
71
+
72
+ it "defaults to 10 chars (YYYY-YY-YY HH:MM)" do
73
+ concat(
74
+ semantic_form_for(@new_post) do |f|
75
+ concat(f.input(:publish_at, :as => :datetime_picker))
76
+ end
77
+ )
78
+ output_buffer.should have_tag "input[size='16']"
79
+ end
80
+
81
+ it "can be set from :input_html options" do
82
+ concat(
83
+ semantic_form_for(@new_post) do |f|
84
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :size => "11" }))
85
+ end
86
+ )
87
+ output_buffer.should have_tag "input[size='11']"
88
+ end
89
+
90
+ it "can be set from options (ignoring input_html)" do
91
+ concat(
92
+ semantic_form_for(@new_post) do |f|
93
+ concat(f.input(:publish_at, :as => :datetime_picker, :size => '12', :input_html => { :size => "11" }))
94
+ end
95
+ )
96
+ output_buffer.should have_tag "input[size='12']"
97
+ end
98
+
99
+ end
100
+
101
+ describe "maxlength attribute" do
102
+
103
+ it "defaults to 10 chars (YYYY-YY-YY HH:MM)" do
104
+ concat(
105
+ semantic_form_for(@new_post) do |f|
106
+ concat(f.input(:publish_at, :as => :datetime_picker))
107
+ end
108
+ )
109
+ output_buffer.should have_tag "input[maxlength='16']"
110
+ end
111
+
112
+ it "can be set from :input_html options" do
113
+ concat(
114
+ semantic_form_for(@new_post) do |f|
115
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :maxlength => "11" }))
116
+ end
117
+ )
118
+ output_buffer.should have_tag "input[maxlength='11']"
119
+ end
120
+
121
+ it "can be set from options (ignoring input_html)" do
122
+ concat(
123
+ semantic_form_for(@new_post) do |f|
124
+ concat(f.input(:publish_at, :as => :datetime_picker, :maxlength => 12, :input_html => { :maxlength => "11" }))
125
+ end
126
+ )
127
+ output_buffer.should have_tag "input[maxlength='12']"
128
+ end
129
+
130
+ end
131
+
132
+ describe "value attribute" do
133
+
134
+ context "when method returns nil" do
135
+
136
+ it "has no value" do
137
+ concat(
138
+ semantic_form_for(@new_post) do |f|
139
+ concat(f.input(:publish_at, :as => :datetime_picker ))
140
+ end
141
+ )
142
+ output_buffer.should_not have_tag "li input[value]"
143
+ end
144
+
145
+ it "can be set from :input_html options" do
146
+ concat(
147
+ semantic_form_for(@new_post) do |f|
148
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :value => "1111-11-11T23:00:00" }))
149
+ end
150
+ )
151
+ output_buffer.should have_tag "input[value='1111-11-11T23:00:00']"
152
+ end
153
+
154
+ end
155
+
156
+ context "when method returns a Date" do
157
+
158
+ before do
159
+ @date = Date.new(2000, 11, 11)
160
+ @new_post.stub(:publish_at).and_return(@date)
161
+ end
162
+
163
+ it "renders the date as YYYY-MM-DDT00:00:00" do
164
+ concat(
165
+ semantic_form_for(@new_post) do |f|
166
+ concat(f.input(:publish_at, :as => :datetime_picker ))
167
+ end
168
+ )
169
+ output_buffer.should have_tag "input[value='2000-11-11T00:00:00']"
170
+ end
171
+
172
+ it "can be set from :input_html options" do
173
+ concat(
174
+ semantic_form_for(@new_post) do |f|
175
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :value => "1111-11-11T00:00:00" }))
176
+ end
177
+ )
178
+ output_buffer.should have_tag "input[value='1111-11-11T00:00:00']"
179
+ end
180
+
181
+ end
182
+
183
+ context "when method returns a Time" do
184
+
185
+ before do
186
+ @time = Time.utc(2000,11,11,11,11,11)
187
+ @new_post.stub(:publish_at).and_return(@time)
188
+ end
189
+
190
+ it "renders the time as a YYYY-MM-DD HH:MM" do
191
+ concat(
192
+ semantic_form_for(@new_post) do |f|
193
+ concat(f.input(:publish_at, :as => :datetime_picker ))
194
+ end
195
+ )
196
+ output_buffer.should have_tag "input[value='2000-11-11T11:11:11']"
197
+ end
198
+
199
+ it "can be set from :input_html options" do
200
+ concat(
201
+ semantic_form_for(@new_post) do |f|
202
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :value => "1111-11-11T11:11:11" }))
203
+ end
204
+ )
205
+ output_buffer.should have_tag "input[value='1111-11-11T11:11:11']"
206
+ end
207
+
208
+ end
209
+
210
+ context "when method returns an empty String" do
211
+
212
+ before do
213
+ @new_post.stub(:publish_at).and_return("")
214
+ end
215
+
216
+ it "will be empty" do
217
+ concat(
218
+ semantic_form_for(@new_post) do |f|
219
+ concat(f.input(:publish_at, :as => :datetime_picker ))
220
+ end
221
+ )
222
+ output_buffer.should have_tag "input[value='']"
223
+ end
224
+
225
+ it "can be set from :input_html options" do
226
+ concat(
227
+ semantic_form_for(@new_post) do |f|
228
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :value => "1111-11-11T11:11:11" }))
229
+ end
230
+ )
231
+ output_buffer.should have_tag "input[value='1111-11-11T11:11:11']"
232
+ end
233
+
234
+ end
235
+
236
+ context "when method returns a String" do
237
+
238
+ before do
239
+ @new_post.stub(:publish_at).and_return("yeah")
240
+ end
241
+
242
+ it "will be the string" do
243
+ concat(
244
+ semantic_form_for(@new_post) do |f|
245
+ concat(f.input(:publish_at, :as => :datetime_picker ))
246
+ end
247
+ )
248
+ output_buffer.should have_tag "input[value='yeah']"
249
+ end
250
+
251
+ it "can be set from :input_html options" do
252
+ concat(
253
+ semantic_form_for(@new_post) do |f|
254
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :value => "1111-11-11T11:11:11" }))
255
+ end
256
+ )
257
+ output_buffer.should have_tag "input[value='1111-11-11T11:11:11']"
258
+ end
259
+
260
+ end
261
+
262
+ end
263
+
264
+ describe "min attribute" do
265
+
266
+ it "will be omitted by default" do
267
+ concat(
268
+ semantic_form_for(@new_post) do |f|
269
+ concat(f.input(:publish_at, :as => :datetime_picker))
270
+ end
271
+ )
272
+ output_buffer.should_not have_tag "input[min]"
273
+ end
274
+
275
+ it "can be set from :input_html options" do
276
+ concat(
277
+ semantic_form_for(@new_post) do |f|
278
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :min => "1970-01-01 12:00" }))
279
+ end
280
+ )
281
+ output_buffer.should have_tag "input[min='1970-01-01 12:00']"
282
+ end
283
+
284
+ end
285
+
286
+ describe "max attribute" do
287
+
288
+ it "will be omitted by default" do
289
+ concat(
290
+ semantic_form_for(@new_post) do |f|
291
+ concat(f.input(:publish_at, :as => :datetime_picker))
292
+ end
293
+ )
294
+ output_buffer.should_not have_tag "input[max]"
295
+ end
296
+
297
+ it "can be set from :input_html options" do
298
+ concat(
299
+ semantic_form_for(@new_post) do |f|
300
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :max => "1970-01-01 12:00" }))
301
+ end
302
+ )
303
+ output_buffer.should have_tag "input[max='1970-01-01 12:00']"
304
+ end
305
+
306
+ end
307
+
308
+ describe "step attribute" do
309
+
310
+ it "defaults to 1" do
311
+ concat(
312
+ semantic_form_for(@new_post) do |f|
313
+ concat(f.input(:publish_at, :as => :datetime_picker))
314
+ end
315
+ )
316
+ output_buffer.should have_tag "input[step='1']"
317
+ end
318
+
319
+ it "can be set from :input_html options" do
320
+ concat(
321
+ semantic_form_for(@new_post) do |f|
322
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :step => "5" }))
323
+ end
324
+ )
325
+ output_buffer.should have_tag "input[step='5']"
326
+ end
327
+
328
+ describe "macros" do
329
+ before do
330
+ concat(
331
+ semantic_form_for(@new_post) do |f|
332
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :step => step }))
333
+ end
334
+ )
335
+ end
336
+
337
+ context ":second" do
338
+ let(:step) { :second }
339
+ it "uses 1" do
340
+ output_buffer.should have_tag "input[step='1']"
341
+ end
342
+ end
343
+
344
+ context ":minute" do
345
+ let(:step) { :minute }
346
+ it "uses 60" do
347
+ output_buffer.should have_tag "input[step='60']"
348
+ end
349
+ end
350
+
351
+ context ":fifteen_minutes" do
352
+ let(:step) { :fifteen_minutes }
353
+ it "uses 900" do
354
+ output_buffer.should have_tag "input[step='900']"
355
+ end
356
+ end
357
+
358
+ context ":quarter_hour" do
359
+ let(:step) { :quarter_hour }
360
+ it "uses 900" do
361
+ output_buffer.should have_tag "input[step='900']"
362
+ end
363
+ end
364
+
365
+ context ":thirty_minutes" do
366
+ let(:step) { :thirty_minutes }
367
+ it "uses 1800" do
368
+ output_buffer.should have_tag "input[step='1800']"
369
+ end
370
+ end
371
+
372
+ context ":half_hour" do
373
+ let(:step) { :half_hour }
374
+ it "uses 1800" do
375
+ output_buffer.should have_tag "input[step='1800']"
376
+ end
377
+ end
378
+
379
+ context ":hour" do
380
+ let(:step) { :hour }
381
+ it "uses 3600" do
382
+ output_buffer.should have_tag "input[step='3600']"
383
+ end
384
+ end
385
+
386
+ context ":sixty_minutes" do
387
+ let(:step) { :sixty_minutes }
388
+ it "uses 3600" do
389
+ output_buffer.should have_tag "input[step='3600']"
390
+ end
391
+ end
392
+
393
+ end
394
+
395
+ end
396
+
397
+ describe "placeholder attribute" do
398
+
399
+ it "will be omitted" do
400
+ concat(
401
+ semantic_form_for(@new_post) do |f|
402
+ concat(f.input(:publish_at, :as => :datetime_picker))
403
+ end
404
+ )
405
+ output_buffer.should_not have_tag "input[placeholder]"
406
+ end
407
+
408
+ it "can be set from :input_html options" do
409
+ concat(
410
+ semantic_form_for(@new_post) do |f|
411
+ concat(f.input(:publish_at, :as => :datetime_picker, :input_html => { :placeholder => "1970-01-01 00:00" }))
412
+ end
413
+ )
414
+ output_buffer.should have_tag "input[placeholder='1970-01-01 00:00']"
415
+ end
416
+
417
+ context "with i18n set" do
418
+ before do
419
+ ::I18n.backend.store_translations :en, :formtastic => { :placeholders => { :publish_at => 'YYYY-MM-DD HH:MM' }}
420
+ end
421
+
422
+ it "can be set with i18n" do
423
+ with_config :i18n_lookups_by_default, true do
424
+ concat(semantic_form_for(@new_post) do |builder|
425
+ concat(builder.input(:publish_at, :as => :datetime_picker))
426
+ end)
427
+ output_buffer.should have_tag('input[@placeholder="YYYY-MM-DD HH:MM"]')
428
+ end
429
+ end
430
+
431
+ it "can be set with input_html, trumping i18n" do
432
+ with_config :i18n_lookups_by_default, true do
433
+ concat(semantic_form_for(@new_post) do |builder|
434
+ concat(builder.input(:publish_at, :as => :datetime_picker, :input_html => { :placeholder => "Something" }))
435
+ end)
436
+ output_buffer.should have_tag('input[@placeholder="Something"]')
437
+ end
438
+ end
439
+ end
440
+
441
+ end
442
+
443
+ describe "when namespace is provided" do
444
+ before do
445
+ concat(semantic_form_for(@new_post, :namespace => "context2") do |builder|
446
+ concat(builder.input(:publish_at, :as => :datetime_picker))
447
+ end)
448
+ end
449
+
450
+ it_should_have_input_wrapper_with_id("context2_post_publish_at_input")
451
+ it_should_have_label_and_input_with_id("context2_post_publish_at")
452
+ end
453
+
454
+ describe "when index is provided" do
455
+ before do
456
+ @output_buffer = ''
457
+ mock_everything
458
+
459
+ concat(semantic_form_for(@new_post) do |builder|
460
+ concat(builder.fields_for(:author, :index => 3) do |author|
461
+ concat(author.input(:created_at, :as => :datetime_picker))
462
+ end)
463
+ end)
464
+ end
465
+
466
+ it 'should index the id of the wrapper' do
467
+ output_buffer.should have_tag("li#post_author_attributes_3_created_at_input")
468
+ end
469
+
470
+ it 'should index the id of the select tag' do
471
+ output_buffer.should have_tag("input#post_author_attributes_3_created_at")
472
+ end
473
+
474
+ it 'should index the name of the select tag' do
475
+ output_buffer.should have_tag("input[@name='post[author_attributes][3][created_at]']")
476
+ end
477
+ end
478
+
479
+ describe "when required" do
480
+ it "should add the required attribute to the input's html options" do
481
+ with_config :use_required_attribute, true do
482
+ concat(semantic_form_for(@new_post) do |builder|
483
+ concat(builder.input(:publish_at, :as => :datetime_picker, :required => true))
484
+ end)
485
+ output_buffer.should have_tag("input[@required]")
486
+ end
487
+ end
488
+ end
489
+
490
+ end