hanami 2.3.2 → 3.0.0.rc1

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 (184) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +55 -19
  3. data/LICENSE +20 -0
  4. data/README.md +18 -35
  5. data/hanami.gemspec +36 -37
  6. data/lib/hanami/config/db.rb +2 -0
  7. data/lib/hanami/config/i18n.rb +138 -0
  8. data/lib/hanami/config/logger.rb +15 -7
  9. data/lib/hanami/config/null_config.rb +1 -1
  10. data/lib/hanami/config/views.rb +17 -0
  11. data/lib/hanami/config.rb +66 -22
  12. data/lib/hanami/errors.rb +6 -0
  13. data/lib/hanami/extensions/action/slice_configured_action.rb +1 -1
  14. data/lib/hanami/extensions/action.rb +2 -2
  15. data/lib/hanami/extensions/mailer/slice_configured_mailer.rb +120 -0
  16. data/lib/hanami/extensions/mailer.rb +28 -0
  17. data/lib/hanami/extensions/operation/slice_configured_db_operation.rb +2 -0
  18. data/lib/hanami/extensions/view/context.rb +26 -4
  19. data/lib/hanami/extensions/view/part.rb +2 -0
  20. data/lib/hanami/extensions/view/slice_configured_context.rb +7 -0
  21. data/lib/hanami/extensions/view/slice_configured_part.rb +2 -0
  22. data/lib/hanami/extensions/view/slice_configured_view.rb +8 -8
  23. data/lib/hanami/extensions/view/standard_helpers.rb +4 -0
  24. data/lib/hanami/extensions.rb +6 -1
  25. data/lib/hanami/helpers/assets_helper.rb +0 -4
  26. data/lib/hanami/helpers/form_helper.rb +1 -1
  27. data/lib/hanami/helpers/i18n_helper.rb +176 -0
  28. data/lib/hanami/logger/rack_formatter.rb +73 -0
  29. data/lib/hanami/logger/sql_formatter.rb +80 -0
  30. data/lib/hanami/logger/sql_logger.rb +48 -0
  31. data/lib/hanami/middleware/render_errors.rb +2 -2
  32. data/lib/hanami/providers/db.rb +7 -2
  33. data/lib/hanami/providers/db_logging.rb +4 -7
  34. data/lib/hanami/providers/i18n/backend.rb +369 -0
  35. data/lib/hanami/providers/i18n/locale/en.yml +57 -0
  36. data/lib/hanami/providers/i18n.rb +114 -0
  37. data/lib/hanami/providers/mailers.rb +101 -0
  38. data/lib/hanami/routes.rb +1 -0
  39. data/lib/hanami/settings/composite_store.rb +53 -0
  40. data/lib/hanami/settings.rb +4 -4
  41. data/lib/hanami/slice/router.rb +15 -10
  42. data/lib/hanami/slice.rb +71 -11
  43. data/lib/hanami/slice_registrar.rb +2 -2
  44. data/lib/hanami/universal_logger.rb +250 -0
  45. data/lib/hanami/version.rb +1 -1
  46. data/lib/hanami/web/rack_logger.rb +2 -80
  47. data/lib/hanami/web/welcome.html.erb +443 -58
  48. data/lib/hanami.rb +4 -2
  49. metadata +28 -276
  50. data/CODE_OF_CONDUCT.md +0 -74
  51. data/FEATURES.md +0 -269
  52. data/LICENSE.md +0 -22
  53. data/spec/integration/action/cookies_spec.rb +0 -58
  54. data/spec/integration/action/csrf_protection_spec.rb +0 -54
  55. data/spec/integration/action/format_config_spec.rb +0 -129
  56. data/spec/integration/action/routes_spec.rb +0 -71
  57. data/spec/integration/action/sessions_spec.rb +0 -50
  58. data/spec/integration/action/slice_configuration_spec.rb +0 -284
  59. data/spec/integration/action/view_rendering/automatic_rendering_spec.rb +0 -247
  60. data/spec/integration/action/view_rendering/paired_view_inference_spec.rb +0 -115
  61. data/spec/integration/action/view_rendering/view_context_spec.rb +0 -221
  62. data/spec/integration/action/view_rendering_spec.rb +0 -89
  63. data/spec/integration/assets/assets_spec.rb +0 -155
  64. data/spec/integration/assets/cross_slice_assets_helpers_spec.rb +0 -129
  65. data/spec/integration/assets/serve_static_assets_spec.rb +0 -152
  66. data/spec/integration/code_loading/loading_from_app_spec.rb +0 -152
  67. data/spec/integration/code_loading/loading_from_lib_spec.rb +0 -242
  68. data/spec/integration/code_loading/loading_from_slice_spec.rb +0 -165
  69. data/spec/integration/container/application_routes_helper_spec.rb +0 -48
  70. data/spec/integration/container/auto_injection_spec.rb +0 -53
  71. data/spec/integration/container/auto_registration_spec.rb +0 -86
  72. data/spec/integration/container/autoloader_spec.rb +0 -82
  73. data/spec/integration/container/imports_spec.rb +0 -253
  74. data/spec/integration/container/prepare_container_spec.rb +0 -125
  75. data/spec/integration/container/provider_environment_spec.rb +0 -52
  76. data/spec/integration/container/provider_lifecycle_spec.rb +0 -61
  77. data/spec/integration/container/shutdown_spec.rb +0 -91
  78. data/spec/integration/container/standard_providers/rack_provider_spec.rb +0 -44
  79. data/spec/integration/container/standard_providers_spec.rb +0 -124
  80. data/spec/integration/db/auto_registration_spec.rb +0 -39
  81. data/spec/integration/db/commands_spec.rb +0 -80
  82. data/spec/integration/db/db_inflector_spec.rb +0 -57
  83. data/spec/integration/db/db_slices_spec.rb +0 -398
  84. data/spec/integration/db/db_spec.rb +0 -245
  85. data/spec/integration/db/gateways_spec.rb +0 -361
  86. data/spec/integration/db/logging_spec.rb +0 -301
  87. data/spec/integration/db/mappers_spec.rb +0 -84
  88. data/spec/integration/db/provider_config_spec.rb +0 -88
  89. data/spec/integration/db/provider_spec.rb +0 -35
  90. data/spec/integration/db/relations_spec.rb +0 -60
  91. data/spec/integration/db/repo_spec.rb +0 -300
  92. data/spec/integration/db/slices_importing_from_parent.rb +0 -130
  93. data/spec/integration/dotenv_loading_spec.rb +0 -138
  94. data/spec/integration/logging/exception_logging_spec.rb +0 -120
  95. data/spec/integration/logging/notifications_spec.rb +0 -68
  96. data/spec/integration/logging/request_logging_spec.rb +0 -202
  97. data/spec/integration/operations/extension_spec.rb +0 -122
  98. data/spec/integration/rack_app/body_parser_spec.rb +0 -108
  99. data/spec/integration/rack_app/method_override_spec.rb +0 -97
  100. data/spec/integration/rack_app/middleware_spec.rb +0 -720
  101. data/spec/integration/rack_app/non_booted_rack_app_spec.rb +0 -104
  102. data/spec/integration/rack_app/rack_app_spec.rb +0 -442
  103. data/spec/integration/rake_tasks_spec.rb +0 -107
  104. data/spec/integration/router/resource_routes_spec.rb +0 -281
  105. data/spec/integration/settings/access_in_slice_class_body_spec.rb +0 -83
  106. data/spec/integration/settings/access_to_constants_spec.rb +0 -46
  107. data/spec/integration/settings/loading_from_env_spec.rb +0 -188
  108. data/spec/integration/settings/settings_component_loading_spec.rb +0 -113
  109. data/spec/integration/settings/slice_registration_spec.rb +0 -145
  110. data/spec/integration/settings/using_types_spec.rb +0 -80
  111. data/spec/integration/setup_spec.rb +0 -165
  112. data/spec/integration/slices/external_slice_spec.rb +0 -91
  113. data/spec/integration/slices/slice_configuration_spec.rb +0 -42
  114. data/spec/integration/slices/slice_loading_spec.rb +0 -171
  115. data/spec/integration/slices/slice_registrations_spec.rb +0 -80
  116. data/spec/integration/slices/slice_routing_spec.rb +0 -219
  117. data/spec/integration/slices_spec.rb +0 -471
  118. data/spec/integration/view/config/default_context_spec.rb +0 -149
  119. data/spec/integration/view/config/inflector_spec.rb +0 -57
  120. data/spec/integration/view/config/part_class_spec.rb +0 -147
  121. data/spec/integration/view/config/part_namespace_spec.rb +0 -103
  122. data/spec/integration/view/config/paths_spec.rb +0 -119
  123. data/spec/integration/view/config/scope_class_spec.rb +0 -147
  124. data/spec/integration/view/config/scope_namespace_spec.rb +0 -103
  125. data/spec/integration/view/config/template_spec.rb +0 -38
  126. data/spec/integration/view/context/assets_spec.rb +0 -79
  127. data/spec/integration/view/context/inflector_spec.rb +0 -40
  128. data/spec/integration/view/context/request_spec.rb +0 -57
  129. data/spec/integration/view/context/routes_spec.rb +0 -84
  130. data/spec/integration/view/helpers/form_helper_spec.rb +0 -174
  131. data/spec/integration/view/helpers/part_helpers_spec.rb +0 -124
  132. data/spec/integration/view/helpers/scope_helpers_spec.rb +0 -84
  133. data/spec/integration/view/helpers/user_defined_helpers/part_helpers_spec.rb +0 -162
  134. data/spec/integration/view/helpers/user_defined_helpers/scope_helpers_spec.rb +0 -119
  135. data/spec/integration/view/parts/default_rendering_spec.rb +0 -138
  136. data/spec/integration/view/slice_configuration_spec.rb +0 -289
  137. data/spec/integration/view/views_spec.rb +0 -103
  138. data/spec/integration/web/content_security_policy_nonce_spec.rb +0 -251
  139. data/spec/integration/web/render_detailed_errors_spec.rb +0 -107
  140. data/spec/integration/web/render_errors_spec.rb +0 -242
  141. data/spec/integration/web/welcome_view_spec.rb +0 -84
  142. data/spec/spec_helper.rb +0 -28
  143. data/spec/support/app_integration.rb +0 -157
  144. data/spec/support/coverage.rb +0 -1
  145. data/spec/support/matchers.rb +0 -32
  146. data/spec/support/rspec.rb +0 -27
  147. data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +0 -96
  148. data/spec/unit/hanami/config/actions/cookies_spec.rb +0 -46
  149. data/spec/unit/hanami/config/actions/csrf_protection_spec.rb +0 -58
  150. data/spec/unit/hanami/config/actions/default_values_spec.rb +0 -43
  151. data/spec/unit/hanami/config/actions/sessions_spec.rb +0 -48
  152. data/spec/unit/hanami/config/actions_spec.rb +0 -52
  153. data/spec/unit/hanami/config/base_url_spec.rb +0 -25
  154. data/spec/unit/hanami/config/console_spec.rb +0 -22
  155. data/spec/unit/hanami/config/db_spec.rb +0 -38
  156. data/spec/unit/hanami/config/inflector_spec.rb +0 -35
  157. data/spec/unit/hanami/config/logger_spec.rb +0 -195
  158. data/spec/unit/hanami/config/render_detailed_errors_spec.rb +0 -25
  159. data/spec/unit/hanami/config/render_errors_spec.rb +0 -25
  160. data/spec/unit/hanami/config/router_spec.rb +0 -44
  161. data/spec/unit/hanami/config/slices_spec.rb +0 -34
  162. data/spec/unit/hanami/config/views_spec.rb +0 -80
  163. data/spec/unit/hanami/env_spec.rb +0 -37
  164. data/spec/unit/hanami/extensions/view/context_spec.rb +0 -59
  165. data/spec/unit/hanami/helpers/assets_helper/asset_url_spec.rb +0 -120
  166. data/spec/unit/hanami/helpers/assets_helper/audio_tag_spec.rb +0 -132
  167. data/spec/unit/hanami/helpers/assets_helper/favicon_tag_spec.rb +0 -87
  168. data/spec/unit/hanami/helpers/assets_helper/image_tag_spec.rb +0 -92
  169. data/spec/unit/hanami/helpers/assets_helper/javascript_tag_spec.rb +0 -143
  170. data/spec/unit/hanami/helpers/assets_helper/stylesheet_tag_spec.rb +0 -126
  171. data/spec/unit/hanami/helpers/assets_helper/video_tag_spec.rb +0 -136
  172. data/spec/unit/hanami/helpers/form_helper_spec.rb +0 -2857
  173. data/spec/unit/hanami/port_spec.rb +0 -117
  174. data/spec/unit/hanami/providers/db/config/default_config_spec.rb +0 -100
  175. data/spec/unit/hanami/providers/db/config/gateway_spec.rb +0 -73
  176. data/spec/unit/hanami/providers/db/config_spec.rb +0 -143
  177. data/spec/unit/hanami/router/errors/not_allowed_error_spec.rb +0 -27
  178. data/spec/unit/hanami/router/errors/not_found_error_spec.rb +0 -22
  179. data/spec/unit/hanami/settings/env_store_spec.rb +0 -52
  180. data/spec/unit/hanami/settings_spec.rb +0 -111
  181. data/spec/unit/hanami/slice_configurable_spec.rb +0 -141
  182. data/spec/unit/hanami/slice_name_spec.rb +0 -47
  183. data/spec/unit/hanami/slice_spec.rb +0 -99
  184. data/spec/unit/hanami/web/rack_logger_spec.rb +0 -99
@@ -1,2857 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "hanami/helpers/form_helper"
4
- require "hanami/view/erb/template"
5
-
6
- RSpec.describe Hanami::Helpers::FormHelper do
7
- subject(:obj) {
8
- Class.new {
9
- include Hanami::Helpers::FormHelper
10
-
11
- attr_reader :_context
12
-
13
- def initialize(context)
14
- @_context = context
15
- end
16
- }.new(context)
17
- }
18
-
19
- let(:context) {
20
- Hanami::View::Context.new(request: request, inflector: Dry::Inflector.new)
21
- }
22
-
23
- let(:request) {
24
- Hanami::Action::Request.new(env: rack_request, params: params, session_enabled: true)
25
- }
26
-
27
- let(:rack_request) {
28
- Rack::MockRequest.env_for("http://example.com/")
29
- }
30
-
31
- let(:params) { {} }
32
-
33
- def form_for(...)
34
- obj.instance_eval { form_for(...) }
35
- end
36
-
37
- def h(&block)
38
- obj.instance_eval(&block)
39
- end
40
-
41
- def render(erb)
42
- Hanami::View::ERB::Template.new { erb }.render(obj)
43
- end
44
-
45
- describe "#form_for" do
46
- it "renders" do
47
- html = form_for("/books")
48
- expect(html).to eq %(<form action="/books" accept-charset="utf-8" method="POST"></form>)
49
- end
50
-
51
- it "allows to assign 'id' attribute" do
52
- html = form_for("/books", id: "book-form")
53
-
54
- expect(html).to eq %(<form action="/books" id="book-form" accept-charset="utf-8" method="POST"></form>)
55
- end
56
-
57
- it "allows to override 'method' attribute ('get')" do
58
- html = form_for("/books", method: "get")
59
- expect(html).to eq %(<form action="/books" method="GET" accept-charset="utf-8"></form>)
60
- end
61
-
62
- it "allows to override 'method' attribute (:get)" do
63
- html = form_for("/books", method: :get)
64
- expect(html).to eq %(<form action="/books" method="GET" accept-charset="utf-8"></form>)
65
- end
66
-
67
- it "allows to override 'method' attribute ('GET')" do
68
- html = form_for("/books", method: "GET")
69
- expect(html).to eq %(<form action="/books" method="GET" accept-charset="utf-8"></form>)
70
- end
71
-
72
- %i[patch put delete].each do |verb|
73
- it "allows to override 'method' attribute (#{verb})" do
74
- html = form_for("/books", method: verb) do |f|
75
- f.text_field "book.title"
76
- end
77
-
78
- expect(html).to eq %(<form action="/books" method="POST" accept-charset="utf-8"><input type="hidden" name="_method" value="#{verb.to_s.upcase}"><input type="text" name="book[title]" id="book-title" value=""></form>)
79
- end
80
- end
81
-
82
- it "allows to specify HTML attributes" do
83
- html = form_for("/books", class: "form-horizontal")
84
- expect(html).to eq %(<form action="/books" class="form-horizontal" accept-charset="utf-8" method="POST"></form>)
85
- end
86
-
87
- context "input name" do
88
- it "sets a base name" do
89
- expected_html = <<~HTML
90
- <form action="/books" accept-charset="utf-8" method="POST">
91
- <input type="text" name="book[author][avatar][url]" id="book-author-avatar-url" value="">
92
- </form>
93
- HTML
94
-
95
- html = form_for("book", "/books") do |f|
96
- f.text_field("author.avatar.url")
97
- end
98
-
99
- expect(html).to eq_html expected_html
100
-
101
- html = form_for("book", "/books") do |f|
102
- f.fields_for("author.avatar") do |fa|
103
- fa.text_field("url")
104
- end
105
- end
106
-
107
- expect(html).to eq_html expected_html
108
- end
109
-
110
- it "renders nested field names" do
111
- html = form_for("/books") do |f|
112
- f.text_field "book.author.avatar.url"
113
- end
114
-
115
- expect(html).to include %(<input type="text" name="book[author][avatar][url]" id="book-author-avatar-url" value="">)
116
- end
117
-
118
- context "using values from scope locals" do
119
- let(:values) { {book: double("book", author: double("author", avatar: double("avatar", url: val)))} }
120
- let(:val) { "https://hanami.test/avatar.png" }
121
-
122
- before do
123
- # TODO: Maybe our `obj` should actually be a real Scope subclass
124
- values = self.values
125
- obj.define_singleton_method(:_locals) { values }
126
- end
127
-
128
- it "renders with value" do
129
- html = form_for("/books") do |f|
130
- f.text_field "book.author.avatar.url"
131
- end
132
-
133
- expect(html).to include %(<input type="text" name="book[author][avatar][url]" id="book-author-avatar-url" value="#{val}">)
134
- end
135
- end
136
-
137
- context "with explicit values given" do
138
- let(:values) { {book: double("book", author: double("author", avatar: double("avatar", url: val)))} }
139
- let(:val) { "https://hanami.test/avatar.png" }
140
-
141
- it "renders with value" do
142
- html = form_for("/books", values: values) do |f|
143
- f.text_field "book.author.avatar.url"
144
- end
145
-
146
- expect(html).to include %(<input type="text" name="book[author][avatar][url]" id="book-author-avatar-url" value="#{val}">)
147
- end
148
-
149
- it "allows to override 'value' attribute" do
150
- html = form_for("/books", values: values) do |f|
151
- f.text_field "book.author.avatar.url", value: "https://hanami.test/another-avatar.jpg"
152
- end
153
-
154
- expect(html).to include %(<input type="text" name="book[author][avatar][url]" id="book-author-avatar-url" value="https://hanami.test/another-avatar.jpg">)
155
- end
156
- end
157
-
158
- context "with filled params" do
159
- let(:params) { {book: {author: {avatar: {url: val}}}} }
160
- let(:val) { "https://hanami.test/avatar.png" }
161
-
162
- it "renders with value" do
163
- html = form_for("/books") do |f|
164
- f.text_field "book.author.avatar.url"
165
- end
166
-
167
- expect(html).to include %(<input type="text" name="book[author][avatar][url]" id="book-author-avatar-url" value="#{val}">)
168
- end
169
-
170
- it "allows to override 'value' attribute" do
171
- html = form_for("/books") do |f|
172
- f.text_field "book.author.avatar.url", value: "https://hanami.test/another-avatar.jpg"
173
- end
174
-
175
- expect(html).to include %(<input type="text" name="book[author][avatar][url]" id="book-author-avatar-url" value="https://hanami.test/another-avatar.jpg">)
176
- end
177
- end
178
- end
179
-
180
- context "CSRF protection" do
181
- let(:csrf_token) { "abc123" }
182
-
183
- before do
184
- allow(request).to receive(:session) { {_csrf_token: csrf_token} }
185
- end
186
-
187
- it "injects hidden field session is enabled" do
188
- html = form_for("/books")
189
- expect(html).to eq %(<form action="/books" accept-charset="utf-8" method="POST"><input type="hidden" name="_csrf_token" value="#{csrf_token}"></form>)
190
- end
191
-
192
- context "with missing token" do
193
- let(:csrf_token) { nil }
194
-
195
- it "doesn't inject hidden field" do
196
- html = form_for("/books")
197
- expect(html).to eq %(<form action="/books" accept-charset="utf-8" method="POST"></form>)
198
- end
199
- end
200
-
201
- context "with csrf_token on get verb" do
202
- it "doesn't inject hidden field" do
203
- html = form_for("/books", method: "GET")
204
- expect(html).to eq %(<form action="/books" method="GET" accept-charset="utf-8"></form>)
205
- end
206
- end
207
-
208
- %i[patch put delete].each do |verb|
209
- it "it injects hidden field when method override (#{verb}) is active" do
210
- html = form_for("/books", method: verb)
211
- expect(html).to eq %(<form action="/books" method="POST" accept-charset="utf-8"><input type="hidden" name="_method" value="#{verb.to_s.upcase}"><input type="hidden" name="_csrf_token" value="#{csrf_token}"></form>)
212
- end
213
- end
214
- end
215
-
216
- context "CSRF meta tags" do
217
- let(:csrf_token) { "abc123" }
218
-
219
- before do
220
- allow(request).to receive(:session) { {_csrf_token: csrf_token} }
221
- end
222
-
223
- def csrf_meta_tags(...)
224
- h { csrf_meta_tags(...) }
225
- end
226
-
227
- it "prints meta tags" do
228
- html = csrf_meta_tags
229
- expect(html).to eq %(<meta name="csrf-param" content="_csrf_token"><meta name="csrf-token" content="#{csrf_token}">)
230
- end
231
-
232
- context "when CSRF token is nil" do
233
- let(:csrf_token) { nil }
234
-
235
- it "returns nil" do
236
- expect(csrf_meta_tags).to be(nil)
237
- end
238
- end
239
- end
240
-
241
- context "remote: true" do
242
- it "adds data-remote=true to form attributes" do
243
- html = form_for("/books", "data-remote": true)
244
- expect(html).to eq %(<form action="/books" data-remote="true" accept-charset="utf-8" method="POST"></form>)
245
- end
246
-
247
- it "adds data-remote=false to form attributes" do
248
- html = form_for("/books", "data-remote": false)
249
- expect(html).to eq %(<form action="/books" data-remote="false" accept-charset="utf-8" method="POST"></form>)
250
- end
251
-
252
- it "adds data-remote= to form attributes" do
253
- html = form_for("/books", "data-remote": nil)
254
- expect(html).to eq %(<form action="/books" accept-charset="utf-8" method="POST"></form>)
255
- end
256
- end
257
-
258
- context "explicitly given params" do
259
- let(:params) { {song: {title: "Orphans"}} }
260
- let(:given_params) { {song: {title: "Arabesque"}} }
261
- let(:action) { "/songs" }
262
-
263
- it "renders" do
264
- html = form_for("/songs", params: given_params) do |f|
265
- f.text_field "song.title"
266
- end
267
-
268
- expect(html).to eq(%(<form action="/songs" accept-charset="utf-8" method="POST"><input type="text" name="song[title]" id="song-title" value="Arabesque"></form>))
269
- end
270
- end
271
- end
272
-
273
- describe "#fields_for" do
274
- it "renders" do
275
- html = render(<<~ERB)
276
- <%= form_for("/books") do |f| %>
277
- <% f.fields_for "book.categories" do |fa| %>
278
- <%= fa.text_field :name %>
279
-
280
- <% fa.fields_for :subcategories do |fb| %>
281
- <%= fb.text_field :name %>
282
- <% end %>
283
-
284
- <%= fa.text_field :name2 %>
285
- <% end %>
286
-
287
- <%= f.text_field "book.title" %>
288
- <% end %>
289
- ERB
290
-
291
- expect(html).to eq_html <<~HTML
292
- <form action="/books" accept-charset="utf-8" method="POST">
293
- <input type="text" name="book[categories][name]" id="book-categories-name" value="">
294
- <input type="text" name="book[categories][subcategories][name]" id="book-categories-subcategories-name" value="">
295
- <input type="text" name="book[categories][name2]" id="book-categories-name2" value="">
296
- <input type="text" name="book[title]" id="book-title" value="">
297
- </form>
298
- HTML
299
- end
300
-
301
- describe "with filled params" do
302
- let(:params) { {book: {title: "TDD", categories: {name: "foo", name2: "bar", subcategories: {name: "sub"}}}} }
303
-
304
- it "renders" do
305
- html = render(<<~ERB)
306
- <%= form_for("/books") do |f| %>
307
- <% f.fields_for "book.categories" do |fa| %>
308
- <%= fa.text_field :name %>
309
-
310
- <% fa.fields_for :subcategories do |fb| %>
311
- <%= fb.text_field :name %>
312
- <% end %>
313
-
314
- <%= fa.text_field :name2 %>
315
- <% end %>
316
-
317
- <%= f.text_field "book.title" %>
318
- <% end %>
319
- ERB
320
-
321
- expect(html).to eq_html <<~HTML
322
- <form action="/books" accept-charset="utf-8" method="POST">
323
- <input type="text" name="book[categories][name]" id="book-categories-name" value="foo">
324
- <input type="text" name="book[categories][subcategories][name]" id="book-categories-subcategories-name" value="sub">
325
- <input type="text" name="book[categories][name2]" id="book-categories-name2" value="bar">
326
- <input type="text" name="book[title]" id="book-title" value="TDD">
327
- </form>
328
- HTML
329
- end
330
- end
331
- end
332
-
333
- describe "#fields_for_collection" do
334
- let(:params) { {book: {categories: [{name: "foo", new: true, genre: nil}]}} }
335
-
336
- it "renders" do
337
- html = render(<<~ERB)
338
- <%= form_for("/books") do |f| %>
339
- <% f.fields_for_collection "book.categories" do |fa| %>
340
- <%= fa.text_field :name %>
341
- <%= fa.hidden_field :name %>
342
- <%= fa.text_area :name %>
343
- <%= fa.check_box :new %>
344
- <%= fa.select :genre, [%w[Terror terror], %w[Comedy comedy]] %>
345
- <%= fa.color_field :name %>
346
- <%= fa.date_field :name %>
347
- <%= fa.datetime_field :name %>
348
- <%= fa.datetime_local_field :name %>
349
- <%= fa.time_field :name %>
350
- <%= fa.month_field :name %>
351
- <%= fa.week_field :name %>
352
- <%= fa.email_field :name %>
353
- <%= fa.url_field :name %>
354
- <%= fa.tel_field :name %>
355
- <%= fa.file_field :name %>
356
- <%= fa.number_field :name %>
357
- <%= fa.range_field :name %>
358
- <%= fa.search_field :name %>
359
- <%= fa.radio_button :name, "Fiction" %>
360
- <%= fa.password_field :name %>
361
- <%= fa.datalist :name, ["Italy", "United States"], "books" %>
362
- <% end %>
363
- <% end %>
364
- ERB
365
-
366
- expected = <<~HTML
367
- <form action="/books" enctype="multipart/form-data" accept-charset="utf-8" method="POST">
368
- <input type="text" name="book[categories][][name]" id="book-categories-0-name" value="foo">
369
- <input type="hidden" name="book[categories][][name]" id="book-categories-0-name" value="foo">
370
- <textarea name="book[categories][][name]" id="book-categories-0-name">
371
- foo</textarea>
372
- <input type="hidden" name="book[categories][][new]" value="0"><input type="checkbox" name="book[categories][][new]" id="book-categories-0-new" value="1" checked="checked">
373
- <select name="book[categories][][genre]" id="book-categories-0-genre"><option value="terror">Terror</option><option value="comedy">Comedy</option></select>
374
- <input type="color" name="book[categories][][name]" id="book-categories-0-name" value="foo">
375
- <input type="date" name="book[categories][][name]" id="book-categories-0-name" value="foo">
376
- <input type="datetime" name="book[categories][][name]" id="book-categories-0-name" value="foo">
377
- <input type="datetime-local" name="book[categories][][name]" id="book-categories-0-name" value="foo">
378
- <input type="time" name="book[categories][][name]" id="book-categories-0-name" value="foo">
379
- <input type="month" name="book[categories][][name]" id="book-categories-0-name" value="foo">
380
- <input type="week" name="book[categories][][name]" id="book-categories-0-name" value="foo">
381
- <input type="email" name="book[categories][][name]" id="book-categories-0-name" value="foo">
382
- <input type="url" name="book[categories][][name]" id="book-categories-0-name" value="">
383
- <input type="tel" name="book[categories][][name]" id="book-categories-0-name" value="foo">
384
- <input type="file" name="book[categories][][name]" id="book-categories-0-name">
385
- <input type="number" name="book[categories][][name]" id="book-categories-0-name" value="foo">
386
- <input type="range" name="book[categories][][name]" id="book-categories-0-name" value="foo">
387
- <input type="search" name="book[categories][][name]" id="book-categories-0-name" value="foo">
388
- <input type="radio" name="book[categories][][name]" value="Fiction">
389
- <input type="password" name="book[categories][][name]" id="book-categories-0-name" value="">
390
- <input type="text" name="book[categories][][name]" id="book-categories-0-name" value="foo" list="books"><datalist id="books"><option value="Italy"></option><option value="United States"></option></datalist>
391
- </form>
392
- HTML
393
-
394
- expect(html).to eq_html(expected)
395
- end
396
-
397
- context "with base name" do
398
- let(:params) { {book: {categories: [{name: "foo"}, {name: "bar"}]}} }
399
-
400
- it "renders" do
401
- html = render(<<~ERB)
402
- <%= form_for("book", "/books") do |f| %>
403
- <% f.fields_for_collection "categories" do |fa| %>
404
- <%= fa.text_field :name %>
405
- <% end %>
406
- <% end %>
407
- ERB
408
-
409
- expected = <<~HTML
410
- <form action="/books" accept-charset="utf-8" method="POST">
411
- <input type="text" name="book[categories][][name]" id="book-categories-0-name" value="foo">
412
- <input type="text" name="book[categories][][name]" id="book-categories-1-name" value="bar">
413
- </form>
414
- HTML
415
-
416
- expect(html).to eq_html(expected)
417
- end
418
- end
419
- end
420
-
421
- describe "#label" do
422
- it "renders capitalized string" do
423
- html = form_for("/books") do |f|
424
- f.label "book.free_shipping"
425
- end
426
-
427
- expect(html).to include %(<label for="book-free-shipping">Free shipping</label>)
428
- end
429
-
430
- it "accepts a symbol" do
431
- html = form_for("/books") do |f|
432
- f.label :free_shipping
433
- end
434
-
435
- expect(html).to include %(<label for="free-shipping">Free shipping</label>)
436
- end
437
-
438
- it "accepts a string as custom content" do
439
- html = form_for("/books") do |f|
440
- f.label "Free Shipping!", for: "book.free_shipping"
441
- end
442
-
443
- expect(html).to include %(<label for="book-free-shipping">Free Shipping!</label>)
444
- end
445
-
446
- it "renders a label with block" do
447
- html = render(<<~ERB)
448
- <%= form_for "/books" do |f| %>
449
- <%= f.label for: "book.free_shipping" do %>
450
- Free Shipping
451
- <%= tag.abbr "*", title: "optional", aria: {label: "optional"} %>
452
- <% end %>
453
- <% end %>
454
- ERB
455
-
456
- expect(html).to eq <<~HTML
457
- <form action="/books" accept-charset="utf-8" method="POST">
458
- <label for="book-free-shipping">
459
- Free Shipping
460
- <abbr title="optional" aria-label="optional">*</abbr>
461
- </label>
462
- </form>
463
- HTML
464
- end
465
- end
466
-
467
- describe "#button" do
468
- it "renders a button" do
469
- html = form_for("/books") do |f|
470
- f.button "Click me"
471
- end
472
-
473
- expect(html).to include %(<button>Click me</button>)
474
- end
475
-
476
- it "renders a button with HTML attributes" do
477
- html = form_for("/books") do |f|
478
- f.button "Click me", class: "btn btn-secondary"
479
- end
480
-
481
- expect(html).to include(%(<button class="btn btn-secondary">Click me</button>))
482
- end
483
-
484
- it "renders a button with block" do
485
- html = render(<<~ERB)
486
- <%= form_for("/books") do |f| %>
487
- <%= f.button class: "btn btn-secondary" do %>
488
- <%= tag.span class: "oi oi-check" %>
489
- <% end %>
490
- <% end %>
491
- ERB
492
-
493
- expect(html).to eq <<~HTML
494
- <form action="/books" accept-charset="utf-8" method="POST">
495
- <button class="btn btn-secondary">
496
- <span class="oi oi-check"></span>
497
- </button>
498
- </form>
499
- HTML
500
- end
501
- end
502
-
503
- describe "#submit" do
504
- it "renders a submit button" do
505
- html = form_for("/books") do |f|
506
- f.submit "Create"
507
- end
508
-
509
- expect(html).to include %(<button type="submit">Create</button>)
510
- end
511
-
512
- it "renders a submit button with HTML attributes" do
513
- html = form_for("/books") do |f|
514
- f.submit "Create", class: "btn btn-primary"
515
- end
516
-
517
- expect(html).to include %(<button type="submit" class="btn btn-primary">Create</button>)
518
- end
519
-
520
- it "renders a submit button with block" do
521
- html = render(<<~ERB)
522
- <%= form_for "/books" do |f| %>
523
- <%= f.submit class: "btn btn-primary" do %>
524
- <%= tag.span class: "oi oi-check" %>
525
- <% end %>
526
- <% end %>
527
- ERB
528
-
529
- expect(html).to eq <<~HTML
530
- <form action="/books" accept-charset="utf-8" method="POST">
531
- <button type="submit" class="btn btn-primary">
532
- <span class="oi oi-check"></span>
533
- </button>
534
- </form>
535
- HTML
536
- end
537
- end
538
-
539
- describe "#image_button" do
540
- it "renders an image button" do
541
- html = form_for("/books") do |f|
542
- f.image_button "https://hanamirb.org/assets/image_button.png"
543
- end
544
-
545
- expect(html).to include %(<input type="image" src="https://hanamirb.org/assets/image_button.png">)
546
- end
547
-
548
- it "renders an image button with HTML attributes" do
549
- html = form_for("/books") do |f|
550
- f.image_button "https://hanamirb.org/assets/image_button.png", name: "image", width: "50"
551
- end
552
-
553
- expect(html).to include %(<input name="image" width="50" type="image" src="https://hanamirb.org/assets/image_button.png">)
554
- end
555
-
556
- it "prevents XSS attacks" do
557
- html = form_for("/books") do |f|
558
- f.image_button "<script>alert('xss');</script>"
559
- end
560
-
561
- expect(html).to include %(<input type="image" src="">)
562
- end
563
- end
564
-
565
- #
566
- # FIELDSET
567
- #
568
-
569
- describe "#fieldset" do
570
- it "renders a fieldset" do
571
- html = render(<<~ERB)
572
- <%= form_for "/books" do |f| %>
573
- <%= f.fieldset do %>
574
- <%= tag.legend "Author" %>
575
- <%= f.label "author.name" %>
576
- <%= f.text_field "author.name" %>
577
- <% end %>
578
- <% end %>
579
- ERB
580
-
581
- expect(html).to include_html <<~HTML
582
- <fieldset>
583
- <legend>Author</legend>
584
- <label for="author-name">Name</label>
585
- <input type="text" name="author[name]" id="author-name" value="">
586
- </fieldset>
587
- HTML
588
- end
589
- end
590
-
591
- #
592
- # INPUT FIELDS
593
- #
594
-
595
- describe "#check_box" do
596
- it "renders" do
597
- html = form_for("/books") do |f|
598
- f.check_box "book.free_shipping"
599
- end
600
-
601
- expect(html).to include %(<input type="hidden" name="book[free_shipping]" value="0"><input type="checkbox" name="book[free_shipping]" id="book-free-shipping" value="1">)
602
- end
603
-
604
- it "allows to pass checked and unchecked value" do
605
- html = form_for("/books") do |f|
606
- f.check_box "book.free_shipping", checked_value: "true", unchecked_value: "false"
607
- end
608
-
609
- expect(html).to include %(<input type="hidden" name="book[free_shipping]" value="false"><input type="checkbox" name="book[free_shipping]" id="book-free-shipping" value="true">)
610
- end
611
-
612
- it "allows to override 'id' attribute" do
613
- html = form_for("/books") do |f|
614
- f.check_box "book.free_shipping", id: "shipping"
615
- end
616
-
617
- expect(html).to include %(<input type="hidden" name="book[free_shipping]" value="0"><input type="checkbox" name="book[free_shipping]" id="shipping" value="1">)
618
- end
619
-
620
- it "allows to override 'name' attribute" do
621
- html = form_for("/books") do |f|
622
- f.check_box "book.free_shipping", name: "book[free]"
623
- end
624
-
625
- expect(html).to include %(<input type="hidden" name="book[free]" value="0"><input type="checkbox" name="book[free]" id="book-free-shipping" value="1">)
626
- end
627
-
628
- it "allows to specify HTML attributes" do
629
- html = form_for("/books") do |f|
630
- f.check_box "book.free_shipping", class: "form-control"
631
- end
632
-
633
- expect(html).to include %(<input type="hidden" name="book[free_shipping]" value="0"><input type="checkbox" name="book[free_shipping]" id="book-free-shipping" value="1" class="form-control">)
634
- end
635
-
636
- it "doesn't render hidden field if 'value' attribute is specified" do
637
- html = form_for("/books") do |f|
638
- f.check_box "book.free_shipping", value: "ok"
639
- end
640
-
641
- expect(html).not_to include %(<input type="hidden" name="book[free_shipping]" value="0">)
642
- expect(html).to include %(<input type="checkbox" name="book[free_shipping]" id="book-free-shipping" value="ok">)
643
- end
644
-
645
- it "renders hidden field if 'value' attribute and 'unchecked_value' option are both specified" do
646
- html = form_for("/books") do |f|
647
- f.check_box "book.free_shipping", value: "yes", unchecked_value: "no"
648
- end
649
-
650
- expect(html).to include %(<input type="hidden" name="book[free_shipping]" value="no"><input type="checkbox" name="book[free_shipping]" id="book-free-shipping" value="yes">)
651
- end
652
-
653
- it "handles multiple checkboxes" do
654
- html = render(<<~ERB)
655
- <%= form_for("/books") do |f| %>
656
- <%= f.check_box "book.languages", name: "book[languages][]", value: "italian", id: nil %>
657
- <%= f.check_box "book.languages", name: "book[languages][]", value: "english", id: nil %>
658
- <% end %>
659
- ERB
660
-
661
- expect(html).to include_html <<~HTML
662
- <input type="checkbox" name="book[languages][]" value="italian">
663
- <input type="checkbox" name="book[languages][]" value="english">
664
- HTML
665
- end
666
-
667
- context "with filled params" do
668
- let(:params) { {book: {free_shipping: val}} }
669
-
670
- context "when the params value equals to check box value" do
671
- let(:val) { "1" }
672
-
673
- it "renders with 'checked' attribute" do
674
- html = form_for("/books") do |f|
675
- f.check_box "book.free_shipping"
676
- end
677
-
678
- expect(html).to include %(<input type="hidden" name="book[free_shipping]" value="0"><input type="checkbox" name="book[free_shipping]" id="book-free-shipping" value="1" checked="checked">)
679
- end
680
- end
681
-
682
- context "when the params value equals to the hidden field value" do
683
- let(:val) { "0" }
684
-
685
- it "renders without 'checked' attribute" do
686
- html = form_for("/books") do |f|
687
- f.check_box "book.free_shipping"
688
- end
689
-
690
- expect(html).to include %(<input type="hidden" name="book[free_shipping]" value="0"><input type="checkbox" name="book[free_shipping]" id="book-free-shipping" value="1">)
691
- end
692
-
693
- it "allows to override 'checked' attribute" do
694
- html = form_for("/books") do |f|
695
- f.check_box "book.free_shipping", checked: "checked"
696
- end
697
-
698
- expect(html).to include %(<input type="hidden" name="book[free_shipping]" value="0"><input type="checkbox" name="book[free_shipping]" id="book-free-shipping" value="1" checked="checked">)
699
- end
700
- end
701
-
702
- context "with a boolean argument" do
703
- let(:val) { true }
704
-
705
- it "renders with 'checked' attribute" do
706
- html = form_for("/books") do |f|
707
- f.check_box "book.free_shipping"
708
- end
709
-
710
- expect(html).to include %(<input type="hidden" name="book[free_shipping]" value="0"><input type="checkbox" name="book[free_shipping]" id="book-free-shipping" value="1" checked="checked">)
711
- end
712
- end
713
-
714
- context "when multiple params are present" do
715
- let(:params) { {book: {languages: ["italian"]}} }
716
-
717
- it "handles multiple checkboxes" do
718
- html = render(<<~ERB)
719
- <%= form_for("/books") do |f| %>
720
- <%= f.check_box "book.languages", name: "book[languages][]", value: "italian", id: nil %>
721
- <%= f.check_box "book.languages", name: "book[languages][]", value: "english", id: nil %>
722
- <% end %>
723
- ERB
724
-
725
- expect(html).to include_html <<~HTML
726
- <input type="checkbox" name="book[languages][]" value="italian" checked="checked">
727
- <input type="checkbox" name="book[languages][]" value="english">
728
- HTML
729
- end
730
- end
731
-
732
- context "checked_value is boolean" do
733
- let(:params) { {book: {free_shipping: "true"}} }
734
-
735
- it "renders with 'checked' attribute" do
736
- html = form_for("/books") do |f|
737
- f.check_box "book.free_shipping", checked_value: true
738
- end
739
-
740
- expect(html).to include %(<input type="checkbox" name="book[free_shipping]" id="book-free-shipping" value="true" checked="checked">)
741
- end
742
- end
743
- end
744
-
745
- context "automatic values" do
746
- context "checkbox" do
747
- context "value boolean, helper boolean, values differ" do
748
- let(:values) { {book: Struct.new(:free_shipping).new(false)} }
749
-
750
- it "renders" do
751
- html = form_for("/books", values: values) do |f|
752
- f.check_box "book.free_shipping", checked_value: true
753
- end
754
-
755
- expect(html).to include %(<input type="checkbox" name="book[free_shipping]" id="book-free-shipping" value="true">)
756
- end
757
- end
758
- end
759
- end
760
- end
761
-
762
- describe "#color_field" do
763
- it "renders" do
764
- html = form_for("/books") do |f|
765
- f.color_field "book.cover"
766
- end
767
-
768
- expect(html).to include %(<input type="color" name="book[cover]" id="book-cover" value="">)
769
- end
770
-
771
- it "allows to override 'id' attribute" do
772
- html = form_for("/books") do |f|
773
- f.color_field "book.cover", id: "b-cover"
774
- end
775
-
776
- expect(html).to include %(<input type="color" name="book[cover]" id="b-cover" value="">)
777
- end
778
-
779
- it "allows to override 'name' attribute" do
780
- html = form_for("/books") do |f|
781
- f.color_field "book.cover", name: "cover"
782
- end
783
-
784
- expect(html).to include %(<input type="color" name="cover" id="book-cover" value="">)
785
- end
786
-
787
- it "allows to override 'value' attribute" do
788
- html = form_for("/books") do |f|
789
- f.color_field "book.cover", value: "#ffffff"
790
- end
791
-
792
- expect(html).to include %(<input type="color" name="book[cover]" id="book-cover" value="#ffffff">)
793
- end
794
-
795
- it "allows to specify HTML attributes" do
796
- html = form_for("/books") do |f|
797
- f.color_field "book.cover", class: "form-control"
798
- end
799
-
800
- expect(html).to include %(<input type="color" name="book[cover]" id="book-cover" value="" class="form-control">)
801
- end
802
-
803
- context "with values" do
804
- let(:values) { {book: Struct.new(:cover).new(val)} }
805
- let(:val) { "#d3397e" }
806
-
807
- it "renders with value" do
808
- html = form_for("/books", values: values) do |f|
809
- f.color_field "book.cover"
810
- end
811
-
812
- expect(html).to include %(<input type="color" name="book[cover]" id="book-cover" value="#{val}">)
813
- end
814
-
815
- it "allows to override 'value' attribute" do
816
- html = form_for("/books", values: values) do |f|
817
- f.color_field "book.cover", value: "#000000"
818
- end
819
-
820
- expect(html).to include %(<input type="color" name="book[cover]" id="book-cover" value="#000000">)
821
- end
822
- end
823
-
824
- context "with filled params" do
825
- let(:params) { {book: {cover: val}} }
826
- let(:val) { "#d3397e" }
827
-
828
- it "renders with value" do
829
- html = form_for("/books") do |f|
830
- f.color_field "book.cover"
831
- end
832
-
833
- expect(html).to include %(<input type="color" name="book[cover]" id="book-cover" value="#{val}">)
834
- end
835
-
836
- it "allows to override 'value' attribute" do
837
- html = form_for("/books") do |f|
838
- f.color_field "book.cover", value: "#000000"
839
- end
840
-
841
- expect(html).to include %(<input type="color" name="book[cover]" id="book-cover" value="#000000">)
842
- end
843
- end
844
- end
845
-
846
- describe "#date_field" do
847
- it "renders" do
848
- html = form_for("/books") do |f|
849
- f.date_field "book.release_date"
850
- end
851
-
852
- expect(html).to include %(<input type="date" name="book[release_date]" id="book-release-date" value="">)
853
- end
854
-
855
- it "allows to override 'id' attribute" do
856
- html = form_for("/books") do |f|
857
- f.date_field "book.release_date", id: "release-date"
858
- end
859
-
860
- expect(html).to include %(<input type="date" name="book[release_date]" id="release-date" value="">)
861
- end
862
-
863
- it "allows to override 'name' attribute" do
864
- html = form_for("/books") do |f|
865
- f.date_field "book.release_date", name: "release_date"
866
- end
867
-
868
- expect(html).to include %(<input type="date" name="release_date" id="book-release-date" value="">)
869
- end
870
-
871
- it "allows to override 'value' attribute" do
872
- html = form_for("/books") do |f|
873
- f.date_field "book.release_date", value: "2015-02-19"
874
- end
875
-
876
- expect(html).to include %(<input type="date" name="book[release_date]" id="book-release-date" value="2015-02-19">)
877
- end
878
-
879
- it "allows to specify HTML attributes" do
880
- html = form_for("/books") do |f|
881
- f.date_field "book.release_date", class: "form-control"
882
- end
883
-
884
- expect(html).to include %(<input type="date" name="book[release_date]" id="book-release-date" value="" class="form-control">)
885
- end
886
-
887
- context "with values" do
888
- let(:values) { {book: Struct.new(:release_date).new(val)} }
889
- let(:val) { "2014-06-23" }
890
-
891
- it "renders with value" do
892
- html = form_for("/books", values: values) do |f|
893
- f.date_field "book.release_date"
894
- end
895
-
896
- expect(html).to include %(<input type="date" name="book[release_date]" id="book-release-date" value="#{val}">)
897
- end
898
-
899
- it "allows to override 'value' attribute" do
900
- html = form_for("/books", values: values) do |f|
901
- f.date_field "book.release_date", value: "2015-03-23"
902
- end
903
-
904
- expect(html).to include %(<input type="date" name="book[release_date]" id="book-release-date" value="2015-03-23">)
905
- end
906
- end
907
-
908
- context "with filled params" do
909
- let(:params) { {book: {release_date: val}} }
910
- let(:val) { "2014-06-23" }
911
-
912
- it "renders with value" do
913
- html = form_for("/books") do |f|
914
- f.date_field "book.release_date"
915
- end
916
-
917
- expect(html).to include %(<input type="date" name="book[release_date]" id="book-release-date" value="#{val}">)
918
- end
919
-
920
- it "allows to override 'value' attribute" do
921
- html = form_for("/books") do |f|
922
- f.date_field "book.release_date", value: "2015-03-23"
923
- end
924
-
925
- expect(html).to include %(<input type="date" name="book[release_date]" id="book-release-date" value="2015-03-23">)
926
- end
927
- end
928
- end
929
-
930
- describe "#datetime_field" do
931
- it "renders" do
932
- html = form_for("/books") do |f|
933
- f.datetime_field "book.published_at"
934
- end
935
-
936
- expect(html).to include %(<input type="datetime" name="book[published_at]" id="book-published-at" value="">)
937
- end
938
-
939
- it "allows to override 'id' attribute" do
940
- html = form_for("/books") do |f|
941
- f.datetime_field "book.published_at", id: "published-timestamp"
942
- end
943
-
944
- expect(html).to include %(<input type="datetime" name="book[published_at]" id="published-timestamp" value="">)
945
- end
946
-
947
- it "allows to override 'name' attribute" do
948
- html = form_for("/books") do |f|
949
- f.datetime_field "book.published_at", name: "book[published][timestamp]"
950
- end
951
-
952
- expect(html).to include %(<input type="datetime" name="book[published][timestamp]" id="book-published-at" value="">)
953
- end
954
-
955
- it "allows to override 'value' attribute" do
956
- html = form_for("/books") do |f|
957
- f.datetime_field "book.published_at", value: "2015-02-19T12:50:36Z"
958
- end
959
-
960
- expect(html).to include %(<input type="datetime" name="book[published_at]" id="book-published-at" value="2015-02-19T12:50:36Z">)
961
- end
962
-
963
- it "allows to specify HTML attributes" do
964
- html = form_for("/books") do |f|
965
- f.datetime_field "book.published_at", class: "form-control"
966
- end
967
-
968
- expect(html).to include %(<input type="datetime" name="book[published_at]" id="book-published-at" value="" class="form-control">)
969
- end
970
-
971
- context "with values" do
972
- let(:values) { {book: Struct.new(:published_at).new(val)} }
973
- let(:val) { "2015-02-19T12:56:31Z" }
974
-
975
- it "renders with value" do
976
- html = form_for("/books", values: values) do |f|
977
- f.datetime_field "book.published_at"
978
- end
979
-
980
- expect(html).to include %(<input type="datetime" name="book[published_at]" id="book-published-at" value="#{val}">)
981
- end
982
-
983
- it "allows to override 'value' attribute" do
984
- html = form_for("/books", values: values) do |f|
985
- f.datetime_field "book.published_at", value: "2015-02-19T12:50:36Z"
986
- end
987
-
988
- expect(html).to include %(<input type="datetime" name="book[published_at]" id="book-published-at" value="2015-02-19T12:50:36Z">)
989
- end
990
- end
991
-
992
- context "with filled params" do
993
- let(:params) { {book: {published_at: val}} }
994
- let(:val) { "2015-02-19T12:56:31Z" }
995
-
996
- it "renders with value" do
997
- html = form_for("/books") do |f|
998
- f.datetime_field "book.published_at"
999
- end
1000
-
1001
- expect(html).to include %(<input type="datetime" name="book[published_at]" id="book-published-at" value="#{val}">)
1002
- end
1003
-
1004
- it "allows to override 'value' attribute" do
1005
- html = form_for("/books") do |f|
1006
- f.datetime_field "book.published_at", value: "2015-02-19T12:50:36Z"
1007
- end
1008
-
1009
- expect(html).to include %(<input type="datetime" name="book[published_at]" id="book-published-at" value="2015-02-19T12:50:36Z">)
1010
- end
1011
- end
1012
- end
1013
-
1014
- describe "#datetime_local_field" do
1015
- it "renders" do
1016
- html = form_for("/books") do |f|
1017
- f.datetime_local_field "book.released_at"
1018
- end
1019
-
1020
- expect(html).to include %(<input type="datetime-local" name="book[released_at]" id="book-released-at" value="">)
1021
- end
1022
-
1023
- it "allows to override 'id' attribute" do
1024
- html = form_for("/books") do |f|
1025
- f.datetime_local_field "book.released_at", id: "local-release-timestamp"
1026
- end
1027
-
1028
- expect(html).to include %(<input type="datetime-local" name="book[released_at]" id="local-release-timestamp" value="">)
1029
- end
1030
-
1031
- it "allows to override 'name' attribute" do
1032
- html = form_for("/books") do |f|
1033
- f.datetime_local_field "book.released_at", name: "book[release-timestamp]"
1034
- end
1035
-
1036
- expect(html).to include %(<input type="datetime-local" name="book[release-timestamp]" id="book-released-at" value="">)
1037
- end
1038
-
1039
- it "allows to override 'value' attribute" do
1040
- html = form_for("/books") do |f|
1041
- f.datetime_local_field "book.released_at", value: "2015-02-19T14:01:28+01:00"
1042
- end
1043
-
1044
- expect(html).to include %(<input type="datetime-local" name="book[released_at]" id="book-released-at" value="2015-02-19T14:01:28+01:00">)
1045
- end
1046
-
1047
- it "allows to specify HTML attributes" do
1048
- html = form_for("/books") do |f|
1049
- f.datetime_local_field "book.released_at", class: "form-control"
1050
- end
1051
-
1052
- expect(html).to include %(<input type="datetime-local" name="book[released_at]" id="book-released-at" value="" class="form-control">)
1053
- end
1054
-
1055
- context "with filled params" do
1056
- let(:params) { {book: {released_at: val}} }
1057
- let(:val) { "2015-02-19T14:11:19+01:00" }
1058
-
1059
- it "renders with value" do
1060
- html = form_for("/books") do |f|
1061
- f.datetime_local_field "book.released_at"
1062
- end
1063
-
1064
- expect(html).to include %(<input type="datetime-local" name="book[released_at]" id="book-released-at" value="#{val}">)
1065
- end
1066
-
1067
- it "allows to override 'value' attribute" do
1068
- html = form_for("/books") do |f|
1069
- f.datetime_local_field "book.released_at", value: "2015-02-19T14:01:28+01:00"
1070
- end
1071
-
1072
- expect(html).to include %(<input type="datetime-local" name="book[released_at]" id="book-released-at" value="2015-02-19T14:01:28+01:00">)
1073
- end
1074
- end
1075
- end
1076
-
1077
- describe "#time_field" do
1078
- it "renders" do
1079
- html = form_for("/books") do |f|
1080
- f.time_field "book.release_hour"
1081
- end
1082
-
1083
- expect(html).to include %(<input type="time" name="book[release_hour]" id="book-release-hour" value="">)
1084
- end
1085
-
1086
- it "allows to override 'id' attribute" do
1087
- html = form_for("/books") do |f|
1088
- f.time_field "book.release_hour", id: "release-hour"
1089
- end
1090
-
1091
- expect(html).to include %(<input type="time" name="book[release_hour]" id="release-hour" value="">)
1092
- end
1093
-
1094
- it "allows to override 'name' attribute" do
1095
- html = form_for("/books") do |f|
1096
- f.time_field "book.release_hour", name: "release_hour"
1097
- end
1098
-
1099
- expect(html).to include %(<input type="time" name="release_hour" id="book-release-hour" value="">)
1100
- end
1101
-
1102
- it "allows to override 'value' attribute" do
1103
- html = form_for("/books") do |f|
1104
- f.time_field "book.release_hour", value: "00:00"
1105
- end
1106
-
1107
- expect(html).to include %(<input type="time" name="book[release_hour]" id="book-release-hour" value="00:00">)
1108
- end
1109
-
1110
- it "allows to specify HTML attributes" do
1111
- html = form_for("/books") do |f|
1112
- f.time_field "book.release_hour", class: "form-control"
1113
- end
1114
-
1115
- expect(html).to include %(<input type="time" name="book[release_hour]" id="book-release-hour" value="" class="form-control">)
1116
- end
1117
-
1118
- context "with values" do
1119
- let(:values) { {book: Struct.new(:release_hour).new(val)} }
1120
- let(:val) { "18:30" }
1121
-
1122
- it "renders with value" do
1123
- html = form_for("/books", values: values) do |f|
1124
- f.time_field "book.release_hour"
1125
- end
1126
-
1127
- expect(html).to include %(<input type="time" name="book[release_hour]" id="book-release-hour" value="#{val}">)
1128
- end
1129
-
1130
- it "allows to override 'value' attribute" do
1131
- html = form_for("/books", values: values) do |f|
1132
- f.time_field "book.release_hour", value: "17:00"
1133
- end
1134
-
1135
- expect(html).to include %(<input type="time" name="book[release_hour]" id="book-release-hour" value="17:00">)
1136
- end
1137
- end
1138
-
1139
- context "with filled params" do
1140
- let(:params) { {book: {release_hour: val}} }
1141
- let(:val) { "11:30" }
1142
-
1143
- it "renders with value" do
1144
- html = form_for("/books") do |f|
1145
- f.time_field "book.release_hour"
1146
- end
1147
-
1148
- expect(html).to include %(<input type="time" name="book[release_hour]" id="book-release-hour" value="#{val}">)
1149
- end
1150
-
1151
- it "allows to override 'value' attribute" do
1152
- html = form_for("/books") do |f|
1153
- f.time_field "book.release_hour", value: "8:15"
1154
- end
1155
-
1156
- expect(html).to include %(<input type="time" name="book[release_hour]" id="book-release-hour" value="8:15">)
1157
- end
1158
- end
1159
- end
1160
-
1161
- describe "#month_field" do
1162
- it "renders" do
1163
- html = form_for("/books") do |f|
1164
- f.month_field "book.release_month"
1165
- end
1166
-
1167
- expect(html).to include %(<input type="month" name="book[release_month]" id="book-release-month" value="">)
1168
- end
1169
-
1170
- it "allows to override 'id' attribute" do
1171
- html = form_for("/books") do |f|
1172
- f.month_field "book.release_month", id: "release-month"
1173
- end
1174
-
1175
- expect(html).to include %(<input type="month" name="book[release_month]" id="release-month" value="">)
1176
- end
1177
-
1178
- it "allows to override 'name' attribute" do
1179
- html = form_for("/books") do |f|
1180
- f.month_field "book.release_month", name: "release_month"
1181
- end
1182
-
1183
- expect(html).to include %(<input type="month" name="release_month" id="book-release-month" value="">)
1184
- end
1185
-
1186
- it "allows to override 'value' attribute" do
1187
- html = form_for("/books") do |f|
1188
- f.month_field "book.release_month", value: "2017-03"
1189
- end
1190
-
1191
- expect(html).to include %(<input type="month" name="book[release_month]" id="book-release-month" value="2017-03">)
1192
- end
1193
-
1194
- it "allows to specify HTML attributes" do
1195
- html = form_for("/books") do |f|
1196
- f.month_field "book.release_month", class: "form-control"
1197
- end
1198
-
1199
- expect(html).to include %(<input type="month" name="book[release_month]" id="book-release-month" value="" class="form-control">)
1200
- end
1201
-
1202
- context "with values" do
1203
- let(:values) { {book: Struct.new(:release_month).new(val)} }
1204
- let(:val) { "2017-03" }
1205
-
1206
- it "renders with value" do
1207
- html = form_for("/books", values: values) do |f|
1208
- f.month_field "book.release_month"
1209
- end
1210
-
1211
- expect(html).to include %(<input type="month" name="book[release_month]" id="book-release-month" value="#{val}">)
1212
- end
1213
-
1214
- it "allows to override 'value' attribute" do
1215
- html = form_for("/books", values: values) do |f|
1216
- f.month_field "book.release_month", value: "2017-04"
1217
- end
1218
-
1219
- expect(html).to include %(<input type="month" name="book[release_month]" id="book-release-month" value="2017-04">)
1220
- end
1221
- end
1222
-
1223
- context "with filled params" do
1224
- let(:params) { {book: {release_month: val}} }
1225
- let(:val) { "2017-10" }
1226
-
1227
- it "renders with value" do
1228
- html = form_for("/books") do |f|
1229
- f.month_field "book.release_month"
1230
- end
1231
-
1232
- expect(html).to include %(<input type="month" name="book[release_month]" id="book-release-month" value="#{val}">)
1233
- end
1234
-
1235
- it "allows to override 'value' attribute" do
1236
- html = form_for("/books") do |f|
1237
- f.month_field "book.release_month", value: "2017-04"
1238
- end
1239
-
1240
- expect(html).to include %(<input type="month" name="book[release_month]" id="book-release-month" value="2017-04">)
1241
- end
1242
- end
1243
- end
1244
-
1245
- describe "#week_field" do
1246
- it "renders" do
1247
- html = form_for("/books") do |f|
1248
- f.week_field "book.release_week"
1249
- end
1250
-
1251
- expect(html).to include %(<input type="week" name="book[release_week]" id="book-release-week" value="">)
1252
- end
1253
-
1254
- it "allows to override 'id' attribute" do
1255
- html = form_for("/books") do |f|
1256
- f.week_field "book.release_week", id: "release-week"
1257
- end
1258
-
1259
- expect(html).to include %(<input type="week" name="book[release_week]" id="release-week" value="">)
1260
- end
1261
-
1262
- it "allows to override 'name' attribute" do
1263
- html = form_for("/books") do |f|
1264
- f.week_field "book.release_week", name: "release_week"
1265
- end
1266
-
1267
- expect(html).to include %(<input type="week" name="release_week" id="book-release-week" value="">)
1268
- end
1269
-
1270
- it "allows to override 'value' attribute" do
1271
- html = form_for("/books") do |f|
1272
- f.week_field "book.release_week", value: "2017-W10"
1273
- end
1274
-
1275
- expect(html).to include %(<input type="week" name="book[release_week]" id="book-release-week" value="2017-W10">)
1276
- end
1277
-
1278
- it "allows to specify HTML attributes" do
1279
- html = form_for("/books") do |f|
1280
- f.week_field "book.release_week", class: "form-control"
1281
- end
1282
-
1283
- expect(html).to include %(<input type="week" name="book[release_week]" id="book-release-week" value="" class="form-control">)
1284
- end
1285
-
1286
- context "with values" do
1287
- let(:values) { {book: Struct.new(:release_week).new(val)} }
1288
- let(:val) { "2017-W10" }
1289
-
1290
- it "renders with value" do
1291
- html = form_for("/books", values: values) do |f|
1292
- f.week_field "book.release_week"
1293
- end
1294
-
1295
- expect(html).to include %(<input type="week" name="book[release_week]" id="book-release-week" value="#{val}">)
1296
- end
1297
-
1298
- it "allows to override 'value' attribute" do
1299
- html = form_for("/books", values: values) do |f|
1300
- f.week_field "book.release_week", value: "2017-W31"
1301
- end
1302
-
1303
- expect(html).to include %(<input type="week" name="book[release_week]" id="book-release-week" value="2017-W31">)
1304
- end
1305
- end
1306
-
1307
- context "with filled params" do
1308
- let(:params) { {book: {release_week: val}} }
1309
- let(:val) { "2017-W44" }
1310
-
1311
- it "renders with value" do
1312
- html = form_for("/books") do |f|
1313
- f.week_field "book.release_week"
1314
- end
1315
-
1316
- expect(html).to include %(<input type="week" name="book[release_week]" id="book-release-week" value="#{val}">)
1317
- end
1318
-
1319
- it "allows to override 'value' attribute" do
1320
- html = form_for("/books") do |f|
1321
- f.week_field "book.release_week", value: "2017-W07"
1322
- end
1323
-
1324
- expect(html).to include %(<input type="week" name="book[release_week]" id="book-release-week" value="2017-W07">)
1325
- end
1326
- end
1327
- end
1328
-
1329
- describe "#email_field" do
1330
- it "renders" do
1331
- html = form_for("/books") do |f|
1332
- f.email_field "book.publisher_email"
1333
- end
1334
-
1335
- expect(html).to include %(<input type="email" name="book[publisher_email]" id="book-publisher-email" value="">)
1336
- end
1337
-
1338
- it "allows to override 'id' attribute" do
1339
- html = form_for("/books") do |f|
1340
- f.email_field "book.publisher_email", id: "publisher-email"
1341
- end
1342
-
1343
- expect(html).to include %(<input type="email" name="book[publisher_email]" id="publisher-email" value="">)
1344
- end
1345
-
1346
- it "allows to override 'name' attribute" do
1347
- html = form_for("/books") do |f|
1348
- f.email_field "book.publisher_email", name: "book[email]"
1349
- end
1350
-
1351
- expect(html).to include %(<input type="email" name="book[email]" id="book-publisher-email" value="">)
1352
- end
1353
-
1354
- it "allows to override 'value' attribute" do
1355
- html = form_for("/books") do |f|
1356
- f.email_field "book.publisher_email", value: "publisher@example.org"
1357
- end
1358
-
1359
- expect(html).to include %(<input type="email" name="book[publisher_email]" id="book-publisher-email" value="publisher@example.org">)
1360
- end
1361
-
1362
- it "allows to specify 'multiple' attribute" do
1363
- html = form_for("/books") do |f|
1364
- f.email_field "book.publisher_email", multiple: true
1365
- end
1366
-
1367
- expect(html).to include %(<input type="email" name="book[publisher_email]" id="book-publisher-email" value="" multiple="multiple">)
1368
- end
1369
-
1370
- it "allows to specify HTML attributes" do
1371
- html = form_for("/books") do |f|
1372
- f.email_field "book.publisher_email", class: "form-control"
1373
- end
1374
-
1375
- expect(html).to include %(<input type="email" name="book[publisher_email]" id="book-publisher-email" value="" class="form-control">)
1376
- end
1377
-
1378
- context "with values" do
1379
- let(:values) { {book: Struct.new(:publisher_email).new(val)} }
1380
- let(:val) { "maria@publisher.org" }
1381
-
1382
- it "renders with value" do
1383
- html = form_for("/books", values: values) do |f|
1384
- f.email_field "book.publisher_email"
1385
- end
1386
-
1387
- expect(html).to include %(<input type="email" name="book[publisher_email]" id="book-publisher-email" value="maria@publisher.org">)
1388
- end
1389
-
1390
- it "allows to override 'value' attribute" do
1391
- html = form_for("/books", values: values) do |f|
1392
- f.email_field "book.publisher_email", value: "publisher@example.org"
1393
- end
1394
-
1395
- expect(html).to include %(<input type="email" name="book[publisher_email]" id="book-publisher-email" value="publisher@example.org">)
1396
- end
1397
- end
1398
-
1399
- context "with filled params" do
1400
- let(:params) { {book: {publisher_email: val}} }
1401
- let(:val) { "maria@publisher.org" }
1402
-
1403
- it "renders with value" do
1404
- html = form_for("/books") do |f|
1405
- f.email_field "book.publisher_email"
1406
- end
1407
-
1408
- expect(html).to include %(<input type="email" name="book[publisher_email]" id="book-publisher-email" value="maria@publisher.org">)
1409
- end
1410
-
1411
- it "allows to override 'value' attribute" do
1412
- html = form_for("/books") do |f|
1413
- f.email_field "book.publisher_email", value: "publisher@example.org"
1414
- end
1415
-
1416
- expect(html).to include %(<input type="email" name="book[publisher_email]" id="book-publisher-email" value="publisher@example.org">)
1417
- end
1418
- end
1419
- end
1420
-
1421
- describe "#url_field" do
1422
- it "renders" do
1423
- html = form_for("/books") do |f|
1424
- f.url_field "book.website"
1425
- end
1426
-
1427
- expect(html).to include %(<input type="url" name="book[website]" id="book-website" value="">)
1428
- end
1429
-
1430
- it "allows to override 'id' attribute" do
1431
- html = form_for("/books") do |f|
1432
- f.url_field "book.website", id: "website"
1433
- end
1434
-
1435
- expect(html).to include %(<input type="url" name="book[website]" id="website" value="">)
1436
- end
1437
-
1438
- it "allows to override 'name' attribute" do
1439
- html = form_for("/books") do |f|
1440
- f.url_field "book.website", name: "book[url]"
1441
- end
1442
-
1443
- expect(html).to include %(<input type="url" name="book[url]" id="book-website" value="">)
1444
- end
1445
-
1446
- it "allows to override 'value' attribute" do
1447
- html = form_for("/books") do |f|
1448
- f.url_field "book.website", value: "http://example.org"
1449
- end
1450
-
1451
- expect(html).to include %(<input type="url" name="book[website]" id="book-website" value="http://example.org">)
1452
- end
1453
-
1454
- it "allows to specify 'multiple' attribute" do
1455
- html = form_for("/books") do |f|
1456
- f.url_field "book.website", multiple: true
1457
- end
1458
-
1459
- expect(html).to include %(<input type="url" name="book[website]" id="book-website" value="" multiple="multiple">)
1460
- end
1461
-
1462
- it "allows to specify HTML attributes" do
1463
- html = form_for("/books") do |f|
1464
- f.url_field "book.website", class: "form-control"
1465
- end
1466
-
1467
- expect(html).to include %(<input type="url" name="book[website]" id="book-website" value="" class="form-control">)
1468
- end
1469
-
1470
- context "with values" do
1471
- let(:values) { {book: Struct.new(:website).new(val)} }
1472
- let(:val) { "http://publisher.org" }
1473
-
1474
- it "renders with value" do
1475
- html = form_for("/books", values: values) do |f|
1476
- f.url_field "book.website"
1477
- end
1478
-
1479
- expect(html).to include %(<input type="url" name="book[website]" id="book-website" value="http://publisher.org">)
1480
- end
1481
-
1482
- it "allows to override 'value' attribute" do
1483
- html = form_for("/books", values: values) do |f|
1484
- f.url_field "book.website", value: "https://www.example.org"
1485
- end
1486
-
1487
- expect(html).to include %(<input type="url" name="book[website]" id="book-website" value="https://www.example.org">)
1488
- end
1489
- end
1490
-
1491
- context "with filled params" do
1492
- let(:params) { {book: {website: val}} }
1493
- let(:val) { "http://publisher.org" }
1494
-
1495
- it "renders with value" do
1496
- html = form_for("/books") do |f|
1497
- f.url_field "book.website"
1498
- end
1499
-
1500
- expect(html).to include %(<input type="url" name="book[website]" id="book-website" value="http://publisher.org">)
1501
- end
1502
-
1503
- it "allows to override 'value' attribute" do
1504
- html = form_for("/books") do |f|
1505
- f.url_field "book.website", value: "http://example.org"
1506
- end
1507
-
1508
- expect(html).to include %(<input type="url" name="book[website]" id="book-website" value="http://example.org">)
1509
- end
1510
- end
1511
-
1512
- context "with escape url" do
1513
- let(:values) { {book: Struct.new(:website).new(val)} }
1514
- let(:val) { %("onclick=javascript:alert('xss')) }
1515
-
1516
- it "renders with automatic value" do
1517
- html = form_for("/books", values: values) do |f|
1518
- f.url_field "book.website"
1519
- end
1520
-
1521
- expect(html).to include %(<input type="url" name="book[website]" id="book-website" value="">)
1522
- end
1523
-
1524
- it "renders with explicit value" do
1525
- html = form_for("/books", values: values) do |f|
1526
- f.url_field "book.website", value: val
1527
- end
1528
-
1529
- expect(html).to include %(<input type="url" name="book[website]" id="book-website" value="">)
1530
- end
1531
- end
1532
- end
1533
-
1534
- describe "#tel_field" do
1535
- it "renders" do
1536
- html = form_for("/books") do |f|
1537
- f.tel_field "book.publisher_telephone"
1538
- end
1539
-
1540
- expect(html).to include %(<input type="tel" name="book[publisher_telephone]" id="book-publisher-telephone" value="">)
1541
- end
1542
-
1543
- it "allows to override 'id' attribute" do
1544
- html = form_for("/books") do |f|
1545
- f.tel_field "book.publisher_telephone", id: "publisher-telephone"
1546
- end
1547
-
1548
- expect(html).to include %(<input type="tel" name="book[publisher_telephone]" id="publisher-telephone" value="">)
1549
- end
1550
-
1551
- it "allows to override 'name' attribute" do
1552
- html = form_for("/books") do |f|
1553
- f.tel_field "book.publisher_telephone", name: "book[telephone]"
1554
- end
1555
-
1556
- expect(html).to include %(<input type="tel" name="book[telephone]" id="book-publisher-telephone" value="">)
1557
- end
1558
-
1559
- it "allows to override 'value' attribute" do
1560
- html = form_for("/books") do |f|
1561
- f.tel_field "book.publisher_telephone", value: "publisher@example.org"
1562
- end
1563
-
1564
- expect(html).to include %(<input type="tel" name="book[publisher_telephone]" id="book-publisher-telephone" value="publisher@example.org">)
1565
- end
1566
-
1567
- it "allows to specify 'multiple' attribute" do
1568
- html = form_for("/books") do |f|
1569
- f.tel_field "book.publisher_telephone", multiple: true
1570
- end
1571
-
1572
- expect(html).to include %(<input type="tel" name="book[publisher_telephone]" id="book-publisher-telephone" value="" multiple="multiple">)
1573
- end
1574
-
1575
- it "allows to specify HTML attributes" do
1576
- html = form_for("/books") do |f|
1577
- f.tel_field "book.publisher_telephone", class: "form-control"
1578
- end
1579
-
1580
- expect(html).to include %(<input type="tel" name="book[publisher_telephone]" id="book-publisher-telephone" value="" class="form-control">)
1581
- end
1582
-
1583
- context "with values" do
1584
- let(:values) { {book: Struct.new(:publisher_telephone).new(val)} }
1585
- let(:val) { "maria@publisher.org" }
1586
-
1587
- it "renders with value" do
1588
- html = form_for("/books", values: values) do |f|
1589
- f.tel_field "book.publisher_telephone"
1590
- end
1591
-
1592
- expect(html).to include %(<input type="tel" name="book[publisher_telephone]" id="book-publisher-telephone" value="maria@publisher.org">)
1593
- end
1594
-
1595
- it "allows to override 'value' attribute" do
1596
- html = form_for("/books", values: values) do |f|
1597
- f.tel_field "book.publisher_telephone", value: "publisher@example.org"
1598
- end
1599
-
1600
- expect(html).to include %(<input type="tel" name="book[publisher_telephone]" id="book-publisher-telephone" value="publisher@example.org">)
1601
- end
1602
- end
1603
-
1604
- context "with filled params" do
1605
- let(:params) { {book: {publisher_telephone: val}} }
1606
- let(:val) { "maria@publisher.org" }
1607
-
1608
- it "renders with value" do
1609
- html = form_for("/books") do |f|
1610
- f.tel_field "book.publisher_telephone"
1611
- end
1612
-
1613
- expect(html).to include %(<input type="tel" name="book[publisher_telephone]" id="book-publisher-telephone" value="maria@publisher.org">)
1614
- end
1615
-
1616
- it "allows to override 'value' attribute" do
1617
- html = form_for("/books") do |f|
1618
- f.tel_field "book.publisher_telephone", value: "publisher@example.org"
1619
- end
1620
-
1621
- expect(html).to include %(<input type="tel" name="book[publisher_telephone]" id="book-publisher-telephone" value="publisher@example.org">)
1622
- end
1623
- end
1624
- end
1625
-
1626
- describe "#file_field" do
1627
- it "renders" do
1628
- html = form_for("/books") do |f|
1629
- f.file_field "book.image_cover"
1630
- end
1631
-
1632
- expect(html).to include %(<input type="file" name="book[image_cover]" id="book-image-cover">)
1633
- end
1634
-
1635
- it "sets 'enctype' attribute to the form" do
1636
- html = form_for("/books") do |f|
1637
- f.file_field "book.image_cover"
1638
- end
1639
-
1640
- expect(html).to include %(<form action="/books" enctype="multipart/form-data" accept-charset="utf-8" method="POST">)
1641
- end
1642
-
1643
- it "sets 'enctype' attribute to the form when there are nested fields" do
1644
- html = form_for("/books") do |f|
1645
- f.fields_for("images") do
1646
- f.file_field("cover")
1647
- end
1648
- end
1649
-
1650
- expect(html).to include %(<form action="/books" enctype="multipart/form-data" accept-charset="utf-8" method="POST">)
1651
- end
1652
-
1653
- it "allows to override 'id' attribute" do
1654
- html = form_for("/books") do |f|
1655
- f.file_field "book.image_cover", id: "book-cover"
1656
- end
1657
-
1658
- expect(html).to include %(<input type="file" name="book[image_cover]" id="book-cover">)
1659
- end
1660
-
1661
- it "allows to override 'name' attribute" do
1662
- html = form_for("/books") do |f|
1663
- f.file_field "book.image_cover", name: "book[cover]"
1664
- end
1665
-
1666
- expect(html).to include %(<input type="file" name="book[cover]" id="book-image-cover">)
1667
- end
1668
-
1669
- it "allows to specify 'multiple' attribute" do
1670
- html = form_for("/books") do |f|
1671
- f.file_field "book.image_cover", multiple: true
1672
- end
1673
-
1674
- expect(html).to include %(<input type="file" name="book[image_cover]" id="book-image-cover" multiple="multiple">)
1675
- end
1676
-
1677
- it "allows to specify single value for 'accept' attribute" do
1678
- html = form_for("/books") do |f|
1679
- f.file_field "book.image_cover", accept: "application/pdf"
1680
- end
1681
-
1682
- expect(html).to include %(<input type="file" name="book[image_cover]" id="book-image-cover" accept="application/pdf">)
1683
- end
1684
-
1685
- it "allows to specify multiple values for 'accept' attribute" do
1686
- html = form_for("/books") do |f|
1687
- f.file_field "book.image_cover", accept: "image/png,image/jpg"
1688
- end
1689
-
1690
- expect(html).to include %(<input type="file" name="book[image_cover]" id="book-image-cover" accept="image/png,image/jpg">)
1691
- end
1692
-
1693
- it "allows to specify multiple values (array) for 'accept' attribute" do
1694
- html = form_for("/books") do |f|
1695
- f.file_field "book.image_cover", accept: ["image/png", "image/jpg"]
1696
- end
1697
-
1698
- expect(html).to include %(<input type="file" name="book[image_cover]" id="book-image-cover" accept="image/png,image/jpg">)
1699
- end
1700
-
1701
- context "with values" do
1702
- let(:values) { {book: Struct.new(:image_cover).new(val)} }
1703
- let(:val) { "image" }
1704
-
1705
- it "ignores value" do
1706
- html = form_for("/books", values: values) do |f|
1707
- f.file_field "book.image_cover"
1708
- end
1709
-
1710
- expect(html).to include %(<input type="file" name="book[image_cover]" id="book-image-cover">)
1711
- end
1712
- end
1713
-
1714
- context "with filled params" do
1715
- let(:params) { {book: {image_cover: val}} }
1716
- let(:val) { "image" }
1717
-
1718
- it "ignores value" do
1719
- html = form_for("/books") do |f|
1720
- f.file_field "book.image_cover"
1721
- end
1722
-
1723
- expect(html).to include %(<input type="file" name="book[image_cover]" id="book-image-cover">)
1724
- end
1725
- end
1726
- end
1727
-
1728
- describe "#hidden_field" do
1729
- it "renders" do
1730
- html = form_for("/books") do |f|
1731
- f.hidden_field "book.author_id"
1732
- end
1733
-
1734
- expect(html).to include %(<input type="hidden" name="book[author_id]" id="book-author-id" value="">)
1735
- end
1736
-
1737
- it "allows to override 'id' attribute" do
1738
- html = form_for("/books") do |f|
1739
- f.hidden_field "book.author_id", id: "author-id"
1740
- end
1741
-
1742
- expect(html).to include %(<input type="hidden" name="book[author_id]" id="author-id" value="">)
1743
- end
1744
-
1745
- it "allows to override 'name' attribute" do
1746
- html = form_for("/books") do |f|
1747
- f.hidden_field "book.author_id", name: "book[author]"
1748
- end
1749
-
1750
- expect(html).to include %(<input type="hidden" name="book[author]" id="book-author-id" value="">)
1751
- end
1752
-
1753
- it "allows to override 'value' attribute" do
1754
- html = form_for("/books") do |f|
1755
- f.hidden_field "book.author_id", value: "23"
1756
- end
1757
-
1758
- expect(html).to include %(<input type="hidden" name="book[author_id]" id="book-author-id" value="23">)
1759
- end
1760
-
1761
- it "allows to specify HTML attributes" do
1762
- html = form_for("/books") do |f|
1763
- f.hidden_field "book.author_id", class: "form-details"
1764
- end
1765
-
1766
- expect(html).to include %(<input type="hidden" name="book[author_id]" id="book-author-id" value="" class="form-details">)
1767
- end
1768
-
1769
- context "with values" do
1770
- let(:values) { {book: Struct.new(:author_id).new(val)} }
1771
- let(:val) { "1" }
1772
-
1773
- it "renders with value" do
1774
- html = form_for("/books", values: values) do |f|
1775
- f.hidden_field "book.author_id"
1776
- end
1777
-
1778
- expect(html).to include %(<input type="hidden" name="book[author_id]" id="book-author-id" value="1">)
1779
- end
1780
-
1781
- it "allows to override 'value' attribute" do
1782
- html = form_for("/books", values: values) do |f|
1783
- f.hidden_field "book.author_id", value: "23"
1784
- end
1785
-
1786
- expect(html).to include %(<input type="hidden" name="book[author_id]" id="book-author-id" value="23">)
1787
- end
1788
- end
1789
-
1790
- context "with filled params" do
1791
- let(:params) { {book: {author_id: val}} }
1792
- let(:val) { "1" }
1793
-
1794
- it "renders with value" do
1795
- html = form_for("/books") do |f|
1796
- f.hidden_field "book.author_id"
1797
- end
1798
-
1799
- expect(html).to include %(<input type="hidden" name="book[author_id]" id="book-author-id" value="1">)
1800
- end
1801
-
1802
- it "allows to override 'value' attribute" do
1803
- html = form_for("/books") do |f|
1804
- f.hidden_field "book.author_id", value: "23"
1805
- end
1806
-
1807
- expect(html).to include %(<input type="hidden" name="book[author_id]" id="book-author-id" value="23">)
1808
- end
1809
- end
1810
- end
1811
-
1812
- describe "#number_field" do
1813
- it "renders the element" do
1814
- html = form_for("/books") do |f|
1815
- f.number_field "book.percent_read"
1816
- end
1817
-
1818
- expect(html).to include %(<input type="number" name="book[percent_read]" id="book-percent-read" value="">)
1819
- end
1820
-
1821
- it "allows to override 'id' attribute" do
1822
- html = form_for("/books") do |f|
1823
- f.number_field "book.percent_read", id: "percent-read"
1824
- end
1825
-
1826
- expect(html).to include %(<input type="number" name="book[percent_read]" id="percent-read" value="">)
1827
- end
1828
-
1829
- it "allows to override the 'name' attribute" do
1830
- html = form_for("/books") do |f|
1831
- f.number_field "book.percent_read", name: "book[read]"
1832
- end
1833
-
1834
- expect(html).to include %(<input type="number" name="book[read]" id="book-percent-read" value="">)
1835
- end
1836
-
1837
- it "allows to override the 'value' attribute" do
1838
- html = form_for("/books") do |f|
1839
- f.number_field "book.percent_read", value: "99"
1840
- end
1841
-
1842
- expect(html).to include %(<input type="number" name="book[percent_read]" id="book-percent-read" value="99">)
1843
- end
1844
-
1845
- it "allows to specify HTML attributes" do
1846
- html = form_for("/books") do |f|
1847
- f.number_field "book.percent_read", class: "form-control"
1848
- end
1849
-
1850
- expect(html).to include %(<input type="number" name="book[percent_read]" id="book-percent-read" value="" class="form-control">)
1851
- end
1852
-
1853
- it "allows to specify a 'min' attribute" do
1854
- html = form_for("/books") do |f|
1855
- f.number_field "book.percent_read", min: 0
1856
- end
1857
-
1858
- expect(html).to include %(<input type="number" name="book[percent_read]" id="book-percent-read" value="" min="0">)
1859
- end
1860
-
1861
- it "allows to specify a 'max' attribute" do
1862
- html = form_for("/books") do |f|
1863
- f.number_field "book.percent_read", max: 100
1864
- end
1865
-
1866
- expect(html).to include %(<input type="number" name="book[percent_read]" id="book-percent-read" value="" max="100">)
1867
- end
1868
-
1869
- it "allows to specify a 'step' attribute" do
1870
- html = form_for("/books") do |f|
1871
- f.number_field "book.percent_read", step: 5
1872
- end
1873
-
1874
- expect(html).to include %(<input type="number" name="book[percent_read]" id="book-percent-read" value="" step="5">)
1875
- end
1876
-
1877
- context "with values" do
1878
- let(:values) { {book: Struct.new(:percent_read).new(val)} }
1879
- let(:val) { 95 }
1880
-
1881
- it "renders with value" do
1882
- html = form_for("/books", values: values) do |f|
1883
- f.number_field "book.percent_read"
1884
- end
1885
-
1886
- expect(html).to include %(<input type="number" name="book[percent_read]" id="book-percent-read" value="95">)
1887
- end
1888
-
1889
- it "allows to override 'value' attribute" do
1890
- html = form_for("/books", values: values) do |f|
1891
- f.number_field "book.percent_read", value: 50
1892
- end
1893
-
1894
- expect(html).to include %(<input type="number" name="book[percent_read]" id="book-percent-read" value="50">)
1895
- end
1896
- end
1897
-
1898
- context "with filled params" do
1899
- let(:params) { {book: {percent_read: val}} }
1900
- let(:val) { 95 }
1901
-
1902
- it "renders with value" do
1903
- html = form_for("/books") do |f|
1904
- f.number_field "book.percent_read"
1905
- end
1906
-
1907
- expect(html).to include %(<input type="number" name="book[percent_read]" id="book-percent-read" value="95">)
1908
- end
1909
-
1910
- it "allows to override 'value' attribute" do
1911
- html = form_for("/books") do |f|
1912
- f.number_field "book.percent_read", value: 50
1913
- end
1914
-
1915
- expect(html).to include %(<input type="number" name="book[percent_read]" id="book-percent-read" value="50">)
1916
- end
1917
- end
1918
- end
1919
-
1920
- describe "#range_field" do
1921
- it "renders the element" do
1922
- html = form_for("/books") do |f|
1923
- f.range_field "book.discount_percentage"
1924
- end
1925
-
1926
- expect(html).to include %(<input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="">)
1927
- end
1928
-
1929
- it "allows to override 'id' attribute" do
1930
- html = form_for("/books") do |f|
1931
- f.range_field "book.discount_percentage", id: "discount-percentage"
1932
- end
1933
-
1934
- expect(html).to include %(<input type="range" name="book[discount_percentage]" id="discount-percentage" value="">)
1935
- end
1936
-
1937
- it "allows to override the 'name' attribute" do
1938
- html = form_for("/books") do |f|
1939
- f.range_field "book.discount_percentage", name: "book[read]"
1940
- end
1941
-
1942
- expect(html).to include %(<input type="range" name="book[read]" id="book-discount-percentage" value="">)
1943
- end
1944
-
1945
- it "allows to override the 'value' attribute" do
1946
- html = form_for("/books") do |f|
1947
- f.range_field "book.discount_percentage", value: "99"
1948
- end
1949
-
1950
- expect(html).to include %(<input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="99">)
1951
- end
1952
-
1953
- it "allows to specify HTML attributes" do
1954
- html = form_for("/books") do |f|
1955
- f.range_field "book.discount_percentage", class: "form-control"
1956
- end
1957
-
1958
- expect(html).to include %(<input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="" class="form-control">)
1959
- end
1960
-
1961
- it "allows to specify a 'min' attribute" do
1962
- html = form_for("/books") do |f|
1963
- f.range_field "book.discount_percentage", min: 0
1964
- end
1965
-
1966
- expect(html).to include %(<input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="" min="0">)
1967
- end
1968
-
1969
- it "allows to specify a 'max' attribute" do
1970
- html = form_for("/books") do |f|
1971
- f.range_field "book.discount_percentage", max: 100
1972
- end
1973
-
1974
- expect(html).to include %(<input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="" max="100">)
1975
- end
1976
-
1977
- it "allows to specify a 'step' attribute" do
1978
- html = form_for("/books") do |f|
1979
- f.range_field "book.discount_percentage", step: 5
1980
- end
1981
-
1982
- expect(html).to include %(<input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="" step="5">)
1983
- end
1984
-
1985
- context "with values" do
1986
- let(:values) { {book: Struct.new(:discount_percentage).new(val)} }
1987
- let(:val) { 95 }
1988
-
1989
- it "renders with value" do
1990
- html = form_for("/books", values: values) do |f|
1991
- f.range_field "book.discount_percentage"
1992
- end
1993
-
1994
- expect(html).to include %(<input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="95">)
1995
- end
1996
-
1997
- it "allows to override 'value' attribute" do
1998
- html = form_for("/books", values: values) do |f|
1999
- f.range_field "book.discount_percentage", value: 50
2000
- end
2001
-
2002
- expect(html).to include %(<input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="50">)
2003
- end
2004
- end
2005
-
2006
- context "with filled params" do
2007
- let(:params) { {book: {discount_percentage: val}} }
2008
- let(:val) { 95 }
2009
-
2010
- it "renders with value" do
2011
- html = form_for("/books") do |f|
2012
- f.range_field "book.discount_percentage"
2013
- end
2014
-
2015
- expect(html).to include %(<input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="95">)
2016
- end
2017
-
2018
- it "allows to override 'value' attribute" do
2019
- html = form_for("/books") do |f|
2020
- f.range_field "book.discount_percentage", value: 50
2021
- end
2022
-
2023
- expect(html).to include %(<input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="50">)
2024
- end
2025
- end
2026
- end
2027
-
2028
- describe "#text_area" do
2029
- it "renders the element" do
2030
- html = form_for("/books") do |f|
2031
- f.text_area "book.description"
2032
- end
2033
-
2034
- expect(html).to include %(<textarea name="book[description]" id="book-description">\n</textarea>)
2035
- end
2036
-
2037
- it "allows to override 'id' attribute" do
2038
- html = form_for("/books") do |f|
2039
- f.text_area "book.description", nil, id: "desc"
2040
- end
2041
-
2042
- expect(html).to include %(<textarea name="book[description]" id="desc">\n</textarea>)
2043
- end
2044
-
2045
- it "allows to override 'name' attribute" do
2046
- html = form_for("/books") do |f|
2047
- f.text_area "book.description", nil, name: "book[desc]"
2048
- end
2049
-
2050
- expect(html).to include %(<textarea name="book[desc]" id="book-description">\n</textarea>)
2051
- end
2052
-
2053
- it "allows to specify HTML attributes" do
2054
- html = form_for("/books") do |f|
2055
- f.text_area "book.description", nil, class: "form-control", cols: "5"
2056
- end
2057
-
2058
- expect(html).to include %(<textarea name="book[description]" id="book-description" class="form-control" cols="5">\n</textarea>)
2059
- end
2060
-
2061
- it "allows to omit content" do
2062
- html = form_for("/books") do |f|
2063
- f.text_area "book.description", class: "form-control", cols: "5"
2064
- end
2065
-
2066
- expect(html).to include %(<textarea name="book[description]" id="book-description" class="form-control" cols="5">\n</textarea>)
2067
- end
2068
-
2069
- it "allows to omit content, by accepting Hash serializable options" do
2070
- options = {class: "form-control", cols: 5}
2071
-
2072
- html = form_for("/books") do |f|
2073
- f.text_area "book.description", options
2074
- end
2075
-
2076
- expect(html).to include %(<textarea name="book[description]" id="book-description" class="form-control" cols="5">\n</textarea>)
2077
- end
2078
-
2079
- context "set content explicitly" do
2080
- let(:content) { "A short description of the book" }
2081
-
2082
- it "allows to set content" do
2083
- html = form_for("/books") do |f|
2084
- f.text_area "book.description", content
2085
- end
2086
-
2087
- expect(html).to include %(<textarea name="book[description]" id="book-description">\n#{content}</textarea>)
2088
- end
2089
- end
2090
-
2091
- context "with values" do
2092
- let(:values) { {book: Struct.new(:description).new(val)} }
2093
- let(:val) { "A short description of the book" }
2094
-
2095
- it "renders with value" do
2096
- html = form_for("/books", values: values) do |f|
2097
- f.text_area "book.description"
2098
- end
2099
-
2100
- expect(html).to include %(<textarea name="book[description]" id="book-description">\n#{val}</textarea>)
2101
- end
2102
-
2103
- it "renders with value, when only attributes are specified" do
2104
- html = form_for("/books", values: values) do |f|
2105
- f.text_area "book.description", class: "form-control"
2106
- end
2107
-
2108
- expect(html).to include %(<textarea name="book[description]" id="book-description" class="form-control">\n#{val}</textarea>)
2109
- end
2110
-
2111
- it "allows to override value" do
2112
- html = form_for("/books", values: values) do |f|
2113
- f.text_area "book.description", "Just a simple description"
2114
- end
2115
-
2116
- expect(html).to include %(<textarea name="book[description]" id="book-description">\nJust a simple description</textarea>)
2117
- end
2118
-
2119
- it "forces blank value" do
2120
- html = form_for("/books", values: values) do |f|
2121
- f.text_area "book.description", ""
2122
- end
2123
-
2124
- expect(html).to include %(<textarea name="book[description]" id="book-description">\n</textarea>)
2125
- end
2126
-
2127
- it "forces blank value, when also attributes are specified" do
2128
- html = form_for("/books", values: values) do |f|
2129
- f.text_area "book.description", "", class: "form-control"
2130
- end
2131
-
2132
- expect(html).to include %(<textarea name="book[description]" id="book-description" class="form-control">\n</textarea>)
2133
- end
2134
- end
2135
-
2136
- context "with filled params" do
2137
- let(:params) { {book: {description: val}} }
2138
- let(:val) { "A short description of the book" }
2139
-
2140
- it "renders with value" do
2141
- html = form_for("/books") do |f|
2142
- f.text_area "book.description"
2143
- end
2144
-
2145
- expect(html).to include %(<textarea name="book[description]" id="book-description">\n#{val}</textarea>)
2146
- end
2147
-
2148
- it "renders with value, when only attributes are specified" do
2149
- html = form_for("/books") do |f|
2150
- f.text_area "book.description", class: "form-control"
2151
- end
2152
-
2153
- expect(html).to include %(<textarea name="book[description]" id="book-description" class="form-control">\n#{val}</textarea>)
2154
- end
2155
-
2156
- it "allows to override value" do
2157
- html = form_for("/books") do |f|
2158
- f.text_area "book.description", "Just a simple description"
2159
- end
2160
-
2161
- expect(html).to include %(<textarea name="book[description]" id="book-description">\nJust a simple description</textarea>)
2162
- end
2163
-
2164
- it "forces blank value" do
2165
- html = form_for("/books") do |f|
2166
- f.text_area "book.description", ""
2167
- end
2168
-
2169
- expect(html).to include %(<textarea name="book[description]" id="book-description">\n</textarea>)
2170
- end
2171
-
2172
- it "forces blank value, when also attributes are specified" do
2173
- html = form_for("/books") do |f|
2174
- f.text_area "book.description", "", class: "form-control"
2175
- end
2176
-
2177
- expect(html).to include %(<textarea name="book[description]" id="book-description" class="form-control">\n</textarea>)
2178
- end
2179
- end
2180
- end
2181
-
2182
- describe "#text_field" do
2183
- it "renders" do
2184
- html = form_for("/books") do |f|
2185
- f.text_field "book.title"
2186
- end
2187
-
2188
- expect(html).to include %(<input type="text" name="book[title]" id="book-title" value="">)
2189
- end
2190
-
2191
- it "allows to override 'id' attribute" do
2192
- html = form_for("/books") do |f|
2193
- f.text_field "book.title", id: "book-short-title"
2194
- end
2195
-
2196
- expect(html).to include %(<input type="text" name="book[title]" id="book-short-title" value="">)
2197
- end
2198
-
2199
- it "allows to override 'name' attribute" do
2200
- html = form_for("/books") do |f|
2201
- f.text_field "book.title", name: "book[short_title]"
2202
- end
2203
-
2204
- expect(html).to include %(<input type="text" name="book[short_title]" id="book-title" value="">)
2205
- end
2206
-
2207
- it "allows to override 'value' attribute" do
2208
- html = form_for("/books") do |f|
2209
- f.text_field "book.title", value: "Refactoring"
2210
- end
2211
-
2212
- expect(html).to include %(<input type="text" name="book[title]" id="book-title" value="Refactoring">)
2213
- end
2214
-
2215
- it "allows to specify HTML attributes" do
2216
- html = form_for("/books") do |f|
2217
- f.text_field "book.title", class: "form-control"
2218
- end
2219
-
2220
- expect(html).to include %(<input type="text" name="book[title]" id="book-title" value="" class="form-control">)
2221
- end
2222
-
2223
- context "with values" do
2224
- let(:values) { {book: Struct.new(:title).new(val)} }
2225
- let(:val) { "Learn some <html>!" }
2226
-
2227
- it "renders with value" do
2228
- html = form_for("/books", values: values) do |f|
2229
- f.text_field "book.title"
2230
- end
2231
-
2232
- expect(html).to include %(<input type="text" name="book[title]" id="book-title" value="Learn some &lt;html&gt;!">)
2233
- end
2234
-
2235
- it "allows to override 'value' attribute" do
2236
- html = form_for("/books", values: values) do |f|
2237
- f.text_field "book.title", value: "DDD"
2238
- end
2239
-
2240
- expect(html).to include %(<input type="text" name="book[title]" id="book-title" value="DDD">)
2241
- end
2242
- end
2243
-
2244
- context "with filled params" do
2245
- let(:params) { {book: {title: val}} }
2246
- let(:val) { "Learn some <html>!" }
2247
-
2248
- it "renders with value" do
2249
- html = form_for("/books") do |f|
2250
- f.text_field "book.title"
2251
- end
2252
-
2253
- expect(html).to include %(<input type="text" name="book[title]" id="book-title" value="Learn some &lt;html&gt;!">)
2254
- end
2255
-
2256
- it "allows to override 'value' attribute" do
2257
- html = form_for("/books") do |f|
2258
- f.text_field "book.title", value: "DDD"
2259
- end
2260
-
2261
- expect(html).to include %(<input type="text" name="book[title]" id="book-title" value="DDD">)
2262
- end
2263
- end
2264
- end
2265
-
2266
- describe "#search_field" do
2267
- it "renders" do
2268
- html = form_for("/books") do |f|
2269
- f.search_field "book.search_title"
2270
- end
2271
-
2272
- expect(html).to include %(<input type="search" name="book[search_title]" id="book-search-title" value="">)
2273
- end
2274
-
2275
- it "allows to override 'id' attribute" do
2276
- html = form_for("/books") do |f|
2277
- f.search_field "book.search_title", id: "book-short-title"
2278
- end
2279
-
2280
- expect(html).to include %(<input type="search" name="book[search_title]" id="book-short-title" value="">)
2281
- end
2282
-
2283
- it "allows to override 'name' attribute" do
2284
- html = form_for("/books") do |f|
2285
- f.search_field "book.search_title", name: "book[short_title]"
2286
- end
2287
-
2288
- expect(html).to include %(<input type="search" name="book[short_title]" id="book-search-title" value="">)
2289
- end
2290
-
2291
- it "allows to override 'value' attribute" do
2292
- html = form_for("/books") do |f|
2293
- f.search_field "book.search_title", value: "Refactoring"
2294
- end
2295
-
2296
- expect(html).to include %(<input type="search" name="book[search_title]" id="book-search-title" value="Refactoring">)
2297
- end
2298
-
2299
- it "allows to specify HTML attributes" do
2300
- html = form_for("/books") do |f|
2301
- f.search_field "book.search_title", class: "form-control"
2302
- end
2303
-
2304
- expect(html).to include %(<input type="search" name="book[search_title]" id="book-search-title" value="" class="form-control">)
2305
- end
2306
-
2307
- context "with values" do
2308
- let(:values) { {book: Struct.new(:search_title).new(val)} }
2309
- let(:val) { "PPoEA" }
2310
-
2311
- it "renders with value" do
2312
- html = form_for("/books", values: values) do |f|
2313
- f.search_field "book.search_title"
2314
- end
2315
-
2316
- expect(html).to include %(<input type="search" name="book[search_title]" id="book-search-title" value="PPoEA">)
2317
- end
2318
-
2319
- it "allows to override 'value' attribute" do
2320
- html = form_for("/books", values: values) do |f|
2321
- f.search_field "book.search_title", value: "DDD"
2322
- end
2323
-
2324
- expect(html).to include %(<input type="search" name="book[search_title]" id="book-search-title" value="DDD">)
2325
- end
2326
- end
2327
-
2328
- context "with filled params" do
2329
- let(:params) { {book: {search_title: val}} }
2330
- let(:val) { "PPoEA" }
2331
-
2332
- it "renders with value" do
2333
- html = form_for("/books") do |f|
2334
- f.search_field "book.search_title"
2335
- end
2336
-
2337
- expect(html).to include %(<input type="search" name="book[search_title]" id="book-search-title" value="PPoEA">)
2338
- end
2339
-
2340
- it "allows to override 'value' attribute" do
2341
- html = form_for("/books") do |f|
2342
- f.search_field "book.search_title", value: "DDD"
2343
- end
2344
-
2345
- expect(html).to include %(<input type="search" name="book[search_title]" id="book-search-title" value="DDD">)
2346
- end
2347
- end
2348
- end
2349
-
2350
- describe "#password_field" do
2351
- it "renders" do
2352
- html = form_for("/books") do |f|
2353
- f.password_field "signup.password"
2354
- end
2355
-
2356
- expect(html).to include %(<input type="password" name="signup[password]" id="signup-password" value="">)
2357
- end
2358
-
2359
- it "allows to override 'id' attribute" do
2360
- html = form_for("/books") do |f|
2361
- f.password_field "signup.password", id: "signup-pass"
2362
- end
2363
-
2364
- expect(html).to include %(<input type="password" name="signup[password]" id="signup-pass" value="">)
2365
- end
2366
-
2367
- it "allows to override 'name' attribute" do
2368
- html = form_for("/books") do |f|
2369
- f.password_field "signup.password", name: "password"
2370
- end
2371
-
2372
- expect(html).to include %(<input type="password" name="password" id="signup-password" value="">)
2373
- end
2374
-
2375
- it "allows to override 'value' attribute" do
2376
- html = form_for("/books") do |f|
2377
- f.password_field "signup.password", value: "topsecret"
2378
- end
2379
-
2380
- expect(html).to include %(<input type="password" name="signup[password]" id="signup-password" value="topsecret">)
2381
- end
2382
-
2383
- it "allows to specify HTML attributes" do
2384
- html = form_for("/books") do |f|
2385
- f.password_field "signup.password", class: "form-control"
2386
- end
2387
-
2388
- expect(html).to include %(<input type="password" name="signup[password]" id="signup-password" value="" class="form-control">)
2389
- end
2390
-
2391
- context "with values" do
2392
- let(:values) { {signup: Struct.new(:password).new(val)} }
2393
- let(:val) { "secret" }
2394
-
2395
- it "ignores value" do
2396
- html = form_for("/books", values: values) do |f|
2397
- f.password_field "signup.password"
2398
- end
2399
-
2400
- expect(html).to include %(<input type="password" name="signup[password]" id="signup-password" value="">)
2401
- end
2402
-
2403
- it "allows to override 'value' attribute" do
2404
- html = form_for("/books", values: values) do |f|
2405
- f.password_field "signup.password", value: "123"
2406
- end
2407
-
2408
- expect(html).to include %(<input type="password" name="signup[password]" id="signup-password" value="123">)
2409
- end
2410
- end
2411
-
2412
- context "with filled params" do
2413
- let(:params) { {signup: {password: val}} }
2414
- let(:val) { "secret" }
2415
-
2416
- it "ignores value" do
2417
- html = form_for("/books") do |f|
2418
- f.password_field "signup.password"
2419
- end
2420
-
2421
- expect(html).to include %(<input type="password" name="signup[password]" id="signup-password" value="">)
2422
- end
2423
-
2424
- it "allows to override 'value' attribute" do
2425
- html = form_for("/books") do |f|
2426
- f.password_field "signup.password", value: "123"
2427
- end
2428
-
2429
- expect(html).to include %(<input type="password" name="signup[password]" id="signup-password" value="123">)
2430
- end
2431
- end
2432
- end
2433
-
2434
- describe "#radio_button" do
2435
- it "renders" do
2436
- html = form_for("/books") do |f|
2437
- f.radio_button("book.category", "Fiction") +
2438
- f.radio_button("book.category", "Non-Fiction")
2439
- end
2440
-
2441
- expect(html).to include %(<input type="radio" name="book[category]" value="Fiction"><input type="radio" name="book[category]" value="Non-Fiction">)
2442
- end
2443
-
2444
- it "allows to override 'name' attribute" do
2445
- html = form_for("/books") do |f|
2446
- f.radio_button("book.category", "Fiction", name: "category_name") +
2447
- f.radio_button("book.category", "Non-Fiction", name: "category_name")
2448
- end
2449
-
2450
- expect(html).to include %(<input type="radio" name="category_name" value="Fiction"><input type="radio" name="category_name" value="Non-Fiction">)
2451
- end
2452
-
2453
- it "allows to specify HTML attributes" do
2454
- html = form_for("/books") do |f|
2455
- f.radio_button("book.category", "Fiction", class: "form-control") +
2456
- f.radio_button("book.category", "Non-Fiction", class: "radio-button")
2457
- end
2458
-
2459
- expect(html).to include %(<input type="radio" name="book[category]" value="Fiction" class="form-control"><input type="radio" name="book[category]" value="Non-Fiction" class="radio-button">)
2460
- end
2461
-
2462
- context "with values" do
2463
- let(:values) { {book: Struct.new(:category).new(val)} }
2464
- let(:val) { "Non-Fiction" }
2465
-
2466
- it "renders with value" do
2467
- html = form_for("/books", values: values) do |f|
2468
- f.radio_button("book.category", "Fiction") +
2469
- f.radio_button("book.category", "Non-Fiction")
2470
- end
2471
-
2472
- expect(html).to include %(<input type="radio" name="book[category]" value="Fiction"><input type="radio" name="book[category]" value="Non-Fiction" checked="checked">)
2473
- end
2474
- end
2475
-
2476
- context "with filled params" do
2477
- context "string value" do
2478
- let(:params) { {book: {category: val}} }
2479
- let(:val) { "Non-Fiction" }
2480
-
2481
- it "renders with value" do
2482
- html = form_for("/books") do |f|
2483
- f.radio_button("book.category", "Fiction") +
2484
- f.radio_button("book.category", "Non-Fiction")
2485
- end
2486
-
2487
- expect(html).to include %(<input type="radio" name="book[category]" value="Fiction"><input type="radio" name="book[category]" value="Non-Fiction" checked="checked">)
2488
- end
2489
- end
2490
-
2491
- context "decimal value" do
2492
- let(:params) { {book: {price: val}} }
2493
- let(:val) { "20.0" }
2494
-
2495
- it "renders with value" do
2496
- html = form_for("/books") do |f|
2497
- f.radio_button("book.price", 10.0) +
2498
- f.radio_button("book.price", 20.0)
2499
- end
2500
-
2501
- expect(html).to include %(<input type="radio" name="book[price]" value="10.0"><input type="radio" name="book[price]" value="20.0" checked="checked">)
2502
- end
2503
- end
2504
- end
2505
- end
2506
-
2507
- describe "#select" do
2508
- let(:option_values) { {"Italy" => "it", "United States" => "us"} }
2509
-
2510
- it "renders" do
2511
- html = form_for("/books") do |f|
2512
- f.select "book.store", option_values
2513
- end
2514
-
2515
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it">Italy</option><option value="us">United States</option></select>)
2516
- end
2517
-
2518
- it "allows to override 'id' attribute" do
2519
- html = form_for("/books") do |f|
2520
- f.select "book.store", option_values, id: "store"
2521
- end
2522
-
2523
- expect(html).to include %(<select name="book[store]" id="store"><option value="it">Italy</option><option value="us">United States</option></select>)
2524
- end
2525
-
2526
- it "allows to override 'name' attribute" do
2527
- html = form_for("/books") do |f|
2528
- f.select "book.store", option_values, name: "store"
2529
- end
2530
-
2531
- expect(html).to include %(<select name="store" id="book-store"><option value="it">Italy</option><option value="us">United States</option></select>)
2532
- end
2533
-
2534
- it "allows to specify HTML attributes" do
2535
- html = form_for("/books") do |f|
2536
- f.select "book.store", option_values, class: "form-control"
2537
- end
2538
-
2539
- expect(html).to include %(<select name="book[store]" id="book-store" class="form-control"><option value="it">Italy</option><option value="us">United States</option></select>)
2540
- end
2541
-
2542
- it "allows to specify HTML attributes for options" do
2543
- html = form_for("/books") do |f|
2544
- f.select "book.store", option_values, options: {class: "form-option"}
2545
- end
2546
-
2547
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it" class="form-option">Italy</option><option value="us" class="form-option">United States</option></select>)
2548
- end
2549
-
2550
- context "with option 'multiple'" do
2551
- it "renders" do
2552
- html = form_for("/books") do |f|
2553
- f.select "book.store", option_values, multiple: true
2554
- end
2555
-
2556
- expect(html).to include %(<select name="book[store][]" id="book-store" multiple="multiple"><option value="it">Italy</option><option value="us">United States</option></select>)
2557
- end
2558
-
2559
- it "allows to select values" do
2560
- html = form_for("/books") do |f|
2561
- f.select "book.store", option_values, multiple: true, options: {selected: %w[it us]}
2562
- end
2563
-
2564
- expect(html).to include %(<select name="book[store][]" id="book-store" multiple="multiple"><option value="it" selected="selected">Italy</option><option value="us" selected="selected">United States</option></select>)
2565
- end
2566
- end
2567
-
2568
- context "with values an structured Array of values" do
2569
- let(:option_values) { [%w[Italy it], ["United States", "us"]] }
2570
-
2571
- it "renders" do
2572
- html = form_for("/books") do |f|
2573
- f.select "book.store", option_values
2574
- end
2575
-
2576
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it">Italy</option><option value="us">United States</option></select>)
2577
- end
2578
-
2579
- context "and filled params" do
2580
- let(:params) { {book: {store: val}} }
2581
- let(:val) { "it" }
2582
-
2583
- it "renders with value" do
2584
- html = form_for("/books") do |f|
2585
- f.select "book.store", option_values
2586
- end
2587
-
2588
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it" selected="selected">Italy</option><option value="us">United States</option></select>)
2589
- end
2590
- end
2591
-
2592
- context "and repeated values" do
2593
- let(:option_values) { [%w[Italy it], ["United States", "us"], %w[Italy it]] }
2594
-
2595
- it "renders" do
2596
- html = form_for("/books") do |f|
2597
- f.select "book.store", option_values
2598
- end
2599
-
2600
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it">Italy</option><option value="us">United States</option><option value="it">Italy</option></select>)
2601
- end
2602
- end
2603
- end
2604
-
2605
- context "with values an Array of objects" do
2606
- let(:values) { [Store.new("it", "Italy"), Store.new("us", "United States")] }
2607
-
2608
- it "renders" do
2609
- html = form_for("/books") do |f|
2610
- f.select "book.store", option_values
2611
- end
2612
-
2613
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it">Italy</option><option value="us">United States</option></select>)
2614
- end
2615
-
2616
- context "and filled params" do
2617
- let(:params) { {book: {store: val}} }
2618
- let(:val) { "it" }
2619
-
2620
- it "renders with value" do
2621
- html = form_for("/books") do |f|
2622
- f.select "book.store", option_values
2623
- end
2624
-
2625
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it" selected="selected">Italy</option><option value="us">United States</option></select>)
2626
- end
2627
- end
2628
- end
2629
-
2630
- context "with values" do
2631
- let(:values) { {book: Struct.new(:store).new(val)} }
2632
- let(:val) { "it" }
2633
-
2634
- it "renders with value" do
2635
- html = form_for("/books", values: values) do |f|
2636
- f.select "book.store", option_values
2637
- end
2638
-
2639
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it" selected="selected">Italy</option><option value="us">United States</option></select>)
2640
- end
2641
- end
2642
-
2643
- context "with filled params" do
2644
- let(:params) { {book: {store: val}} }
2645
- let(:val) { "it" }
2646
-
2647
- it "renders with value" do
2648
- html = form_for("/books") do |f|
2649
- f.select "book.store", option_values
2650
- end
2651
-
2652
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it" selected="selected">Italy</option><option value="us">United States</option></select>)
2653
- end
2654
- end
2655
-
2656
- context "with prompt option" do
2657
- it "allows string" do
2658
- html = form_for("/books") do |f|
2659
- f.select "book.store", option_values, options: {prompt: "Select a store"}
2660
- end
2661
-
2662
- expect(html).to include %(<select name="book[store]" id="book-store"><option>Select a store</option><option value="it">Italy</option><option value="us">United States</option></select>)
2663
- end
2664
-
2665
- it "allows blank string" do
2666
- html = form_for("/books") do |f|
2667
- f.select "book.store", option_values, options: {prompt: ""}
2668
- end
2669
-
2670
- expect(html).to include %(<select name="book[store]" id="book-store"><option></option><option value="it">Italy</option><option value="us">United States</option></select>)
2671
- end
2672
-
2673
- context "with values" do
2674
- let(:values) { {book: Struct.new(:store).new(val)} }
2675
- let(:val) { "it" }
2676
-
2677
- it "renders with value" do
2678
- html = form_for("/books", values: values) do |f|
2679
- f.select "book.store", option_values, options: {prompt: "Select a store"}
2680
- end
2681
-
2682
- expect(html).to include %(<select name="book[store]" id="book-store"><option>Select a store</option><option value="it" selected="selected">Italy</option><option value="us">United States</option></select>)
2683
- end
2684
- end
2685
-
2686
- context "with filled params" do
2687
- context "string values" do
2688
- let(:params) { {book: {store: val}} }
2689
- let(:val) { "it" }
2690
-
2691
- it "renders with value" do
2692
- html = form_for("/books") do |f|
2693
- f.select "book.store", option_values, options: {prompt: "Select a store"}
2694
- end
2695
-
2696
- expect(html).to include %(<select name="book[store]" id="book-store"><option>Select a store</option><option value="it" selected="selected">Italy</option><option value="us">United States</option></select>)
2697
- end
2698
- end
2699
-
2700
- context "integer values" do
2701
- let(:values) { {"Brave new world" => 1, "Solaris" => 2} }
2702
- let(:params) { {bookshelf: {book: val}} }
2703
- let(:val) { "1" }
2704
-
2705
- it "renders" do
2706
- html = form_for("/books") do |f|
2707
- f.select "bookshelf.book", values
2708
- end
2709
-
2710
- expect(html).to include %(<select name="bookshelf[book]" id="bookshelf-book"><option value="1" selected="selected">Brave new world</option><option value="2">Solaris</option></select>)
2711
- end
2712
- end
2713
- end
2714
- end
2715
-
2716
- context "with selected attribute" do
2717
- let(:params) { {book: {store: val}} }
2718
- let(:val) { "it" }
2719
-
2720
- it "sets the selected attribute" do
2721
- html = form_for("/books") do |f|
2722
- f.select "book.store", option_values, options: {selected: val}
2723
- end
2724
-
2725
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it" selected="selected">Italy</option><option value="us">United States</option></select>)
2726
- end
2727
- end
2728
-
2729
- context "with nil as a value" do
2730
- let(:option_values) { {"Italy" => "it", "United States" => "us", "N/A" => nil} }
2731
-
2732
- it "sets nil option as selected by default" do
2733
- html = form_for("/books") do |f|
2734
- f.select "book.store", option_values
2735
- end
2736
-
2737
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it">Italy</option><option value="us">United States</option><option selected="selected">N/A</option></select>)
2738
- end
2739
-
2740
- it "set as selected the option with nil value" do
2741
- html = form_for("/books") do |f|
2742
- f.select "book.store", option_values, options: {selected: nil}
2743
- end
2744
-
2745
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it">Italy</option><option value="us">United States</option><option selected="selected">N/A</option></select>)
2746
- end
2747
-
2748
- it "set as selected the option with a value" do
2749
- html = form_for("/books") do |f|
2750
- f.select "book.store", option_values, options: {selected: "it"}
2751
- end
2752
-
2753
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it" selected="selected">Italy</option><option value="us">United States</option><option>N/A</option></select>)
2754
- end
2755
-
2756
- it "allows to force the selection of none" do
2757
- html = form_for("/books") do |f|
2758
- f.select "book.store", option_values, options: {selected: "none"}
2759
- end
2760
-
2761
- expect(html).to include %(<select name="book[store]" id="book-store"><option value="it">Italy</option><option value="us">United States</option><option>N/A</option></select>)
2762
- end
2763
-
2764
- context "with values" do
2765
- let(:values) { {book: Struct.new(:category).new(val)} }
2766
- let(:option_values) { {"N/A" => nil, "Horror" => "horror", "SciFy" => "scify"} }
2767
- let(:val) { "horror" }
2768
-
2769
- it "sets correct value as selected" do
2770
- html = form_for("/books", values: values) do |f|
2771
- f.select "book.category", option_values
2772
- end
2773
-
2774
- expect(html).to include %(<form action="/books" accept-charset="utf-8" method="POST"><select name="book[category]" id="book-category"><option>N/A</option><option value="horror" selected="selected">Horror</option><option value="scify">SciFy</option></select></form>)
2775
- end
2776
- end
2777
-
2778
- context "with non String values" do
2779
- let(:values) { {book: Struct.new(:category).new(val)} }
2780
- let(:option_values) { {"Horror" => "1", "SciFy" => "2"} }
2781
- let(:val) { 1 }
2782
-
2783
- it "sets correct value as selected" do
2784
- html = form_for("/books", values: values) do |f|
2785
- f.select "book.category", option_values
2786
- end
2787
-
2788
- expect(html).to include %(<form action="/books" accept-charset="utf-8" method="POST"><select name="book[category]" id="book-category"><option value="1" selected="selected">Horror</option><option value="2">SciFy</option></select></form>)
2789
- end
2790
- end
2791
- end
2792
- end
2793
-
2794
- describe "#datalist" do
2795
- let(:values) { ["Italy", "United States"] }
2796
-
2797
- it "renders" do
2798
- html = form_for("/books") do |f|
2799
- f.datalist "book.store", values, "books"
2800
- end
2801
-
2802
- expect(html).to include %(<input type="text" name="book[store]" id="book-store" value="" list="books"><datalist id="books"><option value="Italy"></option><option value="United States"></option></datalist>)
2803
- end
2804
-
2805
- it "just allows to override 'id' attribute of the text input" do
2806
- html = form_for("/books") do |f|
2807
- f.datalist "book.store", values, "books", id: "store"
2808
- end
2809
-
2810
- expect(html).to include %(<input type="text" name="book[store]" id="store" value="" list="books"><datalist id="books"><option value="Italy"></option><option value="United States"></option></datalist>)
2811
- end
2812
-
2813
- it "allows to override 'name' attribute" do
2814
- html = form_for("/books") do |f|
2815
- f.datalist "book.store", values, "books", name: "store"
2816
- end
2817
-
2818
- expect(html).to include %(<input type="text" name="store" id="book-store" value="" list="books"><datalist id="books"><option value="Italy"></option><option value="United States"></option></datalist>)
2819
- end
2820
-
2821
- it "allows to specify HTML attributes" do
2822
- html = form_for("/books") do |f|
2823
- f.datalist "book.store", values, "books", class: "form-control"
2824
- end
2825
-
2826
- expect(html).to include %(<input type="text" name="book[store]" id="book-store" value="" class="form-control" list="books"><datalist id="books"><option value="Italy"></option><option value="United States"></option></datalist>)
2827
- end
2828
-
2829
- it "allows to specify HTML attributes for options" do
2830
- html = form_for("/books") do |f|
2831
- f.datalist "book.store", values, "books", options: {class: "form-option"}
2832
- end
2833
-
2834
- expect(html).to include %(<input type="text" name="book[store]" id="book-store" value="" list="books"><datalist id="books"><option value="Italy" class="form-option"></option><option value="United States" class="form-option"></option></datalist>)
2835
- end
2836
-
2837
- it "allows to specify HTML attributes for datalist" do
2838
- html = form_for("/books") do |f|
2839
- f.datalist "book.store", values, "books", datalist: {class: "form-option"}
2840
- end
2841
-
2842
- expect(html).to include %(<input type="text" name="book[store]" id="book-store" value="" list="books"><datalist class="form-option" id="books"><option value="Italy"></option><option value="United States"></option></datalist>)
2843
- end
2844
-
2845
- context "with a Hash of values" do
2846
- let(:values) { {"Italy" => "it", "United States" => "us"} }
2847
-
2848
- it "renders" do
2849
- html = form_for("/books") do |f|
2850
- f.datalist "book.store", values, "books"
2851
- end
2852
-
2853
- expect(html).to include %(<input type="text" name="book[store]" id="book-store" value="" list="books"><datalist id="books"><option value="Italy">it</option><option value="United States">us</option></datalist>)
2854
- end
2855
- end
2856
- end
2857
- end