mega-safe-tool 0.0.1

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 (171) hide show
  1. checksums.yaml +7 -0
  2. data/formtastic-6.0.0/Appraisals +23 -0
  3. data/formtastic-6.0.0/CONTRIBUTING.md +27 -0
  4. data/formtastic-6.0.0/Gemfile +8 -0
  5. data/formtastic-6.0.0/MIT-LICENSE +20 -0
  6. data/formtastic-6.0.0/README.md +600 -0
  7. data/formtastic-6.0.0/RELEASE_PROCESS +7 -0
  8. data/formtastic-6.0.0/Rakefile +54 -0
  9. data/formtastic-6.0.0/bin/appraisal +8 -0
  10. data/formtastic-6.0.0/formtastic.gemspec +45 -0
  11. data/formtastic-6.0.0/gemfiles/rails_72.gemfile +9 -0
  12. data/formtastic-6.0.0/gemfiles/rails_80.gemfile +9 -0
  13. data/formtastic-6.0.0/gemfiles/rails_81.gemfile +9 -0
  14. data/formtastic-6.0.0/gemfiles/rails_edge.gemfile +9 -0
  15. data/formtastic-6.0.0/lib/formtastic/action_class_finder.rb +19 -0
  16. data/formtastic-6.0.0/lib/formtastic/actions/base.rb +157 -0
  17. data/formtastic-6.0.0/lib/formtastic/actions/button_action.rb +68 -0
  18. data/formtastic-6.0.0/lib/formtastic/actions/buttonish.rb +18 -0
  19. data/formtastic-6.0.0/lib/formtastic/actions/input_action.rb +71 -0
  20. data/formtastic-6.0.0/lib/formtastic/actions/link_action.rb +89 -0
  21. data/formtastic-6.0.0/lib/formtastic/actions.rb +15 -0
  22. data/formtastic-6.0.0/lib/formtastic/deprecation.rb +6 -0
  23. data/formtastic-6.0.0/lib/formtastic/form_builder.rb +109 -0
  24. data/formtastic-6.0.0/lib/formtastic/helpers/action_helper.rb +115 -0
  25. data/formtastic-6.0.0/lib/formtastic/helpers/actions_helper.rb +169 -0
  26. data/formtastic-6.0.0/lib/formtastic/helpers/enum.rb +14 -0
  27. data/formtastic-6.0.0/lib/formtastic/helpers/errors_helper.rb +139 -0
  28. data/formtastic-6.0.0/lib/formtastic/helpers/fieldset_wrapper.rb +85 -0
  29. data/formtastic-6.0.0/lib/formtastic/helpers/file_column_detection.rb +17 -0
  30. data/formtastic-6.0.0/lib/formtastic/helpers/form_helper.rb +204 -0
  31. data/formtastic-6.0.0/lib/formtastic/helpers/input_helper.rb +349 -0
  32. data/formtastic-6.0.0/lib/formtastic/helpers/inputs_helper.rb +421 -0
  33. data/formtastic-6.0.0/lib/formtastic/helpers/reflection.rb +38 -0
  34. data/formtastic-6.0.0/lib/formtastic/helpers.rb +16 -0
  35. data/formtastic-6.0.0/lib/formtastic/html_attributes.rb +33 -0
  36. data/formtastic-6.0.0/lib/formtastic/i18n.rb +33 -0
  37. data/formtastic-6.0.0/lib/formtastic/input_class_finder.rb +19 -0
  38. data/formtastic-6.0.0/lib/formtastic/inputs/base/aria.rb +26 -0
  39. data/formtastic-6.0.0/lib/formtastic/inputs/base/associations.rb +32 -0
  40. data/formtastic-6.0.0/lib/formtastic/inputs/base/choices.rb +109 -0
  41. data/formtastic-6.0.0/lib/formtastic/inputs/base/collections.rb +158 -0
  42. data/formtastic-6.0.0/lib/formtastic/inputs/base/database.rb +20 -0
  43. data/formtastic-6.0.0/lib/formtastic/inputs/base/datetime_pickerish.rb +86 -0
  44. data/formtastic-6.0.0/lib/formtastic/inputs/base/errors.rb +59 -0
  45. data/formtastic-6.0.0/lib/formtastic/inputs/base/fileish.rb +24 -0
  46. data/formtastic-6.0.0/lib/formtastic/inputs/base/hints.rb +32 -0
  47. data/formtastic-6.0.0/lib/formtastic/inputs/base/html.rb +54 -0
  48. data/formtastic-6.0.0/lib/formtastic/inputs/base/labelling.rb +53 -0
  49. data/formtastic-6.0.0/lib/formtastic/inputs/base/naming.rb +43 -0
  50. data/formtastic-6.0.0/lib/formtastic/inputs/base/numeric.rb +51 -0
  51. data/formtastic-6.0.0/lib/formtastic/inputs/base/options.rb +18 -0
  52. data/formtastic-6.0.0/lib/formtastic/inputs/base/placeholder.rb +18 -0
  53. data/formtastic-6.0.0/lib/formtastic/inputs/base/stringish.rb +39 -0
  54. data/formtastic-6.0.0/lib/formtastic/inputs/base/timeish.rb +246 -0
  55. data/formtastic-6.0.0/lib/formtastic/inputs/base/validations.rb +250 -0
  56. data/formtastic-6.0.0/lib/formtastic/inputs/base/wrapping.rb +51 -0
  57. data/formtastic-6.0.0/lib/formtastic/inputs/base.rb +79 -0
  58. data/formtastic-6.0.0/lib/formtastic/inputs/boolean_input.rb +119 -0
  59. data/formtastic-6.0.0/lib/formtastic/inputs/check_boxes_input.rb +198 -0
  60. data/formtastic-6.0.0/lib/formtastic/inputs/color_input.rb +42 -0
  61. data/formtastic-6.0.0/lib/formtastic/inputs/country_input.rb +90 -0
  62. data/formtastic-6.0.0/lib/formtastic/inputs/datalist_input.rb +42 -0
  63. data/formtastic-6.0.0/lib/formtastic/inputs/date_picker_input.rb +94 -0
  64. data/formtastic-6.0.0/lib/formtastic/inputs/date_select_input.rb +35 -0
  65. data/formtastic-6.0.0/lib/formtastic/inputs/datetime_picker_input.rb +104 -0
  66. data/formtastic-6.0.0/lib/formtastic/inputs/datetime_select_input.rb +13 -0
  67. data/formtastic-6.0.0/lib/formtastic/inputs/email_input.rb +42 -0
  68. data/formtastic-6.0.0/lib/formtastic/inputs/file_input.rb +43 -0
  69. data/formtastic-6.0.0/lib/formtastic/inputs/hidden_input.rb +63 -0
  70. data/formtastic-6.0.0/lib/formtastic/inputs/number_input.rb +89 -0
  71. data/formtastic-6.0.0/lib/formtastic/inputs/password_input.rb +42 -0
  72. data/formtastic-6.0.0/lib/formtastic/inputs/phone_input.rb +43 -0
  73. data/formtastic-6.0.0/lib/formtastic/inputs/radio_input.rb +164 -0
  74. data/formtastic-6.0.0/lib/formtastic/inputs/range_input.rb +96 -0
  75. data/formtastic-6.0.0/lib/formtastic/inputs/search_input.rb +42 -0
  76. data/formtastic-6.0.0/lib/formtastic/inputs/select_input.rb +236 -0
  77. data/formtastic-6.0.0/lib/formtastic/inputs/string_input.rb +37 -0
  78. data/formtastic-6.0.0/lib/formtastic/inputs/text_input.rb +49 -0
  79. data/formtastic-6.0.0/lib/formtastic/inputs/time_picker_input.rb +100 -0
  80. data/formtastic-6.0.0/lib/formtastic/inputs/time_select_input.rb +39 -0
  81. data/formtastic-6.0.0/lib/formtastic/inputs/time_zone_input.rb +59 -0
  82. data/formtastic-6.0.0/lib/formtastic/inputs/url_input.rb +42 -0
  83. data/formtastic-6.0.0/lib/formtastic/inputs.rb +43 -0
  84. data/formtastic-6.0.0/lib/formtastic/localized_string.rb +18 -0
  85. data/formtastic-6.0.0/lib/formtastic/localizer.rb +151 -0
  86. data/formtastic-6.0.0/lib/formtastic/namespaced_class_finder.rb +98 -0
  87. data/formtastic-6.0.0/lib/formtastic/version.rb +4 -0
  88. data/formtastic-6.0.0/lib/formtastic.rb +48 -0
  89. data/formtastic-6.0.0/lib/generators/formtastic/form/form_generator.rb +111 -0
  90. data/formtastic-6.0.0/lib/generators/formtastic/input/input_generator.rb +47 -0
  91. data/formtastic-6.0.0/lib/generators/formtastic/install/install_generator.rb +23 -0
  92. data/formtastic-6.0.0/lib/generators/formtastic/stylesheets/stylesheets_generator.rb +15 -0
  93. data/formtastic-6.0.0/lib/generators/templates/_form.html.erb +11 -0
  94. data/formtastic-6.0.0/lib/generators/templates/_form.html.haml +8 -0
  95. data/formtastic-6.0.0/lib/generators/templates/_form.html.slim +8 -0
  96. data/formtastic-6.0.0/lib/generators/templates/formtastic.css +289 -0
  97. data/formtastic-6.0.0/lib/generators/templates/formtastic.rb +118 -0
  98. data/formtastic-6.0.0/lib/generators/templates/input.rb +19 -0
  99. data/formtastic-6.0.0/lib/locale/en.yml +10 -0
  100. data/formtastic-6.0.0/sample/basic_inputs.html +224 -0
  101. data/formtastic-6.0.0/sample/config.ru +69 -0
  102. data/formtastic-6.0.0/sample/index.html +14 -0
  103. data/formtastic-6.0.0/script/integration-template.rb +76 -0
  104. data/formtastic-6.0.0/script/integration.sh +32 -0
  105. data/formtastic-6.0.0/spec/action_class_finder_spec.rb +12 -0
  106. data/formtastic-6.0.0/spec/actions/button_action_spec.rb +63 -0
  107. data/formtastic-6.0.0/spec/actions/generic_action_spec.rb +521 -0
  108. data/formtastic-6.0.0/spec/actions/input_action_spec.rb +59 -0
  109. data/formtastic-6.0.0/spec/actions/link_action_spec.rb +92 -0
  110. data/formtastic-6.0.0/spec/builder/custom_builder_spec.rb +132 -0
  111. data/formtastic-6.0.0/spec/builder/error_proc_spec.rb +27 -0
  112. data/formtastic-6.0.0/spec/builder/semantic_fields_for_spec.rb +213 -0
  113. data/formtastic-6.0.0/spec/fast_spec_helper.rb +12 -0
  114. data/formtastic-6.0.0/spec/generators/formtastic/form/form_generator_spec.rb +132 -0
  115. data/formtastic-6.0.0/spec/generators/formtastic/input/input_generator_spec.rb +125 -0
  116. data/formtastic-6.0.0/spec/generators/formtastic/install/install_generator_spec.rb +48 -0
  117. data/formtastic-6.0.0/spec/generators/formtastic/stylesheets/stylesheets_generator_spec.rb +22 -0
  118. data/formtastic-6.0.0/spec/helpers/action_helper_spec.rb +338 -0
  119. data/formtastic-6.0.0/spec/helpers/actions_helper_spec.rb +143 -0
  120. data/formtastic-6.0.0/spec/helpers/form_helper_spec.rb +224 -0
  121. data/formtastic-6.0.0/spec/helpers/input_helper_spec.rb +991 -0
  122. data/formtastic-6.0.0/spec/helpers/inputs_helper_spec.rb +669 -0
  123. data/formtastic-6.0.0/spec/helpers/reflection_helper_spec.rb +32 -0
  124. data/formtastic-6.0.0/spec/helpers/semantic_errors_helper_spec.rb +220 -0
  125. data/formtastic-6.0.0/spec/i18n_spec.rb +210 -0
  126. data/formtastic-6.0.0/spec/input_class_finder_spec.rb +10 -0
  127. data/formtastic-6.0.0/spec/inputs/base/collections_spec.rb +119 -0
  128. data/formtastic-6.0.0/spec/inputs/base/validations_spec.rb +481 -0
  129. data/formtastic-6.0.0/spec/inputs/boolean_input_spec.rb +254 -0
  130. data/formtastic-6.0.0/spec/inputs/check_boxes_input_spec.rb +547 -0
  131. data/formtastic-6.0.0/spec/inputs/color_input_spec.rb +85 -0
  132. data/formtastic-6.0.0/spec/inputs/country_input_spec.rb +133 -0
  133. data/formtastic-6.0.0/spec/inputs/custom_input_spec.rb +51 -0
  134. data/formtastic-6.0.0/spec/inputs/datalist_input_spec.rb +61 -0
  135. data/formtastic-6.0.0/spec/inputs/date_picker_input_spec.rb +449 -0
  136. data/formtastic-6.0.0/spec/inputs/date_select_input_spec.rb +249 -0
  137. data/formtastic-6.0.0/spec/inputs/datetime_picker_input_spec.rb +490 -0
  138. data/formtastic-6.0.0/spec/inputs/datetime_select_input_spec.rb +209 -0
  139. data/formtastic-6.0.0/spec/inputs/email_input_spec.rb +85 -0
  140. data/formtastic-6.0.0/spec/inputs/file_input_spec.rb +89 -0
  141. data/formtastic-6.0.0/spec/inputs/hidden_input_spec.rb +135 -0
  142. data/formtastic-6.0.0/spec/inputs/include_blank_spec.rb +78 -0
  143. data/formtastic-6.0.0/spec/inputs/label_spec.rb +181 -0
  144. data/formtastic-6.0.0/spec/inputs/number_input_spec.rb +815 -0
  145. data/formtastic-6.0.0/spec/inputs/password_input_spec.rb +99 -0
  146. data/formtastic-6.0.0/spec/inputs/phone_input_spec.rb +85 -0
  147. data/formtastic-6.0.0/spec/inputs/placeholder_spec.rb +71 -0
  148. data/formtastic-6.0.0/spec/inputs/radio_input_spec.rb +326 -0
  149. data/formtastic-6.0.0/spec/inputs/range_input_spec.rb +505 -0
  150. data/formtastic-6.0.0/spec/inputs/readonly_spec.rb +50 -0
  151. data/formtastic-6.0.0/spec/inputs/search_input_spec.rb +84 -0
  152. data/formtastic-6.0.0/spec/inputs/select_input_spec.rb +661 -0
  153. data/formtastic-6.0.0/spec/inputs/string_input_spec.rb +326 -0
  154. data/formtastic-6.0.0/spec/inputs/text_input_spec.rb +187 -0
  155. data/formtastic-6.0.0/spec/inputs/time_picker_input_spec.rb +455 -0
  156. data/formtastic-6.0.0/spec/inputs/time_select_input_spec.rb +261 -0
  157. data/formtastic-6.0.0/spec/inputs/time_zone_input_spec.rb +143 -0
  158. data/formtastic-6.0.0/spec/inputs/url_input_spec.rb +85 -0
  159. data/formtastic-6.0.0/spec/inputs/with_options_spec.rb +43 -0
  160. data/formtastic-6.0.0/spec/localizer_spec.rb +130 -0
  161. data/formtastic-6.0.0/spec/namespaced_class_finder_spec.rb +90 -0
  162. data/formtastic-6.0.0/spec/schema.rb +22 -0
  163. data/formtastic-6.0.0/spec/spec.opts +2 -0
  164. data/formtastic-6.0.0/spec/spec_helper.rb +466 -0
  165. data/formtastic-6.0.0/spec/support/custom_macros.rb +570 -0
  166. data/formtastic-6.0.0/spec/support/deprecation.rb +7 -0
  167. data/formtastic-6.0.0/spec/support/shared_examples.rb +13 -0
  168. data/formtastic-6.0.0/spec/support/specialized_class_finder_shared_example.rb +27 -0
  169. data/formtastic-6.0.0/spec/support/test_environment.rb +46 -0
  170. data/mega-safe-tool.gemspec +11 -0
  171. metadata +209 -0
@@ -0,0 +1,661 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe 'select input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ActionView::OutputBuffer.new ''
10
+ mock_everything
11
+ end
12
+
13
+ describe 'explicit values' do
14
+ describe 'using an array of values' do
15
+ before do
16
+ @array_with_values = ["Title A", "Title B", "Title C"]
17
+ @array_with_keys_and_values = [["Title D", 1], ["Title E", 2], ["Title F", 3]]
18
+ concat(semantic_form_for(@new_post) do |builder|
19
+ concat(builder.input(:title, :as => :select, :collection => @array_with_values))
20
+ concat(builder.input(:title, :as => :select, :collection => @array_with_keys_and_values))
21
+ end)
22
+ end
23
+
24
+ it 'should have a option for each key and/or value' do
25
+ @array_with_values.each do |v|
26
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='#{v}']", :text => /^#{v}$/)
27
+ end
28
+ @array_with_keys_and_values.each do |v|
29
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='#{v.second}']", :text => /^#{v.first}$/)
30
+ end
31
+ end
32
+ end
33
+
34
+ describe 'using a set of values' do
35
+ before do
36
+ @set_with_values = Set.new(["Title A", "Title B", "Title C"])
37
+ @set_with_keys_and_values = [["Title D", :d], ["Title E", :e], ["Title F", :f]]
38
+ concat(semantic_form_for(@new_post) do |builder|
39
+ concat(builder.input(:title, :as => :select, :collection => @set_with_values))
40
+ concat(builder.input(:title, :as => :select, :collection => @set_with_keys_and_values))
41
+ end)
42
+ end
43
+
44
+ it 'should have a option for each key and/or value' do
45
+ @set_with_values.each do |v|
46
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='#{v}']", :text => /^#{v}$/)
47
+ end
48
+ @set_with_keys_and_values.each do |v|
49
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='#{v.second}']", :text => /^#{v.first}$/)
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "using a related model without reflection's options (Mongoid Document)" do
55
+ before do
56
+ allow(@new_post).to receive(:mongoid_reviewer)
57
+ concat(semantic_form_for(@new_post) do |builder|
58
+ concat(builder.input(:mongoid_reviewer, :as => :select))
59
+ end)
60
+ end
61
+
62
+ it 'should draw select options' do
63
+ expect(output_buffer.to_str).to have_tag('form li select')
64
+ expect(output_buffer.to_str).to have_tag('form li select#post_reviewer_id')
65
+ expect(output_buffer.to_str).not_to have_tag('form li select#post_mongoid_reviewer_id')
66
+ end
67
+ end
68
+
69
+ describe 'using a range' do
70
+ before do
71
+ @range_with_values = 1..5
72
+ concat(semantic_form_for(@new_post) do |builder|
73
+ concat(builder.input(:title, :as => :select, :collection => @range_with_values))
74
+ end)
75
+ end
76
+
77
+ it 'should have an option for each value' do
78
+ @range_with_values.each do |v|
79
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='#{v}']", :text => /^#{v}$/)
80
+ end
81
+ end
82
+ end
83
+
84
+ describe 'using a string' do
85
+ before do
86
+ @string ="<option value='0'>0</option><option value='1'>1</option>".html_safe
87
+ concat(semantic_form_for(@new_post) do |builder|
88
+ concat(builder.input(:title, :as => :select, :collection => @string))
89
+ end)
90
+ end
91
+
92
+ it 'should render select options using provided HTML string' do
93
+ 2.times do |v|
94
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='#{v}']", :text => /^#{v}$/)
95
+ end
96
+ end
97
+ end
98
+
99
+ describe 'using a nil name' do
100
+ before do
101
+ concat(semantic_form_for(@new_post) do |builder|
102
+ concat(builder.input(:title, :as => :select, :collection => [], :input_html => {:name => nil}))
103
+ end)
104
+ end
105
+
106
+ it_should_have_select_with_name("post[title]")
107
+ end
108
+ end
109
+
110
+ describe 'for boolean columns' do
111
+ describe 'default formtastic locale' do
112
+ before do
113
+ # Note: Works, but something like Formtastic.root.join(...) would probably be "safer".
114
+ ::I18n.load_path = [File.join(File.dirname(__FILE__), *%w[.. .. lib locale en.yml])]
115
+ ::I18n.backend.send(:init_translations)
116
+
117
+ concat(semantic_form_for(@new_post) do |builder|
118
+ concat(builder.input(:published, :as => :select))
119
+ end)
120
+ end
121
+
122
+ after do
123
+ ::I18n.load_path = []
124
+ ::I18n.backend.store_translations :en, {}
125
+ end
126
+
127
+ it 'should render a select with at least options: true/false' do
128
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='true']", :text => /^Yes$/)
129
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='false']", :text => /^No$/)
130
+ end
131
+ end
132
+
133
+ describe 'custom locale' do
134
+ before do
135
+ @boolean_select_labels = {:yes => 'Yep', :no => 'Nope'}
136
+ ::I18n.backend.store_translations :en, :formtastic => @boolean_select_labels
137
+
138
+ concat(semantic_form_for(@new_post) do |builder|
139
+ concat(builder.input(:published, :as => :select))
140
+ end)
141
+ end
142
+
143
+ after do
144
+ ::I18n.backend.store_translations :en, {}
145
+ end
146
+
147
+ it 'should render a select with at least options: true/false' do
148
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='true']", :text => /#{@boolean_select_labels[:yes]}/)
149
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='false']", :text => /#{@boolean_select_labels[:no]}/)
150
+ end
151
+ end
152
+ end
153
+
154
+ describe 'for a enum column' do
155
+ before do
156
+ allow(@new_post).to receive(:status) { 'inactive' }
157
+ statuses = ActiveSupport::HashWithIndifferentAccess.new("active"=>0, "inactive"=>1)
158
+ allow(@new_post.class).to receive(:statuses) { statuses }
159
+ allow(@new_post).to receive(:defined_enums) { { "status" => statuses } }
160
+ end
161
+
162
+ context 'with translations in a nested association input' do
163
+ before do
164
+ ::I18n.backend.store_translations :en, activerecord: {
165
+ attributes: {
166
+ post: {
167
+ statuses: {
168
+ active: 'I am active',
169
+ inactive: 'I am inactive'
170
+ }
171
+ }
172
+ }
173
+ }
174
+
175
+ allow(@fred).to receive(:posts).and_return([@new_post])
176
+ concat(semantic_form_for(@fred) do |builder|
177
+ concat(builder.inputs(for: @fred.posts.first) do |nested_builder|
178
+ nested_builder.input(:status, as: :select)
179
+ end)
180
+ end)
181
+ end
182
+
183
+ after do
184
+ ::I18n.backend.reload!
185
+ end
186
+
187
+ it 'should use localized enum values' do
188
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='active']", text: 'I am active')
189
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='inactive']", text: 'I am inactive')
190
+ end
191
+ end
192
+
193
+ context 'single choice' do
194
+ before do
195
+ concat(semantic_form_for(@new_post) do |builder|
196
+ concat(builder.input(:status, :as => :select))
197
+ end)
198
+ end
199
+
200
+ it_should_have_input_wrapper_with_class("select")
201
+ it_should_have_input_wrapper_with_class(:input)
202
+ it_should_have_input_wrapper_with_id("post_status_input")
203
+ it_should_have_label_with_text(/Status/)
204
+ it_should_have_label_for('post_status')
205
+ it_should_apply_error_logic_for_input_type(:select)
206
+
207
+ it 'should have a select inside the wrapper' do
208
+ expect(output_buffer.to_str).to have_tag('form li select')
209
+ expect(output_buffer.to_str).to have_tag('form li select#post_status')
210
+ end
211
+
212
+ it 'should have a valid name' do
213
+ expect(output_buffer.to_str).to have_tag("form li select[@name='post[status]']")
214
+ expect(output_buffer.to_str).not_to have_tag("form li select[@name='post[status][]']")
215
+ end
216
+
217
+ it 'should not create a multi-select' do
218
+ expect(output_buffer.to_str).not_to have_tag('form li select[@multiple]')
219
+ end
220
+
221
+ it 'should not add a hidden input' do
222
+ expect(output_buffer.to_str).not_to have_tag('form li input[@type="hidden"]')
223
+ end
224
+
225
+ it 'should create a select without size' do
226
+ expect(output_buffer.to_str).not_to have_tag('form li select[@size]')
227
+ end
228
+
229
+ it 'should have a blank option' do
230
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='']")
231
+ end
232
+
233
+ it 'should have a select option for each defined enum status' do
234
+ expect(output_buffer.to_str).to have_tag("form li select[@name='post[status]'] option", :count => @new_post.class.statuses.count + 1)
235
+ @new_post.class.statuses.each do |label, value|
236
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='#{label}']", :text => /#{label.humanize}/)
237
+ end
238
+ end
239
+
240
+ it 'should have one option with a "selected" attribute (TODO)' do
241
+ expect(output_buffer.to_str).to have_tag("form li select[@name='post[status]'] option[@selected]", :count => 1)
242
+ end
243
+ end
244
+
245
+ context 'multiple choice' do
246
+ it 'raises an error' do
247
+ expect {
248
+ concat(semantic_form_for(@new_post) do |builder|
249
+ concat(builder.input(:status, :as => :select, :multiple => true))
250
+ end)
251
+ }.to raise_error Formtastic::UnsupportedEnumCollection
252
+ end
253
+ end
254
+ end
255
+
256
+ describe 'for a belongs_to association' do
257
+ before do
258
+ concat(semantic_form_for(@new_post) do |builder|
259
+ concat(builder.input(:author, :as => :select))
260
+ concat(builder.input(:reviewer, :as => :select))
261
+ end)
262
+ end
263
+
264
+ it_should_have_input_wrapper_with_class("select")
265
+ it_should_have_input_wrapper_with_class(:input)
266
+ it_should_have_input_wrapper_with_id("post_author_input")
267
+ it_should_have_label_with_text(/Author/)
268
+ it_should_have_label_for('post_author_id')
269
+ it_should_apply_error_logic_for_input_type(:select)
270
+ it_should_call_find_on_association_class_when_no_collection_is_provided(:select)
271
+ it_should_use_the_collection_when_provided(:select, 'option')
272
+
273
+ it 'should have a select inside the wrapper' do
274
+ expect(output_buffer.to_str).to have_tag('form li select')
275
+ expect(output_buffer.to_str).to have_tag('form li select#post_author_id')
276
+ expect(output_buffer.to_str).to have_tag('form li select#post_reviewer_id')
277
+ end
278
+
279
+ it 'should have a valid name' do
280
+ expect(output_buffer.to_str).to have_tag("form li select[@name='post[author_id]']")
281
+ expect(output_buffer.to_str).not_to have_tag("form li select[@name='post[author_id][]']")
282
+ expect(output_buffer.to_str).not_to have_tag("form li select[@name='post[reviewer_id][]']")
283
+ end
284
+
285
+ it 'should not create a multi-select' do
286
+ expect(output_buffer.to_str).not_to have_tag('form li select[@multiple]')
287
+ end
288
+
289
+ it 'should not add a hidden input' do
290
+ expect(output_buffer.to_str).not_to have_tag('form li input[@type="hidden"]')
291
+ end
292
+
293
+ it 'should create a select without size' do
294
+ expect(output_buffer.to_str).not_to have_tag('form li select[@size]')
295
+ end
296
+
297
+ it 'should have a blank option' do
298
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='']")
299
+ end
300
+
301
+ it 'should have a select option for each Author' do
302
+ expect(output_buffer.to_str).to have_tag("form li select[@name='post[author_id]'] option", :count => ::Author.all.size + 1)
303
+ ::Author.all.each do |author|
304
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='#{author.id}']", :text => /#{author.to_label}/)
305
+ end
306
+ end
307
+
308
+ it 'should have one option with a "selected" attribute (bob)' do
309
+ expect(output_buffer.to_str).to have_tag("form li select[@name='post[author_id]'] option[@selected]", :count => 1)
310
+ end
311
+
312
+ it 'should not singularize the association name' do
313
+ allow(@new_post).to receive(:author_status).and_return(@bob)
314
+ allow(@new_post).to receive(:author_status_id).and_return(@bob.id)
315
+ allow(@new_post).to receive(:column_for_attribute).and_return(double('column', :type => :integer, :limit => 255))
316
+
317
+ concat(semantic_form_for(@new_post) do |builder|
318
+ concat(builder.input(:author_status, :as => :select))
319
+ end)
320
+
321
+ expect(output_buffer.to_str).to have_tag('form li select#post_author_status_id')
322
+ end
323
+ end
324
+
325
+ describe "for a belongs_to association with :conditions" do
326
+ before do
327
+ allow(::Post).to receive(:reflect_on_association).with(:author) do
328
+ mock = double('reflection', :scope => nil, :options => {:conditions => {:active => true}}, :klass => ::Author, :macro => :belongs_to)
329
+ allow(mock).to receive(:[]).with(:class_name).and_return("Author")
330
+ mock
331
+ end
332
+ end
333
+
334
+ it "should call author.where with association conditions" do
335
+ expect(::Author).to receive(:where).with({:active => true})
336
+
337
+ semantic_form_for(@new_post) do |builder|
338
+ concat(builder.input(:author, :as => :select))
339
+ end
340
+ end
341
+ end
342
+
343
+ describe "for a belongs_to association with scope" do
344
+ before do
345
+ @active_scope = -> { active }
346
+ allow(::Post).to receive(:reflect_on_association).with(:author) do
347
+ mock = double('reflection', :scope => @active_scope, options: {}, :klass => ::Author, :macro => :belongs_to)
348
+ allow(mock).to receive(:[]).with(:class_name).and_return("Author")
349
+ mock
350
+ end
351
+ end
352
+
353
+ it "should call author.merge with association scope" do
354
+ expect(::Author).to receive(:merge).with(@active_scope)
355
+
356
+ semantic_form_for(@new_post) do |builder|
357
+ concat(builder.input(:author, :as => :select))
358
+ end
359
+ end
360
+ end
361
+
362
+ describe 'for a has_many association' do
363
+ before do
364
+ concat(semantic_form_for(@fred) do |builder|
365
+ concat(builder.input(:posts, :as => :select))
366
+ end)
367
+ end
368
+
369
+ it_should_have_input_wrapper_with_class("select")
370
+ it_should_have_input_wrapper_with_id("author_posts_input")
371
+ it_should_have_label_with_text(/Post/)
372
+ it_should_have_label_for('author_post_ids')
373
+ it_should_apply_error_logic_for_input_type(:select)
374
+ it_should_call_find_on_association_class_when_no_collection_is_provided(:select)
375
+ it_should_use_the_collection_when_provided(:select, 'option')
376
+
377
+ it 'should have a select inside the wrapper' do
378
+ expect(output_buffer.to_str).to have_tag('form li select')
379
+ expect(output_buffer.to_str).to have_tag('form li select#author_post_ids')
380
+ end
381
+
382
+ it 'should have a multi-select select' do
383
+ expect(output_buffer.to_str).to have_tag('form li select[@multiple="multiple"]')
384
+ end
385
+
386
+ it 'should append [] to the name attribute for multiple select' do
387
+ expect(output_buffer.to_str).to have_tag('form li select[@multiple="multiple"][@name="author[post_ids][]"]')
388
+ end
389
+
390
+ it 'should have a hidden field' do
391
+ expect(output_buffer.to_str).to have_tag('form li input[@type="hidden"][@name="author[post_ids][]"]', :count => 1)
392
+ end
393
+
394
+ it 'should have a select option for each Post' do
395
+ expect(output_buffer.to_str).to have_tag('form li select option', :count => ::Post.all.size)
396
+ ::Post.all.each do |post|
397
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='#{post.id}']", :text => /#{post.to_label}/)
398
+ end
399
+ end
400
+
401
+ it 'should not have a blank option by default' do
402
+ expect(output_buffer.to_str).not_to have_tag("form li select option[@value='']")
403
+ end
404
+
405
+ it 'should respect the :include_blank option for single selects' do
406
+ concat(semantic_form_for(@fred) do |builder|
407
+ concat(builder.input(:posts, :as => :select, :multiple => false, :include_blank => true))
408
+ end)
409
+
410
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='']")
411
+ end
412
+
413
+ it 'should respect the :include_blank option for multiple selects' do
414
+ concat(semantic_form_for(@fred) do |builder|
415
+ concat(builder.input(:posts, :as => :select, :multiple => true, :include_blank => true))
416
+ end)
417
+
418
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='']")
419
+ end
420
+
421
+ it 'should have one option with a "selected" attribute' do
422
+ expect(output_buffer.to_str).to have_tag('form li select option[@selected]', :count => 1)
423
+ end
424
+ end
425
+
426
+ describe 'for a has_and_belongs_to_many association' do
427
+ before do
428
+ concat(semantic_form_for(@freds_post) do |builder|
429
+ concat(builder.input(:authors, :as => :select))
430
+ end)
431
+ end
432
+
433
+ it_should_have_input_wrapper_with_class("select")
434
+ it_should_have_input_wrapper_with_id("post_authors_input")
435
+ it_should_have_label_with_text(/Author/)
436
+ it_should_have_label_for('post_author_ids')
437
+ it_should_apply_error_logic_for_input_type(:select)
438
+ it_should_call_find_on_association_class_when_no_collection_is_provided(:select)
439
+ it_should_use_the_collection_when_provided(:select, 'option')
440
+
441
+ it 'should have a select inside the wrapper' do
442
+ expect(output_buffer.to_str).to have_tag('form li select')
443
+ expect(output_buffer.to_str).to have_tag('form li select#post_author_ids')
444
+ end
445
+
446
+ it 'should have a multi-select select' do
447
+ expect(output_buffer.to_str).to have_tag('form li select[@multiple="multiple"]')
448
+ end
449
+
450
+ it 'should have a select option for each Author' do
451
+ expect(output_buffer.to_str).to have_tag('form li select option', :count => ::Author.all.size)
452
+ ::Author.all.each do |author|
453
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='#{author.id}']", :text => /#{author.to_label}/)
454
+ end
455
+ end
456
+
457
+ it 'should not have a blank option by default' do
458
+ expect(output_buffer.to_str).not_to have_tag("form li select option[@value='']")
459
+ end
460
+
461
+ it 'should respect the :include_blank option for single selects' do
462
+ concat(semantic_form_for(@freds_post) do |builder|
463
+ concat(builder.input(:authors, :as => :select, :multiple => false, :include_blank => true))
464
+ end)
465
+
466
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='']")
467
+ end
468
+
469
+ it 'should respect the :include_blank option for multiple selects' do
470
+ concat(semantic_form_for(@freds_post) do |builder|
471
+ concat(builder.input(:authors, :as => :select, :multiple => true, :include_blank => true))
472
+ end)
473
+
474
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='']")
475
+ end
476
+
477
+ it 'should have one option with a "selected" attribute' do
478
+ expect(output_buffer.to_str).to have_tag('form li select option[@selected]', :count => 1)
479
+ end
480
+ end
481
+
482
+ describe 'when :prompt => "choose something" is set' do
483
+ before do
484
+ allow(@new_post).to receive(:author_id).and_return(nil)
485
+ concat(semantic_form_for(@new_post) do |builder|
486
+ concat(builder.input(:author, :as => :select, :prompt => "choose author"))
487
+ end)
488
+ end
489
+
490
+ it 'should have a select with prompt' do
491
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='']", :text => /choose author/, :count => 1)
492
+ end
493
+
494
+ it 'should not have a second blank select option' do
495
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='']", :count => 1)
496
+ end
497
+ end
498
+
499
+ describe 'when no object is given' do
500
+ before(:example) do
501
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
502
+ concat(builder.input(:author, :as => :select, :collection => ::Author.all))
503
+ end)
504
+ end
505
+
506
+ it 'should generate label' do
507
+ expect(output_buffer.to_str).to have_tag('form li label', :text => /Author/)
508
+ expect(output_buffer.to_str).to have_tag("form li label[@for='project_author']")
509
+ end
510
+
511
+ it 'should generate select inputs' do
512
+ expect(output_buffer.to_str).to have_tag('form li select#project_author')
513
+ expect(output_buffer.to_str).to have_tag('form li select option', :count => ::Author.all.size + 1)
514
+ end
515
+
516
+ it 'should generate an option to each item' do
517
+ ::Author.all.each do |author|
518
+ expect(output_buffer.to_str).to have_tag("form li select option[@value='#{author.id}']", :text => /#{author.to_label}/)
519
+ end
520
+ end
521
+ end
522
+
523
+ describe 'when no association exists' do
524
+
525
+ it 'should still generate a valid name attribute' do
526
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
527
+ concat(builder.input(:author_name, :as => :select, :collection => ::Author.all))
528
+ end)
529
+ expect(output_buffer.to_str).to have_tag("form li select[@name='project[author_name]']")
530
+ end
531
+
532
+ describe 'and :multiple is set to true through :input_html' do
533
+ it "should make the select a multi-select" do
534
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
535
+ concat(builder.input(:author_name, :as => :select, :input_html => {:multiple => true} ))
536
+ end)
537
+ expect(output_buffer.to_str).to have_tag("form li select[@multiple]")
538
+ end
539
+ end
540
+
541
+ describe 'and :multiple is set to true' do
542
+ it "should make the select a multi-select" do
543
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
544
+ concat(builder.input(:author_name, :as => :select, :multiple => true, :collection => ["Fred", "Bob"]))
545
+ end)
546
+ expect(output_buffer.to_str).to have_tag("form li select[@multiple]")
547
+ end
548
+ end
549
+
550
+ end
551
+
552
+ describe 'when a grouped collection collection is given' do
553
+ before(:example) do
554
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
555
+ @grouped_opts = [['one', ['pencil', 'crayon', 'pen']],
556
+ ['two', ['eyes', 'hands', 'feet']],
557
+ ['three', ['wickets', 'witches', 'blind mice']]]
558
+ concat(builder.input(:author, :as => :select, :collection => grouped_options_for_select(@grouped_opts, "hands")))
559
+ end)
560
+ end
561
+
562
+ it 'should generate an option to each item' do
563
+ @grouped_opts.each do |opt_pair|
564
+ expect(output_buffer.to_str).to have_tag("form li select optgroup[@label='#{opt_pair[0]}']")
565
+ opt_pair[1].each do |v|
566
+ expect(output_buffer.to_str).to have_tag("form li select optgroup[@label='#{opt_pair[0]}'] option[@value='#{v}']")
567
+ end
568
+ end
569
+ expect(output_buffer.to_str).to have_tag("form li select optgroup option[@selected]","hands")
570
+ end
571
+ end
572
+
573
+ describe "enum" do
574
+ before do
575
+ @output_buffer = ActionView::OutputBuffer.new ''
576
+ @some_meta_descriptions = ["One", "Two", "Three"]
577
+ allow(@new_post).to receive(:meta_description).at_least(:once)
578
+ end
579
+
580
+ describe ":as is not set" do
581
+ before do
582
+ concat(semantic_form_for(@new_post) do |builder|
583
+ concat(builder.input(:meta_description, :collection => @some_meta_descriptions))
584
+ end)
585
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
586
+ concat(builder.input(:meta_description, :collection => @some_meta_descriptions))
587
+ end)
588
+ end
589
+
590
+ it "should render a select field" do
591
+ expect(output_buffer.to_str).to have_tag("form li select", :count => 2)
592
+ end
593
+ end
594
+
595
+ describe ":as is set" do
596
+ before do
597
+ # Should not be a case, but just checking :as got highest priority in setting input type.
598
+ concat(semantic_form_for(@new_post) do |builder|
599
+ concat(builder.input(:meta_description, :as => :string, :collection => @some_meta_descriptions))
600
+ end)
601
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
602
+ concat(builder.input(:meta_description, :as => :string, :collection => @some_meta_descriptions))
603
+ end)
604
+ end
605
+
606
+ it "should render a text field" do
607
+ expect(output_buffer.to_str).to have_tag("form li input[@type='text']", :count => 2)
608
+ end
609
+ end
610
+ end
611
+
612
+ describe 'when a namespace is provided' do
613
+ before do
614
+ concat(semantic_form_for(@freds_post, :namespace => 'context2') do |builder|
615
+ concat(builder.input(:authors, :as => :select))
616
+ end)
617
+ end
618
+ it_should_have_input_wrapper_with_id("context2_post_authors_input")
619
+ it_should_have_select_with_id("context2_post_author_ids")
620
+ it_should_have_label_for("context2_post_author_ids")
621
+ end
622
+
623
+ describe "when index is provided" do
624
+
625
+ before do
626
+ @output_buffer = ActionView::OutputBuffer.new ''
627
+ mock_everything
628
+
629
+ concat(semantic_form_for(@new_post) do |builder|
630
+ concat(builder.fields_for(:author, :index => 3) do |author|
631
+ concat(author.input(:name, :as => :select))
632
+ end)
633
+ end)
634
+ end
635
+
636
+ it 'should index the id of the wrapper' do
637
+ expect(output_buffer.to_str).to have_tag("li#post_author_attributes_3_name_input")
638
+ end
639
+
640
+ it 'should index the id of the select tag' do
641
+ expect(output_buffer.to_str).to have_tag("select#post_author_attributes_3_name")
642
+ end
643
+
644
+ it 'should index the name of the select' do
645
+ expect(output_buffer.to_str).to have_tag("select[@name='post[author_attributes][3][name]']")
646
+ end
647
+
648
+ end
649
+
650
+ context "when required" do
651
+ it "should add the required attribute to the select's html options" do
652
+ with_config :use_required_attribute, true do
653
+ concat(semantic_form_for(@new_post) do |builder|
654
+ concat(builder.input(:author, :as => :select, :required => true))
655
+ end)
656
+ expect(output_buffer.to_str).to have_tag("select[@required]")
657
+ end
658
+ end
659
+ end
660
+
661
+ end