formtastic 3.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. checksums.yaml +5 -13
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/test.yml +61 -0
  4. data/.gitignore +3 -2
  5. data/CHANGELOG.md +61 -0
  6. data/Gemfile.lock +140 -0
  7. data/MIT-LICENSE +1 -1
  8. data/{README.textile → README.md} +191 -168
  9. data/RELEASE_PROCESS +3 -1
  10. data/Rakefile +24 -8
  11. data/app/assets/stylesheets/formtastic.css +1 -1
  12. data/bin/appraisal +8 -0
  13. data/formtastic.gemspec +13 -17
  14. data/gemfiles/rails_6.0/Gemfile +5 -0
  15. data/gemfiles/rails_6.1/Gemfile +5 -0
  16. data/gemfiles/rails_7.0/Gemfile +5 -0
  17. data/gemfiles/rails_7.1/Gemfile +5 -0
  18. data/gemfiles/rails_edge/Gemfile +13 -0
  19. data/lib/formtastic/action_class_finder.rb +19 -0
  20. data/lib/formtastic/actions/base.rb +1 -0
  21. data/lib/formtastic/actions/button_action.rb +56 -53
  22. data/lib/formtastic/actions/buttonish.rb +1 -0
  23. data/lib/formtastic/actions/input_action.rb +60 -57
  24. data/lib/formtastic/actions/link_action.rb +69 -67
  25. data/lib/formtastic/actions.rb +7 -3
  26. data/lib/formtastic/deprecation.rb +6 -0
  27. data/lib/formtastic/engine.rb +4 -1
  28. data/lib/formtastic/form_builder.rb +32 -25
  29. data/lib/formtastic/helpers/action_helper.rb +22 -31
  30. data/lib/formtastic/helpers/actions_helper.rb +1 -0
  31. data/lib/formtastic/helpers/enum.rb +14 -0
  32. data/lib/formtastic/helpers/errors_helper.rb +3 -2
  33. data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -11
  34. data/lib/formtastic/helpers/file_column_detection.rb +1 -0
  35. data/lib/formtastic/helpers/form_helper.rb +4 -3
  36. data/lib/formtastic/helpers/input_helper.rb +59 -80
  37. data/lib/formtastic/helpers/inputs_helper.rb +33 -27
  38. data/lib/formtastic/helpers/reflection.rb +5 -4
  39. data/lib/formtastic/helpers.rb +2 -2
  40. data/lib/formtastic/html_attributes.rb +13 -1
  41. data/lib/formtastic/i18n.rb +2 -1
  42. data/lib/formtastic/input_class_finder.rb +19 -0
  43. data/lib/formtastic/inputs/base/associations.rb +1 -0
  44. data/lib/formtastic/inputs/base/choices.rb +4 -3
  45. data/lib/formtastic/inputs/base/collections.rb +47 -11
  46. data/lib/formtastic/inputs/base/database.rb +8 -5
  47. data/lib/formtastic/inputs/base/datetime_pickerish.rb +1 -0
  48. data/lib/formtastic/inputs/base/errors.rb +7 -6
  49. data/lib/formtastic/inputs/base/fileish.rb +1 -0
  50. data/lib/formtastic/inputs/base/hints.rb +2 -1
  51. data/lib/formtastic/inputs/base/html.rb +12 -10
  52. data/lib/formtastic/inputs/base/labelling.rb +3 -2
  53. data/lib/formtastic/inputs/base/naming.rb +5 -4
  54. data/lib/formtastic/inputs/base/numeric.rb +1 -0
  55. data/lib/formtastic/inputs/base/options.rb +3 -3
  56. data/lib/formtastic/inputs/base/placeholder.rb +1 -0
  57. data/lib/formtastic/inputs/base/stringish.rb +1 -0
  58. data/lib/formtastic/inputs/base/timeish.rb +9 -4
  59. data/lib/formtastic/inputs/base/validations.rb +39 -12
  60. data/lib/formtastic/inputs/base/wrapping.rb +2 -3
  61. data/lib/formtastic/inputs/base.rb +17 -12
  62. data/lib/formtastic/inputs/boolean_input.rb +2 -1
  63. data/lib/formtastic/inputs/check_boxes_input.rb +16 -24
  64. data/lib/formtastic/inputs/color_input.rb +1 -1
  65. data/lib/formtastic/inputs/country_input.rb +4 -1
  66. data/lib/formtastic/inputs/datalist_input.rb +42 -0
  67. data/lib/formtastic/inputs/date_picker_input.rb +1 -0
  68. data/lib/formtastic/inputs/date_select_input.rb +1 -0
  69. data/lib/formtastic/inputs/datetime_picker_input.rb +1 -0
  70. data/lib/formtastic/inputs/datetime_select_input.rb +1 -0
  71. data/lib/formtastic/inputs/email_input.rb +1 -0
  72. data/lib/formtastic/inputs/file_input.rb +3 -2
  73. data/lib/formtastic/inputs/hidden_input.rb +3 -2
  74. data/lib/formtastic/inputs/number_input.rb +1 -0
  75. data/lib/formtastic/inputs/password_input.rb +1 -0
  76. data/lib/formtastic/inputs/phone_input.rb +1 -0
  77. data/lib/formtastic/inputs/radio_input.rb +26 -21
  78. data/lib/formtastic/inputs/range_input.rb +1 -0
  79. data/lib/formtastic/inputs/search_input.rb +1 -0
  80. data/lib/formtastic/inputs/select_input.rb +32 -10
  81. data/lib/formtastic/inputs/string_input.rb +1 -0
  82. data/lib/formtastic/inputs/text_input.rb +1 -0
  83. data/lib/formtastic/inputs/time_picker_input.rb +1 -0
  84. data/lib/formtastic/inputs/time_select_input.rb +1 -0
  85. data/lib/formtastic/inputs/time_zone_input.rb +17 -6
  86. data/lib/formtastic/inputs/url_input.rb +1 -0
  87. data/lib/formtastic/inputs.rb +33 -28
  88. data/lib/formtastic/localized_string.rb +2 -1
  89. data/lib/formtastic/localizer.rb +23 -24
  90. data/lib/formtastic/namespaced_class_finder.rb +98 -0
  91. data/lib/formtastic/version.rb +2 -1
  92. data/lib/formtastic.rb +19 -14
  93. data/lib/generators/formtastic/form/form_generator.rb +8 -2
  94. data/lib/generators/formtastic/input/input_generator.rb +47 -0
  95. data/lib/generators/formtastic/install/install_generator.rb +2 -0
  96. data/lib/generators/templates/formtastic.rb +29 -7
  97. data/lib/generators/templates/input.rb +19 -0
  98. data/sample/basic_inputs.html +1 -1
  99. data/script/integration-template.rb +73 -0
  100. data/script/integration.sh +19 -0
  101. data/spec/action_class_finder_spec.rb +13 -0
  102. data/spec/actions/button_action_spec.rb +21 -20
  103. data/spec/actions/generic_action_spec.rb +134 -133
  104. data/spec/actions/input_action_spec.rb +20 -19
  105. data/spec/actions/link_action_spec.rb +30 -29
  106. data/spec/builder/custom_builder_spec.rb +39 -22
  107. data/spec/builder/error_proc_spec.rb +6 -5
  108. data/spec/builder/semantic_fields_for_spec.rb +46 -45
  109. data/spec/fast_spec_helper.rb +13 -0
  110. data/spec/generators/formtastic/form/form_generator_spec.rb +33 -32
  111. data/spec/generators/formtastic/input/input_generator_spec.rb +125 -0
  112. data/spec/generators/formtastic/install/install_generator_spec.rb +10 -9
  113. data/spec/helpers/action_helper_spec.rb +70 -97
  114. data/spec/helpers/actions_helper_spec.rb +43 -42
  115. data/spec/helpers/form_helper_spec.rb +56 -39
  116. data/spec/helpers/input_helper_spec.rb +314 -255
  117. data/spec/helpers/inputs_helper_spec.rb +217 -202
  118. data/spec/helpers/reflection_helper_spec.rb +7 -6
  119. data/spec/helpers/semantic_errors_helper_spec.rb +26 -25
  120. data/spec/i18n_spec.rb +30 -29
  121. data/spec/input_class_finder_spec.rb +11 -0
  122. data/spec/inputs/base/collections_spec.rb +78 -0
  123. data/spec/inputs/base/validations_spec.rb +481 -0
  124. data/spec/inputs/boolean_input_spec.rb +73 -72
  125. data/spec/inputs/check_boxes_input_spec.rb +174 -123
  126. data/spec/inputs/color_input_spec.rb +53 -64
  127. data/spec/inputs/country_input_spec.rb +23 -22
  128. data/spec/inputs/custom_input_spec.rb +3 -6
  129. data/spec/inputs/datalist_input_spec.rb +62 -0
  130. data/spec/inputs/date_picker_input_spec.rb +114 -113
  131. data/spec/inputs/date_select_input_spec.rb +76 -61
  132. data/spec/inputs/datetime_picker_input_spec.rb +123 -122
  133. data/spec/inputs/datetime_select_input_spec.rb +85 -68
  134. data/spec/inputs/email_input_spec.rb +17 -16
  135. data/spec/inputs/file_input_spec.rb +18 -17
  136. data/spec/inputs/hidden_input_spec.rb +32 -31
  137. data/spec/inputs/include_blank_spec.rb +10 -9
  138. data/spec/inputs/label_spec.rb +36 -31
  139. data/spec/inputs/number_input_spec.rb +212 -211
  140. data/spec/inputs/password_input_spec.rb +17 -16
  141. data/spec/inputs/phone_input_spec.rb +17 -16
  142. data/spec/inputs/placeholder_spec.rb +18 -17
  143. data/spec/inputs/radio_input_spec.rb +92 -65
  144. data/spec/inputs/range_input_spec.rb +136 -135
  145. data/spec/inputs/readonly_spec.rb +51 -0
  146. data/spec/inputs/search_input_spec.rb +16 -15
  147. data/spec/inputs/select_input_spec.rb +209 -102
  148. data/spec/inputs/string_input_spec.rb +51 -50
  149. data/spec/inputs/text_input_spec.rb +34 -33
  150. data/spec/inputs/time_picker_input_spec.rb +115 -114
  151. data/spec/inputs/time_select_input_spec.rb +84 -70
  152. data/spec/inputs/time_zone_input_spec.rb +58 -31
  153. data/spec/inputs/url_input_spec.rb +17 -16
  154. data/spec/inputs/with_options_spec.rb +9 -8
  155. data/spec/localizer_spec.rb +18 -17
  156. data/spec/namespaced_class_finder_spec.rb +91 -0
  157. data/spec/schema.rb +22 -0
  158. data/spec/spec_helper.rb +180 -249
  159. data/spec/support/custom_macros.rb +128 -98
  160. data/spec/support/deprecation.rb +2 -1
  161. data/spec/support/shared_examples.rb +13 -0
  162. data/spec/support/specialized_class_finder_shared_example.rb +28 -0
  163. data/spec/support/test_environment.rb +25 -10
  164. metadata +95 -136
  165. data/.travis.yml +0 -28
  166. data/Appraisals +0 -25
  167. data/CHANGELOG +0 -27
  168. data/gemfiles/rails_3.2.gemfile +0 -7
  169. data/gemfiles/rails_4.0.4.gemfile +0 -7
  170. data/gemfiles/rails_4.1.gemfile +0 -7
  171. data/gemfiles/rails_4.gemfile +0 -7
  172. data/gemfiles/rails_edge.gemfile +0 -10
  173. data/lib/formtastic/util.rb +0 -53
  174. data/spec/support/deferred_garbage_collection.rb +0 -21
  175. data/spec/util_spec.rb +0 -52
@@ -1,13 +1,19 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
  require 'spec_helper'
3
4
 
4
- describe 'check_boxes input' do
5
+ RSpec.describe 'check_boxes input' do
5
6
 
6
7
  include FormtasticSpecHelper
7
8
 
9
+ before do
10
+ @output_buffer = ActionView::OutputBuffer.new ''
11
+ mock_everything
12
+ end
13
+
8
14
  describe 'for a has_many association' do
9
15
  before do
10
- @output_buffer = ''
16
+ @output_buffer = ActionView::OutputBuffer.new ''
11
17
  mock_everything
12
18
 
13
19
  concat(semantic_form_for(@fred) do |builder|
@@ -26,127 +32,127 @@ describe 'check_boxes input' do
26
32
  it_should_use_the_collection_when_provided(:check_boxes, 'input[@type="checkbox"]')
27
33
 
28
34
  it 'should generate a legend containing a label with text for the input' do
29
- output_buffer.should have_tag('form li fieldset legend.label label')
30
- output_buffer.should have_tag('form li fieldset legend.label label', /Posts/)
35
+ expect(output_buffer.to_str).to have_tag('form li fieldset legend.label label')
36
+ expect(output_buffer.to_str).to have_tag('form li fieldset legend.label label', :text => /Posts/)
31
37
  end
32
38
 
33
39
  it 'should not link the label within the legend to any input' do
34
- output_buffer.should_not have_tag('form li fieldset legend label[@for^="author_post_ids_"]')
40
+ expect(output_buffer.to_str).not_to have_tag('form li fieldset legend label[@for^="author_post_ids_"]')
35
41
  end
36
42
 
37
43
  it 'should generate an ordered list with an li.choice for each choice' do
38
- output_buffer.should have_tag('form li fieldset ol')
39
- output_buffer.should have_tag('form li fieldset ol li.choice input[@type=checkbox]', :count => ::Post.all.size)
44
+ expect(output_buffer.to_str).to have_tag('form li fieldset ol')
45
+ expect(output_buffer.to_str).to have_tag('form li fieldset ol li.choice input[@type=checkbox]', :count => ::Post.all.size)
40
46
  end
41
47
 
42
48
  it 'should have one option with a "checked" attribute' do
43
- output_buffer.should have_tag('form li input[@checked]', :count => 1)
49
+ expect(output_buffer.to_str).to have_tag('form li input[@checked]', :count => 1)
44
50
  end
45
51
 
46
52
  it 'should not generate hidden inputs with default value blank' do
47
- output_buffer.should_not have_tag("form li fieldset ol li label input[@type='hidden'][@value='']")
53
+ expect(output_buffer.to_str).not_to have_tag("form li fieldset ol li label input[@type='hidden'][@value='']")
48
54
  end
49
55
 
50
56
  it 'should not render hidden inputs inside the ol' do
51
- output_buffer.should_not have_tag("form li fieldset ol li input[@type='hidden']")
57
+ expect(output_buffer.to_str).not_to have_tag("form li fieldset ol li input[@type='hidden']")
52
58
  end
53
59
 
54
60
  it 'should render one hidden input for each choice outside the ol' do
55
- output_buffer.should have_tag("form li fieldset > input[@type='hidden']", :count => 1)
61
+ expect(output_buffer.to_str).to have_tag("form li fieldset > input[@type='hidden']", :count => 1)
56
62
  end
57
63
 
58
64
  describe "each choice" do
59
-
65
+
60
66
  it 'should not give the choice label the .label class' do
61
- output_buffer.should_not have_tag('li.choice label.label')
67
+ expect(output_buffer.to_str).not_to have_tag('li.choice label.label')
62
68
  end
63
-
69
+
64
70
  it 'should not be marked as required' do
65
- output_buffer.should_not have_tag('li.choice input[@required]')
71
+ expect(output_buffer.to_str).not_to have_tag('li.choice input[@required]')
66
72
  end
67
-
73
+
68
74
  it 'should contain a label for the radio input with a nested input and label text' do
69
75
  ::Post.all.each do |post|
70
- output_buffer.should have_tag('form li fieldset ol li label', /#{post.to_label}/)
71
- output_buffer.should have_tag("form li fieldset ol li label[@for='author_post_ids_#{post.id}']")
76
+ expect(output_buffer.to_str).to have_tag('form li fieldset ol li label', :text => /#{post.to_label}/)
77
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label[@for='author_post_ids_#{post.id}']")
72
78
  end
73
79
  end
74
80
 
75
81
  it 'should use values as li.class when value_as_class is true' do
76
82
  ::Post.all.each do |post|
77
- output_buffer.should have_tag("form li fieldset ol li.post_#{post.id} label")
83
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li.post_#{post.id} label")
78
84
  end
79
85
  end
80
-
86
+
81
87
  it 'should have a checkbox input but no hidden field for each post' do
82
88
  ::Post.all.each do |post|
83
- output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
84
- output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 1)
89
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
90
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 1)
85
91
  end
86
92
  end
87
93
 
88
94
  it 'should have a hidden field with an empty array value for the collection to allow clearing of all checkboxes' do
89
- output_buffer.should have_tag("form li fieldset > input[@type=hidden][@name='author[post_ids][]'][@value='']", :count => 1)
95
+ expect(output_buffer.to_str).to have_tag("form li fieldset > input[@type=hidden][@name='author[post_ids][]'][@value='']", :count => 1)
90
96
  end
91
97
 
92
98
  it 'the hidden field with an empty array value should be followed by the ol' do
93
- output_buffer.should have_tag("form li fieldset > input[@type=hidden][@name='author[post_ids][]'][@value=''] + ol", :count => 1)
99
+ expect(output_buffer.to_str).to have_tag("form li fieldset > input[@type=hidden][@name='author[post_ids][]'][@value=''] + ol", :count => 1)
94
100
  end
95
101
 
96
102
  it 'should not have a hidden field with an empty string value for the collection' do
97
- output_buffer.should_not have_tag("form li fieldset > input[@type=hidden][@name='author[post_ids]'][@value='']", :count => 1)
103
+ expect(output_buffer.to_str).not_to have_tag("form li fieldset > input[@type=hidden][@name='author[post_ids]'][@value='']", :count => 1)
98
104
  end
99
105
 
100
106
  it 'should have a checkbox and a hidden field for each post with :hidden_field => true' do
101
- output_buffer.replace ''
107
+ @output_buffer = ActionView::OutputBuffer.new ''
102
108
 
103
109
  concat(semantic_form_for(@fred) do |builder|
104
110
  concat(builder.input(:posts, :as => :check_boxes, :hidden_fields => true, :value_as_class => true))
105
111
  end)
106
112
 
107
113
  ::Post.all.each do |post|
108
- output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
109
- output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 2)
110
- output_buffer.should have_tag('form li fieldset ol li label', /#{post.to_label}/)
114
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
115
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 2)
116
+ expect(output_buffer.to_str).to have_tag('form li fieldset ol li label', :text => /#{post.to_label}/)
111
117
  end
112
118
 
113
119
  end
114
120
 
115
121
  it "should mark input as checked if it's the the existing choice" do
116
- ::Post.all.include?(@fred.posts.first).should be_true
117
- output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
122
+ expect(::Post.all.include?(@fred.posts.first)).to be_truthy
123
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@checked='checked']")
118
124
  end
119
125
  end
120
126
 
121
127
  describe 'and no object is given' do
122
- before(:each) do
123
- output_buffer.replace ''
128
+ before(:example) do
129
+ @output_buffer = ActionView::OutputBuffer.new ''
124
130
  concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
125
131
  concat(builder.input(:author_id, :as => :check_boxes, :collection => ::Author.all))
126
132
  end)
127
133
  end
128
134
 
129
135
  it 'should generate a fieldset with legend' do
130
- output_buffer.should have_tag('form li fieldset legend', /Author/)
136
+ expect(output_buffer.to_str).to have_tag('form li fieldset legend', :text => /Author/)
131
137
  end
132
138
 
133
139
  it 'shold generate an li tag for each item in the collection' do
134
- output_buffer.should have_tag('form li fieldset ol li input[@type=checkbox]', :count => ::Author.all.size)
140
+ expect(output_buffer.to_str).to have_tag('form li fieldset ol li input[@type=checkbox]', :count => ::Author.all.size)
135
141
  end
136
142
 
137
143
  it 'should generate labels for each item' do
138
144
  ::Author.all.each do |author|
139
- output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
140
- output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
145
+ expect(output_buffer.to_str).to have_tag('form li fieldset ol li label', :text => /#{author.to_label}/)
146
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
141
147
  end
142
148
  end
143
149
 
144
150
  it 'should generate inputs for each item' do
145
151
  ::Author.all.each do |author|
146
- output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
147
- output_buffer.should have_tag("form li fieldset ol li label input[@type='checkbox']")
148
- output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
149
- output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id][]']")
152
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
153
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@type='checkbox']")
154
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@value='#{author.id}']")
155
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@name='project[author_id][]']")
150
156
  end
151
157
  end
152
158
 
@@ -155,15 +161,16 @@ describe 'check_boxes input' do
155
161
  concat(builder.input(:author_id, :as => :check_boxes, :collection => [["<b>Item 1</b>", 1], ["<b>Item 2</b>", 2]]))
156
162
  end)
157
163
 
158
- output_buffer.should have_tag('form li fieldset ol li label') do |label|
159
- label.body.should match /&lt;b&gt;Item [12]&lt;\/b&gt;$/
164
+ expect(output_buffer.to_str).to have_tag('form li fieldset ol li label', text: %r{<b>Item [12]</b>}, count: 2) do |label|
165
+ expect(label).to have_text('<b>Item 1</b>', count: 1)
166
+ expect(label).to have_text('<b>Item 2</b>', count: 1)
160
167
  end
161
168
  end
162
169
  end
163
170
 
164
171
  describe 'when :hidden_fields is set to false' do
165
172
  before do
166
- @output_buffer = ''
173
+ @output_buffer = ActionView::OutputBuffer.new ''
167
174
  mock_everything
168
175
 
169
176
  concat(semantic_form_for(@fred) do |builder|
@@ -173,29 +180,29 @@ describe 'check_boxes input' do
173
180
 
174
181
  it 'should have a checkbox input for each post' do
175
182
  ::Post.all.each do |post|
176
- output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
177
- output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => ::Post.all.length)
183
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
184
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => ::Post.all.length)
178
185
  end
179
186
  end
180
187
 
181
188
  it "should mark input as checked if it's the the existing choice" do
182
- ::Post.all.include?(@fred.posts.first).should be_true
183
- output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
189
+ expect(::Post.all.include?(@fred.posts.first)).to be_truthy
190
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@checked='checked']")
184
191
  end
185
192
 
186
193
  it 'should not generate empty hidden inputs' do
187
- output_buffer.should_not have_tag("form li fieldset ol li label input[@type='hidden'][@value='']", :count => ::Post.all.length)
194
+ expect(output_buffer.to_str).not_to have_tag("form li fieldset ol li label input[@type='hidden'][@value='']", :count => ::Post.all.length)
188
195
  end
189
196
  end
190
197
 
191
198
  describe 'when :disabled is set' do
192
199
  before do
193
- @output_buffer = ''
200
+ @output_buffer = ActionView::OutputBuffer.new ''
194
201
  end
195
202
 
196
203
  describe "no disabled items" do
197
204
  before do
198
- @new_post.stub(:author_ids).and_return(nil)
205
+ allow(@new_post).to receive(:author_ids).and_return(nil)
199
206
 
200
207
  concat(semantic_form_for(@new_post) do |builder|
201
208
  concat(builder.input(:authors, :as => :check_boxes, :disabled => nil))
@@ -203,13 +210,13 @@ describe 'check_boxes input' do
203
210
  end
204
211
 
205
212
  it 'should not have any disabled item(s)' do
206
- output_buffer.should_not have_tag("form li fieldset ol li label input[@disabled='disabled']")
213
+ expect(output_buffer.to_str).not_to have_tag("form li fieldset ol li label input[@disabled='disabled']")
207
214
  end
208
215
  end
209
216
 
210
217
  describe "single disabled item" do
211
218
  before do
212
- @new_post.stub(:author_ids).and_return(nil)
219
+ allow(@new_post).to receive(:author_ids).and_return(nil)
213
220
 
214
221
  concat(semantic_form_for(@new_post) do |builder|
215
222
  concat(builder.input(:authors, :as => :check_boxes, :disabled => @fred.id))
@@ -217,15 +224,15 @@ describe 'check_boxes input' do
217
224
  end
218
225
 
219
226
  it "should have one item disabled; the specified one" do
220
- output_buffer.should have_tag("form li fieldset ol li label input[@disabled='disabled']", :count => 1)
221
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
222
- output_buffer.should have_tag("form li fieldset ol li label input[@disabled='disabled'][@value='#{@fred.id}']")
227
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@disabled='disabled']", :count => 1)
228
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", :text => /fred/i)
229
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@disabled='disabled'][@value='#{@fred.id}']")
223
230
  end
224
231
  end
225
232
 
226
233
  describe "multiple disabled items" do
227
234
  before do
228
- @new_post.stub(:author_ids).and_return(nil)
235
+ allow(@new_post).to receive(:author_ids).and_return(nil)
229
236
 
230
237
  concat(semantic_form_for(@new_post) do |builder|
231
238
  concat(builder.input(:authors, :as => :check_boxes, :disabled => [@bob.id, @fred.id]))
@@ -233,11 +240,11 @@ describe 'check_boxes input' do
233
240
  end
234
241
 
235
242
  it "should have multiple items disabled; the specified ones" do
236
- output_buffer.should have_tag("form li fieldset ol li label input[@disabled='disabled']", :count => 2)
237
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@bob.id}']", /bob/i)
238
- output_buffer.should have_tag("form li fieldset ol li label input[@disabled='disabled'][@value='#{@bob.id}']")
239
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
240
- output_buffer.should have_tag("form li fieldset ol li label input[@disabled='disabled'][@value='#{@fred.id}']")
243
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@disabled='disabled']", :count => 2)
244
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label[@for='post_author_ids_#{@bob.id}']", :text => /bob/i)
245
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@disabled='disabled'][@value='#{@bob.id}']")
246
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", :text => /fred/i)
247
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@disabled='disabled'][@value='#{@fred.id}']")
241
248
  end
242
249
  end
243
250
 
@@ -248,7 +255,7 @@ describe 'check_boxes input' do
248
255
  before do
249
256
  ::I18n.backend.store_translations :en, :formtastic => { :labels => { :post => { :authors => "Translated!" }}}
250
257
  with_config :i18n_lookups_by_default, true do
251
- @new_post.stub(:author_ids).and_return(nil)
258
+ allow(@new_post).to receive(:author_ids).and_return(nil)
252
259
  concat(semantic_form_for(@new_post) do |builder|
253
260
  concat(builder.input(:authors, :as => :check_boxes))
254
261
  end)
@@ -260,62 +267,78 @@ describe 'check_boxes input' do
260
267
  end
261
268
 
262
269
  it "should do foo" do
263
- output_buffer.should have_tag("legend.label label", /Translated/)
270
+ expect(output_buffer.to_str).to have_tag("legend.label label", :text => /Translated/)
264
271
  end
265
272
 
266
273
  end
267
274
 
268
275
  describe "when :label option is set" do
269
276
  before do
270
- @new_post.stub(:author_ids).and_return(nil)
277
+ allow(@new_post).to receive(:author_ids).and_return(nil)
271
278
  concat(semantic_form_for(@new_post) do |builder|
272
279
  concat(builder.input(:authors, :as => :check_boxes, :label => 'The authors'))
273
280
  end)
274
281
  end
275
282
 
276
283
  it "should output the correct label title" do
277
- output_buffer.should have_tag("legend.label label", /The authors/)
284
+ expect(output_buffer.to_str).to have_tag("legend.label label", :text => /The authors/)
278
285
  end
279
286
  end
280
287
 
281
288
  describe "when :label option is false" do
282
289
  before do
283
- @output_buffer = ''
284
- @new_post.stub(:author_ids).and_return(nil)
290
+ @output_buffer = ActionView::OutputBuffer.new ''
291
+ allow(@new_post).to receive(:author_ids).and_return(nil)
285
292
  concat(semantic_form_for(@new_post) do |builder|
286
293
  concat(builder.input(:authors, :as => :check_boxes, :label => false))
287
294
  end)
288
295
  end
289
296
 
290
297
  it "should not output the legend" do
291
- output_buffer.should_not have_tag("legend.label")
298
+ expect(output_buffer.to_str).not_to have_tag("legend.label")
292
299
  end
293
-
300
+
294
301
  it "should not cause escaped HTML" do
295
- output_buffer.should_not include("&gt;")
302
+ expect(output_buffer.to_str).not_to include("&gt;")
296
303
  end
297
-
304
+
298
305
  end
299
306
 
300
307
  describe "when :required option is true" do
301
308
  before do
302
- @new_post.stub(:author_ids).and_return(nil)
309
+ allow(@new_post).to receive(:author_ids).and_return(nil)
303
310
  concat(semantic_form_for(@new_post) do |builder|
304
311
  concat(builder.input(:authors, :as => :check_boxes, :required => true))
305
312
  end)
306
313
  end
307
314
 
308
315
  it "should output the correct label title" do
309
- output_buffer.should have_tag("legend.label label abbr")
316
+ expect(output_buffer.to_str).to have_tag("legend.label label abbr")
310
317
  end
311
318
  end
319
+ end
320
+
321
+ describe 'for a enum column' do
322
+ before do
323
+ allow(@new_post).to receive(:status) { 'inactive' }
324
+ statuses = ActiveSupport::HashWithIndifferentAccess.new("active"=>0, "inactive"=>1)
325
+ allow(@new_post.class).to receive(:statuses) { statuses }
326
+ allow(@new_post).to receive(:defined_enums) { { "status" => statuses } }
327
+ end
312
328
 
329
+ it 'should have a select inside the wrapper' do
330
+ expect {
331
+ concat(semantic_form_for(@new_post) do |builder|
332
+ concat(builder.input(:status, :as => :check_boxes))
333
+ end)
334
+ }.to raise_error(Formtastic::UnsupportedEnumCollection)
335
+ end
313
336
  end
314
337
 
315
338
  describe 'for a has_and_belongs_to_many association' do
316
339
 
317
340
  before do
318
- @output_buffer = ''
341
+ @output_buffer = ActionView::OutputBuffer.new ''
319
342
  mock_everything
320
343
 
321
344
  concat(semantic_form_for(@freds_post) do |builder|
@@ -325,14 +348,39 @@ describe 'check_boxes input' do
325
348
 
326
349
  it 'should render checkboxes' do
327
350
  # I'm aware these two lines test the same thing
328
- output_buffer.should have_tag('input[type="checkbox"]', :count => 2)
329
- output_buffer.should have_tag('input[type="checkbox"]', :count => ::Author.all.size)
351
+ expect(output_buffer.to_str).to have_tag('input[type="checkbox"]', :count => 2)
352
+ expect(output_buffer.to_str).to have_tag('input[type="checkbox"]', :count => ::Author.all.size)
353
+ end
354
+
355
+ it 'should only select checkboxes that are present in the association' do
356
+ # I'm aware these two lines test the same thing
357
+ expect(output_buffer.to_str).to have_tag('input[checked="checked"]', :count => 1)
358
+ expect(output_buffer.to_str).to have_tag('input[checked="checked"]', :count => @freds_post.authors.size)
359
+ end
360
+
361
+ end
362
+
363
+ describe ':collection for a has_and_belongs_to_many association' do
364
+
365
+ before do
366
+ @output_buffer = ActionView::OutputBuffer.new ''
367
+ mock_everything
368
+
369
+ concat(semantic_form_for(@freds_post) do |builder|
370
+ concat(builder.input(:authors, as: :check_boxes, collection: Author.all))
371
+ end)
372
+ end
373
+
374
+ it 'should render checkboxes' do
375
+ # I'm aware these two lines test the same thing
376
+ expect(output_buffer.to_str).to have_tag('input[type="checkbox"]', :count => 2)
377
+ expect(output_buffer.to_str).to have_tag('input[type="checkbox"]', :count => ::Author.all.size)
330
378
  end
331
379
 
332
380
  it 'should only select checkboxes that are present in the association' do
333
381
  # I'm aware these two lines test the same thing
334
- output_buffer.should have_tag('input[checked="checked"]', :count => 1)
335
- output_buffer.should have_tag('input[checked="checked"]', :count => @freds_post.authors.size)
382
+ expect(output_buffer.to_str).to have_tag('input[checked="checked"]', :count => 1)
383
+ expect(output_buffer.to_str).to have_tag('input[checked="checked"]', :count => @freds_post.authors.size)
336
384
  end
337
385
 
338
386
  end
@@ -340,82 +388,85 @@ describe 'check_boxes input' do
340
388
  describe 'for an association when a :collection is provided' do
341
389
  describe 'it should use the specified :member_value option' do
342
390
  before do
343
- @output_buffer = ''
391
+ @output_buffer = ActionView::OutputBuffer.new ''
344
392
  mock_everything
345
393
  end
346
394
 
347
395
  it 'to set the right input value' do
348
396
  item = double('item')
349
- item.should_not_receive(:id)
350
- item.stub(:custom_value).and_return('custom_value')
351
- item.should_receive(:custom_value).exactly(3).times
352
- @new_post.author.should_receive(:custom_value).exactly(1).times
353
- concat(semantic_form_for(@new_post) do |builder|
354
- concat(builder.input(:author, :as => :check_boxes, :member_value => :custom_value, :collection => [item, item, item]))
355
- end)
356
- output_buffer.should have_tag('input[@type=checkbox][@value="custom_value"]', :count => 3)
397
+ expect(item).not_to receive(:id)
398
+ allow(item).to receive(:custom_value).and_return('custom_value')
399
+ expect(item).to receive(:custom_value).exactly(3).times
400
+ expect(@new_post.author).to receive(:custom_value).exactly(1).times
401
+
402
+ with_deprecation_silenced do
403
+ concat(semantic_form_for(@new_post) do |builder|
404
+ concat(builder.input(:author, :as => :check_boxes, :member_value => :custom_value, :collection => [item, item, item]))
405
+ end)
406
+ end
407
+ expect(output_buffer.to_str).to have_tag('input[@type=checkbox][@value="custom_value"]', :count => 3)
357
408
  end
358
409
  end
359
410
  end
360
-
411
+
361
412
  describe 'when :collection is provided as an array of arrays' do
362
413
  before do
363
- @output_buffer = ''
414
+ @output_buffer = ActionView::OutputBuffer.new ''
364
415
  mock_everything
365
- @fred.stub(:genres) { ['fiction', 'biography'] }
366
-
416
+ allow(@fred).to receive(:genres) { ['fiction', 'biography'] }
417
+
367
418
  concat(semantic_form_for(@fred) do |builder|
368
419
  concat(builder.input(:genres, :as => :check_boxes, :collection => [['Fiction', 'fiction'], ['Non-fiction', 'non_fiction'], ['Biography', 'biography']]))
369
420
  end)
370
421
  end
371
-
422
+
372
423
  it 'should check the correct checkboxes' do
373
- output_buffer.should have_tag("form li fieldset ol li label input[@value='fiction'][@checked='checked']")
374
- output_buffer.should have_tag("form li fieldset ol li label input[@value='biography'][@checked='checked']")
424
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@value='fiction'][@checked='checked']")
425
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@value='biography'][@checked='checked']")
375
426
  end
376
427
  end
377
-
428
+
378
429
  describe 'when :collection is a set' do
379
430
  before do
380
- @output_buffer = ''
431
+ @output_buffer = ActionView::OutputBuffer.new ''
381
432
  mock_everything
382
- @fred.stub(:roles) { Set.new([:reviewer, :admin]) }
383
-
433
+ allow(@fred).to receive(:roles) { Set.new([:reviewer, :admin]) }
434
+
384
435
  concat(semantic_form_for(@fred) do |builder|
385
436
  concat(builder.input(:roles, :as => :check_boxes, :collection => [['User', :user], ['Reviewer', :reviewer], ['Administrator', :admin]]))
386
437
  end)
387
438
  end
388
-
439
+
389
440
  it 'should check the correct checkboxes' do
390
- output_buffer.should have_tag("form li fieldset ol li label input[@value='user']")
391
- output_buffer.should have_tag("form li fieldset ol li label input[@value='admin'][@checked='checked']")
392
- output_buffer.should have_tag("form li fieldset ol li label input[@value='reviewer'][@checked='checked']")
441
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@value='user']")
442
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@value='admin'][@checked='checked']")
443
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label input[@value='reviewer'][@checked='checked']")
393
444
  end
394
445
  end
395
446
 
396
447
  describe "when namespace is provided" do
397
448
 
398
449
  before do
399
- @output_buffer = ''
450
+ @output_buffer = ActionView::OutputBuffer.new ''
400
451
  mock_everything
401
452
 
402
453
  concat(semantic_form_for(@fred, :namespace => "context2") do |builder|
403
454
  concat(builder.input(:posts, :as => :check_boxes))
404
455
  end)
405
456
  end
406
-
457
+
407
458
  it "should have a label for #context2_author_post_ids_19" do
408
- output_buffer.should have_tag("form li label[@for='context2_author_post_ids_19']")
459
+ expect(output_buffer.to_str).to have_tag("form li label[@for='context2_author_post_ids_19']")
409
460
  end
410
461
 
411
462
  it_should_have_input_with_id('context2_author_post_ids_19')
412
463
  it_should_have_input_wrapper_with_id("context2_author_posts_input")
413
464
  end
414
-
465
+
415
466
  describe "when index is provided" do
416
467
 
417
468
  before do
418
- @output_buffer = ''
469
+ @output_buffer = ActionView::OutputBuffer.new ''
419
470
  mock_everything
420
471
 
421
472
  concat(semantic_form_for(@fred) do |builder|
@@ -424,25 +475,25 @@ describe 'check_boxes input' do
424
475
  end)
425
476
  end)
426
477
  end
427
-
478
+
428
479
  it 'should index the id of the wrapper' do
429
- output_buffer.should have_tag("li#author_post_3_authors_input")
480
+ expect(output_buffer.to_str).to have_tag("li#author_post_3_authors_input")
430
481
  end
431
-
482
+
432
483
  it 'should index the id of the input tag' do
433
- output_buffer.should have_tag("input#author_post_3_author_ids_42")
484
+ expect(output_buffer.to_str).to have_tag("input#author_post_3_author_ids_42")
434
485
  end
435
486
 
436
487
  it 'should index the name of the checkbox input' do
437
- output_buffer.should have_tag("input[@type='checkbox'][@name='author[post][3][author_ids][]']")
488
+ expect(output_buffer.to_str).to have_tag("input[@type='checkbox'][@name='author[post][3][author_ids][]']")
438
489
  end
439
-
490
+
440
491
  end
441
-
492
+
442
493
 
443
494
  describe "when collection is an array" do
444
495
  before do
445
- @output_buffer = ''
496
+ @output_buffer = ActionView::OutputBuffer.new ''
446
497
  @_collection = [["First", 1], ["Second", 2]]
447
498
  mock_everything
448
499
 
@@ -453,18 +504,18 @@ describe 'check_boxes input' do
453
504
 
454
505
  it "should use array items for labels and values" do
455
506
  @_collection.each do |post|
456
- output_buffer.should have_tag('form li fieldset ol li label', /#{post.first}/)
457
- output_buffer.should have_tag("form li fieldset ol li label[@for='author_post_ids_#{post.last}']")
507
+ expect(output_buffer.to_str).to have_tag('form li fieldset ol li label', :text => /#{post.first}/)
508
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label[@for='author_post_ids_#{post.last}']")
458
509
  end
459
510
  end
460
511
 
461
512
  it "should not check any items" do
462
- output_buffer.should have_tag('form li input[@checked]', :count => 0)
513
+ expect(output_buffer.to_str).to have_tag('form li input[@checked]', :count => 0)
463
514
  end
464
515
 
465
516
  describe "and the attribute has values" do
466
517
  before do
467
- @fred.stub(:posts) { [1] }
518
+ allow(@fred).to receive(:posts) { [1] }
468
519
 
469
520
  concat(semantic_form_for(@fred) do |builder|
470
521
  concat(builder.input(:posts, :as => :check_boxes, :collection => @_collection))
@@ -472,7 +523,7 @@ describe 'check_boxes input' do
472
523
  end
473
524
 
474
525
  it "should check the appropriate items" do
475
- output_buffer.should have_tag("form li input[@value='1'][@checked]")
526
+ expect(output_buffer.to_str).to have_tag("form li input[@value='1'][@checked]")
476
527
  end
477
528
  end
478
529
 
@@ -487,11 +538,11 @@ describe 'check_boxes input' do
487
538
 
488
539
  it "should have injected the html attributes" do
489
540
  @_collection.each do |v|
490
- output_buffer.should have_tag("form li input[@value='#{v[1]}'][@#{v[2].keys[0]}='#{v[2].values[0]}']")
541
+ expect(output_buffer.to_str).to have_tag("form li input[@value='#{v[1]}'][@#{v[2].keys[0]}='#{v[2].values[0]}']")
491
542
  end
492
543
  end
493
544
  end
494
545
  end
495
-
546
+
496
547
  end
497
548