formtastic 2.1.0 → 4.0.0

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 (164) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/test.yml +61 -0
  4. data/.gitignore +4 -2
  5. data/CHANGELOG.md +52 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +105 -0
  8. data/MIT-LICENSE +1 -1
  9. data/{README.textile → README.md} +204 -219
  10. data/RELEASE_PROCESS +3 -1
  11. data/Rakefile +27 -29
  12. data/app/assets/stylesheets/formtastic.css +3 -2
  13. data/bin/appraisal +8 -0
  14. data/formtastic.gemspec +11 -14
  15. data/gemfiles/rails_5.2/Gemfile +5 -0
  16. data/gemfiles/rails_6.0/Gemfile +5 -0
  17. data/gemfiles/rails_6.1/Gemfile +5 -0
  18. data/gemfiles/rails_edge/Gemfile +13 -0
  19. data/lib/formtastic/action_class_finder.rb +18 -0
  20. data/lib/formtastic/actions/button_action.rb +55 -60
  21. data/lib/formtastic/actions/input_action.rb +59 -57
  22. data/lib/formtastic/actions/link_action.rb +68 -67
  23. data/lib/formtastic/actions.rb +6 -3
  24. data/lib/formtastic/deprecation.rb +5 -0
  25. data/lib/formtastic/engine.rb +3 -1
  26. data/lib/formtastic/form_builder.rb +35 -16
  27. data/lib/formtastic/helpers/action_helper.rb +34 -28
  28. data/lib/formtastic/helpers/enum.rb +13 -0
  29. data/lib/formtastic/helpers/errors_helper.rb +2 -2
  30. data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -12
  31. data/lib/formtastic/helpers/form_helper.rb +19 -16
  32. data/lib/formtastic/helpers/input_helper.rb +69 -97
  33. data/lib/formtastic/helpers/inputs_helper.rb +35 -25
  34. data/lib/formtastic/helpers/reflection.rb +4 -4
  35. data/lib/formtastic/helpers.rb +1 -2
  36. data/lib/formtastic/html_attributes.rb +12 -1
  37. data/lib/formtastic/i18n.rb +1 -1
  38. data/lib/formtastic/input_class_finder.rb +18 -0
  39. data/lib/formtastic/inputs/base/choices.rb +2 -2
  40. data/lib/formtastic/inputs/base/collections.rb +46 -14
  41. data/lib/formtastic/inputs/base/database.rb +7 -2
  42. data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
  43. data/lib/formtastic/inputs/base/errors.rb +7 -7
  44. data/lib/formtastic/inputs/base/hints.rb +2 -2
  45. data/lib/formtastic/inputs/base/html.rb +10 -9
  46. data/lib/formtastic/inputs/base/labelling.rb +5 -8
  47. data/lib/formtastic/inputs/base/naming.rb +4 -4
  48. data/lib/formtastic/inputs/base/numeric.rb +1 -1
  49. data/lib/formtastic/inputs/base/options.rb +3 -4
  50. data/lib/formtastic/inputs/base/stringish.rb +10 -2
  51. data/lib/formtastic/inputs/base/timeish.rb +34 -22
  52. data/lib/formtastic/inputs/base/validations.rb +41 -13
  53. data/lib/formtastic/inputs/base/wrapping.rb +29 -26
  54. data/lib/formtastic/inputs/base.rb +22 -15
  55. data/lib/formtastic/inputs/boolean_input.rb +26 -12
  56. data/lib/formtastic/inputs/check_boxes_input.rb +39 -31
  57. data/lib/formtastic/inputs/color_input.rb +41 -0
  58. data/lib/formtastic/inputs/country_input.rb +24 -5
  59. data/lib/formtastic/inputs/datalist_input.rb +41 -0
  60. data/lib/formtastic/inputs/date_picker_input.rb +93 -0
  61. data/lib/formtastic/inputs/{date_input.rb → date_select_input.rb} +1 -1
  62. data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
  63. data/lib/formtastic/inputs/{datetime_input.rb → datetime_select_input.rb} +1 -1
  64. data/lib/formtastic/inputs/file_input.rb +2 -2
  65. data/lib/formtastic/inputs/hidden_input.rb +2 -6
  66. data/lib/formtastic/inputs/radio_input.rb +28 -22
  67. data/lib/formtastic/inputs/select_input.rb +36 -39
  68. data/lib/formtastic/inputs/time_picker_input.rb +99 -0
  69. data/lib/formtastic/inputs/{time_input.rb → time_select_input.rb} +6 -2
  70. data/lib/formtastic/inputs/time_zone_input.rb +16 -6
  71. data/lib/formtastic/inputs.rb +32 -21
  72. data/lib/formtastic/localized_string.rb +1 -1
  73. data/lib/formtastic/localizer.rb +24 -24
  74. data/lib/formtastic/namespaced_class_finder.rb +99 -0
  75. data/lib/formtastic/version.rb +1 -1
  76. data/lib/formtastic.rb +20 -10
  77. data/lib/generators/formtastic/form/form_generator.rb +10 -4
  78. data/lib/generators/formtastic/input/input_generator.rb +46 -0
  79. data/lib/generators/formtastic/install/install_generator.rb +5 -19
  80. data/lib/generators/templates/_form.html.slim +2 -2
  81. data/lib/generators/templates/formtastic.rb +46 -25
  82. data/lib/generators/templates/input.rb +19 -0
  83. data/sample/basic_inputs.html +23 -3
  84. data/script/integration-template.rb +74 -0
  85. data/script/integration.sh +19 -0
  86. data/spec/action_class_finder_spec.rb +12 -0
  87. data/spec/actions/button_action_spec.rb +8 -8
  88. data/spec/actions/generic_action_spec.rb +92 -56
  89. data/spec/actions/input_action_spec.rb +7 -7
  90. data/spec/actions/link_action_spec.rb +10 -10
  91. data/spec/builder/custom_builder_spec.rb +36 -20
  92. data/spec/builder/error_proc_spec.rb +4 -4
  93. data/spec/builder/semantic_fields_for_spec.rb +28 -29
  94. data/spec/fast_spec_helper.rb +12 -0
  95. data/spec/generators/formtastic/form/form_generator_spec.rb +45 -32
  96. data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
  97. data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
  98. data/spec/helpers/action_helper_spec.rb +75 -103
  99. data/spec/helpers/actions_helper_spec.rb +17 -17
  100. data/spec/helpers/form_helper_spec.rb +84 -33
  101. data/spec/helpers/input_helper_spec.rb +333 -285
  102. data/spec/helpers/inputs_helper_spec.rb +167 -121
  103. data/spec/helpers/reflection_helper_spec.rb +3 -3
  104. data/spec/helpers/semantic_errors_helper_spec.rb +23 -23
  105. data/spec/i18n_spec.rb +26 -26
  106. data/spec/input_class_finder_spec.rb +10 -0
  107. data/spec/inputs/base/collections_spec.rb +76 -0
  108. data/spec/inputs/base/validations_spec.rb +480 -0
  109. data/spec/inputs/boolean_input_spec.rb +100 -65
  110. data/spec/inputs/check_boxes_input_spec.rb +200 -101
  111. data/spec/inputs/color_input_spec.rb +85 -0
  112. data/spec/inputs/country_input_spec.rb +20 -20
  113. data/spec/inputs/custom_input_spec.rb +3 -4
  114. data/spec/inputs/datalist_input_spec.rb +61 -0
  115. data/spec/inputs/date_picker_input_spec.rb +449 -0
  116. data/spec/inputs/date_select_input_spec.rb +249 -0
  117. data/spec/inputs/datetime_picker_input_spec.rb +490 -0
  118. data/spec/inputs/datetime_select_input_spec.rb +209 -0
  119. data/spec/inputs/email_input_spec.rb +5 -5
  120. data/spec/inputs/file_input_spec.rb +6 -6
  121. data/spec/inputs/hidden_input_spec.rb +22 -35
  122. data/spec/inputs/include_blank_spec.rb +11 -11
  123. data/spec/inputs/label_spec.rb +62 -25
  124. data/spec/inputs/number_input_spec.rb +112 -112
  125. data/spec/inputs/password_input_spec.rb +5 -5
  126. data/spec/inputs/phone_input_spec.rb +5 -5
  127. data/spec/inputs/placeholder_spec.rb +6 -6
  128. data/spec/inputs/radio_input_spec.rb +99 -55
  129. data/spec/inputs/range_input_spec.rb +66 -66
  130. data/spec/inputs/readonly_spec.rb +50 -0
  131. data/spec/inputs/search_input_spec.rb +5 -5
  132. data/spec/inputs/select_input_spec.rb +170 -170
  133. data/spec/inputs/string_input_spec.rb +68 -16
  134. data/spec/inputs/text_input_spec.rb +16 -16
  135. data/spec/inputs/time_picker_input_spec.rb +455 -0
  136. data/spec/inputs/time_select_input_spec.rb +261 -0
  137. data/spec/inputs/time_zone_input_spec.rb +54 -28
  138. data/spec/inputs/url_input_spec.rb +5 -5
  139. data/spec/inputs/with_options_spec.rb +7 -7
  140. data/spec/localizer_spec.rb +39 -17
  141. data/spec/namespaced_class_finder_spec.rb +79 -0
  142. data/spec/schema.rb +21 -0
  143. data/spec/spec_helper.rb +254 -221
  144. data/spec/support/custom_macros.rb +128 -95
  145. data/spec/support/shared_examples.rb +12 -0
  146. data/spec/support/specialized_class_finder_shared_example.rb +27 -0
  147. data/spec/support/test_environment.rb +26 -10
  148. metadata +177 -238
  149. data/.travis.yml +0 -8
  150. data/Appraisals +0 -11
  151. data/CHANGELOG +0 -371
  152. data/gemfiles/rails-3.0.gemfile +0 -7
  153. data/gemfiles/rails-3.1.gemfile +0 -7
  154. data/gemfiles/rails-3.2.gemfile +0 -7
  155. data/lib/formtastic/helpers/buttons_helper.rb +0 -310
  156. data/lib/formtastic/inputs/base/grouped_collections.rb +0 -77
  157. data/lib/formtastic/util.rb +0 -25
  158. data/lib/tasks/verify_rcov.rb +0 -44
  159. data/spec/helpers/buttons_helper_spec.rb +0 -166
  160. data/spec/helpers/commit_button_helper_spec.rb +0 -530
  161. data/spec/inputs/date_input_spec.rb +0 -227
  162. data/spec/inputs/datetime_input_spec.rb +0 -185
  163. data/spec/inputs/time_input_spec.rb +0 -267
  164. data/spec/support/deferred_garbage_collection.rb +0 -21
@@ -0,0 +1,490 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ RSpec.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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).not_to 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
+ expect(output_buffer).to 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
+ allow(@new_post).to receive(: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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ allow(@new_post).to receive(: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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ allow(@new_post).to receive(: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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ allow(@new_post).to receive(: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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).not_to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).not_to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to have_tag "input[step='1']"
341
+ end
342
+ end
343
+
344
+ context ":minute" do
345
+ let(:step) { :minute }
346
+ it "uses 60" do
347
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to have_tag "input[step='1800']"
376
+ end
377
+ end
378
+
379
+ context ":hour" do
380
+ let(:step) { :hour }
381
+ it "uses 3600" do
382
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).not_to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to 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
+ expect(output_buffer).to have_tag("input#post_author_attributes_3_created_at")
472
+ end
473
+
474
+ it 'should index the name of the select tag' do
475
+ expect(output_buffer).to 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
+ expect(output_buffer).to have_tag("input[@required]")
486
+ end
487
+ end
488
+ end
489
+
490
+ end
@@ -0,0 +1,209 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe 'datetime 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
+ ::I18n.backend.store_translations :en, {}
17
+ output_buffer.replace ''
18
+ concat(semantic_form_for(@new_post) do |builder|
19
+ concat(builder.input(:publish_at, :as => :datetime_select))
20
+ end)
21
+ end
22
+
23
+ it_should_have_input_wrapper_with_class("datetime_select")
24
+ it_should_have_input_wrapper_with_class(:input)
25
+ it_should_have_input_wrapper_with_id("post_publish_at_input")
26
+ it_should_have_a_nested_fieldset
27
+ it_should_have_a_nested_fieldset_with_class('fragments')
28
+ it_should_have_a_nested_ordered_list_with_class('fragments-group')
29
+ it_should_apply_error_logic_for_input_type(:datetime_select)
30
+
31
+ it 'should have a legend and label with the label text inside the fieldset' do
32
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset legend.label label', :text => /Publish at/)
33
+ end
34
+
35
+ it 'should associate the legend label with the first select' do
36
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset legend.label')
37
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset legend.label label')
38
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset legend.label label[@for]')
39
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset legend.label label[@for="post_publish_at_1i"]')
40
+ end
41
+
42
+ it 'should have an ordered list of five items inside the fieldset' do
43
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol.fragments-group')
44
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li.fragment', :count => 5)
45
+ end
46
+
47
+ it 'should have five labels for year, month and day' do
48
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :count => 5)
49
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :text => /year/i)
50
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :text => /month/i)
51
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :text => /day/i)
52
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :text => /hour/i)
53
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :text => /min/i)
54
+ end
55
+
56
+ it 'should have five selects' do
57
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li select', :count => 5)
58
+ end
59
+ end
60
+
61
+ describe "when namespace is provided" do
62
+
63
+ before do
64
+ output_buffer.replace ''
65
+ concat(semantic_form_for(@new_post, :namespace => "context2") do |builder|
66
+ concat(builder.input(:publish_at, :as => :datetime_select))
67
+ end)
68
+ end
69
+
70
+ it_should_have_input_wrapper_with_id("context2_post_publish_at_input")
71
+ it_should_have_select_with_id("context2_post_publish_at_1i")
72
+ it_should_have_select_with_id("context2_post_publish_at_2i")
73
+ it_should_have_select_with_id("context2_post_publish_at_3i")
74
+ it_should_have_select_with_id("context2_post_publish_at_4i")
75
+ it_should_have_select_with_id("context2_post_publish_at_5i")
76
+
77
+ end
78
+
79
+ describe "when index is provided" do
80
+
81
+ before do
82
+ @output_buffer = ''
83
+ mock_everything
84
+
85
+ concat(semantic_form_for(@new_post) do |builder|
86
+ concat(builder.fields_for(:author, :index => 3) do |author|
87
+ concat(author.input(:created_at, :as => :datetime_select))
88
+ end)
89
+ end)
90
+ end
91
+
92
+ it 'should index the id of the wrapper' do
93
+ expect(output_buffer).to have_tag("li#post_author_attributes_3_created_at_input")
94
+ end
95
+
96
+ it 'should index the id of the select tag' do
97
+ expect(output_buffer).to have_tag("select#post_author_attributes_3_created_at_1i")
98
+ expect(output_buffer).to have_tag("select#post_author_attributes_3_created_at_2i")
99
+ expect(output_buffer).to have_tag("select#post_author_attributes_3_created_at_3i")
100
+ expect(output_buffer).to have_tag("select#post_author_attributes_3_created_at_4i")
101
+ expect(output_buffer).to have_tag("select#post_author_attributes_3_created_at_5i")
102
+ end
103
+
104
+ it 'should index the name of the select tag' do
105
+ expect(output_buffer).to have_tag("select[@name='post[author_attributes][3][created_at(1i)]']")
106
+ expect(output_buffer).to have_tag("select[@name='post[author_attributes][3][created_at(2i)]']")
107
+ expect(output_buffer).to have_tag("select[@name='post[author_attributes][3][created_at(3i)]']")
108
+ expect(output_buffer).to have_tag("select[@name='post[author_attributes][3][created_at(4i)]']")
109
+ expect(output_buffer).to have_tag("select[@name='post[author_attributes][3][created_at(5i)]']")
110
+ end
111
+
112
+ end
113
+
114
+
115
+ describe ':labels option' do
116
+ fields = [:year, :month, :day, :hour, :minute]
117
+ fields.each do |field|
118
+ it "should replace the #{field} label with the specified text if :labels[:#{field}] is set" do
119
+ output_buffer.replace ''
120
+ concat(semantic_form_for(@new_post) do |builder|
121
+ concat(builder.input(:created_at, :as => :datetime_select, :labels => { field => "another #{field} label" }))
122
+ end)
123
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :count => fields.length)
124
+ fields.each do |f|
125
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :text => f == field ? /another #{f} label/i : /#{f}/i)
126
+ end
127
+ end
128
+
129
+ it "should not display the label for the #{field} field when :labels[:#{field}] is blank" do
130
+ output_buffer.replace ''
131
+ concat(semantic_form_for(@new_post) do |builder|
132
+ concat(builder.input(:created_at, :as => :datetime_select, :labels => { field => "" }))
133
+ end)
134
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :count => fields.length-1)
135
+ fields.each do |f|
136
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :text => /#{f}/i) unless field == f
137
+ end
138
+ end
139
+
140
+ it "should not display the label for the #{field} field when :labels[:#{field}] is false" do
141
+ output_buffer.replace ''
142
+ concat(semantic_form_for(@new_post) do |builder|
143
+ concat(builder.input(:created_at, :as => :datetime_select, :labels => { field => false }))
144
+ end)
145
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :count => fields.length-1)
146
+ fields.each do |f|
147
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :text => /#{f}/i) unless field == f
148
+ end
149
+ end
150
+
151
+ it "should not render unsafe HTML when :labels[:#{field}] is false" do
152
+ output_buffer.replace ''
153
+ concat(semantic_form_for(@new_post) do |builder|
154
+ concat(builder.input(:created_at, :as => :datetime_select, :include_seconds => true, :labels => { field => false }))
155
+ end)
156
+ expect(output_buffer).not_to include(">")
157
+ end
158
+ end
159
+
160
+ it "should not display labels for any fields when :labels is falsy" do
161
+ output_buffer.replace ''
162
+ concat(semantic_form_for(@new_post) do |builder|
163
+ concat(builder.input(:created_at, :as => :datetime_select, :labels => false))
164
+ end)
165
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset ol li label', :count => 0)
166
+ end
167
+ end
168
+
169
+ describe ":selected option for setting a value" do
170
+ it "should set the selected value for the form" do
171
+ concat(
172
+ semantic_form_for(@new_post) do |f|
173
+ concat(f.input(:created_at, :as => :datetime_select, :selected => DateTime.new(2018, 10, 4, 12, 00)))
174
+ end
175
+ )
176
+
177
+ expect(output_buffer).to have_tag "option[value='2018'][selected='selected']"
178
+ expect(output_buffer).to have_tag "option[value='10'][selected='selected']"
179
+ expect(output_buffer).to have_tag "option[value='4'][selected='selected']"
180
+ expect(output_buffer).to have_tag "option[value='12'][selected='selected']"
181
+ expect(output_buffer).to have_tag "option[value='00'][selected='selected']"
182
+ end
183
+ end
184
+
185
+ describe "when required" do
186
+ it "should add the required attribute to the input's html options" do
187
+ with_config :use_required_attribute, true do
188
+ concat(semantic_form_for(@new_post) do |builder|
189
+ concat(builder.input(:title, :as => :datetime_select, :required => true))
190
+ end)
191
+ expect(output_buffer).to have_tag("select[@required]", :count => 5)
192
+ end
193
+ end
194
+ end
195
+
196
+ describe "when order does not have year first" do
197
+ before do
198
+ output_buffer.replace ''
199
+ concat(semantic_form_for(@new_post) do |builder|
200
+ concat(builder.input(:publish_at, :as => :datetime_select, :order => [:day, :month, :year]))
201
+ end)
202
+ end
203
+
204
+ it 'should associate the legend label with the new first select' do
205
+ expect(output_buffer).to have_tag('form li.datetime_select fieldset legend.label label[@for="post_publish_at_3i"]')
206
+ end
207
+ end
208
+
209
+ end