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,261 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe 'time 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
+ before do
15
+ ::I18n.backend.reload!
16
+ output_buffer.replace ''
17
+ end
18
+
19
+ describe "with :ignore_date => true" do
20
+ before do
21
+ concat(semantic_form_for(@new_post) do |builder|
22
+ concat(builder.input(:publish_at, :as => :time_select, :ignore_date => true))
23
+ end)
24
+ end
25
+
26
+ it 'should not have hidden inputs for day, month and year' do
27
+ expect(output_buffer).not_to have_tag('input#post_publish_at_1i')
28
+ expect(output_buffer).not_to have_tag('input#post_publish_at_2i')
29
+ expect(output_buffer).not_to have_tag('input#post_publish_at_3i')
30
+ end
31
+
32
+ it 'should have an input for hour and minute' do
33
+ expect(output_buffer).to have_tag('select#post_publish_at_4i')
34
+ expect(output_buffer).to have_tag('select#post_publish_at_5i')
35
+ end
36
+
37
+ end
38
+
39
+ describe "with :ignore_date => false" do
40
+ before do
41
+ allow(@new_post).to receive(:publish_at).and_return(Time.parse('2010-11-07'))
42
+ concat(semantic_form_for(@new_post) do |builder|
43
+ concat(builder.input(:publish_at, :as => :time_select, :ignore_date => false))
44
+ end)
45
+ end
46
+
47
+ it 'should have a hidden input for day, month and year' do
48
+ expect(output_buffer).to have_tag('input#post_publish_at_1i')
49
+ expect(output_buffer).to have_tag('input#post_publish_at_2i')
50
+ expect(output_buffer).to have_tag('input#post_publish_at_3i')
51
+ expect(output_buffer).to have_tag('input#post_publish_at_1i[@value="2010"]')
52
+ expect(output_buffer).to have_tag('input#post_publish_at_2i[@value="11"]')
53
+ expect(output_buffer).to have_tag('input#post_publish_at_3i[@value="7"]')
54
+ end
55
+
56
+ it 'should have an select for hour and minute' do
57
+ expect(output_buffer).to have_tag('select#post_publish_at_4i')
58
+ expect(output_buffer).to have_tag('select#post_publish_at_5i')
59
+ end
60
+
61
+ it 'should associate the legend label with the hour select' do
62
+ expect(output_buffer).to have_tag('form li.time_select fieldset legend.label label[@for="post_publish_at_4i"]')
63
+ end
64
+
65
+ end
66
+
67
+ describe "without seconds" do
68
+ before do
69
+ concat(semantic_form_for(@new_post) do |builder|
70
+ concat(builder.input(:publish_at, :as => :time_select))
71
+ end)
72
+ end
73
+
74
+ it_should_have_input_wrapper_with_class("time_select")
75
+ it_should_have_input_wrapper_with_class(:input)
76
+ it_should_have_input_wrapper_with_id("post_publish_at_input")
77
+ it_should_have_a_nested_fieldset
78
+ it_should_have_a_nested_fieldset_with_class('fragments')
79
+ it_should_have_a_nested_ordered_list_with_class('fragments-group')
80
+ it_should_apply_error_logic_for_input_type(:time_select)
81
+
82
+ it 'should have a legend and label with the label text inside the fieldset' do
83
+ expect(output_buffer).to have_tag('form li.time_select fieldset legend.label label', :text => /Publish at/)
84
+ end
85
+
86
+ it 'should associate the legend label with the first select' do
87
+ expect(output_buffer).to have_tag('form li.time_select fieldset legend.label label[@for="post_publish_at_4i"]')
88
+ end
89
+
90
+ it 'should have an ordered list of two items inside the fieldset' do
91
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol.fragments-group')
92
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li.fragment', :count => 2)
93
+ end
94
+
95
+ it 'should have five labels for hour and minute' do
96
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :count => 2)
97
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :text => /hour/i)
98
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :text => /minute/i)
99
+ end
100
+
101
+ it 'should have two selects for hour and minute' do
102
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li', :count => 2)
103
+ end
104
+ end
105
+
106
+ describe "with seconds" do
107
+ before do
108
+ concat(semantic_form_for(@new_post) do |builder|
109
+ concat(builder.input(:publish_at, :as => :time_select, :include_seconds => true))
110
+ end)
111
+ end
112
+
113
+ it 'should have five labels for hour and minute' do
114
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :count => 3)
115
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :text => /hour/i)
116
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :text => /minute/i)
117
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :text => /second/i)
118
+ end
119
+
120
+ it 'should have three selects for hour, minute and seconds' do
121
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li', :count => 3)
122
+ end
123
+
124
+ it 'should generate a sanitized label and matching ids for attribute' do
125
+ 4.upto(6) do |i|
126
+ expect(output_buffer).to have_tag("form li fieldset ol li label[@for='post_publish_at_#{i}i']")
127
+ expect(output_buffer).to have_tag("form li fieldset ol li #post_publish_at_#{i}i")
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ describe ':labels option' do
134
+ fields = [:hour, :minute, :second]
135
+ fields.each do |field|
136
+ it "should replace the #{field} label with the specified text if :labels[:#{field}] is set" do
137
+ output_buffer.replace ''
138
+ concat(semantic_form_for(@new_post) do |builder|
139
+ concat(builder.input(:created_at, :as => :time_select, :include_seconds => true, :labels => { field => "another #{field} label" }))
140
+ end)
141
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :count => fields.length)
142
+ fields.each do |f|
143
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :text => f == field ? /another #{f} label/i : /#{f}/i)
144
+ end
145
+ end
146
+
147
+ it "should not display the label for the #{field} field when :labels[:#{field}] is blank" do
148
+ output_buffer.replace ''
149
+ concat(semantic_form_for(@new_post) do |builder|
150
+ concat(builder.input(:created_at, :as => :time_select, :include_seconds => true, :labels => { field => "" }))
151
+ end)
152
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :count => fields.length-1)
153
+ fields.each do |f|
154
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :text => /#{f}/i) unless field == f
155
+ end
156
+ end
157
+
158
+ it "should not render the label when :labels[:#{field}] is false" do
159
+ output_buffer.replace ''
160
+ concat(semantic_form_for(@new_post) do |builder|
161
+ concat(builder.input(:created_at, :as => :time_select, :include_seconds => true, :labels => { field => false }))
162
+ end)
163
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :count => fields.length-1)
164
+ fields.each do |f|
165
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :text => /#{f}/i) unless field == f
166
+ end
167
+ end
168
+
169
+ it "should not render unsafe HTML when :labels[:#{field}] is false" do
170
+ output_buffer.replace ''
171
+ concat(semantic_form_for(@new_post) do |builder|
172
+ concat(builder.input(:created_at, :as => :time_select, :include_seconds => true, :labels => { field => false }))
173
+ end)
174
+ expect(output_buffer).not_to include(">")
175
+ end
176
+
177
+ end
178
+
179
+ it "should not render labels when :labels is falsy" do
180
+ output_buffer.replace ''
181
+ concat(semantic_form_for(@new_post) do |builder|
182
+ concat(builder.input(:created_at, :as => :time_select, :include_seconds => true, :labels => false))
183
+ end)
184
+ expect(output_buffer).to have_tag('form li.time_select fieldset ol li label', :count => 0)
185
+ end
186
+ end
187
+
188
+ describe ":selected option for setting a value" do
189
+ it "should set the selected value for the form" do
190
+ concat(
191
+ semantic_form_for(@new_post) do |f|
192
+ concat(f.input(:created_at, :as => :datetime_select, :selected => DateTime.new(2018, 10, 4, 12, 00)))
193
+ end
194
+ )
195
+
196
+ expect(output_buffer).to have_tag "option[value='12'][selected='selected']"
197
+ expect(output_buffer).to have_tag "option[value='00'][selected='selected']"
198
+ end
199
+ end
200
+
201
+ describe ':namespace option' do
202
+ before do
203
+ concat(semantic_form_for(@new_post, :namespace => 'form2') do |builder|
204
+ concat(builder.input(:publish_at, :as => :time_select))
205
+ end)
206
+ end
207
+
208
+ it 'should have a tag matching the namespace' do
209
+ expect(output_buffer).to have_tag('#form2_post_publish_at_input')
210
+ expect(output_buffer).to have_tag('#form2_post_publish_at_4i')
211
+ expect(output_buffer).to have_tag('#form2_post_publish_at_5i')
212
+ end
213
+ end
214
+
215
+ describe "when required" do
216
+ it "should add the required attribute to the input's html options" do
217
+ with_config :use_required_attribute, true do
218
+ concat(semantic_form_for(@new_post) do |builder|
219
+ concat(builder.input(:title, :as => :time_select, :required => true))
220
+ end)
221
+ expect(output_buffer).to have_tag("select[@required]", :count => 2)
222
+ end
223
+ end
224
+ end
225
+
226
+ describe "when index is provided" do
227
+
228
+ before do
229
+ concat(semantic_form_for(@new_post) do |builder|
230
+ concat(builder.fields_for(:author, :index => 3) do |author|
231
+ concat(author.input(:created_at, :as => :time_select))
232
+ end)
233
+ end)
234
+ end
235
+
236
+ it 'should index the id of the wrapper' do
237
+ expect(output_buffer).to have_tag("li#post_author_attributes_3_created_at_input")
238
+ end
239
+
240
+ it 'should index the id of the select tag' do
241
+ expect(output_buffer).to have_tag("input#post_author_attributes_3_created_at_1i")
242
+ expect(output_buffer).to have_tag("input#post_author_attributes_3_created_at_2i")
243
+ expect(output_buffer).to have_tag("input#post_author_attributes_3_created_at_3i")
244
+ expect(output_buffer).to have_tag("select#post_author_attributes_3_created_at_4i")
245
+ expect(output_buffer).to have_tag("select#post_author_attributes_3_created_at_5i")
246
+ end
247
+
248
+ it 'should index the name of the select tag' do
249
+ expect(output_buffer).to have_tag("input[@name='post[author_attributes][3][created_at(1i)]']")
250
+ expect(output_buffer).to have_tag("input[@name='post[author_attributes][3][created_at(2i)]']")
251
+ expect(output_buffer).to have_tag("input[@name='post[author_attributes][3][created_at(3i)]']")
252
+ expect(output_buffer).to have_tag("select[@name='post[author_attributes][3][created_at(4i)]']")
253
+ expect(output_buffer).to have_tag("select[@name='post[author_attributes][3][created_at(5i)]']")
254
+ end
255
+
256
+ end
257
+
258
+ end
259
+
260
+
261
+
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'spec_helper'
3
3
 
4
- describe 'time_zone input' do
4
+ RSpec.describe 'time_zone input' do
5
5
 
6
6
  include FormtasticSpecHelper
7
7
 
@@ -20,22 +20,22 @@ describe 'time_zone input' do
20
20
  it_should_apply_error_logic_for_input_type(:time_zone)
21
21
 
22
22
  it 'should generate a label for the input' do
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/)
23
+ expect(output_buffer).to have_tag('form li label')
24
+ expect(output_buffer).to have_tag('form li label[@for="post_time_zone"]')
25
+ expect(output_buffer).to have_tag('form li label', :text => /Time zone/)
26
26
  end
27
27
 
28
28
  it "should generate a select" do
29
- output_buffer.should have_tag("form li select")
30
- output_buffer.should have_tag("form li select#post_time_zone")
31
- output_buffer.should have_tag("form li select[@name=\"post[time_zone]\"]")
29
+ expect(output_buffer).to have_tag("form li select")
30
+ expect(output_buffer).to have_tag("form li select#post_time_zone")
31
+ expect(output_buffer).to have_tag("form li select[@name=\"post[time_zone]\"]")
32
32
  end
33
33
 
34
34
  it 'should use input_html to style inputs' do
35
35
  concat(semantic_form_for(@new_post) do |builder|
36
36
  concat(builder.input(:time_zone, :input_html => { :class => 'myclass' }))
37
37
  end)
38
- output_buffer.should have_tag("form li select.myclass")
38
+ expect(output_buffer).to have_tag("form li select.myclass")
39
39
  end
40
40
 
41
41
  describe "when namespace is provided" do
@@ -54,7 +54,7 @@ describe 'time_zone input' do
54
54
  it_should_have_label_for("context2_post_time_zone")
55
55
 
56
56
  end
57
-
57
+
58
58
  describe "when index is provided" do
59
59
 
60
60
  before do
@@ -67,51 +67,77 @@ describe 'time_zone input' do
67
67
  end)
68
68
  end)
69
69
  end
70
-
70
+
71
71
  it 'should index the id of the wrapper' do
72
- output_buffer.should have_tag("li#post_author_attributes_3_name_input")
72
+ expect(output_buffer).to have_tag("li#post_author_attributes_3_name_input")
73
73
  end
74
-
74
+
75
75
  it 'should index the id of the select tag' do
76
- output_buffer.should have_tag("select#post_author_attributes_3_name")
76
+ expect(output_buffer).to have_tag("select#post_author_attributes_3_name")
77
77
  end
78
-
78
+
79
79
  it 'should index the name of the select tag' do
80
- output_buffer.should have_tag("select[@name='post[author_attributes][3][name]']")
80
+ expect(output_buffer).to have_tag("select[@name='post[author_attributes][3][name]']")
81
81
  end
82
-
82
+
83
83
  end
84
-
84
+
85
85
 
86
86
  describe 'when no object is given' do
87
- before(:each) do
87
+ before(:example) do
88
88
  concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
89
89
  concat(builder.input(:time_zone, :as => :time_zone))
90
90
  end)
91
91
  end
92
92
 
93
93
  it 'should generate labels' do
94
- output_buffer.should have_tag('form li label')
95
- output_buffer.should have_tag('form li label[@for="project_time_zone"]')
96
- output_buffer.should have_tag('form li label', /Time zone/)
94
+ expect(output_buffer).to have_tag('form li label')
95
+ expect(output_buffer).to have_tag('form li label[@for="project_time_zone"]')
96
+ expect(output_buffer).to have_tag('form li label', :text => /Time zone/)
97
97
  end
98
98
 
99
99
  it 'should generate select inputs' do
100
- output_buffer.should have_tag("form li select")
101
- output_buffer.should have_tag("form li select#project_time_zone")
102
- output_buffer.should have_tag("form li select[@name=\"project[time_zone]\"]")
100
+ expect(output_buffer).to have_tag("form li select")
101
+ expect(output_buffer).to have_tag("form li select#project_time_zone")
102
+ expect(output_buffer).to have_tag("form li select[@name=\"project[time_zone]\"]")
103
103
  end
104
104
  end
105
-
105
+
106
106
  context "when required" do
107
107
  it "should add the required attribute to the input's html options" do
108
- with_config :use_required_attribute, true do
108
+ with_config :use_required_attribute, true do
109
109
  concat(semantic_form_for(@new_post) do |builder|
110
110
  concat(builder.input(:title, :as => :time_zone, :required => true))
111
111
  end)
112
- output_buffer.should have_tag("select[@required]")
112
+ expect(output_buffer).to have_tag("select[@required]")
113
+ end
114
+ end
115
+ end
116
+
117
+ describe "when priority time zone is provided" do
118
+ let(:time_zones) { [ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii']] }
119
+ let(:input_html_options) do
120
+ { id: "post_title", required: false, autofocus: false, readonly: false }
121
+ end
122
+
123
+ context "by priority_zone option" do
124
+ it "passes right time_zones" do
125
+ expect_any_instance_of(Formtastic::FormBuilder).to receive(:time_zone_select).with(:title, time_zones, {}, input_html_options)
126
+ semantic_form_for(@new_post) do |builder|
127
+ builder.input(:title, as: :time_zone, priority_zones: time_zones)
128
+ end
129
+ end
130
+ end
131
+
132
+ context "by configuration" do
133
+ it "passes right time_zones" do
134
+ expect_any_instance_of(Formtastic::FormBuilder).to receive(:time_zone_select).with(:title, time_zones, {}, input_html_options)
135
+ with_config :priority_time_zones, time_zones do
136
+ semantic_form_for(@new_post) do |builder|
137
+ builder.input(:title, as: :time_zone)
138
+ end
139
+ end
113
140
  end
114
141
  end
115
142
  end
116
-
117
143
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'spec_helper'
3
3
 
4
- describe 'url input' do
4
+ RSpec.describe 'url input' do
5
5
 
6
6
  include FormtasticSpecHelper
7
7
 
@@ -56,15 +56,15 @@ describe 'url input' do
56
56
  end
57
57
 
58
58
  it 'should index the id of the wrapper' do
59
- output_buffer.should have_tag("li#post_author_attributes_3_name_input")
59
+ expect(output_buffer).to have_tag("li#post_author_attributes_3_name_input")
60
60
  end
61
61
 
62
62
  it 'should index the id of the select tag' do
63
- output_buffer.should have_tag("input#post_author_attributes_3_name")
63
+ expect(output_buffer).to have_tag("input#post_author_attributes_3_name")
64
64
  end
65
65
 
66
66
  it 'should index the name of the select tag' do
67
- output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']")
67
+ expect(output_buffer).to have_tag("input[@name='post[author_attributes][3][name]']")
68
68
  end
69
69
 
70
70
  end
@@ -76,7 +76,7 @@ describe 'url input' do
76
76
  concat(semantic_form_for(@new_post) do |builder|
77
77
  concat(builder.input(:title, :as => :url, :required => true))
78
78
  end)
79
- output_buffer.should have_tag("input[@required]")
79
+ expect(output_buffer).to have_tag("input[@required]")
80
80
  end
81
81
  end
82
82
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'spec_helper'
3
3
 
4
- describe 'string input' do
4
+ RSpec.describe 'string input' do
5
5
 
6
6
  include FormtasticSpecHelper
7
7
 
@@ -21,23 +21,23 @@ describe 'string input' do
21
21
  end
22
22
 
23
23
  it "should have extra class on title" do
24
- output_buffer.should have_tag("form li#post_title_input.extra")
24
+ expect(output_buffer).to have_tag("form li#post_title_input.extra")
25
25
  end
26
26
  it "should have title as string" do
27
- output_buffer.should have_tag("form li#post_title_input.string")
27
+ expect(output_buffer).to have_tag("form li#post_title_input.string")
28
28
  end
29
29
  it "should not have title as radio" do
30
- output_buffer.should_not have_tag("form li#post_title_input.radio")
30
+ expect(output_buffer).not_to have_tag("form li#post_title_input.radio")
31
31
  end
32
32
 
33
33
  it "should have extra class on author" do
34
- output_buffer.should have_tag("form li#post_author_input.extra")
34
+ expect(output_buffer).to have_tag("form li#post_author_input.extra")
35
35
  end
36
36
  it "should not have author as string" do
37
- output_buffer.should_not have_tag("form li#post_author_input.string")
37
+ expect(output_buffer).not_to have_tag("form li#post_author_input.string")
38
38
  end
39
39
  it "should have author as radio" do
40
- output_buffer.should have_tag("form li#post_author_input.radio")
40
+ expect(output_buffer).to have_tag("form li#post_author_input.radio")
41
41
  end
42
42
  end
43
43
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'spec_helper'
3
3
 
4
- describe 'Formtastic::Localizer' do
4
+ RSpec.describe 'Formtastic::Localizer' do
5
5
  describe "Cache" do
6
6
  before do
7
7
  @cache = Formtastic::Localizer::Cache.new
@@ -11,27 +11,27 @@ describe 'Formtastic::Localizer' do
11
11
  end
12
12
 
13
13
  it "should get value" do
14
- @cache.get(@key).should == 'value'
15
- @cache.get(@undefined_key).should be_nil
14
+ expect(@cache.get(@key)).to eq('value')
15
+ expect(@cache.get(@undefined_key)).to be_nil
16
16
  end
17
17
 
18
18
  it "should check if key exists?" do
19
- @cache.has_key?(@key).should be_true
20
- @cache.has_key?(@undefined_key).should be_false
19
+ expect(@cache.has_key?(@key)).to be_truthy
20
+ expect(@cache.has_key?(@undefined_key)).to be_falsey
21
21
  end
22
22
 
23
23
  it "should set a key" do
24
24
  @cache.set(['model', 'name2'], 'value2')
25
- @cache.get(['model', 'name2']).should == 'value2'
25
+ expect(@cache.get(['model', 'name2'])).to eq('value2')
26
26
  end
27
27
 
28
28
  it "should return hash" do
29
- @cache.cache.should be_an_instance_of(Hash)
29
+ expect(@cache.cache).to be_an_instance_of(Hash)
30
30
  end
31
31
 
32
32
  it "should clear the cache" do
33
33
  @cache.clear!
34
- @cache.get(@key).should be_nil
34
+ expect(@cache.get(@key)).to be_nil
35
35
  end
36
36
  end
37
37
 
@@ -53,11 +53,11 @@ describe 'Formtastic::Localizer' do
53
53
  end
54
54
 
55
55
  it "should be defined" do
56
- lambda { Formtastic::Localizer }.should_not raise_error(::NameError)
56
+ expect { Formtastic::Localizer }.not_to raise_error
57
57
  end
58
58
 
59
59
  it "should have a cache" do
60
- Formtastic::Localizer.cache.should be_an_instance_of(Formtastic::Localizer::Cache)
60
+ expect(Formtastic::Localizer.cache).to be_an_instance_of(Formtastic::Localizer::Cache)
61
61
  end
62
62
 
63
63
  describe "localize" do
@@ -75,19 +75,19 @@ describe 'Formtastic::Localizer' do
75
75
  end
76
76
 
77
77
  it "should translate key with i18n" do
78
- @localizer.localize(:name, :name, :label).should == 'POST.NAME'
78
+ expect(@localizer.localize(:name, :name, :label)).to eq('POST.NAME')
79
79
  end
80
80
 
81
81
  describe "with caching" do
82
82
  it "should not update translation when stored translations change" do
83
83
  with_config :i18n_cache_lookups, true do
84
- @localizer.localize(:name, :name, :label).should == 'POST.NAME'
84
+ expect(@localizer.localize(:name, :name, :label)).to eq('POST.NAME')
85
85
  store_post_translations('POST.NEW_NAME')
86
86
 
87
- @localizer.localize(:name, :name, :label).should == 'POST.NAME'
87
+ expect(@localizer.localize(:name, :name, :label)).to eq('POST.NAME')
88
88
 
89
89
  Formtastic::Localizer.cache.clear!
90
- @localizer.localize(:name, :name, :label).should == 'POST.NEW_NAME'
90
+ expect(@localizer.localize(:name, :name, :label)).to eq('POST.NEW_NAME')
91
91
  end
92
92
  end
93
93
  end
@@ -95,14 +95,36 @@ describe 'Formtastic::Localizer' do
95
95
  describe "without caching" do
96
96
  it "should update translation when stored translations change" do
97
97
  with_config :i18n_cache_lookups, false do
98
- @localizer.localize(:name, :name, :label).should == 'POST.NAME'
98
+ expect(@localizer.localize(:name, :name, :label)).to eq('POST.NAME')
99
99
  store_post_translations('POST.NEW_NAME')
100
- @localizer.localize(:name, :name, :label).should == 'POST.NEW_NAME'
100
+ expect(@localizer.localize(:name, :name, :label)).to eq('POST.NEW_NAME')
101
101
  end
102
102
  end
103
103
  end
104
+
105
+ describe "with custom resource name" do
106
+ before do
107
+ ::I18n.backend.store_translations :en, {:formtastic => {
108
+ :labels => {
109
+ :post => { :name => 'POST.NAME' },
110
+ :message => { :name => 'MESSAGE.NAME' }
111
+ }
112
+ }
113
+ }
114
+
115
+ with_config :i18n_lookups_by_default, true do
116
+ semantic_form_for(@new_post, :as => :message) do |builder|
117
+ @localizer = Formtastic::Localizer.new(builder)
118
+ end
119
+ end
120
+ end
121
+
122
+ it "should translate custom key with i18n" do
123
+ expect(@localizer.localize(:name, :name, :label)).to eq('MESSAGE.NAME')
124
+ end
125
+ end
104
126
  end
105
127
 
106
128
  end
107
129
 
108
- end
130
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'formtastic/namespaced_class_finder'
4
+
5
+ RSpec.describe Formtastic::NamespacedClassFinder do
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ stub_const('SearchPath', Module.new)
10
+ end
11
+
12
+ let(:search_path) { [ SearchPath ] }
13
+ subject(:finder) { Formtastic::NamespacedClassFinder.new(search_path) }
14
+
15
+ shared_examples 'Namespaced Class Finder' do
16
+ subject(:found_class) { finder.find(:custom_class) }
17
+
18
+ context 'Input defined in the Object scope' do
19
+ before do
20
+ stub_const('CustomClass', Class.new)
21
+ end
22
+
23
+ it { expect(found_class).to be(CustomClass) }
24
+ end
25
+
26
+ context 'Input defined in the search path' do
27
+ before do
28
+ stub_const('SearchPath::CustomClass', Class.new)
29
+ end
30
+
31
+ it { expect(found_class).to be(SearchPath::CustomClass) }
32
+ end
33
+
34
+ context 'Input defined both in the Object scope and the search path' do
35
+ before do
36
+ stub_const('CustomClass', Class.new)
37
+ stub_const('SearchPath::CustomClass', Class.new)
38
+ end
39
+
40
+ it { expect(found_class).to be(SearchPath::CustomClass) }
41
+ end
42
+
43
+ context 'Input defined outside the search path' do
44
+ before do
45
+ stub_const('Foo', Module.new)
46
+ stub_const('Foo::CustomClass', Class.new)
47
+ end
48
+
49
+ let(:error) { Formtastic::NamespacedClassFinder::NotFoundError }
50
+
51
+ it { expect { found_class }.to raise_error(error) }
52
+ end
53
+ end
54
+
55
+ context '#finder' do
56
+ before do
57
+ allow(Rails.application.config).to receive(:cache_classes).and_return(cache_classes)
58
+ end
59
+
60
+ context 'when cache_classes is on' do
61
+ let(:cache_classes) { true }
62
+ it_behaves_like 'Namespaced Class Finder'
63
+ end
64
+
65
+ context 'when cache_classes is off' do
66
+ let(:cache_classes) { false }
67
+ it_behaves_like 'Namespaced Class Finder'
68
+ end
69
+ end
70
+
71
+ context '#find' do
72
+ it 'caches calls' do
73
+ expect(subject).to receive(:resolve).once.and_call_original
74
+ subject.find(:object)
75
+ subject.find(:object)
76
+ end
77
+ end
78
+
79
+ end