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
@@ -1,310 +0,0 @@
1
- module Formtastic
2
- module Helpers
3
-
4
- # ButtonsHelper encapsulates the responsibilties of the {#buttons} and {#commit_button} helpers
5
- # for submitting forms.
6
- #
7
- # {#buttons} is used to wrap the form's button(s) and actions in a `<fieldset>` and `<ol>`,
8
- # with each item in the list containing the markup representing a single button.
9
- #
10
- # {#buttons} is usually called with a block containing a single {#commit_button} call:
11
- #
12
- # <%= semantic_form_for @post do |f| %>
13
- # ...
14
- # <%= f.buttons do %>
15
- # <%= f.commit_button
16
- # <% end %>
17
- # <% end %>
18
- #
19
- # The HTML output will be something like:
20
- #
21
- # <form class="formtastic" method="post" action="...">
22
- # ...
23
- # <fieldset class="buttons">
24
- # <ol>
25
- # <li class="commit button">
26
- # <input type="submit" name="commit" value="Create Post" class="create">
27
- # </li>
28
- # </ol>
29
- # </fieldset>
30
- # </form>
31
- #
32
- # While this may seem slightly over-engineered, it is consistent with the way form inputs are
33
- # handled, and makes room for other types of buttons and actions in future versions (such as
34
- # cancel buttons or links, reset buttons and even alternate actions like 'save and continue
35
- # editing').
36
- #
37
- # It's important to note that the `semantic_form_for` and {#buttons} blocks wrap the
38
- # standard Rails `form_for` helper and form builder, so you have full access to every standard
39
- # Rails form helper, with any HTML markup and ERB syntax, allowing you to "break free" from
40
- # Formtastic when it doesn't suit to create your own buttons, links and actions:
41
- #
42
- # <%= semantic_form_for @post do |f| %>
43
- # ...
44
- # <%= f.buttons do %>
45
- # <li class="save">
46
- # <%= f.submit "Save" %>
47
- # <li>
48
- # <li class="cancel-link">
49
- # Or <%= link_to "Cancel", posts_url %>
50
- # <li>
51
- # <% end %>
52
- # <% end %>
53
- #
54
- # There are many other syntax variations and arguments to customize your form. See the
55
- # full documentation of {#buttons} and {#commit_button} for details.
56
- #
57
- # @deprecated ButtonsHelper will be removed after 2.1
58
- module ButtonsHelper
59
- include Formtastic::Helpers::FieldsetWrapper
60
- include Formtastic::LocalizedString
61
-
62
- # Creates a fieldset and ol tag wrapping for use around a set of buttons. It can be
63
- # called either with a block (in which you can do the usual Rails form stuff, HTML, ERB, etc),
64
- # or with a list of named buttons. These two examples are functionally equivalent:
65
- #
66
- # # With a block:
67
- # <% semantic_form_for @post do |f| %>
68
- # ...
69
- # <% f.buttons do %>
70
- # <%= f.commit_button %>
71
- # <% end %>
72
- # <% end %>
73
- #
74
- # # With a list of fields:
75
- # <% semantic_form_for @post do |f| %>
76
- # <%= f.buttons :commit %>
77
- # <% end %>
78
- #
79
- # # Output:
80
- # <form ...>
81
- # <fieldset class="buttons">
82
- # <ol>
83
- # <li class="commit button">
84
- # <input type="submit" ...>
85
- # </li>
86
- # </ol>
87
- # </fieldset>
88
- # </form>
89
- #
90
- # Only one type of named button is supported at this time (:commit), and it's assumed to be
91
- # the default choice, so this is also functionally equivalent, but may change in the future:
92
- #
93
- # # With no args:
94
- # <% semantic_form_for @post do |f| %>
95
- # ...
96
- # <%= f.buttons %>
97
- # <% end %>
98
- #
99
- # While this may seem slightly over-engineered, it is consistent with the way form inputs are
100
- # handled, and makes room for other types of buttons and actions in future versions (such as
101
- # cancel buttons or links, reset buttons and even alternate actions like 'save and continue
102
- # editing').
103
- #
104
- # All options except `:name` and `:title` are passed down to the fieldset as HTML
105
- # attributes (`id`, `class`, `style`...). If provided, the `:name` or `:title` option is
106
- # passed into a `<legend>` inside the `<fieldset>` to name the set of buttons.
107
- #
108
- # @example Quickly add button(s) to the form, accepting all default values, options and behaviors
109
- # <% semantic_form_for @post do |f| %>
110
- # ...
111
- # <%= f.buttons %>
112
- # <% end %>
113
- #
114
- # @example Specify which named buttons you want, accepting all default values, options and behaviors
115
- # <% semantic_form_for @post do |f| %>
116
- # ...
117
- # <%= f.buttons :commit %>
118
- # <% end %>
119
- #
120
- # @example Specify which named buttons you want, and name the fieldset
121
- # <% semantic_form_for @post do |f| %>
122
- # ...
123
- # <%= f.buttons :commit, :name => "Actions" %>
124
- # or
125
- # <%= f.buttons :commit, :label => "Actions" %>
126
- # <% end %>
127
- #
128
- # @example Get full control over the commit_button options
129
- # <% semantic_form_for @post do |f| %>
130
- # ...
131
- # <%= f.buttons do %>
132
- # <%= f.commit_button :label => "Go", :button_html => { :class => "pretty" :disable_with => "Wait..." }, :wrapper_html => { ... }
133
- # <% end %>
134
- # <% end %>
135
- #
136
- # @example Make your own custom buttons, links or actions with standard Rails helpers or HTML
137
- # <% semantic_form_for @post do |f| %>
138
- # ...
139
- # <%= f.buttons do %>
140
- # <li class="submit">
141
- # <%= f.submit "Submit" %>
142
- # </li>
143
- # <li class="reset">
144
- # <input type="reset" value="Reset">
145
- # </li>
146
- # <li class="cancel">
147
- # <%= link_to "Cancel", posts_url %>
148
- # </li>
149
- # <% end %>
150
- # <% end %>
151
- #
152
- # @example Add HTML attributes to the fieldset
153
- # <% semantic_form_for @post do |f| %>
154
- # ...
155
- # <%= f.buttons :commit, :style => "border:1px;" %>
156
- # or
157
- # <%= f.buttons :style => "border:1px;" do %>
158
- # ...
159
- # <% end %>
160
- # <% end %>
161
- #
162
- # @option *args :label [String, Symbol]
163
- # Optionally specify text for the legend of the fieldset
164
- #
165
- # @option *args :name [String, Symbol]
166
- # Optionally specify text for the legend of the fieldset (alias for `:label`)
167
- #
168
- # @todo document i18n keys
169
- # @deprecated f.buttons is deprecated in favor of f.actions and will be removed after 2.1
170
- def buttons(*args, &block)
171
- ::ActiveSupport::Deprecation.warn("f.buttons is deprecated in favour of f.actions and will be removed from Formtastic after 2.1. Please see ActionsHelper and InputAction or ButtonAction for more information")
172
-
173
- html_options = args.extract_options!
174
- html_options[:class] ||= "buttons"
175
-
176
- if block_given?
177
- field_set_and_list_wrapping(html_options, &block)
178
- else
179
- args = [:commit] if args.empty?
180
- contents = args.map { |button_name| send(:"#{button_name}_button") }
181
- field_set_and_list_wrapping(html_options, contents)
182
- end
183
- end
184
-
185
- # Creates a submit input tag with the value "Save [model name]" (for existing records) or
186
- # "Create [model name]" (for new records) by default. The output is an `<input>` tag with the
187
- # `type` of `submit` and a class of either `create` or `update` (if Formtastic can determin if)
188
- # the record is new or not) with `submit` as a fallback class. The submit button is wrapped in
189
- # an `<li>` tag with a class of `commit`, and is intended to be rendered inside a {#buttons}
190
- # block which wraps the button in a `fieldset` and `ol`.
191
- #
192
- # The textual value of the label can be changed from this default through the `:label`
193
- # argument or through i18n.
194
- #
195
- # You can pass HTML attributes down to the `<input>` tag with the `:button_html` option, and
196
- # pass HTML attributes to the wrapping `<li>` tag with the `:wrapper_html` option.
197
- #
198
- # @example Basic usage
199
- # # form
200
- # <%= semantic_form_for @post do |f| %>
201
- # ...
202
- # <%= f.buttons do %>
203
- # <%= f.commit_button %>
204
- # <% end %>
205
- # <% end %>
206
- #
207
- # # output
208
- # <form ...>
209
- # ...
210
- # <fieldset class="buttons">
211
- # <ol>
212
- # <li class="commit button">
213
- # <input name="commit" type="submit" value="Create Post" class="create">
214
- # </li>
215
- # </ol>
216
- # </fieldset>
217
- # </form>
218
- #
219
- # @example Set the value through the `:label` option
220
- # <%= f.commit_button :label => "Go" %>
221
- #
222
- # @example Set the value through the optional first argument (like Rails' `f.submit`)
223
- # <%= f.commit_button "Go" %>
224
- #
225
- # @example Pass HTML attributes down to the `<input>`
226
- # <%= f.commit_button :button_html => { :class => 'pretty', :accesskey => 'g', :disable_with => "Wait..." } %>
227
- # <%= f.commit_button :label => "Go", :button_html => { :class => 'pretty', :accesskey => 'g', :disable_with => "Wait..." } %>
228
- # <%= f.commit_button "Go", :button_html => { :class => 'pretty', :accesskey => 'g', :disable_with => "Wait..." } %>
229
- #
230
- # @example Pass HTML attributes down to the `<li>` wrapper
231
- # <%= f.commit_button :wrapper_html => { :class => 'special', :id => 'whatever' } %>
232
- # <%= f.commit_button :label => "Go", :wrapper_html => { :class => 'special', :id => 'whatever' } %>
233
- # <%= f.commit_button "Go", :wrapper_html => { :class => 'special', :id => 'whatever' } %>
234
- #
235
- # @option *args :label [String, Symbol]
236
- # Override the label text with a String or a symbold for an i18n translation key
237
- #
238
- # @option *args :button_html [Hash]
239
- # Override or add to the HTML attributes to be passed down to the `<input>` tag
240
- #
241
- # @option *args :wrapper_html [Hash]
242
- # Override or add to the HTML attributes to be passed down to the wrapping `<li>` tag
243
- #
244
- # @todo document i18n keys
245
- # @todo strange that `:accesskey` seems to be supported in the top level args as well as `:button_html`
246
- # @deprecated f.commit_button is deprecated in favor of f.actions and will be removed after 2.1
247
- def commit_button(*args)
248
- ::ActiveSupport::Deprecation.warn("f.commit_button is deprecated in favour of f.action(:submit) and will be removed from Formtastic after 2.1. Please see ActionsHelper and InputAction or ButtonAction for more information")
249
-
250
- options = args.extract_options!
251
- text = options.delete(:label) || args.shift
252
-
253
- text = (localized_string(commit_button_i18n_key, text, :action, :model => commit_button_object_name) ||
254
- Formtastic::I18n.t(commit_button_i18n_key, :model => commit_button_object_name)) unless text.is_a?(::String)
255
-
256
- button_html = options.delete(:button_html) || {}
257
- button_html[:id] ||= "#{@object_name}_submit"
258
- button_html.merge!(:class => [button_html[:class], commit_button_i18n_key].compact.join(' '))
259
-
260
- wrapper_html = options.delete(:wrapper_html) || {}
261
- wrapper_html[:class] = (commit_button_wrapper_html_class << wrapper_html[:class]).flatten.compact.join(' ')
262
-
263
- accesskey = (options.delete(:accesskey) || default_commit_button_accesskey) unless button_html.has_key?(:accesskey)
264
- button_html = button_html.merge(:accesskey => accesskey) if accesskey
265
-
266
- template.content_tag(:li, Formtastic::Util.html_safe(submit(text, button_html)), wrapper_html)
267
- end
268
-
269
- def commit_button_object_name
270
- if new_or_persisted_object?
271
- # Deal with some complications with ActiveRecord::Base.human_name and two name models (eg UserPost)
272
- # ActiveRecord::Base.human_name falls back to ActiveRecord::Base.name.humanize ("Userpost")
273
- # if there's no i18n, which is pretty crappy. In this circumstance we want to detect this
274
- # fall back (human_name == name.humanize) and do our own thing name.underscore.humanize ("User Post")
275
- if @object.class.model_name.respond_to?(:human)
276
- object_name = @object.class.model_name.human
277
- else
278
- object_human_name = @object.class.human_name # default is UserPost => "Userpost", but i18n may do better ("User post")
279
- crappy_human_name = @object.class.name.humanize # UserPost => "Userpost"
280
- decent_human_name = @object.class.name.underscore.humanize # UserPost => "User post"
281
- object_name = (object_human_name == crappy_human_name) ? decent_human_name : object_human_name
282
- end
283
- else
284
- object_name = @object_name.to_s.send(label_str_method)
285
- end
286
-
287
- object_name
288
- end
289
-
290
- def commit_button_i18n_key
291
- if new_or_persisted_object?
292
- key = @object.persisted? ? :update : :create
293
- else
294
- key = :submit
295
- end
296
-
297
- key
298
- end
299
-
300
- def commit_button_wrapper_html_class
301
- ['commit', 'button'] # TODO: Add class reflecting on form action.
302
- end
303
-
304
- def new_or_persisted_object?
305
- @object && (@object.respond_to?(:persisted?) || @object.respond_to?(:new_record?))
306
- end
307
-
308
- end
309
- end
310
- end
@@ -1,77 +0,0 @@
1
- module Formtastic
2
- module Inputs
3
- module Base
4
- module GroupedCollections
5
-
6
- def raw_grouped_collection
7
- @raw_grouped_collection ||= raw_collection.map { |option| option.send(options[:group_by]) }.uniq
8
- end
9
-
10
- def grouped_collection
11
- @grouped_collection ||= raw_grouped_collection.sort_by { |group_item| group_item.send(group_label_method) }
12
- end
13
-
14
- def group_label_method
15
- @group_label_method ||= (group_label_method_from_options || group_label_method_from_grouped_collection)
16
- end
17
-
18
- def group_label_method_from_options
19
- options[:group_label]
20
- end
21
-
22
- def group_label_method_from_grouped_collection
23
- label_and_value_method_from_collection(raw_grouped_collection).first
24
- end
25
-
26
- def group_association
27
- @group_association ||= (group_association_from_options || group_association_from_reflection)
28
- end
29
-
30
- def group_association_from_options
31
- options[:group_association]
32
- end
33
-
34
- def group_by
35
- options[:group_by]
36
- end
37
-
38
- def group_association_from_reflection
39
- method_to_group_association_by = reflection.klass.reflect_on_association(group_by)
40
- group_class = method_to_group_association_by.klass
41
-
42
- # This will return in the normal case
43
- return method.to_s.pluralize.to_sym if group_class.reflect_on_association(method.to_s.pluralize)
44
-
45
- # This is for belongs_to associations named differently than their class
46
- # form.input :parent, :group_by => :customer
47
- # eg.
48
- # class Project
49
- # belongs_to :parent, :class_name => 'Project', :foreign_key => 'parent_id'
50
- # belongs_to :customer
51
- # end
52
- # class Customer
53
- # has_many :projects
54
- # end
55
- group_method = group_class.to_s.underscore.pluralize.to_sym
56
- return group_method if group_class.reflect_on_association(group_method) # :projects
57
-
58
- # This is for has_many associations named differently than their class
59
- # eg.
60
- # class Project
61
- # belongs_to :parent, :class_name => 'Project', :foreign_key => 'parent_id'
62
- # belongs_to :customer
63
- # end
64
- # class Customer
65
- # has_many :tasks, :class_name => 'Project', :foreign_key => 'customer_id'
66
- # end
67
- possible_associations = group_class.reflect_on_all_associations(:has_many).find_all {|assoc| assoc.klass == reflection.klass }
68
- return possible_associations.first.name.to_sym if possible_associations.count == 1
69
-
70
- raise "Cannot infer group association for #{method} grouped by #{group_by}, there were #{possible_associations.empty? ? 'no' : possible_associations.size} possible associations. Please specify using :group_association"
71
- end
72
-
73
- end
74
- end
75
- end
76
- end
77
-
@@ -1,25 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # Adapted from the rails3 compatibility shim in Haml 2.2
4
- module Formtastic
5
- # @private
6
- module Util
7
- extend self
8
- ## Rails XSS Safety
9
-
10
- # Returns the given text, marked as being HTML-safe.
11
- # With older versions of the Rails XSS-safety mechanism,
12
- # this destructively modifies the HTML-safety of `text`.
13
- #
14
- # @param text [String]
15
- # @return [String] `text`, marked as HTML-safe
16
- def html_safe(text)
17
- if text.respond_to?(:html_safe)
18
- text.html_safe
19
- else
20
- text
21
- end
22
- end
23
-
24
- end
25
- end
@@ -1,44 +0,0 @@
1
- require 'colored'
2
-
3
- # @private
4
- module RCov
5
-
6
- class VerifyTask < Rake::TaskLib
7
-
8
- attr_accessor :name
9
- attr_accessor :index_html
10
- attr_accessor :verbose
11
- attr_accessor :threshold
12
- attr_accessor :require_exact_threshold
13
-
14
- def initialize(name=:verify_rcov)
15
- @name = name
16
- @index_html = 'coverage/index.html'
17
- @verbose = true
18
- @require_exact_threshold = true
19
- yield self if block_given?
20
- raise "Threshold must be set" if @threshold.nil?
21
- define
22
- end
23
-
24
- def define
25
- desc "Verify that rcov coverage is at least #{threshold}%"
26
- task @name do
27
- total_coverage = 0
28
- File.open(index_html).each_line do |line|
29
- if line =~ /<tt class='coverage_total'>\s*(\d+\.\d+)%\s*<\/tt>/
30
- total_coverage = $1.to_f
31
- break
32
- end
33
- end
34
- output_coverage(total_coverage)
35
- end
36
- end
37
-
38
- def output_coverage(total_coverage)
39
- puts "Coverage: #{total_coverage}% (threshold: #{threshold}%)".green if verbose && total_coverage >= threshold
40
- raise "Coverage must be at least #{threshold}% but was #{total_coverage}%".red if total_coverage < threshold
41
- raise "Coverage has increased above the threshold of #{threshold}% to #{total_coverage}%. You should update your threshold value.".red if (total_coverage > threshold) and require_exact_threshold
42
- end
43
- end
44
- end
@@ -1,166 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe 'Formtastic::FormBuilder#buttons' do
5
-
6
- include FormtasticSpecHelper
7
-
8
- before do
9
- @output_buffer = ''
10
- mock_everything
11
- end
12
-
13
- describe 'with a block' do
14
- describe 'when no options are provided' do
15
- before do
16
- with_deprecation_silenced do
17
- concat(semantic_form_for(@new_post) do |builder|
18
- buttons = builder.buttons do
19
- concat('hello')
20
- end
21
- concat(buttons)
22
- end)
23
- end
24
- end
25
-
26
- it 'should render a fieldset inside the form, with a class of "inputs"' do
27
- output_buffer.should have_tag("form fieldset.buttons")
28
- end
29
-
30
- it 'should render an ol inside the fieldset' do
31
- output_buffer.should have_tag("form fieldset.buttons ol")
32
- end
33
-
34
- it 'should render the contents of the block inside the ol' do
35
- output_buffer.should have_tag("form fieldset.buttons ol", /hello/)
36
- end
37
-
38
- it 'should not render a legend inside the fieldset' do
39
- output_buffer.should_not have_tag("form fieldset.buttons legend")
40
- end
41
- end
42
-
43
- describe 'when a :name option is provided' do
44
- before do
45
- @legend_text = "Advanced options"
46
-
47
- with_deprecation_silenced do
48
- concat(semantic_form_for(@new_post) do |builder|
49
- builder.buttons :name => @legend_text do
50
- end
51
- end)
52
- end
53
- end
54
-
55
- it 'should render a fieldset inside the form' do
56
- output_buffer.should have_tag("form fieldset legend", /#{@legend_text}/)
57
- end
58
-
59
- end
60
-
61
- describe 'when other options are provided' do
62
- before do
63
- @id_option = 'advanced'
64
- @class_option = 'wide'
65
-
66
- with_deprecation_silenced do
67
- concat(semantic_form_for(@new_post) do |builder|
68
- builder.buttons :id => @id_option, :class => @class_option do
69
- end
70
- end)
71
- end
72
- end
73
-
74
- it 'should pass the options into the fieldset tag as attributes' do
75
- output_buffer.should have_tag("form fieldset##{@id_option}")
76
- output_buffer.should have_tag("form fieldset.#{@class_option}")
77
- end
78
-
79
- end
80
-
81
- end
82
-
83
- describe 'without a block' do
84
-
85
- describe 'with no args (default buttons)' do
86
-
87
- before do
88
- with_deprecation_silenced do
89
- concat(semantic_form_for(@new_post) do |builder|
90
- concat(builder.buttons)
91
- end)
92
- end
93
- end
94
-
95
- it 'should render a form' do
96
- output_buffer.should have_tag('form')
97
- end
98
-
99
- it 'should render a buttons fieldset inside the form' do
100
- output_buffer.should have_tag('form fieldset.buttons')
101
- end
102
-
103
- it 'should not render a legend in the fieldset' do
104
- output_buffer.should_not have_tag('form fieldset.buttons legend')
105
- end
106
-
107
- it 'should render an ol in the fieldset' do
108
- output_buffer.should have_tag('form fieldset.buttons ol')
109
- end
110
-
111
- it 'should render a list item in the ol for each default button' do
112
- output_buffer.should have_tag('form fieldset.buttons ol li', :count => 1)
113
- end
114
-
115
- it 'should render a commit list item for the commit button' do
116
- output_buffer.should have_tag('form fieldset.buttons ol li.commit')
117
- end
118
-
119
- end
120
-
121
- describe 'with button names as args' do
122
-
123
- before do
124
- with_deprecation_silenced do
125
- concat(semantic_form_for(@new_post) do |builder|
126
- concat(builder.buttons(:commit))
127
- end)
128
- end
129
- end
130
-
131
- it 'should render a form with a fieldset containing a list item for each button arg' do
132
- output_buffer.should have_tag('form > fieldset.buttons > ol > li', :count => 1)
133
- output_buffer.should have_tag('form > fieldset.buttons > ol > li.commit')
134
- end
135
-
136
- end
137
-
138
- describe 'with button names as args and an options hash' do
139
-
140
- before do
141
- with_deprecation_silenced do
142
- concat(semantic_form_for(@new_post) do |builder|
143
- concat(builder.buttons(:commit, :name => "Now click a button", :id => "my-id"))
144
- end)
145
- end
146
- end
147
-
148
- it 'should render a form with a fieldset containing a list item for each button arg' do
149
- output_buffer.should have_tag('form > fieldset.buttons > ol > li', :count => 1)
150
- output_buffer.should have_tag('form > fieldset.buttons > ol > li.commit', :count => 1)
151
- end
152
-
153
- it 'should pass the options down to the fieldset' do
154
- output_buffer.should have_tag('form > fieldset#my-id.buttons')
155
- end
156
-
157
- it 'should use the special :name option as a text for the legend tag' do
158
- output_buffer.should have_tag('form > fieldset#my-id.buttons > legend', /Now click a button/)
159
- end
160
-
161
- end
162
-
163
- end
164
-
165
- end
166
-